When to use OpenVPN instead of WireGuard:
- Corporate firewalls that block UDP — WireGuard only speaks UDP. If your network's firewall drops everything except TCP 80 and 443, WireGuard won't connect at all. OpenVPN on TCP 443 disguises itself as HTTPS traffic and passes through.
- Legacy client compatibility — You're supporting devices running older operating systems, embedded systems, or managed corporate laptops where you can't install WireGuard. OpenVPN clients have been shipping for 15+ years and are available on basically every platform.
- TCP fallback is a hard requirement — Some environments (hotel WiFi, airport networks, certain countries) actively interfere with UDP. If your users need a connection that works even on the most hostile networks, OpenVPN's TCP mode is the answer.
📋 What I actually use this for:
One of my clients runs a corporate network that blocks all UDP and only allows outbound TCP on ports 80, 443, and 8080. WireGuard is dead on arrival there. I keep an OpenVPN server running on TCP 443 on a $5/month VPS specifically for when I need to work from their offices. It also gets occasional use from a few countries that actively block WireGuard's UDP traffic at the ISP level — OpenVPN on 443 slips through because it looks identical to regular HTTPS.
The Easy Way: Docker with kylemanna/openvpn
Using kylemanna/openvpn (Recommended)
This Docker image wraps the certificate generation and server configuration into a few commands. If you don't need fine-grained control over the PKI, start here:
# Create volume for config
docker volume create --name ovpn-data
# Generate config
docker run -v ovpn-data:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u udp://YOUR_SERVER_IP
# Initialize PKI
docker run -v ovpn-data:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki
# Start the server
docker run -v ovpn-data:/etc/openvpn -d -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn
# Generate a client configuration
docker run -v ovpn-data:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full CLIENTNAME nopass
docker run -v ovpn-data:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn
That .ovpn file contains everything a client needs — certificates, keys, and connection settings in one file. Send it to the client device and import it.
Manual Installation
Install OpenVPN and Easy-RSA
# Ubuntu/Debian
sudo apt update
sudo apt install openvpn easy-rsa
Set Up Certificate Authority
Easy-RSA is unnecessarily complicated for what it does. All you actually need is a CA certificate, a server certificate, and client certificates — three things that OpenSSL can do in about five commands. Instead, Easy-RSA gives you a multi-step workflow with its own directory structure, its own variable files, and its own terminology. That said, it's what OpenVPN's documentation recommends, and it does handle revocation lists properly. So here we are.
# Create PKI directory
make-cadir ~/openvpn-ca
cd ~/openvpn-ca
# Edit vars file
nano vars
Set your variables:
set_var EASYRSA_REQ_COUNTRY "US"
set_var EASYRSA_REQ_PROVINCE "California"
set_var EASYRSA_REQ_CITY "San Francisco"
set_var EASYRSA_REQ_ORG "MyOrg"
set_var EASYRSA_REQ_EMAIL "[email protected]"
set_var EASYRSA_REQ_OU "Community"
set_var EASYRSA_ALGO "ec"
set_var EASYRSA_DIGEST "sha512"
Initialize and build CA:
./easyrsa init-pki
./easyrsa build-ca
Generate Server Certificate
./easyrsa gen-req server nopass
./easyrsa sign-req server server
Generate Diffie-Hellman Parameters
./easyrsa gen-dh
This generates a 2048-bit DH parameter file. Expect it to take a few minutes depending on your server's CPU.
Generate TLS Auth Key
openvpn --genkey secret ta.key
Copy Certificates to OpenVPN Directory
sudo cp pki/ca.crt /etc/openvpn/server/
sudo cp pki/issued/server.crt /etc/openvpn/server/
sudo cp pki/private/server.key /etc/openvpn/server/
sudo cp pki/dh.pem /etc/openvpn/server/
sudo cp ta.key /etc/openvpn/server/
Server Configuration
sudo nano /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 8.8.8.8"
keepalive 10 120
tls-auth ta.key 0
cipher AES-256-GCM
auth SHA256
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
Enable IP Forwarding
Without IP forwarding, your VPN clients will connect but have no internet access. This is the single most common cause of the "connected but can't reach anything" problem.
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Configure Firewall
# NAT rules
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
# Allow VPN traffic
sudo ufw allow 1194/udp
sudo ufw allow OpenSSH
sudo ufw enable
Make iptables rules survive a reboot:
sudo apt install iptables-persistent
sudo netfilter-persistent save
Start the Server
sudo systemctl start openvpn-server@server
sudo systemctl enable openvpn-server@server
sudo systemctl status openvpn-server@server
Generate Client Configurations
cd ~/openvpn-ca
./easyrsa gen-req client1 nopass
./easyrsa sign-req client client1
Create the client configuration file. Paste the actual contents of each certificate and key file between the XML-style tags:
client
dev tun
proto udp
remote YOUR_SERVER_IP 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
key-direction 1
verb 3
[paste ca.crt contents]
[paste client1.crt contents]
[paste client1.key contents]
[paste ta.key contents]
Client Setup
- Windows/Mac: Download OpenVPN Connect, import.ovpn file
- Linux:
sudo openvpn --config client.ovpn - iOS/Android: OpenVPN Connect app, import config
TCP Mode for Restrictive Networks
This is the main reason most people deploy OpenVPN in 2026. Change two lines in the server config and two in the client config:
Server config changes:
port 443
proto tcp
Client config changes:
proto tcp
remote YOUR_SERVER_IP 443
TCP adds overhead compared to UDP — expect 10-20% lower throughput and slightly higher latency due to TCP-over-TCP. But it works on networks where nothing else will.
When Things Go Wrong
Check Server Logs
sudo tail -f /var/log/openvpn/openvpn.log
Client Can't Connect
- Is the port open? Check firewall (cloud and host level)
- Are certificates valid? Check dates
- Is the server running?
systemctl status openvpn-server@server
Connected But No Internet
- IP forwarding enabled?
- NAT rules in place?
- DNS being pushed correctly?
Conclusion
If your use case is on the list above — corporate firewalls blocking UDP, legacy clients that can't run WireGuard, or networks that require TCP fallback — OpenVPN is the right choice. The setup takes longer, Easy-RSA adds unnecessary friction, and the throughput is lower. But it connects where WireGuard can't, and that's the only thing that matters when you're sitting behind a restrictive firewall with work to do.
If your use case isn't on that list, use WireGuard.
💬 Comments