ssh config: can I have 2 host wildcards?
Simplified Example:
host one
user cat
host two
hostname 2
host three
hostname 3
host *
hostname 1
host *
user apple
identityFile ~/.ssh/id_rsa
host y
hostname 7
host t
hostname 8
host *
user duck
identityFile ~/.ssh/quack
Is this possible?
The hosts above the 1st host *
would inherit it’s values only, and the 2nd hosts would only inherent the host *
beneath them.
If not is there a way to achieve this?
I don’t know what exactly you want to achieve here, but I know three things:
-
Unless noted otherwise in the manual, for each parameter, the first obtained value will be used.
-
Host
restricts the following declarations (up to the nextHost
orMatch
keyword) to be only for those hosts that match one of the patterns given after the keyword. -
It’s good not to think of
Host
/Match
as separate sections. It’s good to perceive the config file as a single large config where some settings are filtered.In this answer I will call them "sections", only because I need to call them something.
In your simplified example, hostname 1
under the first host *
will "win" with any hostname
later in the file because host *
always matches. And everything under the last host *
is totally useless because user
and identityFile
appear earlier in the file under the second host *
.
The manual explicitly states:
Since the first obtained value for each parameter is used, more host-specific declarations should be given near the beginning of the file, and general defaults at the end.
Multiple Host *
sections are allowed, i.e. they will not break the syntax; but they hardly ever make sense. Assuming you use no parameters that stack when used multiple times (there are few), consider the following procedure:
-
Neighboring
Host *
sections (like your 1st and your 2nd) can be written as one section. MergeHost *
sections where possible. If some parameter appears in more than oneHost *
section to be merged then remember the first one will "win", discard all others. -
For each
Host *
section, top to bottom:- If the
Host *
section is not at the end and declares a parameter that appears later in the file (i.e. underHost whatever
later in the file) then the later declaration is irrelevant and may be removed because the one in theHost *
section (or something earlier) will win anyway. Remove the irrelevant declaration. Loop until there is nothing more to remove. - Now the
Host *
section is not at the end and contains only parameters that don’t appear later in the file (i.e. underHost whatever
later in the file). This means the section can as well be at the end. Move it to the end. - It’s possible there are now two
Host *
sections at the end. If so, merge them.
- If the
This procedure will give you exactly one Host *
section at the end of the config file.
A Host *
section not at the end of the file makes sense in these cases:
-
For parameters that stack when used multiple times. Usually their order matters. E.g. you may want to specify a
Host *
section withIdentityFile
at the beginning of the file, so a certain "main" key will always be tried first, no matter what the host is. ThenHost whatever
sections may specify keys (specific to hosts) to be tried later. Finally aHost *
section at the end of the file may specify "generic" key(s) to be tried last. -
In case you want to override some parameter(s) that may appear later in the file in the future. Imagine you want to make sure that if somebody (including you) tries to set that parameter later in the file (e.g. under
Host y
) then his or her try will be futile. This may easily lead to frustration though. -
In case you want to temporarily override some parameter(s) that appear later in the file. For this you create a temporary
Host *
section not at the end of the file and you don’t apply the above procedure (that would move the section to the end), because you want to be able to easily revert the change by simply removing the section and thus restoring the old state of the config file. Applying the procedure would possibly remove some declarations in other sections and then reverting would not be as easy.