A while ago in the Transparent SSH host-jumping (Advanced) post I described a technique on how one could jump quite effortlessly through a chain of intermediate hosts. However, there was a catch: the user names and ports across the whole chain should be the same and there was no easy way to change that.
Given that I recently paid quite a lot of attention to the ProxyCommand directive I decided to look into the implementation of the helper script that will allow one to tweak parameters for the hosts in the chain.
You can read the original post for the details of how this host-jumping technique works, here I am only going to provide the proxy script and the corresponding ssh config parameter block to use the script.
The goal was to support the following syntax:
It was a little challenge to come up with the character for identifying the user part for intermediate hosts:
@- cannot be used since SSH parses the command line before providing the string to the ProxyCommand script
%- cannot be used since SSH was thinking that I’m trying to do an expansion of the internal SSH variable
&- are all shell unfriendly
So I decided on the
^ character as a delimiter.
In the proposed command above the “default_user” is the user name we ultimately want to use for logging into the last host in the chain (it happens that this user name will be used for any host in the chain where no alternative name is provided).
Each host in the chain could also be provided with the relevant port or, if the
port is omitted, it will use the global port configuration (usually 22/tcp but
can be changed with the
-p argument to ssh). The script is a bit not optimised
(bash is really slow on string processing, but I decided to stick with pure
bash where it was possible):
The above is a proof of the concept and it “works for me” :). I am using it every day when I need to access boxes behind a bastion host. Your mileage may vary and you are free to create your own version of the script that would perform better (I would be really glad if a version of such a script could be shared with me).
The corresponding configuration block in the ssh config file looks as follows:
Well, this is a bit messy since OpenSSH introduced the
%C macro in version 6.7
ControlPath string gets too long for OpenSSH to create a
socket on the filesystem for long chains of hosts.