Why switch to keys
With password logins on, anyone who can reach your server's SSH port can keep guessing. OpenSSH allows them by default: the manual lists the default for PasswordAuthentication as yes. Keys are much harder to guess, and turning passwords off also blocks bugs in the password check itself. This week's OpenSSH flaw on Alpine Linux is an example: Alpine's advisory says servers with password logins switched off are not affected.
You need a user account on the server that you can already reach, with permission to use sudo or doas.
1. Create a key on your computer
Run this on your own computer, not on the server:
ssh-keygen -t ed25519
Press Enter to accept the usual location and type a passphrasea password that protects the key file itself, so a stolen copy of the file is not enough to log in. You get two files in the .ssh folder of your home directory: id_ed25519, the private key, which never leaves your computer, and id_ed25519.pub, the public key, which goes on the server.
2. Copy the public key to the server
On Linux and macOS:
ssh-copy-id user@server
It asks for your password one last time and adds the key to ~/.ssh/authorized_keys on the server. If ssh-copy-id is not available, for example on Windows, open id_ed25519.pub, copy its single line, and paste it into ~/.ssh/authorized_keys on the server. The .ssh folder should be readable only by you (chmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys).
3. Test the key before changing anything
Keep your current session open. In a new terminal window, run ssh user@server. If it asks for your key's passphrase, or logs you straight in, the key works. If it asks for the account password, stop and fix the key first, or you will lock yourself out in the next step.
4. Turn password logins off
On the server, add these two lines to the SSH server settings, either in /etc/ssh/sshd_config or in a new file in /etc/ssh/sshd_config.d/ if your system uses that folder:
PasswordAuthentication no
KbdInteractiveAuthentication no
The second line closes the other password-style method, keyboard-interactivea login method in which the server asks questions, usually the password, through a prompt; the old name for the setting is ChallengeResponseAuthentication. For the root account, the OpenSSH default, PermitRootLogin prohibit-password, already blocks password logins.
There is one trap. The manual says that for each setting, "the first obtained value will be used". Some systems, including some cloud images, ship their own file in sshd_config.d that sets PasswordAuthentication yes, and if that file is read first, your line has no effect. Step 6 shows how to catch that.
5. Check the file and restart the service
Run sudo sshd -t. It checks the configuration and prints nothing if it is valid. Then restart the SSH service:
- Debian and Ubuntu:
sudo systemctl restart ssh - Fedora, Red Hat and similar:
sudo systemctl restart sshd - Alpine:
rc-service sshd restart
Keep your old session open until you have finished the next step.
6. Make sure it worked
On the server, run:
sudo sshd -T | grep -i -E 'passwordauthentication|kbdinteractiveauthentication'
sshd -T prints the settings sshd will really use. Both lines should end in no. If one says yes, look in /etc/ssh/sshd_config.d/ for a file that sets it earlier.
From your computer, try to force a password login:
ssh -o PubkeyAuthentication=no user@server
The server should refuse with "Permission denied (publickey)". Your normal ssh user@server should still work with the key.
If something goes wrong
If you lose access, use the console that your hosting provider or virtual machine software offers, undo the change, and restart the SSH service. That is why the old session stays open until the end. Keep a copy of your private key somewhere safe: if you lose the only copy, you will need that console to add a new public key.
Sources
Primary sources we checked for this article: