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?

Asked By: Nickotine

||

I don’t know what exactly you want to achieve here, but I know three things:

  1. Unless noted otherwise in the manual, for each parameter, the first obtained value will be used.

  2. Host restricts the following declarations (up to the next Host or Match keyword) to be only for those hosts that match one of the patterns given after the keyword.

  3. 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:

  1. Neighboring Host * sections (like your 1st and your 2nd) can be written as one section. Merge Host * sections where possible. If some parameter appears in more than one Host * section to be merged then remember the first one will "win", discard all others.

  2. For each Host * section, top to bottom:

    1. If the Host * section is not at the end and declares a parameter that appears later in the file (i.e. under Host whatever later in the file) then the later declaration is irrelevant and may be removed because the one in the Host * section (or something earlier) will win anyway. Remove the irrelevant declaration. Loop until there is nothing more to remove.
    2. Now the Host * section is not at the end and contains only parameters that don’t appear later in the file (i.e. under Host whatever later in the file). This means the section can as well be at the end. Move it to the end.
    3. It’s possible there are now two Host * sections at the end. If so, merge them.

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:

  1. For parameters that stack when used multiple times. Usually their order matters. E.g. you may want to specify a Host * section with IdentityFile at the beginning of the file, so a certain "main" key will always be tried first, no matter what the host is. Then Host whatever sections may specify keys (specific to hosts) to be tried later. Finally a Host * section at the end of the file may specify "generic" key(s) to be tried last.

  2. 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.

  3. 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.

Answered By: Kamil Maciorowski
Categories: Answers Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.