OpenVPN Server on Linux: A Hardened Setup Guide - 夜莺博客

OpenVPN Server on Linux: A Hardened Setup Guide

OpenVPN remains a practical choice for site-to-site tunnels and road-warrior access because it is open, well understood and runs everywhere. It is also easy to deploy insecurely: hardcoded secrets, a shared client certificate, no TLS version control, and no protection against a compromised client key. This guide sets up a server the right way — separate PKI, per-client certificates, modern TLS settings — and covers the operational details that decide whether tunnels stay up under real network conditions.

Architecture first

  • PKI — a certificate authority signs the server and each client certificate. Revocation via CRL is what lets you cut off a lost device.
  • TLS mode — the server and client verify each other. Combined with a tls-crypt key it also defeats unauthenticated probe traffic.
  • Routing model — routed (tun) for almost everything; bridged (tap) only where you genuinely need Layer 2.
  • Topologysubnet topology so every client gets a stable virtual IP; needed for firewall rules and for monitoring.

Step 1 — build the PKI

# Using easy-rsa (package: easy-rsa), run in a dedicated, permission-restricted directory
cd /etc/openvpn/easy-rsa
./easyrsa init-pki
./easyrsa build-ca nopass
./easyrsa gen-req server nopass
./easyrsa sign-req server server
./easyrsa gen-dh
openvpn --genkey secret /etc/openvpn/tls-crypt.key

# one certificate per client - never share
./easyrsa gen-req client-laptop nopass
./easyrsa sign-req client client-laptop

Per-client certificates are the difference between revoking one device and reissuing everything. Revoke with ./easyrsa revoke client-laptop && ./easyrsa gen-crl and make sure the server configuration references the CRL file.

Step 2 — server configuration

# /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun
topology subnet

ca   /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
key  /etc/openvpn/easy-rsa/pki/private/server.key
dh   /etc/openvpn/easy-rsa/pki/dh.pem
crl-verify /etc/openvpn/easy-rsa/pki/crl.pem
tls-crypt /etc/openvpn/tls-crypt.key

server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 10.8.0.1"

tls-version-min 1.2
tls-cipher TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384
data-ciphers AES-256-GCM
auth SHA256
remote-cert-tls client

user  nobody
group nogroup
persist-key
persist-tun

keepalive 10 60
explicit-exit-notify 1
verb 3
status /var/log/openvpn/status.log 30
log-append /var/log/openvpn/openvpn.log

The security-relevant lines: tls-version-min 1.2, an AEAD cipher suite, remote-cert-tls client (prevents a client certificate being used as a server certificate), dropping privileges to nobody, and tls-crypt to reject unauthenticated handshakes before any crypto work happens.

Step 3 — routing and firewall

# Enable forwarding
sysctl -w net.ipv4.ip_forward=1
echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/99-openvpn.conf

# NAT clients out of the primary interface
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
iptables -A INPUT -i eth0 -p udp --dport 1194 -j ACCEPT
iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i tun0 -j ACCEPT

If clients connect but cannot reach anything, the forwarding/NAT pair is almost always the cause — check the counters on the FORWARD chain rules before touching the tunnel configuration. Persist firewall rules with your distribution's mechanism so a reboot does not silently break the VPN.

Step 4 — client configuration

client
dev tun
proto udp
remote vpn.example.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
tls-version-min 1.2
data-ciphers AES-256-GCM
auth SHA256
verb 3

<ca> ... </ca>
<cert> ... </cert>
<key> ... </key>
<tls-crypt> ... </tls-crypt>

Use redirect-gateway def1 only if you want all client traffic tunnelled. For split-tunnel designs, push explicit routes instead — it reduces server bandwidth and the blast radius of a client compromise.

Operating it

systemctl status openvpn-server@server
tail -f /var/log/openvpn/openvpn.log
cat /var/log/openvpn/status.log
openvpn --config client.ovpn --verb 4    # client-side debugging
  • Keepalive tuning: keepalive 10 60 means ping every 10 seconds, restart after 60 seconds of silence. On flaky mobile links, lengthen the timeout before blaming the server.
  • MTU: if large transfers stall while pings work, reduce tun-mtu or set mssfix to clamp TCP MSS — fragmentation through consumer paths is the classic "some sites do not load over VPN" bug.
  • Monitoring: alert if the status file stops updating or if connected client count drops to zero unexpectedly.
  • Certificate hygiene: set an expiration on client certificates and automate revocation; unmanaged certs outlive the laptops they were issued for.
  • Backups: losing the CA means reissuing every client; store the PKI offline and encrypted.

Common failure modes

Symptom Cause
TLS handshake error on every client CRL file missing or expired after a revocation
Connects, no internet Missing MASQUERADE rule or forwarding disabled
Only some clients fail Duplicate client certificate in use, or the client cert was revoked
Frequent reconnects UDP blocked by a carrier, or keepalive too aggressive for the path

Performance and concurrency

OpenVPN is single-threaded per tunnel and, in classic builds, largely single-threaded per process. That is fine for hundreds of clients on a modest server but becomes the constraint when you scale.

Lever Effect Trade-off
AEAD ciphers (AES-GCM, ChaCha20) Faster than CBC modes, hardware accelerated Requires both ends to support them
sndbuf / rcvbuf tuning Higher throughput on long RTT paths More kernel memory per tunnel
UDP over TCP-with-tunnel Better performance, no TCP meltdown Blocked on some restrictive networks
Multiple server instances (ports 1194, 1195, ...) Uses more CPU cores More configuration to keep consistent
DCO (data channel offload) where available Kernel-level forwarding, much higher throughput Platform dependent

Tunnel-over-TCP is worth calling out as an anti-pattern: encapsulating TCP in TCP causes retransmission cascades that make a lossy link perform worse than it would with UDP. If a client network blocks UDP, reduce MTU and clamp MSS rather than switching to TCP transport as a first resort.

Monitoring and capacity planning

  • Status file: the status directive writes connected client details at a defined interval — feed it to your monitoring so client counts and byte counters are visible.
  • Throughput: track per-tunnel bandwidth to detect a compromised or misconfigured client consuming disproportionate capacity.
  • Handshake failures: a rising rate of TLS errors usually means a certificate or CRL problem, or clients with an older OpenVPN client version.
  • Concurrency limit: know how many clients one server can hold at your cipher and bandwidth per client; measure rather than estimate.
  • Capacity per CPU core: a rough planning figure for AES-GCM with modern hardware is in the hundreds of megabits per core, but verify against your own traffic profile.

Alternative approaches worth considering in 2026

OpenVPN is mature and portable, but it is not the only option and choosing it should be a decision rather than a default:

Option Strength Weakness
OpenVPN Universal clients, well understood, TCP fallback available Performance per core, complex PKI management
WireGuard Simple configuration, strong performance, in-kernel No built-in user authentication or certificate management
IPsec/IKEv2 Native on most client platforms Interoperability quirks between vendors
Zero-trust overlay Identity-based access, no full-tunnel requirement Operational complexity and cost

For site-to-site links with fixed endpoints, WireGuard or IPsec typically wins on operational simplicity. OpenVPN remains a good fit for mixed client estates, restricted networks and environments where the PKI you already run integrates with the existing certificate management system.

Related articles

For highly available VPN gateways, pair this with Keepalived VRRP and HAProxy virtual IP failover. Throughput tuning is covered in Linux network tuning with sysctl, and a vendor-side comparison point is in FortiGate SSL VPN web mode configuration.

原文链接:https://openvpn.net/community-resources/how-to/