From cb7b2f1d06f0f93adec37e8cf5e1fd18ac89c52e Mon Sep 17 00:00:00 2001 From: Felipe M Date: Fri, 12 Aug 2022 13:28:13 +0200 Subject: [PATCH] post: Using ssh_config Match to connect to a host using multiple IP or Hostnames --- .../contents.lr | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 content/blog/2022-08-12-using-ssh-config-match-to-connect-to-a-host-using-multiple-ip-or-hostnames/contents.lr diff --git a/content/blog/2022-08-12-using-ssh-config-match-to-connect-to-a-host-using-multiple-ip-or-hostnames/contents.lr b/content/blog/2022-08-12-using-ssh-config-match-to-connect-to-a-host-using-multiple-ip-or-hostnames/contents.lr new file mode 100644 index 0000000..9025d2f --- /dev/null +++ b/content/blog/2022-08-12-using-ssh-config-match-to-connect-to-a-host-using-multiple-ip-or-hostnames/contents.lr @@ -0,0 +1,78 @@ +title: Using ssh_config Match to connect to a host using multiple IP or Hostnames +--- +pub_date: 2022-08-12 +--- +_discoverable: yes +--- +body: + +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: + +``` bash +# .ssh/config +Host laptop.lan + HostName 192.168.1.2 # Internal network IP + +Host laptop.sdn + Hostname 10.0.0.2 # SDN IP +``` + +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: + +``` bash +# .ssh/config +Host laptop + HostName laptop.lan +``` + +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. + +``` bash +$ dig +short laptop.lan +192.168.1.2 # At home + +$ dig +short laptop.lan +# Empty result when away from home +``` + +Now, here comes the [`Match`](https://man7.org/linux/man-pages/man5/ssh_config.5.html) magic: + +``` bash +# .ssh/config +Host laptop + HostName laptop.lan + +Match originalhost laptop exec "[[ $(/usr/bin/dig +short laptop.lan) == '' ]]" + HostName laptop.sdn +``` + +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 match `laptop` +- `exec "[[ $(/usr/bin/dig +short laptop.lan) == '' ]]"`: Execute `dig` 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 compare `dig`s output to an empty string to evaluate + if we can resolve the `laptop.lan` domain name (check the `[[ ]]`). +- `HostName laptop.sdn` If both rules match, replace the `HostName` 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](https://man7.org/linux/man-pages/man5/ssh_config.5.html)