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