HOWTO connect to SSH via SSL with sslh

13 Aug 2013, 09:38

Since I’m in the commandline fulltime, SSH is an indispensable tool for ‘getting things done’ - heck, I even run it on my Android phone now so I can poke around there (haven’t broken anything… yet), so when I’m traveling or at a client’s site that doesn’t allow outgoing ssh (port :22) we have a problem. In the past I’ve always mapped SSH to some port other than :22 to prevent drive-by brute forcing login attempts, so I’ve put it on :443 (which is rarely blocked for outgoing is connections), but now that I’m running this site with SSL, that is no longer an option. Yes, we could try out :8080 (Tomcat’s port), :8443 (Tomcat’s SSL port) or :8181 (Debian’s old Tomcat port), but we’ll always have a better chance to get out over :443. While I’ve read how this might be possible using the great HAProxy, that always seemed like overkill and begged for a simplier solution. Apparently there already was one, I had just never heard of it; sslh is an applicative protocol multiplexer, that forward ports initially sent to :443 on to other needed ports. Their description on what it can do:

Probes for HTTP, SSL, SSH, OpenVPN, tinc, XMPP are implemented, and any other protocol that can be tested using a regular expression, can be recognised. A typical use case is to allow serving several services on port 443 (e.g. to connect to ssh from inside a corporate firewall, which almost never block port 443) while still serving HTTPS on that port.

Sounds perfect, so I went to install and configure it, and it was easier than I expected so let’s get started - first of all I found a schmatic that illustrates what’s happening [source]

The package is already in Debian’s Wheezy repo, and likely others, so for me it was simple to get rolling:

apt-get install sslh

Now let’s take a look at how to configure it and get it working. First we’ll want to tell the webserver to listen on 127.0.0.1:443, instead of on all interfaces, 0.0.0.0:443, which it is usually doing by default. I use nginx, so it was a matter of changing the following

listen 443 ssl;

to

listen 127.0.0.1:443 ssl;

Now we’ll then test the nginx config to make sure we don’t have any ttyyppos (it happens)

nginx -t

If all is good, we’ll restart nginx so it’ll start listening on 127.0.0.1 and not 0.0.0.0

Did it work? Great! If not, rerun the command with ssh -v to debug the issue.

This opens up a lot of new options, from connecting to a local XMMP/jabber server to a more reliable way to conect home via OpenVPN, but also raises the question of security. I’ll do some tests on that and report back on what is exposed by sshl to the outside when a client hits :443.