ETOOBUSY 🚀 minimal blogging for the impatient
SSH through a proxy
A setup to connect an SSH client to a destination through a web proxy.
Networks are partitioned, and this is a Good Thing. Sometimes it’s possible to overcome some of the restrictions, which is good to know (it’s at least good to know the limits of the fences that are in place, anyway).
In this case, we’re assuming that all traffic to the outside is allowed through a web proxy, with the clear intent to allow… web traffic only.
Now Alice wants to connect with her laptop in the inside network to her server in the outside network, using SSH. Which is, as we saw, forbidden because all ports are forbidden for direct access.
In this case, Alice can try to convince the proxy to let her through with a little effort and some help from a few programs.
The gist of this technique is to make the SSH client “proxy aware” by
means of a helper program, by means of the
ProxyCommand option. Let’s
see some examples.
Netcat from BSD
A basic command to make it work relies on the availability of the BSD flavor of Netcat:
ssh -o "ProxyCommand=nc -X connect -x $proxy_host:$proxy_port %h %p" \ $user@$target_host
The variables have sensible names: data about proxy goes in
$proxy_host:$proxy_port, the rest is the usual connection details.
-X has been set to
connect in the example; it can also be set to
5, respectively for a SOCKS4 or SOCKS5 proxy type.
More can be found here.
Netcat from Nmap
The BSD flavor of Netcat has options
-x which are not part of
the original Netcat. It turns out that the Nmap flavor of Netcat
(usually named ncat) has two equivalent long options, respectively
ssh -o "ProxyCommand=ncat --proxy-type http --proxy $proxy_host:$proxy_port %h %p" \ $user@$target_host
The hint is still here, though it’s not that explicit about the flavor of Netcat. Whatever!
Also in this case it’s possible to specify a different
(which corresponds to using a CONNECT
setting it to socks4
and socks5` instead.
There are a few programs that will always appear as too damn useful and simple to use for me to really understand them, and socat is one of them.
It too supports going through the proxy:
ssh -o "ProxyCommand=socat - PROXY:$proxy_host:%h:%p,proxyport=$proxy_port" \ $user@$target_host
It’s interesting that no answer in this post makes any reference to Netcat… go figure.
Also in this case, there is a variant for the SOCKS4 proxy:
ssh -o "ProxyCommand=socat - SOCKS4:$proxy_host:%h:%p,socksport=$proxy_port" \ $user@$target_host
The versions of socat I had access to are all in the 1.7 series and don’t support SOCKS5 though. If one that does is available, though, this is the command copied from the post cited above:
ssh -o "ProxyCommand=socat - 'SOCKS5:%h:%p|TCP:$proxy_host:$proxy_port'" \ $user@$target_host
This appears to be supported in socat version 2 only, which I don’t have… so I’m not sure that the above line actually works. Cross fingers!
Saving for the future
Whatever the tool, it’s possible to set the
ProxyCommand option in the
~/.ssh/config file to avoid typing the option over and over:
Host target HostName target.example.com User foobar ProxyCommand ncat --proxy-type http --proxy proxy.example.com:8080 %h %p
This said… so long, and stay safe folks!