My last article talked about installing an OpenVPN service on OpenBSD and FreeBSD. Unfortunately, one of my servers (on FreeBSD) died some days after, and, actually, I don’t have time to reinstall one from scratch, so, this article will be only on OpenBSD.

Why hiding a VPN solution? Sometimes, your internet provider or your free hotspot in the street will not allow some network flow and will force you to use only classical and common transport port in TCP (80, 443) or UDP (53), all other network flow will be dropped

[sslh](https://github.com/yrutschle/sslh) is a really interesting tool. With this one, you can multiplex different kind of connection an forward them in another place. In our example, we will configure sslh to listen on https port (443) and forward different kind of network traffic (ssh, http, https and openvpn). You can launch sslh with two different services, by using sslh_fork (multithreaded and multiprocesses) or sslh_select (one thread and less tested). I will use sslh_fork, I am using it for a long time now, and I never had any kind of issue with it.

pkg_add sslh  
mkdir -p /etc/sslh  
touch /etc/sslh/sslh.cfg  
rcctl enable sslh_fork  
rcctl set sslh_fork flags -F /etc/sslh/sslh.cfg

Our main configuration is located in /etc/sslh/sslh.cfg, but, if you want, you can also create a file directly in /etc/sslh.cfg. The content is straight forward and pretty simple to understand.

verbose: true;  
foreground: false;  
inetd: false;  
numeric: false;  
transparent: false;  
timeout: 2;  
user: "_sslh";  
pidfile: "/var/run/sslh.pid";  
chroot: "/var/empty";  
syslog_facility: "auth";

listen:  
(  
    { host: "${your_remote_hostname}"  
    ; port: "80"  
    ; keepalive: true; },  
    { host: "${your_remote_hostname}"  
    ; port: "443"  
    ; keepalive: true; }  
);

protocols:  
(  
     { name: "http"  
     ; host: "localhost"  
     ; port: "80"; },

{ name: "tls"  
     ; host: "localhost"  
     ; port: "443"; },

{ name: "ssh"  
     ; host: "localhost"  
     ; port: "22"; },

{ name: "openvpn"   
     ; host: "${your_remote_hostname}"  
     ; port: "1194" }  
);

on-timeout: "timeout";

Where ${your_remote_hostname} contain the hostname for all your forwarded request. By default, I am using localhost except for OpenVPN, this one only listen on my remote(s) interfaces. We can now test our configuration and start our service.

sslh -f -F /etc/sslh/sslh.cfg  
rcctl start sslh_fork

# In depth

The first part of the configuration contains only some flags for the global sslh running process. The second part, listen, contains the configuration of all listening socket controlled by sslh. In our example, sslh will listen on 2 remotes ports, http (TCP/80) and https (TCP/443).

The last part is one of the most important part, and will contain all forwarded connection based on different kind of pattern. In our example, we manage to forward 4 connections types:

  • http connections are redirected to localhost on port 80

  • https connections are redirected to localhost on port 443

  • ssh connections are redirected to localhost on port 22

  • openvpn connections are redirected to our remote ip address based on hostname on port 1194

# What’s wrong?

This method works well in many cases, but, sometimes, system and network administrators create complex and particularly hardcore filtering rules and, furthermore, will use some tools like snort (NIDS, Network Intrusion Detection System) to filter the flow. This kind of tools are enough intelligent to filter specific content from different port. If you really want to bypass this kind of tools, you should use stunnel or another tool to hide properly our tunnel.

Another thing, sslh is actually only for TCP, and doesn’t support UDP connection. You can use [nstxd](http://thomer.com/howtos/nstx.html) or [iodine](https://code.kryo.se/iodine/)and create an IP tunnel over UDP on port 53 (default dns port).

# Monitoring sslh

As usual, a good and simple solution to ensure our service is still running, is to use a monitoring tool. In my case, I am using monit with its KISS philosophy. The configuration is really simple, I only create a new file in /etc/monit.d/service-sslhcontaining:

check process sshl with pidfile /var/run/sslh.pid

If sslh dies for any kind of reason, monitwill send me an email.

# Last words…

sslh is a good tool, and works very well on any Unix systems. The configuration is straight forward and give you a lot of flexibility (you can also use pattern based on regex). If you want to have your own VPN accessible from everywhere, it’s a good beginning!