Skip to main content

SSH keys and access: stop using passwords

Generate a key pair, install the public key, and disable password login safely.

Password authentication over SSH is the single most attacked surface on any server. Keys are stronger and, once set up, more convenient.

Generate a key pair

On your own computer (not the server):

bash
ssh-keygen -t ed25519 -a 100 -C "you@laptop"
  • -t ed25519 — modern, fast, small keys. rsa with 4096 bits is the compatibility fallback for very old systems.

  • -a 100 — KDF rounds; makes the on-disk private key slower to brute-force if it is ever stolen.

  • -C — a comment, usually an email, so you can tell keys apart later.

Accept the default path. Set a passphrase. A passphrase-protected key plus ssh-agent is both safe and painless: you type it once per session, not once per connection.

You now have:

  • ~/.ssh/id_ed25519 — the private key. Never leaves your machine. Never paste it anywhere.

  • ~/.ssh/id_ed25519.pub — the public key. Safe to share; this is what goes on servers.

Install the public key

During provisioning: paste the contents of the .pub file into the SSH key field. This is the easiest path.

On an existing server:

bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]

If ssh-copy-id is unavailable, append the key manually:

bash
cat ~/.ssh/id_ed25519.pub | ssh [email protected] \
  'mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'

Permissions matter. SSH refuses to use keys or directories that are group- or world-writable.

Verify before you disable passwords

Open a second terminal and log in with the key while your first session is still open. Only once key login works should you remove the password route. Locking yourself out because you skipped this step is the most common self-inflicted wound in server administration.

Disable password authentication

Edit the SSH daemon config:

bash
# Debian/Ubuntu servers ship a drop-in directory; use it:
printf 'PasswordAuthentication no\nKbdInteractiveAuthentication no\nPermitRootLogin prohibit-password\n' \
  > /etc/ssh/sshd_config.d/99-keys-only.conf

# Validate, then reload (never restart blindly)
sshd -t && systemctl reload ssh    # 'sshd' on RHEL-family

Keep your existing session open. Test a new connection. Only close the old one when the new one works.

Using an SSH agent

Add your key to the agent so you are not re-typing the passphrase:

bash
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

On macOS the agent is automatic; on Linux your desktop environment usually starts one for you.

A note on root and sudo

A common pattern is to keep root SSH disabled entirely and log in as an unprivileged user who may sudo. Create one:

bash
adduser tim
usermod -aG sudo tim               # 'wheel' on RHEL-family
# copy the key into /home/tim/.ssh/authorized_keys with correct ownership
mkdir -p /home/tim/.ssh && cp ~/.ssh/authorized_keys /home/tim/.ssh/
chown -R tim:tim /home/tim/.ssh && chmod 700 /home/tim/.ssh && chmod 600 /home/tim/.ssh/authorized_keys

Then set PermitRootLogin no. You still get full power via sudo, and every privileged action is attributable to a person.

Related reading