Introduction

SSLH is like a magic trick. It allows you, for example, to have both HTTPS and SSH on a WAN address on port 443. How is this possible? Can we have a single listening port for multiple services?

Indeed! You just need to see SSLH as a layer 7 proxy capable of filtering and differentiating between SSL frames and SSH frames.

Installation

Debian

On Debian, it’s an easy move:

  aptitude install sslh
  

FreeBSD

For installation on FreeBSD:

  pkg_add -vr sslh
  

OpenBSD

On OpenBSD for version 1.7:

  wget http://www.rutschle.net/tech/sslh-1.7a.tar.gz
tar -xzvf sslh-1.7a.tar.gz
cd sslh-1.7a
cc -o sslh -DLIBWRAP sslh.c -lwrap
cp sslh /usr/local/sbin
  

For the latest versions:

  wget http://www.rutschle.net/tech/sslh-1.10.tar.gz
tar -xzvf sslh-1.10.tar.gz
cd sslh-1.10
make
make install
  

Note: With the latest versions, you’ll end up with 2 binaries: sslh-fork and sslh-select. sslh-select is for a single thread while sslh-fork is multi-threaded.

Configuration

Debian

If you’re on Debian, it’s simple. Create a file in /etc/default/sslh with the following content:

  LISTEN=ifname:443
SSH=localhost:22
SSL=localhost:443
  
  • LISTEN: This is the IP of the interface and the listening port of SSLH. It must be the input listening port (WAN for example), the one through which your clients will pass.
  • SSH: The address and port corresponding to your SSH port
  • SSL: The address and port corresponding to your HTTPS port

FreeBSD

To configure SSLH, just add these lines to rc.conf:

  # SSLH
sslh_enable="YES"
sslh_mode="select"
# sslh_fib="NONE"
sslh_pidfile="/var/run/sslh/sslh.pid"
sslh_ssltarget="websrv:443"
sslh_sshtarget="localhost:22"
sslh_sshtimeout="2"
sslh_listening="192.168.0.254:443"
sslh_uid="nobody"
  

OpenBSD

On OpenBSD, I chose to add these lines to /etc/rc.local with my configuration directly in the command line:

  if [ -x /usr/local/sbin/sslh ] ; then
    # Versions < 1.7a
    /usr/local/sbin/sslh -p <interface:443> -s <ssh_srv:22> -l <web_https:443>
    # Versions >= 1.10
    /usr/local/sbin/sslh -P /tmp/sslh.pid -p <interface:443> --ssh <ssh_srv:22> --ssl <web_https:443>
    echo 'SSLH'
fi
  

Again, adapt these lines according to your needs.

pfSense

On pfSense, we’ll create an init-like file:

  #!/bin/sh
sslh_listen_ip=<interface_ip>
sslh_listen_port=<port>
ssh_redirect_ip=<interface_ip>
ssh_redirect_port=<port>
ssl_redirect_ip=<interface_ip>
ssl_redirect_port=<port>

rc_start() {
	/sbin/sslh-fork -P /tmp/sslh.pid -p $sslh_listen_ip:$sslh_listen_port --ssh $ssh_redirect_ip:$ssh_redirect_port --ssl $ssl_redirect_ip:$ssl_redirect_port &
}

rc_stop() {
	/usr/bin/killall sslh-fork
}

case $1 in
	start)
		rc_start
		;;
	stop)
		rc_stop
		;;
	restart)
		rc_stop
		rc_start
		;;
esac
  

Adapt the beginning of the script with your desired information.

Then set the appropriate permissions:

  chmod +x /usr/local/etc/rc.d/sslh.sh
  

FAQ

I have Zombie sslh processes on OpenBSD

I’ve experienced zombie processes with each connection attempt to the SSH server. To fix this issue, here’s a patch for version 0.7:

  462a463,464
>    if (fork() > 0) exit(0); /* Detach */
>
467,468d468
<    if (fork() > 0) exit(0); /* Detach */
<
  

Last updated 10 Jun 2012, 09:31 CEST. history