Yubikeys and SSH

About a year ago I found out that the Yubikey Neo can be used as a SmartCard which can keep a secret key on-board. You can also use an actual SmartCard if you have one. But the setup procedure is quite involved and you need gpg.

Yubikey to the rescue! Or maybe OpenSSH in this case: As this explains, most Yubikeys, including the cheap blue ones which can only do U2F or FIDO2, can work with OpenSSH 8.2 to provide the private key without storing the secret key unencrypted on disk. Similar to using a SmartCard, but much easier.

More important is that those keys are supported by GitHub since May 2021 and GitLab 14.8+ since March 2022.

Create a key:

❯ ssh-keygen -t ecdsa-sk
Generating public/private ecdsa-sk key pair.
You may need to touch your authenticator to authorize key generation.
Enter PIN for authenticator: 
You may need to touch your authenticator (again) to authorize key generation.
Enter file in which to save the key (/home/harald/.ssh/id_ecdsa_sk): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/harald/.ssh/id_ecdsa_sk
Your public key has been saved in /home/harald/.ssh/id_ecdsa_sk.pub
The key fingerprint is:
SHA256:2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx8 harald@m75q
The key's randomart image is:
+-[ECDSA-SK 256]--+
|            .ooo |
|      .*+ . .    |
❯ ls -la .ssh/id_ecdsa_sk*
-rw------- 1 harald users 626 Apr 11 20:35 .ssh/id_ecdsa_sk
-rw-r--r-- 1 harald users 224 Apr 11 20:35 .ssh/id_ecdsa_sk.pub

Once the public key part is added on the target system in its ~/.ssh/authorized_keys file, you can connect to it like this:

❯ ssh -i .ssh/id_ecdsa_sk t621.lan
Confirm user presence for key ECDSA-SK SHA256:2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx8
Welcome to Ubuntu 21.10 (GNU/Linux 5.13.0-39-generic x86_64)

Note that the private key ~/.ssh/id_ecdsa_sk is encrypted by the Yubikey, so this is a complete 2-factor authentication here, plus it checks for the user presence. And the maybe best part: that works on old U2F-only keys as well as new FIDO2 security keys. Love it!

Some FIDO2 keys can store the private key on the key directly which is convenient, but unfortunately less secure. Unlike SmartCards which have a limit for unsuccessful attempts, Yubikeys miss that feature for the U2F/FIDO2 part.

In case of errors…

I found 2 potential problems:

  • ssh-keygen failed with a “Key enrollment failed: invalid format”. If you run ssh-keygen with -vvv, you’ll see a line “debug1: sk_probe: 0 device(s) detected”. What this means is that /dev/hidrawX either does not exist or has the wrong permissions. Default is “0600” and owner is “root:root”.
    • Quick fix: sudo chmod a+rw /dev/hidrawX
    • Better fix: edit /lib/udev/rules.d/60-fido-id.rules and add a ‘, MODE=”0666″‘ to the line which starts with SUBSYSTEM==”hidraw”, then do a sudo udevadm control –reload and when you plug in the Yubikey, /dev/hidrawX will have 0666 permissions.
      You might need to install libyubikey-udev.
    • The above problem is likely only an issue when you do not use a graphical UI. If you log in via a graphical UI, all input devices should be owned by the logged in user.
  • Your OpenSSH version is older than 8.2. Check with “ssh -V”

What about ed25519-sk instead of ecdsa-sk?

ed25519-sk is only supported by FIDO2 Yubikeys keys and possibly not even all of them do depending on the firmware version.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.