I wanted to set up a way that my keys could not be intercepted by some rogue who stole my laptop. Realistically, given that I have access to many servers, someone who stole my laptop could potentially wreak untold havoc. For a long time I have avoided using authorized_keys based authentication for this reason, preferring to type my password when prompted. But now I come into contact with several servers that simply flat-out forbid password authentication. So it was time for a change.

The basic change needed is to add a passphrase to the SSH key. You can do this through

ssh-keygen -m PEM -p -f ~/.ssh/id_rsa

PEM format is required for compatibility with certain tools, cough, Paramiko, which do not support RSA format private keys.

The next step is, how do you avoid typing your passphrase at every turn? The answer is usually ssh-agent, which can hold unlocked keys in memory. On Debian, ssh-agent is started by your display manager as part of the Xsession configuration.

I didn't want to be immediately prompted for a key unlock every time I rebooted, so I found this very cool new option from newer SSH versions:

# ~/.ssh/config

# This will make sure that any new keys get added to ssh-agent using ssh-add(1)
# on a lazy basis (whenever the host is first connected to).
AddKeysToAgent yes

So using this mitigates any need for manual calls to ssh-add.

Bear in mind that using this encrypted key will break any noninteractive scripts that you need to use. This will affect rsync, git-annex, etc. For these cases I am not yet sure of the best option. The simplest approach, and the one that I used, is to create two SSH identities, one encrypted and one unencrypted, and deploy the unencrypted private key only to servers. Servers can then use pull-based access, and only if the server is already compromised does an attacker essentially own everything. Someone with only workstation access can't get server access without typing the passphrase first.

But wait, we still need to expire the keys to force the passphrase to be re-entered. Otherwise a clever attacker can take as long as they like to examine the known_hosts file and own everything. Debian deploys a file /etc/X11/Xsession.d/90x11-common_ssh-agent with the package x11-common. This file defined the startup commands that Xsession uses to launch ssh-agent. It includes this line:

SSHAGENTARGS=

Just modify this line and include an argument to specify the lifetime that you want for the identities. I chose one hour, so I wrote the line below.

SSHAGENTARGS="-t 1h"

The rules for specifying times are specified in the manual page sshd_config(5), under the section TIME FORMATS.