SSH Public Key Authentication

A lot of people use SSH to log into remote hosts. SSH is secure and works well, but if you have to access many hosts with long, well-chosen passwords there is a lot of typing to do just for authentication.

In this article I'll walk you through a basic public key authentication setup. Password authentication may be more frequently used, but public key authentication is very convenient after the initial work is done. OpenSSH is used in the examples below, but the same process works much the same on other systems (for example putty/pageant on Windows).

In a nutshell, we'll generate a public/private key pair on a local account and install the public key in all remote accounts we want to access. Then we can log into the accounts using the private key's password instead of the remote account's password. To avoid having to type the password multiple times, we'll use a key agent which keeps the password in memory.

First of all, we generate a public/private key pair using ssh-keygen:

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/matthias/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/matthias/.ssh/id_rsa.
Your public key has been saved in /home/matthias/.ssh/id_rsa.pub.
The key fingerprint is:
6b:3c:60:9a:84:5a:06:59:62:f4:6b:25:d3:5b:0e:67 matthias@alanis
$

Accept the default filename and then pick a strong but memorizable passphrase for your private key. If you ever forget the passphrase there is no way to recover it and the key will be useless. Don't generate keys without a passphrase: An attacker breaking into your local account would then be able to log into all your remote accounts, too.

You can later change the passphrase using ssh-keygen's -p switch. There are a lot of other command line options, but the defaults are usually just fine.

Now that the key pair is generated, we install the public key (from the id_dsa.pub file) in all remote accounts we want to log into conveniently. The private key in id_dsa has to be kept secret but needs to stay in your local ~/.ssh directory. Installing the public key works by appending it to the remote ~/.ssh/authorized_keys files. This can be done manually or using the ssh-copy-id tool:

$ ssh-copy-id remoteuser@example.com
[...]
$

The tool prompts for the remote account's password and then copies the public key. After this, you should be able to log in:

$ ssh remoteuser@example.com
Enter passphrase for key '/home/matthias/.ssh/id_dsa':
[...]

Note that this time we're being asked for the private key's password, so the basic setup is done.

Typing the private key's password multiple times (once per account) is tedious, so we want to enter it only once per local session. The ssh-agent and ssh-add tools shipped with OpenSSH can help here. The ssh-agent program runs as a per-user daemon in background. If the SSH_AGENT_PID environment variable is set then the agent is already running - which is pretty common on modern Linux distributions. Otherwise you can add the call to ssh-agent to your shell profile (eg. ~/.profile) or an X session startup script:

eval $(ssh-agent -s)

As soon as the agent is running, you can use it from your local interactive session to register a private key. To do this you have to execute the ssh-add utility:

$ ssh-add
Enter passphrase for /home/matthias/.ssh/id_dsa:
Identity added: /home/matthias/.ssh/id_dsa (/home/matthias/.ssh/id_dsa)
$

After that, you can log into your remote accounts without having to enter the password.

social