Configure default VPN to work on TCP via port 443

I would like to update default configuration of VPN to work on TCP via 443 port. I’m expecting it allows me to use VPN on networks, where is blocked default protocol and port. I tried it few months ago and failed. Now I have time to try it again.

I’ve created draft of community article here: https://doc.turris.cz/doc/en/public/vpn_on_tcp_via_port_443#open_443_port_on_a_firewall

This guide should work more or less. Can someone more familiar with sslh and other stuffs help me to configure it and finish this guide?

Any help is welcomed.

I didnt test it, but shouldnt be sufficient redirect traffic to 1194 on firewall?

config redirect
	option name 'Router OpenVPN 443->1194'
	option target 'DNAT'
	option src 'wan'
	option proto 'udp tcp'
	option src_dport '443'
	option dest_port '1194'

This is a seemingly elegant solution, but IIRC it won’t work unless you tell OpenVPN that your doing it (if required, I’ll look up the relevant parameter for you).

It also has the downside of ‘losing’ <external interface>:443, so it can no longer be used for inbound HTTPS.

And wont work if outbound 1194 is blocked (but see below) on the client network.

To receive best advice, you really should tell us why you want to do this. If you think you might be able to ‘punch’ your way out a corporate firewall, then I should warn you that most decent firewalls wont be so easily fooled (I refer to stateful packet inspection).

Maybe you could look at OpenVPNs port sharing feature? See: SSLH or similar port multiplexing - #4 by dbonnes - SW tweaks - Turris forum (or there is SSLH).

The other thing you might see is people trying OpenVPN over or port 22, or port 53 (with much the same problems as using port 443). In both cases, there is a much better solution that just using a port swap.

And do remember that OpenVPN is more efficient over UDP than TCP…

I wanted a setup such that whatever network I was on, I could establish an outbound personal VPN to my home router, and thus to the internet from there. This allowed me: a) privacy, b) functionality (e.g. I could have outbound MS-RDP/3389,even though only port 80/443 was open).

I used an OpenWrt-based travel router (i.e. something like: https://www.gl-inet.com/products/gl-mt300n-v2/) that I carried with me, and to which I could connect wirelessly, and it did all the heavy lifting, going from the easy wins (OpenVPN over UDP/1194), through to HTTPS tunneling.

Very complicated, and all great fun.

In the end, however, I just use http://guacamole.apache.org.

The main problem, is that no one solution will solve all your problem/cope with every hotel network. Even guacamole has it’s drawbacks/difficulties.

What I would do is this:

a) get OpenVPN working over UDP/1194, and TCP/1194 (you can have multiple OpenVPN listeners on an OpenWrt-based box)
b) then get OpenVPN working over TCP/443 using PortSharing
c) get adventurous with an SSH tunnel, and DNS tunnelling

I did use SSLH for a while, but OpenVPN Port Sharing (which is similar) always seemed to as well/faster (unless you want SSH over SSL/HTTPS).

And set up a guacamole server (with 2FA) inside an LXC container (maybe with URL redirection in front of it).

There is an excessive number of posts re: OpenWrt and OpenVPN. Just Google. Or have a look at the OpenWrt/LEDE community documentation.

Sorry, the linked article is too vague and (please don’t take this the wrong way) a little naive.

However, I warn you that OpenVPN may not accept a conversation sent to TCP/443 (by the client), but received on TCP/1194 (by the server) by default.

I really would just remove SSLH and use the Port Sharing feature instead. Start without Port Sharing (i.e. OpenVPN listening on 443, and then once you get that working, add port sharing to divert non-OpenVPN traffic to LightHTTPd.

If you want, execute these command and post the result:

uci show openvpn
uci show | grep 443
uci show | grep 1194
netstat -nltp

When the time comes to add Port Sharing, it could be as easy as simply adding the equivalent of:

uci set openvpn.vpn.port_share="localhost 4443"

I should warn you that SSLH is slower than OpenVPN’s Port Sharing feature (and more complex), and thus is only useful if you want to mux SSH as well as OpenVPN/SSL.

Are you? What do you mean by server? OpenVPN server, or SSLH server?

uci set sslh.default.listen=0.0.0.0:443

This tells SSLH to listen on every interface, on port 443. Therefore, the OpenVPN/HTTPS clients must initiate a conversation to destination port 443 (this is the default port for HTTPS, but not OpenVPN, which uses UDP by default in any case).

uci set sslh.default.openvpn=192.168.44.1:1194

This tells SSLH that the OpenVPN server is listening on port 1194. In short, the OpenVPN client ‘speaks’ to :443, but the OpenVPN server is listening on :1194.

You should keep :80 & :443 available on the internal interface for Foris’ HTTP/HTTPS - this is good practice. The following code snippet is from some of my very old scripts, but FWIW:

. /lib/functions/network.sh; network_get_ipaddr WAN_IPADDR wan
echo ${WAN_IPADDR}

So you could at least:

uci set sslh.default.listen=${WAN_IPADDR}:443

If you don’t specifically want SSH muxing (and you haven’t indicated you do), then I strongly suggest:
a) have OpenVPN listening on :443 on the external interface (similar to what I did above)
b) have LightHTTPd listening on the internal interface (0.0.0.0 may be OK, YMMV)
c) utilise OpenVPN’s port sharing feature on the external interface

I am using NAT for changing “outside” OpenVPN port without problems (not 443 though)… Maybe I am lucky one :slight_smile:

Just for curiosity, I tried 443, shared by www and OpenVPN:

  • port sharing, and for me it doesnt work. When I tried connect to HTTPS, got

WARNING: Bad encapsulated packet length from peer (5635), which must be > 0 and <= 1627 – please ensure that --tun-mtu or --link-mtu is equal on both peers – this condition could also indicate a possible active attack on the TCP link – [Attempting restart…]

. Openvpn connection works fine.

  • sslh solution works out of the box

Actually, I’m backing off this claim (you might notice I edited a previous post) - I got a bit confused (my whole setup is behind nginx, and I was using URL rediection).

Hmmm… Does that error happen when you try to start the OpenVPN server, or when the client goes to initiate a VPN?

I’m wondering: did you remember to stop LightHTTPd from listening on :443?

Yes, YMMV for all of us.

Neither one. VPN started and working fine. Problem is, when I try connect from Internet browser (scenario, when port-sharing should redirect traffic to https). www server is working, when tested directly…