Hacker News new | ask | show | jobs
by anthonyryan1 182 days ago
One approach I started using a could of years ago was storing SSH private keys in the TPM, and using it via PKCS11 in SSH agent.

One benefit of Microsoft requiring them for Windows 11 support is that nearly every recent computer has a TPM, either hardware or emulated by the CPU firmware.

It guarantees that the private key can never be exfiltrated or copied. But it doesn't stop malicious software on your machine from doing bad things from your machine.

So I'm not certain how much protection it really offers on this scenario.

Linux example: https://wiki.gentoo.org/wiki/Trusted_Platform_Module/SSH

macOS example (I haven't tested personally): https://gist.github.com/arianvp/5f59f1783e3eaf1a2d4cd8e952bb...

1 comments

Or use a FIDO token to protect your SSH key, which becomes useless without the hardware token.

https://wiki.archlinux.org/title/SSH_keys#FIDO/U2F

That's what I do. For those of us too lazy to read the article, tl;dr:

  ssh-keygen -t ed25519-sk
or, if your FIDO token doesn't support edwards curves:

  ssh-keygen -t ecdsa-sk
tap the token when ssh asks for it, done.

Use the ssh key as usual. OpenSSH will ask you to tap the token every time you use it: silent git pushes without you confirming it by tapping the token become impossible. Extracting the key from your machine does nothing — it's useless without the hardware token.

Except that an attacker can modify the ssh config to enable session multiplexing with a long timeout and then piggy-back off that connection, right?
Looks like on the server side this can be mitigated somewhat by the MaxStartups¹ setting for OpenSSH or equivalent behavior for other services that support SSH auth (e.g., Git forges like GitHub):

  MaxStartups
               Specifies the maximum number of concurrent unauthenticated
               connections to the SSH daemon.  Additional connections
               will be dropped until authentication succeeds or the
               LoginGraceTime expires for a connection.  The default is
               10:30:100.

               Alternatively, random early drop can be enabled by
               specifying the three colon separated values
               start:rate:full (e.g. "10:30:60").  sshd(8) will refuse
               connection attempts with a probability of rate/100 (30%)
               if there are currently start (10) unauthenticated
               connections.  The probability increases linearly and all
               connection attempts are refused if the number of
               unauthenticated connections reaches full (60).
So it looks like it's possible to support ControlMaster while still somewhat hampering mass-cloning thousands of repos via SSH key without reauthenticating.

Admittedly I'd put this more in the category of making endpoint compromise easier to detect than that of actually preventing any particular theft of data or manipulation of systems. But it might still be worth doing! If it means only a few dozen or only a hundred repos get compromised before detection instead of a few thousand, that's a good thing.

Besides all that (or MaxSessions, as another user mentions), if an attacker compromises a developer laptop and can only open those connections as long as the developer is online, that's one thing. But a plaintext key that they can grab and reuse from their own box is obviously an even sweeter prize!

"The SSH key on my YubiKey is useless to attackers" is obviously the wrong way to think about this, but using a smartcard for SSH keys is still a way to avoid storing plaintext secrets. It's good hygiene.

--

https://www.man7.org/linux/man-pages/man5/sshd_config.5.html

Are you saying that because there are still more complicated potential attacks hardware tokens offer zero benefits?

Anyway, what about the sshd server having this config line:

    sshd_config MaxSessions 1
could that help?