SSLH: A SSL/SSH Multiplexer for Linux

What is sslh?

sslh accepts connections in HTTP, HTTPS, SSH, OpenVPN, tinc, XMPP, or any other protocol that can be tested using a regular expression, on the same port. This makes it possible to connect to any of these servers on port 443 while still serving HTTPS on that port.

What it does for you?

Basically you can access your remote server/system via HTTP, HTTPS, SSH, OpenVPN and some other protocols. But the only problem is some internet service providers or your company firewalls don’t allow you to connect to remote servers/systems via these ports except some specific ports such as HTTP (80), HTTPS (443). So what if you want to access the servers via SSH when all the other ports are blocked?

The only solution is that you can use the same port HTTPS (443), for SSH protocol. This is where a tiny tool called sshlh will help you to acheive this goal. It simply allows you to connect to the servers via SSH on port 443, while the web server is using the same port.

Install sslh

On Ubuntu/Debian:

$ sudo apt-get install sslh

On CentOS/RHEL:

It will not be found on official repositories. So install RPMForge repository using the following command.

[root@server ~]# rpm -ivh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.i686.rpm

Now install sslh:

$ yum install sslh -y

Configure webserver

By default, your webserver will listen on all network interfaces. Make sure that the apache is listening only to localhost:443 port instead of *.443 port. After editing the webserver config file, restart apache service.

Configure SSLH

Open the sslh config file.

On Ubuntu/Debian:

$ sudo vi /etc/default/sslh

Change the line Run=no to yes:

# Default options for sslh initscript
# sourced by /etc/init.d/sslh

# Disabled by default, to force yourself
# to read the configuration:
# - /usr/share/doc/sslh/README.Debian (quick start)
# - /usr/share/doc/sslh/README, at "Configuration" section
# - sslh(8) via "man sslh" for more configuration details.
# Once configuration ready, you *must* set RUN to yes here
# and try to start sslh (standalone mode only)

RUN=yes

# binary to use: forked (sslh) or single-thread (sslh-select) version
DAEMON=/usr/sbin/sslh
DAEMON_OPTS="--user sslh --listen 0.0.0.0:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --pidfile /var/run/sslh/sslh.pid"

Save and exit the file. Restart sslh daemon:

sudo /etc/init.d/sslh restart
* Restarting ssl/ssh multiplexer sslh                                   [ OK ]

On CentOS/RHEL:

vi /etc/rc.d/init.d/sslh

Find the following line:

OPTIONS="--user nobody --pidfile $PIDFILE -p  0.0.0.0:8443 --ssl 127.0.0.1:443 --ssh 127.0.0.1:22"

Change the port 8443 to 443 as shown below:

OPTIONS="--user nobody --pidfile $PIDFILE -p  0.0.0.0:443 --ssl 127.0.0.1:443 --ssh 127.0.0.1:22"

Save and exit the file. Restart the sslh daemon:

[root@server ~]# /etc/init.d/sslh start
Starting SSL-SSH-Switch: /bin/bash: /usr/local/sbin/sslh: No such file or directory [FAILED]

You may get an error like this. This is because sslh executable path may be defined incorrectly in sslh config file. So open up sslh config file and change the path. You can find the executable path of sslh using the following command:

[root@server ~]# which sslh
/usr/sbin/sslh

As per the above output /usr/sbin/sslh is our sslh executable path. So lets change it in config file:

vi /etc/rc.d/init.d/sslh 
[...]
# Source function library.
. /etc/init.d/functions
# ./sslh -p  0.0.0.0:8443 -l 127.0.0.1:443 -s 127.0.0.1:22

SSLH="/usr/sbin/sslh"
PIDFILE="/var/run/sslh"
[...]

Save and exit the file. Now start the sslh daemon:

[root@server ~]# /etc/init.d/sslh start

Now it will start without any error.

Testing SSLH

The SSLH is running well now, you can check it with the follwoing command:

On RHEL/CentOS:

[root@server ~]# ps -ef | grep sslh 
nobody    1660     1  0 19:24 ?        00:00:00 /usr/sbin/sslh --user nobody --pidfile /var/run/sslh -p 0.0.0.0 443 --ssl 127.0.0.1 443 --ssh 127.0.0.1 22
nobody    1662  1660  0 19:24 ?        00:00:00 /usr/sbin/sslh --user nobody --pidfile /var/run/sslh -p 0.0.0.0 443 --ssl 127.0.0.1 443 --ssh 127.0.0.1 22
nobody    1684  1662  0 19:33 ?        00:00:00 /usr/sbin/sslh --user nobody --pidfile /var/run/sslh -p 0.0.0.0 443 --ssl 127.0.0.1 443 --ssh 127.0.0.1 22
root      1751  1688  0 19:48 pts/1    00:00:00 grep sslh

On Ubuntu/Debian:

sk@sk:~$ ps -ef | grep sslh
sslh     11053     1  0 19:20 ?        00:00:00 /usr/sbin/sslh --user sslh --listen 0.0.0.0 443 --ssh 127.0.0.1 22 --ssl 127.0.0.1 443 --pidfile /var/run/sslh/sslh.pid
sslh     11055 11053  0 19:20 ?        00:00:00 /usr/sbin/sslh --user sslh --listen 0.0.0.0 443 --ssh 127.0.0.1 22 --ssl 127.0.0.1 443 --pidfile /var/run/sslh/sslh.pid
sk       11060  2718  0 19:21 pts/2    00:00:00 grep --color=auto sslh

Now try to connect to your server via SSH with port 443:

sk@sk:~$ ssh -p 443 root@192.168.1.200
Last login: Wed Jul  3 19:33:51 2013 from localhost

You’ll be able to connect to server via ssh with port 443 instead of default SSH port.