Install SSLH on Ubuntu 18.04

What is sslh?

sslh probes for HTTP, TLS/SSL (including SNI and ALPN), SSH, OpenVPN, tinc, XMPP are implemented, and any other protocol that can be tested using a regular expression, can be recognized and then forwards based on its findings to where it needs to go.

Quick overview

The reason I wanted to use sslh was to use a bunch of different processes to run over port 443 so I could check lots of information about my home server from anywhere and perform admin tasks if needed without being subject to restrictive firewalls. But, I was very concerned that with 15+ websites, sslh would not know which website to go to. So, instead of just worrying, I just “turned it on” to see what would happen…
First off, keep all your websites running on ports 80 and 443. I am doing it this way because I did not want to change all of my configurations which would have sucked to do. Run sslh on a different port, for this guide I used 4443, but you can use whatever port you like (that isn’t in use anyway: netstat -peanut | grep LISTEN). Then, on your router, forward all 443 traffic to the port you choose for sslh. So in this example, 443 -> 4443.
This is how it works in a nutshell, and I hope this guide helps you configure it and gets you up and running!

Word of caution

I would say that this set up isn’t exactly the most secure one. I ran all the commands below as an admin and if I could do it over again, would probably have made a dedicated user. I also would like to eventually (not any time soon), make the systemd service file more secure and add in the ability to know what IP are actually connecting to my web services. For now, all they show are localhost connections… so secure from that perspective, but not useful if you have bots, spam, etc. and need the ability to block and/or use this information.

Install sslh on Ubuntu 18.04 Server

Install conf2struct

  1. cpan Conf::Libconfig
  2. Type yes to have perl autoconfig as much as possible
  3. git clone https://github.com/yrutschle/conf2struct.git&&cd conf2struct
  4. make
  5. make install

Install sslh

  1. apt install libwrap0-dev libconfig-dev libbsd-dev
  2. git clone https://github.com/yrutschle/sslh.git&&cd sslh
  3. make
    Get an error like:
sslh-conf.c:39:10: fatal error: pcreposix.h: No such file or directory
  1. apt install libpcre3-dev
    If no errors, or after installing the package above and after running make again:
  2. make install

Configure your system(d)

  1. cp scripts/etc.init.d.sslh /etc/init.d/sslh
  2. update-rc.d sslh defaults

Make a sslh config file

  1. nano /etc/sslh.cfg
  2. Replace what you will use here (and use your external IP for the listen section OR local ip [just not 127.0.0.1]):
verbose: 1;
foreground: false;
inetd: false;
numeric: false;
transparent: false;
timeout: 5;
user: "nobody";
pidfile: "/var/run/sslh.pid";
chroot: "/var/empty";

listen:
(
{ host: "pub.lic.ip.addr"; port: "443"; }
);

protocols:
(
{ name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; fork: true; },
#{ name: "openvpn"; host: "localhost"; port: "1194"; },
#{ name: "xmpp"; host: "localhost"; port: "5222"; },
#{ name: "http"; host: "localhost"; port: "80"; },
#{ name: "ssl"; host: "localhost"; port: "443"; log_level: 0; },
#{ name: "anyprot"; host: "localhost"; port: "443"; }
);
  1. This is the “bare minimum” file that you need to make sure everything is up and running.
  2. For a more advanced file to configure everything in your wildest dreams see this file.
  3. Ultimately, the config I used when everything was said and done:
verbose: 1;
foreground: false;
inetd: false;
numeric: false;
transparent: false;
timeout: 3;
user: "nobody";
pidfile: "/var/run/sslh.pid";
chroot: "/var/empty";

# Change "192.168.2.28" to your local ip address `ifconfig` (untested in this guide, but use your public ip address here).
listen:
(
{ host: "192.168.2.28"; port: "4443"; }
);

protocols:
(
{ name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; keepalive: true; fork: true; log_level: 0; tfo_ok: true },
{ name: "openvpn"; host: "localhost"; port: "1194"; log_level: 0; },
# { name: "regex"; host: "localhost"; port: "1194"; regex_patterns: [ "^\x00[\x0D-\xFF]$", "^\x00[\x0D-\xFF]\x38" ]; },
{ name: "tls"; host: "localhost"; port: "443"; alpn_protocols: [ "h2", "http/1.1", "h2c" ]; log_level: 1; tfo_ok: true },
# { name: "tls"; host: "localhost"; port: "443"; alpn_protocols: [ "webrtc", "c-webrtc" ]; sni_hostnames: [ "im.somethingelse.net" ]; log_level: 0; tfo_ok: true },
{ name: "tls"; host: "localhost"; port: "5349"; alpn_protocols: [ "stun.turn" ]; log_level: 0; tfo_ok: true }, #not working...#
{ name: "tls"; host: "localhost"; port: "443"; log_level: 1; tfo_ok: true },
{ name: "anyprot"; host: "localhost"; port: "443"; },
{ name: "timeout"; service: "daytime"; host: "localhost"; port: "daytime"; }
);

# Optionally, specify to which protocol to connect in case of timeout (defaults to "ssh").
on-timeout: "timeout";

# ADDITIONAL PROTOCOL EXAMPLES
# just match ALPN { name: "tls"; host: "localhost"; port: "xmpp-client"; alpn_protocols: [ "xmpp-client" ]; log_level: 0; tfo_ok: true },
# just match SNI { name: "tls"; host: "localhost"; port: "xmpp-client"; sni_hostnames: [ "im.rutschle.net", "im.englishintoulouse.com" ]; log_level: 0; tfo_ok: true },
# Let's Encrypt (tls-alpn-* challenges) { name: "tls"; host: "localhost"; port: "letsencrypt-client"; alpn_protocols: [ "acme-tls/1" ]; log_level: 0;},
# OpenVPN { name: "regex"; host: "localhost"; port: "1194"; regex_patterns: [ "^\x00[\x0D-\xFF]$", "^\x00[\x0D-\xFF]\x38" ]; },
# Jabber { name: "regex"; host: "localhost"; port: "5222"; regex_patterns: [ "jabber" ]; minlength: 60; # Won't even try to match the regex if we don't have that many bytes },
# Catch-all (but better use 'anyprot') { name: "regex"; host: "localhost"; port: "443"; regex_patterns: [ "" ]; },

Start sslh

  1. systemctl start sslh
  2. You’ll more than likely get a lot of errors like:
sslh[16209]: /etc/init.d/sslh: 30: /etc/init.d/sslh: /sbin/sslh: not found

and/or

sslh[16885]: chrooting into /var/empty
sslh[16885]: common.c:818:chroot: No such file or directory
  1. For the first error nano /etc/init.d/sslh and my PREFIX was empty. I typed which sslh to find out sslh install path, and put /usr in PREFIX.
  2. Reload the changes systemctl daemon-reload
  3. For the second error, create the empty directory and change permissions to nobody:
mkdir /var/empty
chown -R nobody:nobody /var/empty
  1. For any other errors, just use: journalctl -xe -u sslh
  2. After you have fixed all the errors (if any), start the server systemctl start sslh
  3. Ensure that it is actually running using either systemctl status sslh or netstat -peanut | grep :443

Change traffic from router

  1. Every router is different, but basically, change your port forward from your existing rule of 443 -> 443 to 443 -> 4443.
  2. If you have any existing connections, you will more than likely need to reboot your router in order to disconnect them, and enable your new rule.

GOOD LUCK!!!

And I hope this guide helped you.

If you need any help, there are several ways to get a hold of me:
diaspora*: danieldoubet@nota.404.mn
Matrix: daniel@dou.bet

Other

The featured imaged was retrieved from HackerNoon at 9:54AM on October 14, 2019.

Leave a comment

Your email address will not be published. Required fields are marked *