SSH public key authentication
Using SSH key-based authentication replaces passwords, significantly reducing the risk of brute-force access or breaches stemming from weak credentials. OpenSSH, widely used on Linux and Unix, natively supports public keys and lets you disable passwords once the system is correctly configured. Done well, this setup increases the security of remote access.
In 2023 the "Terrapin" attack was disclosed, which tampers with SSH channel integrity in certain encrypted modes, making it possible to downgrade authentication algorithms by exploiting packet sequence numbers. This shows the importance of configuring modern algorithms, keeping OpenSSH updated, and reducing the active attack surface (e.g. disabling plaintext methods).
Generating the key pair
Choosing the algorithm
On modern OpenSSH versions (Ubuntu 22.04+), it's advisable to use strong algorithms like ed25519 or ECDSA instead of RSA with minimal key lengths (e.g. RSA 2048). Recent versions include security patches without compromising compatibility.
Generation command
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519 -C "username@host"
-a 100 sets the number of key derivation rounds (useful if the key is passphrase-protected)
The file with the .pub extension is the public key; the file without an extension is the private key
Protecting the private key
Using a passphrase is strongly recommended. To remove it later:
ssh-keygen -p -f ~/.ssh/id_ed25519
Leave the new passphrase field empty to remove it.
Secure backup
The private key should be stored somewhere safe (protected hardware, encrypted backup). The public key can be copied to target servers.
Distributing the public key to the server
Prepare the .ssh folder
On the server, in the target user's home directory:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
Adding the public key
Use ssh-copy-id or a manual method:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
Alternatively, manually copy the contents of the .pub file and append it to ~/.ssh/authorized_keys:
cat id_ed25519.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Verifying access
Close the current SSH session and try a new login:
ssh user@server
The client should authenticate via the key, without asking for the user's account password (though it may ask for the key's local passphrase).
Using ssh-agent / passphrase caching
To avoid typing the passphrase on every session:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
Configuring the SSH server (sshd) to disable passwords
Once you've verified that key authentication works correctly, you can modify the SSH daemon to disable password authentication, reducing the attack vector.
Back up the configuration file
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
Key changes in /etc/ssh/sshd_config
Directives to set (or change):
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
PermitRootLogin prohibit-password
PubkeyAuthentication yes enables key-based authentication
PasswordAuthentication no disables password authentication
ChallengeResponseAuthentication no disables challenge-response mode
UsePAM no disables PAM if it interferes with authentication
PermitRootLogin prohibit-password allows root login only via key
You can also set more restrictive policies:
AllowUsers user1 user2
PermitEmptyPasswords no
Checking the configuration
sudo sshd -t
Restarting the SSH service
sudo systemctl restart sshd
It's important to keep OpenSSH continuously updated and to monitor logs of failed attempts. In professional environments, key rotation policies and updates against emerging attacks are essential steps.