15

My SSH config file is set up to use a specific IdentityFile in the Host * section as the default key. For one particular host, I want to offer a different key (and only that key, never the default key).

My ~/.ssh/config file looks like this:

Host specialhost
HostName specialhostname.mydomain.com
IdentityFile %d/.ssh/special-key
LogLevel debug
IdentitiesOnly yes 

Host *
IdentityFile %d/.ssh/regular-key
IdentitiesOnly yes 

Regardless of what I do, or regardless of the order of sections in the config file, my SSH client (OS X OpenSSH_6.2p2) offers the 'regular-key' first (which the server accepts, which is not what I wanted).

The ssh_config man page states the following about IdentityFile:

It is possible to have multiple identity files specified in configuration files; all these identities will be tried in sequence.

The "sequence" it refers to is unclear to me, since the IdentityFile listed in the Host * section is always offered first, even if "specialhost" is listed prior to it (as in the example above). The IdentitiesOnly trick suggested here only seems to be relevant to keys offered by ssh-agent. A few other similar questions have not yielded any answers.

I want to leave the regular-key in the Host * section because I use that key with dozens of other hosts and I don't want to duplicate the IdentityFile in every host entry.

Is there any way to force SSH to offer only the 'special-key' using just the SSH config (and without copying my IdentityFile directives to every other host)? I can see how I might achieve this by taking the keys out of the Host * section, adding them to the agent, and then using IdentitiesOnly yes for specialhost, but I would really prefer to avoid using ssh-agent unless there is no other way.

1 Answer 1

28

A Host line can have more than one pattern. And it's not really spelled out in the documentation, but a "!" (exclamation) at the beginning of a pattern means "apply this section to hosts that don't match the pattern". In other words, you can do this:

Host * !special1 !special2
IdentityFile etc...

And it should match any host except "special1" and "special2".

I don't think the order of the patterns is important. The hostname being checked has to match one non-exclamation pattern, and it has to not match any exclamation patterns.

3
  • A little clarification: you much specify a hostname to exclude. If you use an alias with a Host set, the alias won't work as an exclusion.
    – Xan
    Feb 13, 2019 at 14:00
  • 1
    This did it. My ssh client was matching Host * in all cases, and always picking it's IdentityFile regardless of what I tried. Note: you can also match a wildcard, if needed, e.g.: Host * !*.example.com Oct 2, 2019 at 8:34
  • 1
    This is not really sustainable with a growing list of specialized hosts, but it seems there is no better option...
    – xeruf
    Jan 3, 2021 at 23:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .