YubiKey for SSH, Sudo, and Everything Else
One piece of metal, most of your authentication, and the drawer full of regrets

Contents
I have owned a hardware security key for years, and for most of the first one I used it to log into exactly one website. It lived in a drawer with the USB-C adapters and the mini-DisplayPort dongles, which is a fair description of where most of them end up. The thing that changed was mundane: I realised that the same twenty-five quid lump of metal could be the second factor for my SSH access, my sudo prompts, my disk encryption, and my password manager — all at once, all with the same tap — and that I had been treating a general-purpose cryptographic device as a single-purpose website gadget.
This is the sweep I wish someone had handed me at the start: what the device actually is, what each of its personalities does, and which of the advertised uses are genuinely worth the setup time. I will also be honest about the parts that are irritating, because there are several, and the backup-key problem in particular is the one that bites people six months in when they are standing in front of a machine that will not let them in.
Why hardware, before how
The argument for a hardware key is narrow and it is worth stating precisely rather than gesturing at “it’s more secure”. A private key sitting in ~/.ssh/id_ed25519 is a file. Files get read. Any process running as your user can read it, any backup tool can copy it, any malicious npm install postinstall script can exfiltrate it while you are reading the changelog. A passphrase helps, but only until you type it, at which point ssh-agent holds the decrypted material in memory for the rest of the session and anything that can attach to your agent socket can use it.
A hardware key changes the shape of that problem. The private key material is generated inside the device and never leaves it. Software asks the device to sign a challenge; the device signs and hands back the signature. Malware on your laptop can ask for signatures while the key is plugged in, which is a real and under-discussed limitation — but it cannot copy the key and use it next Tuesday from a machine in a different country. You have converted an indefinite compromise into a compromise bounded by physical presence. Add the touch requirement and you bound it further: each signature needs a finger on the contact.
That is the whole pitch. It is not “unhackable”. It is “the secret cannot be stolen remotely, and each use requires a human”. For a homelab, where the realistic threat is a stolen laptop or a supply-chain nasty rather than a nation state, that covers most of what I actually worry about. I sketched the broader version of that reasoning in a homelab threat model, and hardware keys sit squarely in the “cheap mitigation for a plausible attack” quadrant.
The four personalities in one device
The single most confusing thing about these keys is that one device presents several unrelated applications, each with its own history, its own tooling, and its own failure modes. Knowing which one you are talking to explains about eighty per cent of the errors you will hit.
FIDO2/WebAuthn is the modern one. It handles browser logins and, since OpenSSH 8.2, SSH keys of type ed25519-sk. This is the personality you want for almost everything new.
PIV is a smartcard standard, originally a US federal identity spec, and it gives you certificate slots that work with anything speaking PKCS#11. Useful when something refuses to speak FIDO2 — some VPN clients, some enterprise kit.
OpenPGP is a separate applet with its own PIN and its own three key slots (sign, encrypt, authenticate). It can also do SSH via gpg-agent, which is how people did hardware-backed SSH before ed25519-sk existed. It works. It is also a lot of machinery.
OTP is the old one: the long string of characters the key types when you touch it, plus TOTP storage. Mostly legacy, though the TOTP side is a decent alternative to keeping your codes in an app on the same phone you use to log in. I compared that trade-off in TOTP and WebAuthn.
My advice, unequivocally: use FIDO2 for everything it can do, and only fall back to PIV or OpenPGP when something genuinely refuses. The GPG path in particular is a tar pit of agent socket forwarding, gpg-connect-agent updatestartuptty, and mysterious “card not present” errors that resolve themselves when you unplug and replug. Life is short.
SSH, the part that actually pays for the device
This is the use that justifies the purchase. Generate a key whose private half lives on the token:
| |
Three flags matter. -t ed25519-sk makes it a FIDO2-backed key — the -sk suffix means “security key”. -O resident stores the credential on the device, meaning you can walk up to a fresh machine and pull your keys back out with ssh-keygen -K; without it, the file on disk is a required handle and losing it loses the key. -O verify-required demands the device PIN in addition to the touch, which turns a stolen key from an immediate problem into a bounded one — the device locks itself after eight wrong PIN attempts.
What lands on disk is a stub. The id_ed25519_sk file contains a key handle and a reference to the device, and it is useless on its own. You can back it up to a USB stick with no drama, which is a pleasant novelty after years of treating private keys like radioactive material.
The experience day-to-day: you type ssh [email protected], the prompt says Confirm user presence for key ED25519-SK, you tap, you are in. The delay is under a second. Connection multiplexing means a long working session only asks once:
| |
IdentitiesOnly yes matters more than it looks. Without it, ssh offers every key the agent knows about before reaching yours, and if you have more than five you will hit the server’s MaxAuthTries and get a confusing “Too many authentication failures” that has nothing to do with the hardware.
The one requirement worth checking before you commit: every server you connect to needs OpenSSH 8.2 or newer to understand ed25519-sk public keys. Anything shipped since 2020 is fine. That ancient box in the corner running an LTS from 2018 is not, and it will reject the key with an unhelpful error. Keep a passphrase-protected software key for that one machine and plan its retirement. I go deeper on the -sk key type specifically in FIDO2 SSH keys.
Sudo, which is nicer than expected
pam-u2f lets the same key satisfy a sudo prompt. The setup is short, and the danger is real, so read the whole section before running anything.
| |
Then edit /etc/pam.d/sudo and add one line above the existing @include common-auth:
| |
cue prints “Please touch the device” so you are not staring at a silent terminal wondering if it has hung. required means the touch is mandatory in addition to your password — that is what you want. Using sufficient instead makes the touch replace your password entirely, which sounds convenient and means anyone who picks up your unlocked laptop with the key inserted has root. I do not do that.
Now the part that saves your afternoon. Keep a second terminal open with an active root session while you test this. A typo in a PAM file can lock you out of privilege escalation entirely, and the recovery is a reboot into recovery mode. Open a second window, run sudo -i, leave it there, and only then test in the first window. If it breaks, you fix /etc/pam.d/sudo from the session you kept.
One more caution: the u2f_keys file lives in your home directory, so if /home is on a separate encrypted volume that mounts late, or you are on NFS, PAM may not be able to read it at the moment it matters. Move it to /etc/u2f_mappings and point at it with authfile=/etc/u2f_mappings if you hit that.
Disk encryption and the rest
systemd-cryptenroll can bind a LUKS volume to a FIDO2 token, which replaces typing a long passphrase at every boot with a tap:
| |
Add fido2-device=auto to the relevant line in /etc/crypttab and rebuild your initramfs. Crucially, do not remove your passphrase slot. The token becomes a convenience layer over a passphrase that still works; a LUKS header with only a hardware enrolment is a data-loss event waiting for you to lose the hardware. For a headless machine this is the wrong tool entirely — nobody is standing there to tap — and the remote unlock approach is what you want instead.
The browser side needs no explanation: register it on your email provider, your registrar, your Git forge, and your password manager. Registering it on the registrar is the one people skip and the one that matters most, because domain control is how everything else gets unwound. And if you self-host Vaultwarden, FIDO2 as the second factor on the admin account is fifteen minutes well spent.
Troubleshooting the errors you will actually see
sign_and_send_pubkey: signing failed for ED25519-SK ... device not found — on Linux this is nearly always udev. The device exists but your user cannot open it. Install libfido2 and check that a rules file grants your user access to the hidraw node; log out and back in afterwards, because group membership does not apply to your existing session.
Key enrollment failed: invalid format — your OpenSSH is older than 8.2, or libfido2 is missing. Check with ssh -V.
The touch prompt appears twice. You have both ssh-agent and a desktop agent (GNOME Keyring, commonly) racing for the same key. Pick one. echo $SSH_AUTH_SOCK tells you who won.
Nothing happens at all and the key does not flash. Try a different port and a different cable. I have lost more time to a charge-only USB-C cable than to any cryptographic subtlety in this entire stack.
ssh-keygen -K returns nothing on a new machine. Your key was not created with -O resident. The credential exists only as the handle file you no longer have. This is unrecoverable, which is the whole argument for -O resident.
The backup key problem
Here is the part that gets glossed over. A hardware key can be lost, left in a hotel-room laptop, or simply fail. If it is the only thing standing between you and every account you own, losing it is a catastrophe with no undo.
Buy two. Enrol both, everywhere, at the same time — the same evening, in the same sitting, going down a written list. The second one lives somewhere physically separate: a safe, a drawer at a family member’s house, wherever you will not accidentally carry both in the same bag. Every service you register the primary on, register the secondary on immediately. The failure mode is not “I forgot to buy a spare”; it is “I bought a spare and enrolled it on four of my eleven services, and the seven it missed are the ones I needed”.
Keep the recovery codes too, printed, on paper, somewhere sensible. A hardware key protects against remote theft. Paper in a drawer protects against you.
Is it worth it?
For SSH: yes, without hesitation. Twenty minutes of setup, a tap per connection, and your homelab’s front door key becomes something that cannot be copied off your laptop by a compromised dependency. That is the best security-per-effort trade in this whole article.
For sudo: yes, with the caveat that you must test it with a root session open. The touch is a genuine speed bump against someone at your unlocked machine.
For LUKS on a laptop: sure, as a convenience layer over a passphrase you keep. For headless machines: no.
For GPG: only if you already live in GPG. Do not adopt it to get hardware SSH — ed25519-sk does that better with a tenth of the machinery.
Who should skip it: if you have one server and one laptop and a passphrase-protected key, the marginal gain is small. The value scales with the number of machines and the number of people who could plausibly get code running on your laptop. Somewhere around five machines and one npm-heavy side project, the maths tips. That is roughly where I was when the key came out of the drawer, and it has not gone back in.




