How to have multiple services on port 443(Debian/Ubuntu)

How to have multiple services on port 443(Debian/Ubuntu)

Have a website running on a VPS, and port 22 is blocked at your job or school?

Well, this post will show you how to have SSH and HTTPS all on one port! This can even be expanded to have HTTP, OpenVPN, and even more running on a single port! If you know about Linux, you’ll know only one program can bind to a port at any given time, so in order to accomplish what I’m explaining you’ll need a port multiplexer. My favorite port multiplexer is SSLH.

The easy way out is to add an additional IP address to your server, and bind HTTPS and SSH to separate IP addresses. But, for the harder way, keep on reading.

SSLH

Installing

Installing SSLH is really simple, you can either compile it, or use your distribution’s package manager. I prefer to use the package manager, as it’s easier. All you have to do is:

 sudo apt install sslh

and you’re good to go!

Configure

Configuring SSLH is just as easy as installing it. The configuration file is located at

 /etc/default/sslh

so you’ll need sudo access and a text editor. I prefer nano, but you can use vi, vim, ed, or anything else. Anyways, open that file with your favorite text editor, and here’s a sample config:

 DAEMON_OPTS="--user sslh --listen 0.0.0.0:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:4433"

You’ll notice that ssl is on port 4433 in this config, you can change that to whatever port you decide to use. I wouldn’t recommend having that on port 443 as well, as I haven’t been able to get that to work. Anyways, it doesn’t matter, as all visitors will be able to access it on port 443.

What about transparent mode?

SSLH supports a mode called transparent, which allows programs behind it, like apache and SSH, to see the real ip of the user,something the default config can’t(as everything appears to be from localhost). Anyways, this does require some extra configurations, which I will show you.

First, change the options to:

 DAEMON_OPTS="--user sslh --transparent --listen <real, external IP>:443 --ssh <real, external IP>:22 --ssl <real, external IP>:4433"

and add your real external IP address. Next, you’ll need to configure the iptables rules, which for the config I showed, would be something like:

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

and be sure to change your interface(mine is ens3).

Limitations

The tutorial I showed here will only work on IPv4, not IPv6. In order to that, just follow this post, or go to the GitHub page.

NGINX

Recent versions of NGINX are capable of having SSL and one non-SSL protocol on a single TCP port. In order to do this, you will need at least NGINX version 1.15.2, which is not the default for Ubuntu 16.04 anyways. Anyways, to do this, you will to put the following¬†OUTSIDE¬†of an “http” block.

stream{
        upstream openvpn {
                server 127.0.0.1:1194;
        }

        upstream https {
                server 127.0.0.1:443;
        }

        map $ssl_preread_protocol $upstream {
                default openvpn;
                "TLSv1.2" https;
                "TLSv1.3" https;
        }
        server {
                listen external_ip:443;
                proxy_pass $upstream;
                ssl_preread on;
        }
}

In this example, the SSL backend is configured to listen on localhost 443, and OpenVPN is on localhost 1194.

Yes, I know it’s TLS not SSL.

Sources(a.ka. where the snippet was copied from, and slightly modified): NGINX.com

Leave a Reply(Markdown is On)

%d bloggers like this: