Shami's Blog

DevOps because uptime is not optional

Using SSH ProxyJump only when necessary

Edit: Used grep -F instead of fgrep

One thing I’ve wanted to do for the longest time was to be able to use SSH with an alias and have ssh choose the bastion host automatically.

This trick was ok at first, but I wanted something more flexible and I came up with the following:

 1Match host web1 exec "~/.ssh/network_detect/office"
 2  Hostname 10.1.0.1
 3  IdentityFile ~/.ssh/public_keys/ed25519.pub
 4  ProxyJump none
 5
 6Match host web1 exec "~/.ssh/network_detect/home"
 7  Hostname 10.1.0.1
 8  IdentityFile ~/.ssh/public_keys/ed25519.pub
 9  ProxyJump home-bastion
10
11Match host web1 exec "~/.ssh/network_detect/wireguard"
12  Hostname 10.1.0.1
13  IdentityFile ~/.ssh/public_keys/ed25519.pub
14  ProxyJump wg-bastion

Now for the network_detect

 1# ~/.ssh/network_detect/office
 2#!/usr/bin/env bash
 3
 4ip addr show | grep -F -q 'inet 10.1.0'
 5
 6# ~/.ssh/network_detect/home
 7#!/usr/bin/env bash
 8
 9ip addr show | grep -F -q 'inet 192.168.1'
10
11# ~/.ssh/network_detect/wireguard
12#!/usr/bin/env bash
13
14ip link show wg_connection_name > /dev/null 2>&1

Which basically returns true based on the networks the client is connected to, either by searching for the network address or checking if the interface exists. This also allows using more than one bastion host.

ssh will go through all Match statemens in the order they appear in this file and apply previously-unapplied configurations, so the configuration above can be reduced to

1Match host web1
2  Hostname 10.1.0.1
3  IdentityFile ~/.ssh/public_keys/ed25519.pub
4
5Match host web1 exec "~/.ssh/network_detect/home"
6  ProxyJump home-bastion
7
8Match host web1 exec "~/.ssh/network_detect/wireguard"
9  ProxyJump wg-bastion

When the user runs ssh web1, the following takes place:

  1. Match host web1 will be found, Hostname 10.1.0.1 and IdentityFile ~/.ssh/public_keys/ed25519.pub will be applied.
  2. ssh runs ~/.ssh/network_detect/home, if that returns 0 then ProxyJump home-bastion will be applied.
  3. ssh runs ~/.ssh/network_detect/wireguard, if that returns 0 then ProxyJump wg-bastion will be applied, but only if ProxyJump home-bastion was not applied already.
  4. If either ProxyJump home-bastion or ProxyJump wg-bastion was applied, the bastion host is used, otherwise connect to the server directly.

So if you’re home and have wireguard running, ssh will always connect through home-bastion

About Me

Dev gone Ops gone DevOps. Any views expressed on this blog are mine alone and do not necessarily reflect the views of my employer.

Categories