Where to start First steps track · 15 stages
Linux Labs

SSH keys and ssh-agent

5 min OpenSSH 9.6

Key pairs for passwordless login; sshd rejects ~/.ssh if it is writable by the group or by others.

Cheat sheet

7 commands Printable version
  • ssh-keygen -t ed25519 generate a pair
  • ssh-copy-id user@host install it on the server
  • ssh-keygen -l -f key.pub fingerprint
  • chmod 700 ~/.ssh directory — owner only
  • chmod 600 ~/.ssh/authorized_keys key file — owner only
  • ssh-add ~/.ssh/id_ed25519 load into the agent
  • ssh -i ~/.ssh/key -o IdentitiesOnly=yes host use a specific key

Overview

Key-based authentication is stronger than a password. The pair: a private key (stays with you, secret) and a public key (placed on the server in ~/.ssh/authorized_keys). The server encrypts a challenge with the public key — only the owner of the private key can decrypt it.

bash
ssh-keygen -t ed25519 -C "me@laptop"   # generate (ed25519 is the modern choice)
# private: ~/.ssh/id_ed25519  ·  public: ~/.ssh/id_ed25519.pub
ssh-copy-id user@host                  # push the public key to the server

Recipes

3

Generation

bash
ssh-keygen -t ed25519 -C "me@laptop"          # recommended type
ssh-keygen -t rsa -b 4096 -C "legacy"         # if RSA is required (old systems)
ssh-keygen -t ed25519 -f ~/.ssh/deploy_key    # a custom filename (several keys)
ssh-keygen -p -f ~/.ssh/id_ed25519            # change/add a passphrase on the key
ssh-keygen -y -f ~/.ssh/id_ed25519            # recover the .pub from the private key
ssh-keygen -l -f ~/.ssh/id_ed25519.pub        # fingerprint
ssh-keygen -t ed25519 -N '' -f key            # no passphrase (for automation/CI)

Installing on the server:

bash
ssh-copy-id user@host                          # the simplest way
ssh-copy-id -i ~/.ssh/deploy_key.pub user@host # with a specific key
cat ~/.ssh/id_ed25519.pub | ssh host 'cat >> ~/.ssh/authorized_keys'   # manually

File permissions

sshd enables StrictModes by default: it rejects ~/.ssh and the files in it if the group or others can write to them (the g+w/o+w bits), even when the owner is the right user. 700/600 is not the only value that passes the check, but it's the simplest recommendation that works:

bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_ed25519            # private key — owner only
chmod 644 ~/.ssh/id_ed25519.pub
chown -R "$USER:$USER" ~/.ssh

ssh-agent

The agent keeps the decrypted key in memory so you don't have to type the key's passphrase every time:

bash
eval "$(ssh-agent -s)"            # start the agent
ssh-add ~/.ssh/id_ed25519        # add the key (asks for its passphrase once)
ssh-add -l                       # which keys are loaded
ssh-add -t 3600 ~/.ssh/key       # auto-unload after an hour
ssh-add -d ~/.ssh/key            # remove one key
ssh-add -D                       # remove all keys
ssh -A user@host                 # agent forwarding — trusted hosts only!

Troubleshooting

5

Permission denied (publickey)

  1. Is the public key present in ~/.ssh/authorized_keys on the server?
  2. Permissions: ~/.ssh=700, authorized_keys=600, owner is the user itself. In the server's journal: journalctl -u ssh → "Authentication refused: bad ownership or modes".
  3. Is the client sending the right key? ssh -v host shows which keys it tries; specify explicitly with ssh -i ~/.ssh/key host or set it in ~/.ssh/config (IdentityFile).

It asks for the key's passphrase every time

The key isn't in the agent: ssh-add ~/.ssh/id_ed25519. For it to happen automatically — AddKeysToAgent yes in ~/.ssh/config (see ssh-client).

The server doesn't accept keys at all

On the server, in sshd_config: PubkeyAuthentication yes, and the directory/file isn't bypassing AuthorizedKeysFile. After editing — sudo systemctl reload ssh (see sshd).

Several keys — the wrong one is offered / "Too many authentication failures"

The agent tries every key and hits the server's limit. Specify one explicitly: ssh -i key -o IdentitiesOnly=yes host.

Lost the private key

It cannot be recovered — generate a new one and update authorized_keys on the servers. (You can extract the public key from the private one with ssh-keygen -y, but never the other way around.)

Terms

5
authentication
Verification of a claimed identity, for example using a password or key. Also appears in: PostgreSQL, sshd, chage, PAM: login checks, password policy and lockout and 4 more
SSH host key
An SSH server identity key pair, distinct from user login keys.
SSH user key pair
A client private key and corresponding public key for account authentication.
key fingerprint
A compact key representation for comparison with a trusted value.
authorized_keys
A server-side file of public keys authorized for an account. Also appears in: Ansible: inventory, modules and one-off commands, ssh, scp, sshd, cloud-init and 1 more

See also

  • ssh-client — Connecting over SSH, copying with scp/rsync, ~/.ssh/config, port forwarding.
  • sshd — The SSH server — remote access by keys, config, and hardening.
Loading…