SSH key and config helper

Set up SSH key login step by step: create the key, copy it, get a short ssh name, then switch off passwords safely.

Last updated

In short: Create an Ed25519 key with ssh-keygen -t ed25519 -a 100 and a passphrase, copy it to the server with ssh-copy-id -i ~/.ssh/key.pub user@server, and test that it logs you in without the server password. Add a Host block to ~/.ssh/config so ssh homeserver is enough. Only then set PasswordAuthentication no in /etc/ssh/sshd_config.d/, check with sudo sshd -t and reload, keeping your current session open.

Your input never leaves your browser. Everything is calculated on your device; nothing you type is sent to a server.

Key type
The server
The key file
Server hardening (step 6)

Step 1: create the key pair (on your own computer)

ssh-keygen asks for a passphrase: use one. It encrypts the private key file, so a stolen laptop or leaked backup does not open your server. With the ssh-agent you type it once per session, not at every login.

mkdir -p -m 700 ~/.ssh
ssh-keygen -t ed25519 -a 100 -C me@laptop -f ~/.ssh/id_ed25519_homeserver
mkdir -p -m 700 ~/.ssh
Creates your SSH folder if needed, readable only by you.
-t ed25519
Ed25519: short keys, fast, and no weak settings to get wrong. Supported by OpenSSH since 6.5 (2014), so by every current server.
-a 100
Runs the passphrase through 100 rounds of bcrypt instead of the default 16, which makes guessing the passphrase of a stolen key much slower.
-C me@laptop
A label stored with the public key, so you can tell keys apart later in the server's authorized_keys file.
-f ~/.ssh/id_ed25519_homeserver
Saves the private key as ~/.ssh/id_ed25519_homeserver (never share it) and the public key as ~/.ssh/id_ed25519_homeserver.pub (safe to copy anywhere).

Step 2: put the public key on the server

This logs in with your password one last time and adds the public key to ~/.ssh/authorized_keys on the server. The first time you connect, ssh shows the server's fingerprint and asks whether to trust it: compare it with the output of ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub on the server's own console, then type yes.

ssh-copy-id -i ~/.ssh/id_ed25519_homeserver.pub admin@192.168.1.10
-i ~/.ssh/id_ed25519_homeserver.pub
Copies only this public key, not every key you have.
No ssh-copy-id (Windows)?
Run this instead in Git Bash or WSL: cat ~/.ssh/id_ed25519_homeserver.pub | ssh admin@192.168.1.10 'mkdir -p -m 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'

Step 3: test that the key works

This refuses every login method except the key, so it proves the key alone gets you in. It may ask for the key's passphrase (that is fine) but must never ask for the server password. Type exit to leave.

ssh -i ~/.ssh/id_ed25519_homeserver -o IdentitiesOnly=yes -o PreferredAuthentications=publickey admin@192.168.1.10
-o IdentitiesOnly=yes
Offers only this key, not others from the ssh-agent.
-o PreferredAuthentications=publickey
Allows key login only: if the key is not accepted you get Permission denied (publickey) instead of a password prompt.

Step 4: a short name in ~/.ssh/config

Add this block to the file. Afterwards ssh homeserver is enough, and scp, rsync and editors with remote SSH understand the name too.

Save as ~/.ssh/config

Host homeserver
    HostName 192.168.1.10
    User admin
    Port 22
    IdentityFile ~/.ssh/id_ed25519_homeserver
    IdentitiesOnly yes
    AddKeysToAgent yes
Host homeserver
The short name you type. The indented lines below it apply only to this name.
HostName 192.168.1.10
The real address of the server.
User admin
The user name on the server, so you can leave out user@.
Port 22
The SSH port; 22 is the default, written out so it is easy to change later.
IdentityFile ~/.ssh/id_ed25519_homeserver
The private key to use for this server.
IdentitiesOnly yes
Offers only that key. Without it, ssh tries every key in the agent first, and servers stop after a few tries with 'Too many authentication failures'.
AddKeysToAgent yes
After you type the passphrase once, the key stays unlocked in the ssh-agent for the rest of your session.

Step 5: save the config and connect

In nano, paste with Ctrl+Shift+V, save with Ctrl+O and Enter, and exit with Ctrl+X.

touch ~/.ssh/config
chmod 600 ~/.ssh/config
nano ~/.ssh/config
ssh homeserver
touch ~/.ssh/config
Creates the file if it does not exist yet; an existing file is left as it is.
chmod 600 ~/.ssh/config
ssh refuses a config file that other users can write to ('Bad owner or permissions').
ssh homeserver
Connects with all the settings from the Host block.

Step 6: turn off password logins (on the server)

Warning: Only do this after step 3 logged you in with the key. If key login does not work and passwords are off, you are locked out and need the server's own screen and keyboard (or your provider's console) to get back in. Keep your current SSH session open until the new login is tested.

Save as /etc/ssh/sshd_config.d/10-key-only.conf

# Key-only SSH logins. Enable only after key login was tested.
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
Allows key logins (the default, written out to be sure).
PasswordAuthentication no
Refuses password logins, which stops password-guessing bots completely.
KbdInteractiveAuthentication no
Closes the other way passwords get in: keyboard-interactive login through PAM, which openSUSE and others use. It was called ChallengeResponseAuthentication before OpenSSH 8.7.
PermitRootLogin no
root cannot log in over SSH at all; log in as your own user and use sudo.

Step 7: check, apply and test the new login

sshd uses the first value it finds for each setting, and most distributions read /etc/ssh/sshd_config.d/ before the rest of the main file; the 10- prefix makes this file win over others such as 50-cloud-init.conf on Ubuntu cloud images. Keep your current session open while you run the last two commands.

sudo nano /etc/ssh/sshd_config.d/10-key-only.conf
sudo sshd -t
sudo sshd -T | grep -Ei '^(pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication|permitrootlogin|allowusers)'
sudo systemctl reload sshd
ssh homeserver
ssh -o PubkeyAuthentication=no homeserver
sudo sshd -t
Checks the whole configuration for mistakes. No output means it is valid; never reload after an error here.
sudo sshd -T | grep ...
Prints the settings sshd really uses. Expect passwordauthentication no. If it still says yes, your sshd_config has no Include line for sshd_config.d, or an earlier file sets it: put the lines at the top of /etc/ssh/sshd_config instead.
sudo systemctl reload sshd
Applies the change; open sessions stay connected. The service is called sshd on openSUSE, Fedora, RHEL and Arch.
ssh homeserver
A new login with the key must still work. Only close your old session after this succeeds.
ssh -o PubkeyAuthentication=no homeserver
Must now fail with Permission denied (publickey), which proves passwords are refused.

Next: open only the ports you need with the firewalld port helper, or use the new key for nightly copies with the backup command builder.

Review generated files before you use them. Provided as-is — see Terms.

How does the SSH key and config helper work?

SSH key login uses a key pair: a private key that stays on your computer and a public key that you copy to every server you want to log in to. When you connect, the server checks that you hold the private key matching a public key in its ~/.ssh/authorized_keys file, without the private key ever crossing the network. Unlike a password, a key cannot be guessed, and a server that only accepts keys shrugs off the password-guessing bots that hit every public SSH port.

ssh-keygen creates the pair. Ed25519 is the modern default: short keys, fast, and no key size to get wrong. The passphrase encrypts the private key file on disk, and -a 100 makes each guess at that passphrase slower (ssh-keygen(1)). ssh-copy-id then logs in with your password one last time and appends the public key to the server's authorized_keys with the right permissions.

~/.ssh/config stores per-server settings under a Host name, so ssh homeserver replaces a long command with address, user, port and key (ssh_config(5)). IdentitiesOnly yes makes ssh offer only the key named for that server, which avoids "Too many authentication failures" when your agent holds several keys.

The last step is on the server: PasswordAuthentication no and KbdInteractiveAuthentication no in a file in /etc/ssh/sshd_config.d/ (sshd_config(5)). Order matters: turn passwords off only after the key login is tested, check the file with sshd -t before reloading, and keep one session open until a fresh login works. This helper only writes commands; no key is generated in your browser and nothing you type is sent anywhere.

Worked examples

A home server on the LAN

Input Ed25519, short name homeserver, 192.168.1.10, user admin, port 22 gives ssh-keygen -t ed25519 -a 100 -C me@laptop -f ~/.ssh/id_ed25519_homeserver

The key gets its own file named after the server, so it is obvious later which key is for what. The Host block then sets HostName 192.168.1.10, User admin and IdentityFile ~/.ssh/id_ed25519_homeserver, and ssh homeserver logs you in.

A VPS on port 2222, only one user allowed

Input Short name vps, vps.example.com, user deploy, port 2222, AllowUsers, Debian or Ubuntu gives ssh-copy-id -i ~/.ssh/id_ed25519_vps.pub -p 2222 deploy@vps.example.com

Every command gets -p 2222 and the Host block writes Port 2222, so later you never type it again. The drop-in adds AllowUsers deploy, and the reload command is sudo systemctl reload ssh, because the service is called ssh on Debian and Ubuntu.

A NAS where you log in as root

Input Short name nas, 192.168.1.20, user root gives PermitRootLogin prohibit-password

PermitRootLogin no would lock you out, because root is the account you use, so the helper switches to prohibit-password: root can still log in, but only with the key. It also warns that a normal user with sudo is the better setup.

Frequently asked questions

Which SSH key type should I use: Ed25519 or RSA?

Ed25519. The keys are short, fast and have no size or settings to get wrong, and every OpenSSH since version 6.5 (2014) supports them. Use RSA with -b 4096 only for old servers, network gear or services that reject Ed25519. If you have a FIDO2 security key, ed25519-sk keeps the private key on the hardware and needs a touch for every login; both sides need OpenSSH 8.2 or newer.

Should I put a passphrase on my SSH key?

Yes, for keys you use yourself. Without one, anyone who copies the private key file (a stolen laptop, a backup, malware) can log in to your servers. The passphrase encrypts the file, and with the ssh-agent (AddKeysToAgent yes) you type it once per session, not at every login. Keys used by unattended jobs such as a nightly backup timer cannot have one; give those their own key and restrict it on the server.

How do I disable SSH password login without locking myself out?

First prove the key works: ssh -o PreferredAuthentications=publickey user@server must log you in without asking for the server password. Then add PasswordAuthentication no and KbdInteractiveAuthentication no in a file in /etc/ssh/sshd_config.d/, run sudo sshd -t (no output means valid), check sudo sshd -T | grep -i passwordauthentication, and reload the service. Keep your current session open and log in again from a second terminal before you close it; open sessions survive a reload.

Why does SSH say 'Too many authentication failures'?

Your ssh-agent holds several keys and ssh offers them one by one; the server counts each as a failed try and disconnects after MaxAuthTries (6 by default) before the right key comes up. Add IdentitiesOnly yes and IdentityFile to the Host block in ~/.ssh/config, so ssh offers only the key for that server.

Why does SSH still ask for a password even though I copied my key?

Usually permissions: sshd ignores authorized_keys when ~/.ssh is not 700, authorized_keys not 600, or your home folder is writable by others. Fix it on the server with chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys. On Fedora and RHEL a wrong SELinux label has the same effect; restorecon -Rv ~/.ssh fixes it. Run ssh -v to see which keys are offered, and check the server log with sudo journalctl -u sshd (ssh on Debian and Ubuntu) for the reason.

What does a Host block in ~/.ssh/config do?

It gives a server a short name and stores how to reach it: HostName (the real address), User, Port and IdentityFile. After that, ssh homeserver replaces ssh -i ~/.ssh/id_ed25519_homeserver -p 2222 admin@192.168.1.10, and scp, rsync, git and editors with remote SSH use the same name. For each setting, ssh uses the first value it finds, so put specific Host blocks above a general Host * block.