The instructions below assume you are using Ubuntu 16.04 but they will work for other Linuxes with minor modifications. The instructions below will also conflict with a webserver listening on port 443 ( https ) so you’ll need to disable it. Once the setup below is complete your https connections will get seamlessly forwarded to port 80.
Setup letsencrypt keys
For the SSL connection to be secure and trusted by browsers and other software you need to have a certificate signed by a recognised certificate authority. The easiest way to do this is to use letsencypt’s certbot. I’m not going to go into how to get the certificate as there are too many ways depending on your configuration. Just follow letsencrypt’s documentation to generate a key for your "servernname.com" that will get used in the rest of these instructions.
You could also use a self signed key but that may cause you problems with stateful firewalls.
With your certificate installed on the server you can now setup stunnel to use it. crow shows a partial setup here. I think he’s limited the ciphers for increased security but I found it was not necessary.
sudo apt-get install stunnel4
So the setup in /etc/stunnel/stunnel.conf I am using looks like this
pid = /var/run/stunnel.pid cert = /etc/letsencrypt/live/servername.com/fullchain.pem key = /etc/letsencrypt/live/servername.com/privkey.pem [ssh] accept = servername.com:443 connect = localhost:80
You also need to enable stunnel in /etc/default/stunnel4.conf by setting ENABLED=1
restart stunnel to use the new configuration.
systemctl restart stunnel4
At this point you can test the stunnel setup by going to “http://servername.com” with your browser and you will have a secure connection to your http server.
To prep for the sslh configuration change
connect = localhost:80
in /etc/stunnel/stunnel.conf to
connect = localhost:1022
and then restart stunnel again.
sslh will redirect the sessions decrypted by stunnel to the correct port on your server.
You need to install sslh
sudo apt-get install sslh
The minimum services I wanted are ssh and http so my configuration in /etc/default/sslh looks like this.
RUN=yes # binary to use: forked (sslh) or single-thread (sslh-select) version DAEMON=/usr/sbin/sslh DAEMON_OPTS="--user sslh --listen 127.0.0.1:1022 --http 127.0.0.1:80 --ssh 127.0.0.1:22 --pidfile /var/run/sslh/sslh.pid"
The sslh documentation says that OpenVPN, tinc, XMPP are also supported but I didn’t need those so my configuration doesn’t support them. You can now restart sslh
sudo systemctl restart sslh
This would be another good time to test the stunnel -> sslh -> httpd redirection by visiting “http://servername.com” in your browser.
Client side ssh setup
Once all of the above is complete and assuming that you have an ssh server that you can connect to on port 22 of your server the ssh client can be setup to use the ssl tunnel. The ssh session needs to wrapped in the ssl session to be able to connect to the server so I used the ssh ProxyCommand to accomplish this. Add the section below to your ~/.ssh/config on your client machine
Host servername.com ProxyCommand /usr/bin/socat - OPENSSL:servername.com:443
From the client you should now be able to connect to your server by doing
If you get errors from ProxyCommand about your keys or if you used a self signed certificate you will need to turn off key verification.
Host servername.com ProxyCommand /usr/bin/socat - OPENSSL:servername.com:443,verify=0
There is usually one other modification I have in my ssh config and that is a DynamicProxy so that stateful packet inspection doesn’t interfere. So the final configuration looks like this.
Host servername.com DynamicForward localhost:2121 ProxyCommand /usr/bin/socat - OPENSSL:servername.com:443
The interested reader should look into FoxyProxy to see how this might be used.