OpenVPN on 443
Lately I’ve been working on a project where security is very important. In order to connect to the hosting provider I needed to use a specific VPN provided by FortiNet. What’s interesting about this VPN solution is that apparently it uses HTTPS. this gave me the idea to look for a solution like this for me as well, but I did not want to rent another public IP just for a VPN.
On some articles I read that OpenVPN would be capable to “share” the port 443 with the web server/reverse proxy, etc. Truth be told it’s actually OpenVPN listening on 443 and forwarding all the requests that it does not understand to the web server wich is actually made to listen on another port.
And it works fine, after setting it up Qualy’s SSL test is still validating my web server as A+.
The next step is to test the VPN solution from behind a very restrictive firewall. I hope to be able to test it as one of my clients is behind such a firewall and I plan to pay him a visit.
And here’s the detail on how to obtain this:
I’m running my reverse proxy on Debian 12 bookworm. Installing OpenVPN is one command away:
apt install openvpn
I prefer to keep my vpn certificates and private keys on another computer than the vpn server. This time I even generated them on this computer. To do this I use this specific folder from easy-rsa-old repository.
First you need to edit the vars file to match your certificate names. Then load theese variables and generate the cetificates:
source ./vars ./clean-all ./build-ca ./build-key-server servername ./build-key client1 ./build-key client2 etc. ./build-dh
port 443 port-share 127.0.0.1 1443 proto tcp proto tcp6 dev tun ca ca.crt cert servername.crt key servername.key topology subnet server 10.8.0.0 255.255.255.0 ifconfig-pool-persist /var/log/openvpn/ipp.txt push "route 192.168.100.0 255.255.255.0" push "redirect-gateway def1 bypass-dhcp" ;push "dhcp-option DNS 188.8.131.52" ;push "dhcp-option DNS 184.108.40.206" keepalive 10 120 tls-auth ta.key 0 # This file is secret cipher AES-256-GCM persist-key persist-tun status /var/log/openvpn/openvpn-status.log verb 3
copy ca.crt servername.crt and servername.key from the machine the certificate was generated.
Also to generate ta.key you should run:
openvpn --genkey tls-auth ta.key
Save this file’s contents for the client config. My reverse proxy is haproxy. In my config file I had to change something like:
bind :1443 v4v6 ssl crt /etc/haproxy/haproxy.pem alpn h2,http/1.1 bind :::1443 v4v6 ssl crt /etc/haproxy/haproxy.pem alpn h2,http/1.1
Then start/restart daemons:
systemctl restart haproxy.service systemctl enable --now firstname.lastname@example.org
Then to se what happens
journalctl -fu -n 100 openvpn@servername
client dev tun proto tcp proto tcp6 remote servername.com 443 resolv-retry infinite nobind persist-key persist-tun <ca> -----BEGIN CERTIFICATE----- # here we put the contents of ca.crt -----END CERTIFICATE----- </ca> <cert> -----BEGIN CERTIFICATE----- # contents of client1.crt -----END CERTIFICATE----- </cert> <key> -----BEGIN PRIVATE KEY----- # contents of client1.key -----END PRIVATE KEY----- </key> remote-cert-tls server key-direction 1 tls-cipher "DEFAULT:@SECLEVEL=0" <tls-auth> -----BEGIN OpenVPN Static key V1----- # contents of ta.key -----END OpenVPN Static key V1----- </tls-auth> cipher AES-256-GCM verb 3