SSH keys replace passwords with a cryptographic key pair: a private key that stays on your computer and a public key you place on servers. Keys can’t be guessed by brute force, and once set up you log in without typing a password. They’re the single most effective security improvement for a new server.

1. Generate a key pair

On your local computer (Linux, macOS, or Windows 10/11 PowerShell):

ssh-keygen -t ed25519 -C "you@laptop"
  • -t ed25519 — the modern default: short keys, fast, secure. Use -t rsa -b 4096 only for very old servers that don’t support Ed25519.
  • -C — a comment to recognise the key later (anything you like).

ssh-keygen asks where to save it (accept the default ~/.ssh/id_ed25519) and for a passphrase. Use one: it encrypts the private key, so a stolen laptop or backup doesn’t hand over your servers. ssh-agent (below) means you won’t type it constantly.

You now have:

~/.ssh/id_ed25519       # private key — never share, never copy to servers
~/.ssh/id_ed25519.pub   # public key — safe to share

2. Copy the public key to the server

The easy way:

ssh-copy-id [email protected]
ssh-copy-id -p 2222 [email protected]     # custom port

It logs in with your password once and appends the public key to ~/.ssh/authorized_keys on the server, with correct permissions.

Without ssh-copy-id (for example on Windows):

type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh [email protected] "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Or paste the contents of the .pub file into ~/.ssh/authorized_keys on the server by hand — one key per line.

3. Log in

ssh [email protected]

You’re asked for the key’s passphrase (if set), not the server password. Add -v to see which keys SSH offers if something doesn’t work.

4. Use ssh-agent so you type the passphrase once

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -l              # list loaded keys
  • macOS: add UseKeychain yes and AddKeysToAgent yes under Host * in ~/.ssh/config to store the passphrase in the Keychain.
  • Windows: enable the “OpenSSH Authentication Agent” service, then ssh-add.
  • Linux desktops: GNOME and KDE usually run an agent already.

5. Disable password logins (after testing!)

Once key login works — test it in a second terminal first — turn off password authentication on the server so bots can’t guess passwords at all. In /etc/ssh/sshd_config (or a file in /etc/ssh/sshd_config.d/):

PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
sudo sshd -t && sudo systemctl reload ssh     # "sshd" on RHEL-family systems

Keep your current session open until you’ve confirmed a fresh login works. On Ubuntu, check that a file like /etc/ssh/sshd_config.d/50-cloud-init.conf doesn’t set PasswordAuthentication yes and override you. More hardening steps: SSH key authentication only and disabling root login.

Managing multiple keys

Use separate keys for different purposes (work, personal, deploy) and map them in ~/.ssh/config:

Host web1
    HostName 203.0.113.10
    User deploy
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

Host github.com
    IdentityFile ~/.ssh/id_ed25519_github

IdentitiesOnly yes stops SSH from offering every key in the agent, which can trigger “Too many authentication failures”. See the SSH config file guide.

Useful ssh-keygen commands

ssh-keygen -p -f ~/.ssh/id_ed25519          # change or add a passphrase
ssh-keygen -y -f ~/.ssh/id_ed25519          # print the public key from a private key
ssh-keygen -lf ~/.ssh/id_ed25519.pub        # fingerprint
ssh-keygen -R 203.0.113.10                  # remove a host from known_hosts (after a reinstall)
ssh-keygen -t ed25519 -f ~/.ssh/deploy -N "" -C "ci-deploy"   # no-passphrase key for automation

After reinstalling a server, its host key changes and SSH warns REMOTE HOST IDENTIFICATION HAS CHANGED. If you know you reinstalled it, ssh-keygen -R host clears the old entry. If you didn’t, investigate before connecting.

Restricting keys on the server

Options in front of a key in authorized_keys limit what it can do — ideal for automation:

from="198.51.100.7",no-port-forwarding,no-pty,command="/usr/local/bin/backup-receive" ssh-ed25519 AAAA… backup@web1

This key works only from one IP and can only run one command.

Hardware keys

With OpenSSH 8.2+, a FIDO2 security key (YubiKey and similar) can hold the private key:

ssh-keygen -t ed25519-sk -O resident

The key can’t be copied off the device, and each login requires a touch. See YubiKey SSH.

Troubleshooting

  • Still asked for a password — the server isn’t accepting the key. Usually permissions: ~/.ssh must be 700, authorized_keys 600, and the home directory not group-writable. Full checklist: Permission denied (publickey).
  • WARNING: UNPROTECTED PRIVATE KEY FILE! — your local private key is readable by others: chmod 600 ~/.ssh/id_ed25519.
  • Windows: Bad permissions — the key file is readable by other Windows users; fix it in file Properties → Security, leaving only your account.

New to SSH altogether? Read how to SSH into your VPS. Every VPS.DO server accepts SSH keys from the first login.

  • SSH
  • Security
  • Linux