Dynamic SSH jump hosts

This blog post is in response to this post by Mattias Geniar . I found his post through the Cron.Weekly newsletter which I highly recommend subscribing to.

SSH jump hosts are generally used as gateways into other networks, whether thats entering a DMZ or ensuring your session comes from a trusted IP. They should be seamless when done right, using the ProxyCommand for example. They can also be done very poorly, looking at you Agent Forwarding . Dynamic jump hosts are useful so you don’t have to create multiple separate host entries in your .ssh/config file.

Let’s play out a scenario. You have several hosts named web-01.example.com -> web-10.example.com that are hosted in dc1.example.com. dc1 only allows SSH connections from your office IP (which you aren’t currently in) and from your jump host (jump-01.example.com). You can either enter a separate line for each and every host in your .ssh/config file like this:

Host web-01.example.com
    ProxyCommand ssh you@jump-01.example.com nc %h %p
Host web-02.example.com
    ProxyCommand ssh you@jump-01.example.com nc %h %p

Or you could also do a wildcard host like this:

Host web-*
    ProxyCommand ssh you@jump-01.example.com nc %h %p

But that assumes that you only have machines named web-* available via that single jump host and the jump host will be used even when you’re in the office.

What if we place the wildcard somewhere else? If you combine sed and the ProxyCommand you can use have dynamic jump hosts with a single config for the whole DC. Checkout the example below.

Host *-via-dc1
    ProxyCommand ssh you@jump-01.example.com nc $(echo %h | sed 's/-via-dc1$//') %p

This means when you’re in the office you can SSH to web-01.example.com and get to the server directly. When you’re outside the office and need to come from a trusted IP you just change the host and SSH to web-01.example.com-via-dc1 and boom! You’re going through your jump host.