Tunnel SSH over SSL

By | 2013/11/27

Tunnel SSH over SSL

Have you ever found yourself behind a restrictive firewall that only allows outbound http(s) traffic, but you need to SSH out? Perhaps you’ve tried running SSH on port 443 (https) but those connections have been denied as well. In this post I’ll outline how to configure stunnel on an SSH server to allow encrypted SSH connections over port 443 (https).

This configuration is done in two parts. The first half is done on the remote SSH server. The second half is done on the local machine. In this case I’m running Ubuntu Server and Ubuntu Desktop for the client.

Server Side Instructions:

First off we’ll need to install the stunnel package:

sudo apt-get install stunnel4

Once the package is installed we’ll need to configure stunnel with an SSL certificate and a config file. First, the SSL certificate:

openssl genrsa 1024 > stunnel.key
openssl req -new -key stunnel.key -x509 -days 1000 -out stunnel.crt
cat stunnel.crt stunnel.key > stunnel.pem
sudo mv stunnel.pem /etc/stunnel/

Configure stunnel to tunnel 443 (https) to 22 (ssh):

By default stunnel doesn’t provide any config files. We’ll create a simple config file to meet the needs of using SSH over SSL. Create a new file, /etc/stunnel/stunnel.conf and copy in the contents below:

pid = /var/run/stunnel.pid
cert = /etc/stunnel/stunnel.pem

[ssh]
accept = public_ip:443
connect = 127.0.0.1:22

The above configuration tells stunnel where to find the certificate we generated and where to accept and forward connections. In this case stunnel will listen on the public_ip on port 443 (https) and redirect connections there back to localhost on 22 (ssh).

In order to start the stunnel service we’ll need to activate it in /etc/default/stunnel4. Change the ENABLED line from 0 to 1.

Finally, we can start the service and move on to the client configuration:

sudo service stunnel4 start

You can verify that stunnel is now listening by using the netstat command:

netstat -natp | grep :443

Client Side Instructions:

The rest of these instructions are done on the local machine.

As was done on the server, we’ll need to install the stunnel package:

sudo apt-get install stunnel4

The client configuration also needs the same SSL certificate that we generated above. copy/paste or otherwise duplicate the .pem file we generated in the Server Side Instructions and save it to the same location, /etc/stunnel/stunnel.pem.

We’ll need to create a similar configuration file, only this time we’ll change the accept and connect sections. Use the example below to populate the /etc/stunnel/stunnel.conf on your client.

pid = /var/run/stunnel.pid
cert = /etc/stunnel/stunnel.pem

[ssh]
accept = 127.0.0.1:2200
connect = remote_ip:443

With the config file and certificate in place we’re ready to enable stunnel and start the service. Enable the service (as above) in the /etc/default/stunnel4 and then start the service.

sudo service stunnel4 start

Make the connection

With the stunnel service now running on both the server and the client we’re ready to make the secure connection. Now when you connect to your local machine on port 2200 it will make a connection to the remote IP on port 443, create a secure SSL connection, and connect to port 22 on the other end. Your encrypted SSH connections are now wrapped in an encrypted SSL connection using port 443.

ssh localhost -p 2200

Conclusion

stunnel can be used to encrypt a wide range of services. In this case creating an SSL connection over the standard https port allows you to SSH out even when the standard SSH port is blocked. This configuration will become part of my standard setup on my SSH servers. You never know when you’ll find yourself in a situation where you’ll need this kind of access!