SSH over SSL, episode 2: replacing proxytunnel with socat

If you are reading this, you might be interested in the full list of my articles about doing SSH over SSL. I have been improving my configuration over the years, so the more recent, the better:

Last week, I wrote an article about how to quickly set up a server and a client for doing ssh over ssl. In this article, I was using proxytunnel, but I realized today that it could probably be replaced with socat (socat can do almost anything)...

The principle is simple: Following the first part of the tutorial, you make your server accept proxy_connect requests to its private port localhost:22 through its public port 443, encapsulating the whole thing in SSL (as a reminder, 22 and 443 are respectively the standard ports for ssh and ssl).

We now want to configure the ssh clients in order to connect through this ssl tunnel. I said I was configuring the clients with proxytunnel. The exact command (in .ssh/config) was:

proxytunnel -q -E -p -d

I'll explain it:

  • -q is for quiet
  • -E is for encrypting between the proxy and us
  • -p is for choosing the proxy
  • -d is for requesting a destination (from the proxy point of view)

So basically, this means: "connect stdio to on port 443 (-p , in an encrypted way (-E), then from this server, require to be connected to (-d".

For those who like to play with all sorts of streams, socat is really the best tool ever invented. I was wondering if I could reproduce proxytunnel's behavior with socat, and it turns out you can. Here is how to proceed: First, create an ssl tunnel between your client's localhost:1080 and

socat TCP-LISTEN:1080

This way, the port 443 of is now available unencrypted on localhost:1080 Then, use socat and its proxy mode to ask for localhost:1080 (which is actually unencrypted) to connect to localhost:22 (which is then

socat - PROXY:,proxyport=1080

Bingo! You should see the ssh prompt. For the fun, I replaced in my .ssh/config the former

ProxyCommand proxytunnel -q -E -p -d


ProxyCommand socat TCP-LISTEN:1080,verify=0 & socat - PROXY:,proxyport=1080

Edit 2015-05-07: See Vincent's comment for a cool idea to wrap the ssh command with the -fMN options.

It works just fine. There is however a flaw in what I did: I use a hardcoded port, thus I can't establish two ssh connections at the same time. Forwarding the on localhost:1080 fails the second time, since this port is already occupied by the first connection. The best way to fix that would be to use stdio for the proxy_connect requests, instead of a port of localhost (since the number of these port is limited). However, with my version of socat (, I don't see how to proceed differently: the PROXY method requires three arguments and one of them is a port. If one of my readers has a suggestion, he/she's welcome. This remains a cool hack!

Edit: The great Marco Fontani gave a cool solution (see the comments). Here is how my .ssh/config looks like:

    ProxyCommand socat TCP-LISTEN:1080,verify=0 & sleep 1 && socat - PROXY:,proxyport=1080
    DynamicForward 1080
    ServerAliveInterval 60
    ControlMaster auto
    ControlPath ~/.ssh/tmp/%h_%p_%r

Comments !