IdentityFile directive only ever adds identity files (as of 7.4)
In some complicated scenarios (especially with 2FA devices), even
IdentitiesOnly can potentially give
you too many identities between relatively generic
entries and host-specific ones. Since there is only so far it's
sensible to push
Host ... entries with negated hostnames before
you wind up with a terrible mess, there are situations where it
would be nice to be able to say something like:
Host *.ourdomain IdentityFile ... IdentityFile ... [...] Host something-picky.ourdomain IdentityFile NONE IdentityFile /u/cks/.ssh/identities/specific IdentitiesOnly yes [...]
Here, you want to offer a collection of identities from various sources to most hosts, but there are some hosts that both require very specific identities and will cut your connection off if you offer too many identities (as mentioned back here).
I have in the past said that 'as far as I knew'
directives were purely cumulative (eg in comments on this entry). This held out a small sliver of hope that
there was some way of doing this that I either couldn't see in the
manpages or that just wasn't documented. As it happens, I recently
decided to look at the OpenSSH source code for 7.4 (the latest
officially released version) to put this to rest once and for all,
and the bad news is that I have to stop qualifying my words. As far
as I can tell from the source code, there is absolutely no way of
wiping out existing
IdentityFile directives that have been added
by various matching
There's an array of identities (up to the maximum 100 that's allowed),
and the code only ever adds identities to it. Nothing removes entries
or resets the number of valid entries in the array.
Oh well. It would have been nice, and maybe someday the OpenSSH people will add some sort of feature for this.
In the process of reading bits of the OpenSSH code, I ran across an interesting comment in sshconnect2.c's pubkey_prepare():
/* * try keys in the following order: * 1. certificates listed in the config file * 2. other input certificates * 3. agent keys that are found in the config file * 4. other agent keys * 5. keys that are only listed in the config file */
IdentitiesOnly does not appear to affect this order, it merely
causes some keys to be excluded.)
To add to an earlier entry of mine, keys
-i fall into the 'in the config file' case, because
what that actually means is 'keys from
-i, from the user's
configuration file, and from the system configuration file, in that
order'. They all get added to the list of keys with the same function,
-i is processed first.
(This means that my earlier writeup of the SSH identity offering order is a bit incomplete, but at this point I'm sufficiently tired of wrestling with this particular undocumented SSH mess that I'm not going to carefully do a whole bunch of tests to verify what the code comment says here. Having skimmed the code, I believe the comment.)