What SSH identities will be offered to a remote server and when
I've already written an entry on what SSH keys in your .ssh/config will be offered to servers, but it wasn't quite complete and I still managed to confuse myself about this recently. So today I'm going to try to write down in one place more or less everything I know about this.
Assuming that you're using
ssh-agent and you don't have
IdentitiesOnly set anywhere, the following is what keys
will be offered to the remote server:
- All keys from
ssh-agent, in the order they were loaded into
- The key from a
-iargument, if any.
- Any key(s) from matching
.ssh/config, in the order they are listed (and matched) in the file. Yes, all keys from all matching stanzas;
IdentityFiledirectives are cumulative, which can be a bit surprising.
(If there are no
.ssh/config, OpenSSH will fall back to the default
.ssh/id_*keys if they exist.)
(If you aren't using
ssh-agent, only #2 and #3 are applicable
and you can pretty much ignore the rest of this entry.)
If there is a '
IdentitiesOnly yes' directive in any matching
.ssh/config stanza (whether it is in a '
Host *' or a specific
Host <whatever>'), the only keys from
ssh-agent that will be
offered in #1 are the keys that would otherwise be offered in both
#2 and #3. Unfortunately
IdentitiesOnly doesn't change the order
that keys are offered in; keys in
ssh-agent are still offered
first (in #1) and in the order they were loaded into
not the order that they would be offered in if
Where the '
IdentitiesOnly yes' directive comes from makes no
difference, as you'd pretty much expect. The only difference between
having it in eg '
Hosts *' versus only (some) specific '
<whatever>' entries is how many connections it applies to. This
leads to an important observation:
The main effect of a universal
IdentitiesOnlydirective is to make it harmless to load a ton of keys into your
OpenSSH servers have a relatively low limit on how many public keys
they will let you offer to them; usually it's six or less (technically
it's a limit on total authentication 'attempts', which can wind up
including eg a regular password). Since OpenSSH normally offers all
keys from your
ssh-agent, loading too many keys into it can cause
authentication problems (how many problems you have depends on how
many places you can authenticate to with the first five or six keys
loaded). Setting a universal '
IdentitiesOnly yes' means that you
can safely load even host-specific keys into
ssh-agent and still
have everything usable.
(This is the
sshd configuration directive
Note that specifying
-i does not help if you're offering too many
ssh-agent, because the
ssh-agent keys are offered
first. You must enable
IdentitiesOnly as well, either in
or as a command line option. Even this may not be a complete cure
.ssh/config enables too many
and those keys are loaded into
ssh-agent so that they get offered
If the key for
-i is loaded into your
ssh-agent, OpenSSH will
ssh-agent version for authentication. This will cause a
confirmation check if the key was loaded with '
ssh-add -c' (and
yes, this still happens even if the
-i key is unencrypted).
ssh-agent confirmation checks only happen when the key is
about to be used to authenticate you, not when it is initially
offered to the server.)
PS: you can see what keys you're going to be offering in what order
ssh -v -v ...'. Look for the 'debug2: key: ...' lines, and
also 'debug1: Offering ...' lines. Note that keys with paths and
explicit' may still come from
ssh-agent; that explicit
path just means that they're known through an
Sidebar: the drawback of a universal
The short version is 'agent forwarding from elsewhere'. Suppose
that you are on machine A, with a
ssh-agent collection of keys,
and you log into machine B with agent forwarding (for whatever
reason). If machine B is set up with
up with universal
IdentitiesOnly, you will be totally unable to
ssh-agent keys that machine B doesn't know about. This
can sort of defeat the purpose of agent forwarding.
There is a potential half way around this, which is that
can be used without the private key file. Given a stanza:
Host * IdentitiesOnly yes IdentityFile /u/cks/.ssh/ids/key-ed2
If you have a
key-ed2.pub file but no
key-ed2 private key file,
this key will still be offered to servers. If you have
loaded into your
ssh-agent through some alternate path, SSH
can authenticate you to the remote server; otherwise
offer the key, have it accepted by the server, and then discover
that it can't authenticate with it because there is no private key.
SSH will continue to try any remaining authentication methods,
including more identities.
(This is the inverse of how SSH only needs you to decrypt private keys when it's about to use them.)
However, this causes SSH to offer the key all the time, using up
some of your
MaxAuthTries even in situations where the key is not
usable. Unfortunately, as far as I can tell there is no way to tell
SSH 'offer this key only if
ssh-agent supports it', which is what
we really want here.