Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

How this works is we'll change our Apache reverse-proxy listening port to something else (like 4443), then bind port 443 to SSLH.  SSLH will analyse traffic incoming to port 443, and if it's standard https then it transparently forwards this traffic to port 4443, and if it's OpenVPN traffic then it forwards it to our standard server-side OpenVPN port 1194. 

SSLH also supports SSH traffic as well, so you could also route SSH traffic through port 443.  This means having https, openvpn, and SSH traffic all going through a single port (443) on your server (although we won't cover adding SSH here - leave a comment if you have issues also adding SSH traffic to SSLH).

Guide

The steps outlined here assumes you've setup an Apache reverse-proxy in which you take care of SSL termination with the relevant SSL certs within said reverse-proxy which listens (is binded) to port 443.  It also assumes that you've setup OpenVPN as outlined previously in this article and are using port 1194 for OpenVPN.

...

Table of Contents
minLevel3

Change OpenVPN to tcp-server mode

First let's make a small change to our OpenVPN by replacing

...

Info

Note that with this change you'll also need to change your .ovpn client configuration to use proto tcp-client and port 443 (e.g. the SSLH port instead of the internal OpenVPN port).

Change Apache SSL listening port and update any vhosts directives

Next, we're going to change our Apache SSL listening port to 4443 (you should check that this port is free - if not choose another valid arbitrary port number).

...

Don't restart Apache2 just yet...

Install and configure sslh

Next we're let's install SSLHinstall SSLH using distro's package manager.  If you're running a Debian or Ubuntu Server you would do:

Code Block
sudo apt install sslh

and select Select standalone mode when asked to select a mode.

...

For transparent mode to work we also need to modify iptables.  To ease configuration I created a one-off scriptscript which will set the requisite ip table rules.  Note that these settings won't survive a reboot so once we're happy we're going to make these settings persistent.

Copy the following to a file in your path (I suggest /usr/local/sbin), make it executable, and execute with sudo.:

Code Block
languagebash
cd /usr/local/sbin
sudo vim sslh-transparent

and copy/paste the following: 

Code Block
languagebash
#!/bin/bash

iptables -t mangle -N SSLH
iptables -t mangle -A OUTPUT --protocol tcp --out-interface enp0s25 --sport 4443 --jump SSLH
iptables -t mangle -A OUTPUT --protocol tcp --out-interface enp0s25 --sport 1194 --jump SSLH
iptables -t mangle -A SSLH --jump MARK --set-mark 0x1
iptables -t mangle -A SSLH --jump ACCEPT
ip rule add fwmark 0x1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100

ip6tables -t mangle -N SSLH
ip6tables -t mangle -A OUTPUT --protocol tcp --out-interface enp0s25 --sport 4443 --jump SSLH
ip6tables -t mangle -A OUTPUT --protocol tcp --out-interface enp0s25 --sport 1194 --jump SSLH
ip6tables -t mangle -A SSLH --jump MARK --set-mark 0x1
ip6tables -t mangle -A SSLH --jump ACCEPT
ip -6 rule add fwmark 0x1 lookup 100
ip -6 route add local ::/0 dev lo table 100

...

Info

NOTE: you'll need to replace enp0s25 with the main network interface of your server.

Make it executable:

Code Block
languagebash
sudo chmod +x /usr/local/sbin/sslh-transparent

You should now be able to set the iptables by executing our created script.

Making the iptable settings needed for SSLH persistent

The iptables set from our script won't survive a reboot.  Let's make it persistent (note I assume a systemd enabled distro here):

Create a simple systemd service which will execute our script on boot (after our network interfaces are online):

Code Block
languagebash
sudo vim /etc/systemd/system/sslh-transparent.service

and copy/paste the following:

Code Block
[Unit]
Description=sslh transparent (see /usr/local/sbin/ssl-transparent)
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/sbin/sslh-transparent

[Install]
WantedBy=multi-user.target

Once saved, enable SSLH persistence on our system:

Code Block
languagebash
sudo systemctl daemon-reload
sudo systemctl start sslh-transparent
sudo systemctl enable sslh-transparent

Now these rules should have been applied to our system and will also be applied on system restart.

Restart Apache, start sslh, and test...

Right, it's time to test the setup.  To do so we need to restart Apache, start SSLH:

...

If all went well you should be able to still access your webserver AND connect to OpenVPN on port 443.

Finalise configuration

We'll finalise the configuration (once you've tested it) by enabling sslh (so it starts on boot) and by making the iptable rules (above) persistent.

...

Code Block
languagebash
sudo systemctl enable sslh

...

References

  1. https://stackoverflow.com/questions/34304022/change-ssl-port-of-apache2-server-err-ssl-protocol-error
  2. http://www.rutschle.net/tech/sslh/README.html

Content by Label
showLabelsfalse
max5
spacesTKB
showSpacefalse
sortmodified
reversetrue
typepage
cqllabel in ("openvpn","apache","sslh") and type = "page" and space = "TKB"
labelssslh apache openvpn

...