What ssh-agent does with multiple keys loaded

May 23, 2014

Ssh-agent is probably normally used to handle a single identity key, but it can hold more than one if you want. One of the things that the ssh-agent and ssh manpages are a bit silent on is what happens if you have multiple SSH keys loaded into a single ssh-agent. Since I've been dealing with this as the result of transitioning from one set of SSH keys to another, I'm going to write down what I've learned so far.

(The simple version of why I decided to roll over my SSH keys is that I decided to transition from keys that had once been used without encryption to keys that were created encrypted.)

Before I started loading multiple keys into ssh-agent, what I expected to happen is that the choice of which ssh-agent key to use would be controlled by the key that ssh itself would normally use. If you had, for example, 'IdentityFile .../key1-rsa', then I expected ssh to ask ssh-agent to do operations only with that key. This is not what happens. Instead what happens by default is that ssh tries all keys loaded into ssh-agent, one after another, in the order that they were loaded into ssh-agent.

You can partly override this behavior with the IdentitiesOnly configuration directive, which will restrict the keys that ssh tries to only the identities listed either as IdentityFile directives or supplied on the command line with -i. However this is an incomplete override because it doesn't prioritize the -i identity the way a normal (agentless) ssh will; ssh will first ask ssh-agent for any IdentityFile keys it has and only then fall back to a non-agent key given with -i. This implies that if you have a script and you want it to always use a particular restricted identity even if more general ones are available (as I do in one case) you need to clear $SSH_AUTH_SOCK in the script.

(This can apply any time you have a remote system that accepts multiple identities from you but applies different access permissions or access restrictions to them. Remember that IdentityFile directives add together and -i stacks with with them too, so even if you have a specific identity configured for something, a general 'Host *' identity or the like will also be tried.)

There are a couple of interesting uses I can see for this multiple key behavior. One of them is making a transition between old and new SSH keys easier. First off, you can load both your new and your old key into ssh-agent; you'll then use your new key on systems that have been updated to accept only it but have a transparent fallback to systems that only have your old key. More cleverly you can use this to uncover systems that haven't been updated to your new key by loading only your new key into ssh-agent but leaving your old encrypted key configured as your IdentityFile. If you try to ssh to somewhere but get prompted to unlock your old key, you've found a host that either prefers your old key to your new key or doesn't have your new key at all.

Another use is encrypting secondary keys (for example your Github key) but still loading them into ssh-agent for passwordless use. Since ssh with ssh-agent will try multiple keys, pushing to Github and other such uses will eventually try the right keys. You can force this to happen earlier by setting IdentitiesOnly in .ssh/config for the particular hosts involved; this will definitely be necessary if you have a lot of SSH keys, because SSH servers only accept so many key attempts (cf).

(Some of this information comes from this stackoverflow answer.)

(Talking of the interaction of ssh and ssh-agent, it's a pity that as far as I know ssh can't be told 'load keys into ssh-agent when you unlock them'. This would make it very convenient to incrementally load keys into ssh-agent as you turn out to need them while not having them sitting around unlocked in a session if you didn't.)

Written on 23 May 2014.
« Why Java is a compiled language and Python is not
Computing has two versions of 'necessary' »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri May 23 23:18:31 2014
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.