Introduction
Purpose of having OpenVPN and Web server at port 443
Let’s imagine that you have the OpenVPN server listening on port 1194, and you are connecting from some public or work network not controlled by you. In this case there may be a situation where only outcoming connections to common ports are allowed (for example 80 and 443 so user can only surf the web), so you can not connect to your OpenVPN server and encrypt your traffic from network administrator.
In this particular case you can try moving your OpenVPN service to listen on port 443. But what to do if you also use your server for hosting some websites so port 443 is already in use? To solve this problem it is reasonable to use some proxy or load balancing solution and redirect network traffic from incoming port 443 to appropriate local service port 1194, 8080, etc.
How it works
You can configure HAProxy to terminate SSL and then route traffic based on SNI (Server Name Indication) or other criteria to either your OpenVPN server or to different websites. Here’s a high-level overview of how you can achieve this:
-
SSL Termination: HAProxy will handle incoming SSL connections on port 443. It will decrypt the traffic, inspect it, and then decide where to forward it.
-
Traffic Routing: Based on criteria such as the requested hostname or the content of the initial packets, HAProxy can route traffic to different backend servers:
- HTTPS traffic can be forwarded to your web servers.
- OpenVPN traffic can be forwarded to the OpenVPN server.
- Hiding VPN Traffic: By serving OpenVPN on port 443, it becomes harder for network administrators to distinguish between regular HTTPS traffic and VPN traffic. This can help in environments where VPN usage is restricted or monitored.
Setup
The setup guide assumes that you already have up and running this services on your system:
- OpenVPN service running in TCP mode.
- One or multiple http web services.
Personally I run every web service as a docker (docker compose) containers and bind their http ports to some free port on localhost (for example multiple web apps are on local interface, but different port http://localhost:20001
, http://localhost:20002
, etc).
Install HAProxy
First, install HAProxy on your system:
sudo apt install haproxy
Then enable and start HAProxy systemd daemon:
sudo systemctl enable --now haproxy.service
Configure HAProxy
Plaсe your SSL certificates to /etc/ssl/haproxy
. The directory and certificates should be accessible only for root user. For example, if you have domain1.com
, domain2.com
domains that you want to host web services for, you should have certificate and key pairs for each domain in the directory with appropriate naming, for example:
- domain1.com.pem
- domain1.com.pem.key
- domain2.com.pem
- domain2.com.pem.key
Then edit the file /etc/haproxy/haporxy.cfg
, and add the needed sections.
Define backends for Web apps and OpenVPN.
For example, if I have 2 web sites listening on ports 20001, 20002 and OpenVPN listening on port 1194, the configuration will be:
|
|
Configure HTTPS balancing
Next we need to create a frontend which will be bound to localhost:8443
and will manage redirect based on domain. It will allow to host web apps for multiple domains. Also backend for localhost:8443
should be created, it will be used later to connect from port frontend which will be listened on incoming port 443.
In this example connection is redirected to corresponding web app based on domain SNI check, for example:
|
|
Configure incoming frontend for public 443 port
This is main frontend which is listened on public 443 port and manages regirect to needed backend based on SNI.
First it checks if SNI ends with some of mathing domains (domain1.com or domain2.com), this kind of checks allows to host any subdomain in future (for example dev.domain1.com
, prod.domain2.com
, etc). And in the end if no SNI check passed it means that we have a connection to OpenVPN, this rule is defined as the default.
|
|
Full configuration example
|
|
Extras
How to validate HAProxy configuration
HAProxy can validate the configuration file and tell you if there is any error.
To check the configuration, run:
sudo haporxy -c -f /etc/haproxy/haproxy.cfg
How to apply HAProxy changes
To apply changes to HAProxy configuration, simply restart the daemon:
sudo systemctl restart --now haproxy.service
Conclusion
Using HAProxy to handle SSL termination and multiplexing traffic over port 443 can be an effective way to hide VPN usage and bypass network restrictions. This setup can be particularly useful in environments where only port 443 is open or VPN traffic is actively monitored and restricted. By carefully configuring HAProxy, you can create a flexible and secure solution that meets your needs.
Benefits
-
Port Multiplexing: using port 443 for both VPN and web traffic allows you to work around network restrictions that only allow port 443.
-
Hiding VPN Usage: by serving OpenVPN on port 443, the VPN traffic blends in with normal HTTPS traffic, making it harder to detect and block.
-
Flexibility: you can handle multiple services on a single IP and port, reducing the number of open ports and simplifying firewall rules.
Considerations
-
Detection: while this method can help bypass some restrictions, sophisticated network monitoring tools can still potentially detect OpenVPN traffic based on traffic patterns and behavior, even on port 443.
-
Performance: HAProxy needs to decrypt and inspect SSL traffic, which can add overhead. Ensure your server has sufficient resources to handle the additional load.
-
Security: terminating SSL at HAProxy means it handles the encryption and decryption. Make sure HAProxy and the server it’s running on are secured and kept up to date.