If you own a MacBook Pro with Touch Id I highly recommend https://github.com/sekey/sekey. It generates ssh keys in the secure enclave (mini HSM chip) and allows you to login to remote machines with Touch Id. The key can never leave the secure enclave.
That sounds awesome, but isn't that risky? Doesn't that mean you could never make a backup of the key, so if your macbook broke then you'd permanently lose access to whatever the key was protecting?
The solution is not to make backups _of_ a key, but to make backup keys and enroll more than one in authorization lists.
This also helps immensely when you want to retire a key, whether due to loss of control or concerns about its strength in the future. Being in the practice of having a set of authorized keys, you can safely remove older ones from authorization lists without locking yourself out.
I should make a patch instead of wishing, but it'd be nice if there was a ~/.ssh/authorized_keys.d/ directory where you could drop lists of keys, instead of trying to merge in changes to the one file ...
It's kinda ugly, but you could do this by putting `Include config.d/*` at the top of your ~/.ssh/config in order to make ~/.ssh/config.d a thing (LPT: do this anyways; it's a huge quality of life improvement), then dropping in config files to point at keys.
It's a change in mindset to treat SSH keys as unique, non-duplicatable physical objects, but it's very comforting to be able to reason precisely about the whereabouts of a given key.
It does mean you have to get better at keeping your public key lists up to date, so that revoking a key doesn't need a bunch of manual steps. But that's something Ansible/Chef/Puppet are good at.
Unfortunately, Github among other providers are still in the dark ages and don't recognize ssh certificates. You have to install each key as it's issued.
I added SSH agent on ChromeOS support to my CAC/PIV middleware (which supports many platforms), but I have not yet released it. Is anyone interested in testing it out ?
For a different approach (this approach is mentioned briefly at the beginning of the post, and dismissed with "I did not like that very much"), see also drduh's Yubikey guide: https://github.com/drduh/YubiKey-Guide#ssh
Note that the PIV approach used in the OP does not support RSA4096, while the OpenPGP approach does (since Yubikeys support RSA4096 in OpenPGP mode but not in PIV mode).
One upside of PIV-for-SSH rather than GPG-for-SSH is that the Yubikey support for PIV touch requirements / PIN lockouts is more powerful. You can set the PIN to lock after $n fails, and require reset after $n admin PIN fails, and you can set it to require physical touch to auth/sign/etc.
That carries over for SSH: in the most strict touch-mode, a separate touch is required for each authentication attempt. This requirement holds true even if you were to forward your SSH agent to the remote host: SSHing from there to another system would require another physical touch.
I also have configured my Yubikey 4 to require a physical touch for every SSH auth attempt even in GPG-for-SSH. The PIN stuff also carries over to my knowledge -- at least, I need to use my user PIN to unlock my SSH key for the first attempt (subsequent ones require a touch). It's possible that the configuration I am using is not well-known, but it appears to match exactly the PIV case you describe. Except perhaps the n=3 is fixed for GPG-for-SSH (not sure about this) and you think n=/=3 is a valuable configuration option?
(not sure about the SSH agent forwarding as I haven't tested that, would be surprised if it worked without a physical touch)
Basically I don't see the differences you describe in day to day usage at all.
Would you be willing to share the way you've configured the GPG setup?
Definitely curious for making it work like this. The last time I looked at it, I could make it require touch/PIN the first time the GPG key was used, but after it got loaded into gpg-agent, it continued to work for the lifetime of the agent w/o PIN/touch. That said, I'm entirely willing to admit the possibility I missed the right flags to do what I wanted.
I do like n =/= 1 in general (I've provisioned some yubikeys where the person using the key doesn't have the admin PIN, and so I like to give myself a bit more buffer before I have to meet up with them to unlock the key, but for my own keys, n == 3 would be totally fine.
Independent and out of curiosity, do you ever have to
run things like a cmd over ssh in parallel across multiple servers? Just curious to understand if a “long touch” or something that “unlocks” your private key temporarily would be interesting.
Disclaimer: I work on Solo key, we’re thinking to what’s the best way to support ssh.
I don’t do that and it wouldn’t be useful for me personally, but I’m just a single data point.
What's much more important for me is the underlying capabilities -- a key which supports rsa4096 is great, a key which supports curve25519 in some fashion would be incredible.
Was going to post this, less steps needed than op.
I use my yubikeys as ssh keys and it's awesome, id suggest anyone who does should use the "cached" touch policy as you can then connect to many servers within the 15 seconds without having to keep tapping (good for ansible runs!)
Mac users can just brew install opensc but you'll need to link/copy opensc-pkcs11.so into /usr/local/lib
As a heads up, you shouldn't need to copy the opensc-pkcs11 library, you can instead launch ssh-agent with the -P flag to whitelist the library path. I have the following as an alias:
Do you happen to have any tutorial handy that explain the steps needed for a mac os user to set that up?
I have a U2F key from NXP that works very well as a 2nd factor auth for my email account, however, I'm having a really hard time finding documentation on how to use it to store my ssh private key.
I just did `brew install opensc` and though it'd probably magiically work form there, but no luck.
(Editing to point out that this is an elaboration, not a correction. ie here is why this doesn't work)
The things a FIDO token / Security Key knows how to do are not really sufficient to authenticate with SSH public key Auth mode.
Specifically FIDO tokens know how to magically create a new public key and a cookie and promise they can subsequently sign specific messages that prove they know the private key if given back the cookie.
This is a very narrow feature set, deliberately to support the U2F / WebAuthn process only.
Someone could add a completely new SSH Auth method that works with this but the existing SSH public key method requires that you start by claiming "Hey, I know this key, can that work?". Whereas a FIDO token may not (and yours doesn't) even be able to tell anyone which keys it "knows" (because in fact it doesn't really know them at all, they are effectively encrypted inside the cookies it relies on, but only it knows how to decrypt those!).
Question for those who have been using authentication hardware (nitrokeys, yubikeys, titan): are you typically buying in pairs in order to insure against loss/damage, or do you envisage that you would be able to continue to function without significant disruption of the workflow to which use of the hardware has accustomed you?
i recently bought a backup yubikey for this exact reason. I really don't want to go through the pain of having accidentally locked myself out, just because I damaged my keyfob