ssh keys done right
SSH lets you log in to a remote machine over an encrypted connection. Passwords work, but keys are stronger and more convenient. Here is how they work and how to set them up properly.
what happens when you connect
client server | | | 1. key exchange (ml-kem + x25519) | |----------------------------------------->| |<-----------------------------------------| | both now share a secret | | | | 2. host key + signature | |<-----------------------------------------| | client checks ~/.ssh/known_hosts | | | | 3. user public key + signature | |----------------------------------------->| | server checks authorized_keys | | | |<=========== 4. encrypted session =======>|
Your private key never crosses the network. You prove you hold it by signing data that is unique to this session, and the server checks the signature against the public key in authorized_keys.
The first time you connect, SSH shows the server's host key fingerprint and asks you to confirm it. This is trust on first use. If that key changes later, SSH refuses loudly. That can mean a reinstalled server, or someone in the middle.
make a key
ssh-keygen -t ed25519 -C "laptop"
~/.ssh/id_ed25519 private key, never share it ~/.ssh/id_ed25519.pub public key, give it out freely
Use Ed25519: it is fast, small and hard to get wrong. Set a passphrase, which encrypts the private key on disk, and let ssh-agent hold it so you only type it once per session.
put it on a server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host ssh user@host
lock the server down
Once key login works, turn off passwords in /etc/ssh/sshd_config:
PasswordAuthentication no KbdInteractiveAuthentication no PermitRootLogin prohibit-password
Reload the SSH service, and keep your current session open until a new login works.
going further
ssh-keygen -t ed25519-skkeeps the private key on a FIDO2 hardware key- ssh certificates: sign user keys with a CA instead of copying them to every server
~/.ssh/config: short host names and a key per host- OpenSSH 10 uses the post-quantum hybrid
mlkem768x25519-sha256key exchange by default