gsallesl.github.io

SSH ProxyCommand Resolver

SSH ProxyResolver dynamically determines the ProxyCommand to use for a SSH Host alias based on your current network connection and a configuration you provide.

SSH ProxyCommand configuration parameter provides a great way to nicely access a computer not directly accessible on the internet with a simple command.

This configuration parameter is particularly useful on a laptop SSH configuration to access such a system. You may have to change this parameter when switching between networks:

  • When connected to the same network as myhost:
# .ssh/config
Host myhost
HostName IPAddress
  • When proxying via a server facing the internet that can access myhost:
# .ssh/config
Host myhost
ProxyCommand ssh internet_facing_server_IP -W IPAddress:some_port
  • When using a meeting point on another server, for example when the system facing the internet and on the same network as myhost is down:

On my host:

ssh -NR 2345:localhost:22  internet_facing_server2_IP

On the client:

# .ssh/config
Host myhost
ProxyCommand ssh internet_facing_server2_IP -W localhost:2345

If the system myhost actually hosts some of your code on git bare repositories, you may be constrained to use a single SSH alias and adapt the SSH configuration depending on the network you are connected to so that you can still perform pull and push operations. However, you may want to avoid modifying your configuration many times a day.

To avoid having to make these changes manually, here is a little tool, ProxyCommandResolver (pcr), which will pick up the correct ProxyCommand to use for you. pcr uses a configuration file that make an association between an SSH Host alias, multiple ProxyCommand and your current connection parameters (Wifi access point name for example) and returns the ProxyCommand to be used.

So far, the connection parameters supported by pcr are the default routing interface, your wifi ESSID, your NetworkManager connection name or your current IP address.

The tool consists of:

The corresponding SSH configuration to make use of this script is the following. One of the nice feature of the proxy command parameter is that it allows to take the output of a command as a parameter with the following syntax.

Host foo
ProxyCommand $(/path/to/pcr.py %h) # for example $HOME/.ssh/pcr.py

The configuration elements works as follow: * ProxyHost: correspond to the configuration that apply to a SSH Host alias.

  • Host: the Host Alias as defined in the SSH configuration

  • Proxy: Delimits a ProxyCommand and the conditions that lead to this specific ProxyCommand

  • DefaultNetworkInterfaceName: the name of the default network interface that must be matched

  • LocalConnectionName: either the ESSID or the name of the connection defined in the NetworkManager.

  • DefaultNetworkIPAddress: the IP address of your default interface.

A Condition section defines one or multiple conditions that must apply to chose a specific ProxyCommand. A Proxy that have the fallback="yes" attribute is used in case of any of the previous Proxy's Condition(s) worked.

This script is designed to work on Linux and has been tested on Ubuntu LTS only. Use at your own risks!

I hope it will help you to save some of your SSH configuration edition time ;)