Using ssh_config Match to connect to a host using multiple IP or Hostnames
My main computer is a MacBook Pro from 2017, but I have some servers laying around and one other laptop connected at home with ArchLinux installed that I use mainly for development. I connect to it remotely either directly using a SSH/Mosh + Tmux + Emacs/Vim combination, or using the pretty convenient VSCode Remote Extensions when I’m not feeling much of a hacker.
Thing is, I may access this computer either from my home network directly if I’m at home or via a SDN if I am not (at the office, coffeeshop, visiting family, etc).
My approach was to setup the hosts directly on my ~/.ssh/ssh_config
as you would with different machines:
|
|
That way, I would connect to each one of them depending on the situation. Using tmux and ssh is not that much of a problem
since I could just detach from home, go away, then connect via SDN an everything would be there (though I had to remember
which alias to use instead of just ssh laptop
). For VSCode is not that convenient since I would need to close the connection,
made a new one to the new host and so on. Surely we could made this simpler, right?
In my home network, my main router is also my DNS server (with Ad Blocking, rules and all kind of fancy things), and that
server resolves my local domain (*.lan
) to LAN IP Addresses, so I can start with a simple config as I had previously:
|
|
Now, what happens if I’m not at home? I could solve this in several ways:
- I could
ping
my router, but that could collide with other networks out there. - I could check if my Wifi BSSID is one of the APs at home, but I could also connect via Ethernet.
- I could check if I can resolve the
laptop.lan
address, though this requires network access, but in the end is the one I ended up using.
|
|
Now, here comes the Match
magic:
|
|
Using Match
we can replace properties for a defined host using matches. In this ad-hoc example what I did is:
Match originalhost laptop
: The connection host need to matchlaptop
exec "[[ $(/usr/bin/dig +short laptop.lan) == '' ]]"
: Executedig
and try to resolve my LAN’s laptop domain name. This needs to be a successful command for it to match, in this case we comparedig
s output to an empty string to evaluate if we can resolve thelaptop.lan
domain name (check the[[ ]]
).HostName laptop.sdn
If both rules match, replace theHostName
property with the laptop’s SDN domain name.
This is a pretty easy way to just ssh laptop
wherever I am. I didn’t knew about this particular
keyword until today, and it’s pretty powerful!
Documentation: ssh_config(5) manpage