[$ xmrhost] _

$ diff /etc/vpn/wireguard /etc/vpn/openvpn

[$ ] WireGuard vs OpenVPN — for self-hosted personal VPN

// TLDR

For a personal VPN on an offshore VPS in 2026, WireGuard is the default and OpenVPN is the legacy fallback. WireGuard's wire protocol is smaller (~4000 lines of kernel code vs OpenVPN's ~70,000), faster, and uses modern cryptographic primitives (ChaCha20-Poly1305, Curve25519, BLAKE2s, SipHash, HKDF). OpenVPN retains advantages on restrictive-NAT traversal (TCP fallback) and in environments where deep-packet inspection blocks UDP traffic. For everything else, prefer WireGuard.

// AT A GLANCE

$ compare --short

// dimension // wireguard // openvpn
transport UDP only UDP or TCP
codebase size ~4,000 lines (kernel module) ~70,000 lines (userspace daemon)
audit surface small; formally analysed large; mature but complex
crypto primitives ChaCha20-Poly1305, Curve25519, BLAKE2s, SipHash, HKDF configurable; default AES-GCM + RSA + SHA2
cipher negotiation none (fixed primitives) TLS-style negotiation
key management static public keys per peer PKI / TLS certificates
throughput (gigabit-class VPS) ~900 Mbps ~250-400 Mbps
latency overhead per packet ~50 µs ~150-300 µs
NAT traversal UDP punch + keepalive UDP or TCP fallback (TCP/443 widely tolerated)
DPI evasion poor (fixed handshake) moderate (TCP/443 + tls-crypt)
in-kernel implementation yes (Linux 5.6+) no (userspace tun)
config format INI-style, ~10 lines domain-specific, 30-100 lines
roaming (mobile) native supported, reconnect-heavy

// WIREGUARD — DESIGN POINT

$ man wireguard

WireGuard's design centre is "minimum viable VPN": a fixed cryptographic primitive set (no negotiation, no algorithm-choice attacks), a UDP-only transport (no TCP-over-TCP retransmit cascade), and a static-public-key peer model that fits in ~4,000 lines of kernel code. Jason Donenfeld's original 2017 paper laid out the argument that VPN complexity is the dominant security failure mode and that a smaller protocol surface defeats more attacks than a configurable one. The protocol has been in mainline Linux since 5.6 (March 2020) and in mainline FreeBSD since 13.0 (April 2021).

Operationally, this manifests as:

  • 10-line configs. A typical wg0.conf is [Interface] (private key, address, listen port) + [Peer] (public key, allowed IPs, optional endpoint). No PKI, no certificate rotation, no DH-parameter file.
  • Roaming-by-default. Peers can change their external IP without re-establishing — WireGuard re-binds the tunnel on the next valid handshake. Mobile clients flipping between Wi-Fi and cellular don't reconnect; they re-handshake silently.
  • Crypto fixed. ChaCha20-Poly1305 for AEAD, Curve25519 for ECDH, BLAKE2s for hashing, SipHash for hash- table lookup. No negotiation = no downgrade attack surface.
  • Kernel module + wg-quick. The interface is a regular Linux network device. wg-quick up wg0 reads the config, sets up the device, and adds routes. No daemon.

// OPENVPN — DESIGN POINT

$ man openvpn

OpenVPN, originally released 2001 by James Yonan, predates the WireGuard design constraints and reflects an earlier-era trade-off: configurability is a feature, TLS is the established public-key substrate, and userspace-tun is portable across kernels. The codebase is mature, audited (Cure53 + QuarksLab 2017), and widely deployed (Pritunl, OpenVPN Access Server, AirVPN, ProtonVPN, the bulk of commercial VPN-by-subscription services).

Operationally:

  • TLS / PKI. The handshake is TLS over UDP (or TCP). Each client has a certificate signed by a CA the server trusts. Revocation goes through standard CRL / OCSP.
  • TCP fallback. OpenVPN can run over TCP/443, which is the most-permitted port on any network. Useful for hostile-firewall environments where UDP is dropped.
  • tls-crypt and tls-auth. Pre-shared key wrapped around the TLS handshake makes pre-handshake DPI hard. This is the closest OpenVPN gets to handshake obfuscation; it is not a full pluggable-transport but it does defeat naive DPI.
  • Configurable cipher set. Negotiates AES-GCM / ChaCha20-Poly1305 / AES-CBC. The negotiation surface is itself a security consideration (Sweet32 in 2016 demonstrated this); pin modern ciphers in the config and disable the rest.
  • Userspace daemon. No kernel-module dependency; runs on systems without WireGuard kernel support (FreeBSD pre-13, old Linux kernels, macOS without compose).

// HOW TO CHOOSE

$ man choose-vpn

  • Default to WireGuard if: the host runs Linux ≥ 5.6 or FreeBSD ≥ 13.0; clients are Linux / macOS / Android / iOS / Windows 11 (all support WireGuard natively or via official client); the network path does not block UDP. This covers ~95% of personal-VPN use cases.
  • Choose OpenVPN if: the threat model includes DPI-active networks (hotel Wi-Fi, restrictive corporate / hotel firewalls, jurisdictions where TCP/443 is the only viable out-bound port); the host runs an OS without WireGuard kernel support; the deployment already has a TLS PKI in place that should be reused.
  • Run both: the offshore VPS can host both daemons on different ports. WireGuard as the daily driver, OpenVPN on TCP/443 as the fallback for hostile-network days. The configuration cost is one extra port + one extra firewall rule.
  • Consider neither: for the threat model "I want anonymity, not just encryption", a self-hosted VPN is the wrong tool — the destination IP traces back to the VPS, which traces back to the payment. Run a Tor client, route via /node/lokinet-exit, or use Tor Browser depending on the workload.

// THREAT-MODEL NOTES

$ man vpn-threat-model

Both protocols protect the VPN tunnel from passive interception and from on-path tampering. Neither anonymises traffic past the VPS exit — the destination server sees the VPS IP. Neither defends against an adversary that controls the VPS. Neither defends against an adversary that has compromised the client.

Both have post-quantum migration questions: ChaCha20-Poly1305 + Curve25519 are not post-quantum-secure (a sufficiently capable quantum adversary breaks Curve25519 key exchange). WireGuard's community draft for post-quantum hybrid handshake exists but is not yet mainline. OpenVPN inherits OpenSSL's post-quantum trajectory (ML-KEM hybrids landing in OpenSSL 3.x). For threat models on a 5+ year horizon this matters; for personal-VPN-day-today it does not.

See /threat-models#vpn for the full self-hosted-VPN dossier and the four-tuple controls.

// SEE ALSO

$ ls /usr/share/doc/xmrhost/vpn