YubiKey: SSH with FIDO2
The YubiKey supports four methods to enable hardware-backed SSH authentication.
- FIDO2
- PIV
- PGP
- OTP
FIDO2 provides the highest security and comes with low complexity. The private key is non-exportable.
Limitations
OpenSSH v 8.2.p1 is a requirement better 8.3 for the verify-required option, shouldn’t be an issue since both versions were released in 2020.
Windows SSH at the time of writing not supported.
The Mac OS bundled openssh version doesn’t support it but this can be fixed.
Configuration
Generate ed25519-sk keys
In a Enterprise enviroment you would add -O verify-required to make use of your fido pin additionaly to the touch
I get prompted for my existing fido2 pin this is only for the setup. The Password can stay empty this is only for the key handle file. If you set password you will be prompted for the password what adds no additional security
My default ssh slot is already used a different slot can be be used by supplying application=ssh:bitlex-homelab
ssh-keygen -t ed25519-sk -O resident -O application=ssh:bitlex-homelab -C "slexi@bitlex.li"
Generating public/private ed25519-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/slexi/.ssh/id_ed25519_sk): /home/slexi/.ssh/bitlex-homelab_ed25519_sk
Enter passphrase for "/home/slexi/.ssh/bitlex-homelab_ed25519_sk" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/slexi/.ssh/bitlex-homelab_ed25519_sk
Your public key has been saved in /home/slexi/.ssh/bitlex-homelab_ed25519_sk.pub
The key fingerprint is:
SHA256:C0rn46hCkoTODRdrPnin6lPTe6Eh8sd5dfouoMgP6r8 slexi@bitlex.li
@slexi ls bitlex*
bitlex-homelab_ed25519_sk # = Key Handle file this file must be present to initiate authentication, but is useless without the yubikey
bitlex-homelab_ed25519_sk.pub # = public key
The private is on the yubikey.
Configure ssh-agent socket
Enable and start the ssh-agent for my user
systemctl --user enable --now ssh-agent
Read the service definition
@slexi systemctl --user cat ssh-agent.service
# /usr/lib/systemd/user/
ssh-agent.service
# Requires SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket" to be set in envi
ronment
[Unit]
ConditionEnvironment=!SSH_AGENT_PID
Description=OpenSSH key agent
Documentation=man:ssh-agent(1) man:ssh-add(1) man:ssh(1)
Requires=ssh-agent.socket
[Service]
ExecStart=/usr/bin/ssh-agent -D
SuccessExitStatus=2
Type=simple
[Install]
Also=ssh-agent.socket
On Arch, I added the socket shown above to my shell configuration.
export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"
SSH-Agent configuration
The .ssh/config defines how we connect to the server.
We tell the ssh-agent to pick up our key handle file to initiate a connection and optionally set the user.
.ssh/config
Host <destination-server>
IdentityFile ~/.ssh bitlex-homelab_ed25519_sk
IdentitiesOnly yes
User debian
Destination Server configuration
Put the pub-key in .ssh/authorized_keys on the destination server can be done with
ssh-copy-id -i ~/.ssh/bitlex-homelab_ed25519_sk.pub <user>@<destination-server>
Test it
ssh <ip/hostname>
Additional
On a new machine, the key file can be extracted from the YubiKey, which will prompt you for your FIDO2 PIN.
ssh-keygen -K
To calculate the pub key again
ssh-keygen -y -f ~/.ssh/bitlex-homelab_ed25519_sk > ~/.ssh/bitlex-homelab_ed25519_sk.pub
References
https://developers.yubico.com/SSH/
https://amboar.github.io/notes/2023/05/01/sshd-fido2-touch-required.html