Shared port 443 OpenVPN and multiple websites

Abstract:

On a business trip, the connection to my OpenVPN server was blocked (intially I was exposing the OpenVPN service on UDP 1994)… I wanted to ‘conceal’ / ‘hide’ this by multiplexing / sharing the port 443 between my self-hosted webservers and OpenVPN.

Then after I proposed the NGO “Moramour” (I was part of this NGO for a long time) to revive their discontinued website, I now had to share port 443 between: OpenVPN + my personnal default dock-in website [gueudier.fr], + my own blog [www.gueudier.fr] + moramour’s website [www.moramour.org] this one coming with a distinct/different certificate

Tools used :

  • Pfsense,
  • HAProxy Package,
  • OpenVPN, Package,

The settings :

TCP Front-end :

First, on HAProxy, the inbound traffic shall be splitted based on used TCP protocols:

  • OpenVPN
  • HTTPS

This is acheived with a “TCP” Fronted :

Listen addressCustom addressPortSSL Offloading
WAN address (IPv4)443
WAN address (IPv6)443
External address
ACL nameType of ACLValueNota
HTTPcustom acl:req.ssl_hello_type 1checks if payload is HTTPS protocol
gueudier.frcustom acl:req.ssl_sni -m end gueudier.frchecks if SNI is ending with gueudier.fr
moramour.orgcustom acl:req.ssl_sni -m end moramour.orgchecks if SNI is ending with gueudier.fr
OpenVPNcustom acl:! req.len 0cheks if payload is OpenVPN protocol
Definition of ACL

Nota: For OpenVPN ACL I tried a bunch of things, not working:

  • payload(0,2) -m bin 003c
  • payload(0,1) – m bin 38 As I noticed the first packet coming was with payload(0,1) = P_CONTROL_HARD_RESET_CLIENT_V2 = “7”(dec) “0011 1″(bin) && KEY_ID = “0”(dec) “000”(bin) thus “0011 1000″(bin) = “38”(dec)… nice try not working.
Type of actionCondition ACL namesValueNota
customaction: tcp-request inspect-delay 15000leave some time (3s) to process payload.
tcp-request content acceptHTTPif payload is HTTPS accept it
Use Backendhttp gueudier.frHTTPS-GUEUDIER.FRif payload is HTTPS
AND
SNI ends with gueudier.fr send it to BACKEND GUEUDIER.FR
Use Backendhttp moramour.orgHTTPS-MORAMOUR.ORGif payload is HTTPS
AND
SNI ends with moramour.org
>> send it to BACKEND MORAMOUR.ORG
tcp-request content accept! http OpenVPNif payload is not HTTPS and OpenVPN accept it
Use Backend! http OpenVPNVPNif payload is not HTTPS and OpenVPN
>> send it to backend VPN
Definition of action

VPN Backend :

NameForwardtoAddressPortEncrypt(SSL)SSL cheksWeightAction
VPNaddress+port:127.0.0.11194nono
VPN Backend configuration

Underlying VPN Server configuration :

The OpenVPN server shall be set to listen for TCP on port 1194 on localhost.

GUEUDIER.FR and MORAMOUR.ORG Backends :

The configuration below is deemed necessary as I want distinct / different SSL certificates for the two websites hosted.

The two ssl certificates for the two webstites are “off loaded” by HAProxy, on two distinct HTTP FRONTEDs

So the two TCP Backends send to HTTP Frontends

NameForwardtoAddressPortEncrypt(SSL)SSL CheckWeightAction
HTTPS-GUEUDIER.FRFRONTEND-GUEUDIER.FRnono
GUEUDIER.FR Backend configuration
NameForwardtoAddressPortEncrypt(SSL)SSL CheckWeightAction
HTTPS-FRONTEND-GUEUDIER.FRFRONTEND-MORAMOUR.ORGnono
Moramour.org Backend configuration

GUEUDIER.FR and MORAMOUR.ORG HTTPS Frontend :

Two frontends shall be created with distinct ports on WAN:

Listen addressCustom addressPortSSL Offloading
WAN address (IPv4)9443Yes
WAN address (IPv6)9443Yes
External address
Listen addressCustom addressPortSSL Offloading
WAN address (IPv4)9444Yes
WAN address (IPv6)9444Yes

Don’t forget to add some ACL, and set the proper certificate on each HTTPS Frontend

HTTP Frontend:

Don’t forget to add a general HTTP frontend to handle non encryted, mine only redirect all to HTTPS.

Related posts

Let’s keep contact

Vincent EUDIER

Vincent EUDIER is a 20 years experience Energy Project / Program Manager with strong emphasis on development,

My résumé