A Yubikey for SSH, GPG, and Sudo

One small key that turns your secrets into something you can't accidentally copy

Contents

Every private key on your laptop shares one fatal property: it is a file. Files get copied. If malware runs as your user, or a backup lands somewhere it shouldn’t, or someone walks off with the disk, your SSH private key goes with it, and a passphrase only buys you the time it takes to brute-force. The whole class of problem comes from the secret being extractable. A hardware token removes that property. The private key is generated inside a tamper-resistant chip and physically cannot leave it. The token will use the key to sign a challenge, but it will never hand the key over, to you or to anyone who steals your machine.

I moved my SSH, GPG and sudo authentication onto a YubiKey a while back, and the day-to-day experience turned out to be better than I expected — a tap to log in, a tap to sign a commit, and a smug little glow whenever I read about someone’s exfiltrated keys. Here is how the three pieces fit together, why each one is worth doing, and where the sharp edges are.

Why a hardware key beats a file

Advertisement

A private key file protects you against an attacker who can guess your passphrase. It does nothing against an attacker who already has code running as you, because that attacker can read the file and log your keystrokes as you type the passphrase to unlock it. This is the ordinary case for a compromised laptop, and it is exactly the case a file cannot survive.

The token changes the shape of the attack. To use a hardware-bound key, an attacker needs the physical device and your PIN, and the device wipes its secrets after a handful of wrong PIN attempts. Remote theft of the key becomes impossible because there is nothing to steal — the bytes never exist outside the chip. Most tokens go further and require a physical touch to authorise each operation, so even with the device plugged in, malware cannot silently sign a thousand things while you make tea. It gets one signature per deliberate tap.

That is the entire pitch. You trade a small amount of convenience (you must carry the thing, and buy a spare) for making key theft a hands-on physical crime instead of a quiet remote copy. For anything that guards access to your infrastructure, that trade is worth making.

SSH with a FIDO2 resident key

The simplest of the three to set up is SSH, thanks to the -sk key types that OpenSSH gained in version 8.2. These generate a keypair where the private half lives on the token and only a small “key handle” lives on disk. Generate one like this:

1
2
3
4
5
$ ssh-keygen -t ed25519-sk -O resident -O verify-required -C "laptop-yubikey"
Generating public/private ed25519-sk key pair.
You may need to touch your authenticator to authorize key generation.
Enter PIN for authenticator:
Enter file in which to save the key (~/.ssh/id_ed25519_sk):

Two options earn their keep here. resident stores the key handle on the token itself, so you can walk up to any machine and pull your key down with ssh-keygen -K — handy when your laptop dies. verify-required forces a PIN entry in addition to the physical touch, which means a stolen-and-plugged-in token is still useless without the PIN.

The public key that drops out goes into authorized_keys on your servers exactly like any other. When you connect, the server sends a challenge, OpenSSH passes it to the token, the token blinks, you tap, and you are in. The private key never touches the wire or the disk of the machine you are typing on.

If a server runs an OpenSSH older than 8.2 it won’t understand the sk key type, so keep a conventional key as a fallback for those, or upgrade them. And if you use an SSH agent, load the handle once with ssh-add ~/.ssh/id_ed25519_sk so you are not fishing for the PIN on every hop.

GPG on the smartcard

Advertisement

GPG is the fiddliest of the three and the most rewarding once it clicks, because a YubiKey speaks the OpenPGP smartcard protocol natively. The plan is to generate your keys, move the private subkeys onto the card, and delete the on-disk copies so the only place they exist is the hardware.

The critical discipline is your master key. Generate it, use it to certify your subkeys, then take it offline — onto an encrypted USB stick kept in a drawer — and never let it near a networked machine again. The card holds three subkeys for the daily work: sign, encrypt, and authenticate. If the card is lost you revoke the subkeys with the master and issue new ones; your identity survives.

1
2
3
4
5
6
7
8
$ gpg --card-status          # confirm the token is seen as a smartcard
$ gpg --expert --edit-key YOUR_KEY_ID
gpg> key 1                   # select the signing subkey
gpg> keytocard               # move it onto the card
gpg> key 1                   # deselect
gpg> key 2                   # encryption subkey
gpg> keytocard
gpg> save

keytocard moves the secret onto the device and, after you save, replaces the on-disk secret with a stub that says “this key lives on card serial number X”. From then on any signing or decryption prompts for the card and a touch.

The immediate payoff for a homelab is signed git commits that are genuinely yours, because the signing key cannot be exfiltrated from a compromised laptop. Point git at it and every commit carries a signature no one can forge without your physical token:

1
2
git config --global user.signingkey YOUR_SIGNING_SUBKEY_ID
git config --global commit.gpgsign true

A second payoff is that the same GPG authentication subkey can drive SSH via gpg-agent’s SSH support, if you would rather have one key type do everything. I keep the FIDO2 route for SSH because it is simpler, but the option is there.

This dovetails neatly with keeping your other secrets off disk. Once you are comfortable with the card doing your signing, managing the rest of your secrets with SOPS and age follows the same instinct: the sensitive material lives encrypted or in hardware, never in plain text in a repo or a dotfile.

Sudo and login with pam-u2f

The third piece asks the token for a touch whenever you sudo or log in, using the pam-u2f module. Install it, register your key, then wire it into PAM. Registration writes a mapping of your username to the token’s credential:

1
2
3
4
$ sudo apt install libpam-u2f
$ mkdir -p ~/.config/Yubico
$ pamu2fcfg > ~/.config/Yubico/u2f_keys
# touch the key when it blinks

Now add the module to the relevant PAM stack. For sudo that is /etc/pam.d/sudo:

1
2
3
4
# require a Yubikey touch in addition to the password
auth   required   pam_u2f.so   authfile=/etc/security/u2f_keys cue

# ...existing lines below

required makes the touch mandatory, so sudo now needs your password and a tap. If you would rather the touch replace the password entirely, use sufficient and put it above pam_unix.so. The cue option prints a “please touch the device” prompt so you are not left staring at a hung terminal wondering why nothing is happening.

Two safety rules are non-negotiable here. Register a second YubiKey and add its line to the same u2f_keys file, because the day your only token dies is the day you are locked out of sudo on every box. And move the file to a root-owned path like /etc/security/u2f_keys referenced with authfile=, so a user cannot edit their own mapping to add an attacker’s key.

Troubleshooting

“Sign_and_send_pubkey: signing failed for … agent refused operation”. Your SSH agent is holding a stale handle, or verify-required wants a PIN the agent can’t supply non-interactively. Restart the agent, re-add the key, and make sure a PIN-entry program (pinentry) is installed and reachable.

GPG can’t see the card. The two usual culprits are scdaemon wedged in a bad state or pcscd fighting it for the device. gpgconf --kill scdaemon and unplug/replug the token clears most cases. If you also run pcscd for other smartcard uses, the two can deadlock over exclusive access — pick one owner for the device.

Locked out of sudo after editing PAM. This is why you keep a root shell open in another terminal before touching /etc/pam.d/sudo. If you skipped that and locked yourself out, boot to single-user mode or a rescue environment and revert the file. Test PAM changes with a throwaway session first, every time.

Touch never registers. Some tokens distinguish a short tap from a long hold, and some operations need one where you are giving the other. If a blink times out, try holding for a full second. Persistent failures usually mean a udev rules issue — the non-root user can’t access the USB device — fixed by installing your distro’s libu2f-udev package and replugging.

PIN locked after wrong attempts. The card blocks the PIN after three wrong tries and the admin PIN after three more. ykman openpgp access can reset it if you still have the admin PIN or the reset code; lose both and the OpenPGP applet must be wiped and re-provisioned from your offline master. This is the entire reason the master key lives on that USB stick in the drawer.

Is it worth it?

For a laptop that holds the keys to your homelab, yes, and it is not close. The threat a hardware token neutralises — silent remote theft of your private keys by anything running as you — is the single most damaging thing that can happen to your credentials, and no passphrase or file permission defends against it. Moving those keys into a chip that will not surrender them turns that disaster into a physical burglary, which is a far rarer and far harder crime.

The honest costs are real. You must buy two keys, not one, and treat the spare as seriously as the primary. GPG in particular has a learning curve steep enough that I would not recommend starting there — begin with FIDO2 SSH, which you can have working in ten minutes, live with it for a week, and add sudo and GPG once the workflow feels natural. Keep your offline master key backed up and your recovery path tested, because a hardware token turns “I forgot my passphrase” into “I lost my only key”, and the second is worse if you didn’t plan for it.

This is one of the higher-leverage security changes available to a single person running their own infrastructure, and it pairs well with the rest of the stack — a token for your identity, SOPS and age for your data secrets, and a threat model to tell you which of your keys are actually worth this much care. Buy the pair, start with SSH, and enjoy the small green blink.

Advertisement
Advertisement
Smarc
Written by Smarc

Founder and editor of vo.rs. A lifelong tinkerer who self-hosts far more than is sensible, hardens Linux boxes for fun, and prods the latest AI tools to see what they can really do. The how-to guides here are the notes Smarc wishes had existed the first time round.