How To Share One Port Number For HTTPS, ssh, and OpenVPN

Some corporate security folk try to ‘secure’ their networks by only permitting a small subset of ports outbound, such as port 80 and 443 only.

That’s annoying, particularly when you’re using their WiFi and trying to turn on your VPN so you can securely access your corporate systems because you don’t trust whatever is happening on that corporate’s network. This happened to me earlier today for the first time in ages.

The last time it happened, I just ran a VPN listener on port 443, which solved the problem nicely, but only for the VPN. What if you want to run a webserver on that machine as well?

You might be thinking that an nginx server could proxy the connection to the VPN with a stream {} context, but alas, no. This doesn’t work, because that’s for bare UDP or TCP connections only. The normal HTTPS multiplexing solution uses name-based virtual hosting which uses the HTTP Host: header to figure out which virtual server to talk to. That’s not available when you’re making an ssh or OpenVPN connection.

sslh To The Rescue

The handy tool you want is available for Linux and is called sslh.

There’s a good guide to configuring it here and the documentation is here.

I’ll summarise in case the guide goes away.

First you install it using your package manager. I use Ubuntu, so it’s a simple:

sudo apt install sslh

Then you configure it via /etc/ssl/default like so:

# Once configuration ready, you *must* set RUN to yes here
# and try to start sslh (standalone mode only)

DAEMON_OPTS="--user sslh --listen <public_ip>:443 --ssh --ssl --openvpn --pidfile /var/run/sslh/"

Then, reconfigure your web server to listen on localhost:443 instead of <public_ip>:443 so you don’t get two daemons trying to listen on the same port at once.

sslh will then determine what kind of protocol is connecting on port 443 and redirect it to the appropriate server using a port hand-off.



Bookmark the permalink.

One Comment

  1. Very Very helpful thank you!!!

Comments are closed