42

My understanding of the way ~/.ssh/config works is that each 'Host ' line takes effect for any host matching after that point in the config file.

I have a number of personal servers and work servers that I need to connect to. I'm trying to do something like the following:

# General Settings
ControlMaster auto
ControlPath   ~/.ssh/controlmaster/%r@%h:%p
ForwardAgent  yes
ForwardX11    yes
GSSAPIAuthentication no
PubkeyAuthentication yes

# Personal Servers
Host *
User harleypig
IdentityFile ~/.ssh/personal_id_rsa

Host host1
Hostname host1.com

Host host2
Hostname host2.com

# Work Servers
Host *
User alan.young
IdentityFile ~/.ssh/work_id_rsa

Host work1
Hostname work1.companyserver.com

Host work2
Hostname work2.companyserver.com

Host *
User devuser

Host dev1
Hostname dev1.companyserver.com

Host dev2
Hostname dev2.companyserver.com

The docs seem to indicate that host1 and host2 should use 'personal_id_rsa' and the user harleypig. work1, work2, dev1 and dev2 should use 'work_id_rsa' and the first two should be the user 'alan.young' and dev1 and dev2 should be the user 'devuser'

However, this is not happening. Whatever 'Host *' I put first is what all of the following hosts try to connect with. Am I misunderstanding or missing something?

harleypig
  • 523
  • 1
  • 4
  • 5

2 Answers2

59

From the ssh_config manual:

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.

So in your example, all hosts will use User harleypig and IdentityFile ~/.ssh/personal_id_rsa.

Think of Host directives with wildcards as fallbacks: use the following settings only if they haven't been set yet. You need to write something like this:

Host host1
Hostname host1.com
Host host2
Hostname host2.com
Host host*
User harleypig
IdentityFile ~/.ssh/personal_id_rsa

You can put multiple patterns on a Host line if a given set of host aliases can't be matched with wildcards, e.g. Host host* more* outlier.

chb
  • 584
  • 7
  • 17
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • Can `Host` has subdirectory? I mean: `Host host2.com/companyName` – Dr.jacky Aug 07 '20 at 19:21
  • @Dr.jacky That's not a subdirectory. The slash character is not a directory separator here. It works if you run `ssh host2.com/companyName`, but it may not work in other contexts. For example you can't use `rsync host2.com/companyName:/remote/path /local/path` because rsync doesn't recognize `host2.com/companyName` as a hostname. Use `-` as a separator instead. – Gilles 'SO- stop being evil' Aug 07 '20 at 20:30
  • 1
    You're right. For my case, it should be like this: `git clone [email protected]:companyName/repoName.git`. and in `.gitconfig`: `Host github.com-companyName`. – Dr.jacky Aug 07 '20 at 20:31
21

You are definitely doing it wrong.

  • You should always put Host * as the last entry.
  • You can not have multiple Host * entries

If your work machines have a name format which you can generalize to target just the work machines, for e.g: machine1.work.com, host.work.com, fileserver.work.com then you can target your work machines as:

Host *.work.com
User alan.young
IdentityFile ~/.ssh/work_id_rsa

Same applies for your personal machines.

  • For me, putting `Host *` at the beginning of the file seems to work fine. Perhaps the fact that you're using a wildcard trumps the fact that it is the first entry when prioritizing them? – Zaz Feb 11 '16 at 22:31
  • Btw, the `Host *.work.com` is an invalid syntax. It only works the other way around: `Host myserver*` – Daniel Andrei Mincă Feb 20 '17 at 20:09
  • 9
    @MincăDanielAndrei it works both ways, its just a wildcard expression and you can use it as any other wildcard. Host git-codecommit.*.amazonaws.com This is a working example from my ~/.ssh/config – Hameedullah Khan Feb 21 '17 at 13:01
  • @HameedullahKhan seriously, I've tried that and it's not responding. If you do `Host *subdomain.com` it's not going to respond. – Daniel Andrei Mincă Feb 22 '17 at 20:38
  • And I'm not the only one noticing this btw.... Check for yourselves: http://superuser.com/q/469329/446958 – Daniel Andrei Mincă Feb 22 '17 at 20:50
  • Dear @MincăDanielAndrei if you look at the answer you pointed at, the similar wildcard expression is used in the answer i.e Host *.mydomain.com host1. Are you pointing to something else in my answer or its just this wild card expression? If its the wildcard expression then it is the correct syntax. If for some reason you are not able to make it work for you share your ~/.ssh/config and we can have a look at it. – Hameedullah Khan Feb 23 '17 at 15:03
  • 1
    @MincăDanielAndrei That behavior is documented in the man pages, if it doesn't work (for me neither) it is a bug. – goetz Jun 05 '17 at 04:34
  • 4
    @HameedullahKhan That's wrong, you can in fact have multiple `Host *`, the documentation is not very clear, but just try it. – goetz Jul 09 '17 at 16:38