guest@6admin.io:~$

SSH: authentication via private/public keys

SSH authentication by password works, but it is weak: the password is typed at every connection, it can be brute-forced (fail2ban mitigates but does not solve) and it does not distinguish “who” from “what”. SSH keys solve all three: the private key proves identity, the public key authorizes access and once configured, no more password.

Generate the pair

ssh-keygen -t rsa -b 4096 -C "comment"

The -t rsa generates an RSA pair, the -b 4096 sets the size (2048 minimum, 4096 recommended). The -C is a free comment (usually the email or hostname). Two files: id_rsa (the private key, never leaves the workstation) and id_rsa.pub (the public key, to copy to servers).

Deploy the public key

ssh-copy-id user@server

This command copies the content of id_rsa.pub into ~/.ssh/authorized_keys on the server (chmod 600, .ssh 700). It can also be done manually:

cat ~/.ssh/id_rsa.pub | ssh user@server "cat >> ~/.ssh/authorized_keys"

Once deployed, the connection happens without a password:

ssh user@server

The SSH agent

The private key passphrase can be cached by ssh-agent:

eval $(ssh-agent)
ssh-add ~/.ssh/id_rsa

The passphrase is asked once, then the agent signs connections without asking again. With keychain, the agent persists between sessions (it stores the socket in a file that subsequent shells reuse).

Disabling password authentication

Once all keys are deployed, you can close the door:

# /etc/ssh/sshd_config
PasswordAuthentication no
ChallengeResponseAuthentication no
/etc/init.d/ssh restart

At this point, only holders of the private key can connect. Password brute-force no longer works (there is no password). The SSH server goes from “accessible by anyone with a password” to “accessible by whoever has the key”. This is the biggest security upgrade for an SSH server and it takes 5 minutes.

The authorized_keys concept

The ~/.ssh/authorized_keys file contains one public key per line. Each line authorizes access for the corresponding private key. Each line can be restricted:

command="/usr/bin/rsync --server --daemon .",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAA...

This line authorizes ONLY rsync (no shell, no port forwarding, no X11, no terminal). This is the secure backup mechanism: the backup machine has a key that can only do one thing.

[edit: 2026] SSH keys are still the standard authentication mechanism, Ed25519 has replaced RSA as the default choice and SSH certificates (ssh-keygen -s) have added an expiration and revocation layer. The PasswordAuthentication no remains the first thing to do on a fresh SSH server. SSH rootkits that hook PAM still exist and the defense remains the same: password disabled, keys only and an audit of authorized_keys (they accumulate and nobody cleans them).

[edit: 2026] The Ansible implementation of all this: the ssh role .