WireGuard vs OpenVPN vs Tailscale
The first thing to get straight is that comparing WireGuard, OpenVPN, and Tailscale is a category error as usually framed, because they do not all sit at the same layer. WireGuard and OpenVPN are data-plane protocols — they define how two endpoints encrypt and exchange packets. Tailscale is a control plane that uses WireGuard as its data plane: it does not encrypt your packets with some third protocol, it orchestrates WireGuard tunnels for you, solving the key distribution, NAT traversal, and access control that raw WireGuard leaves entirely to you. So the real comparison is two-and-a-half-way: WireGuard versus OpenVPN as cryptographic protocols, and then Tailscale (or Headscale, or Netbird) as the question of whether you want a coordination service managing WireGuard on your behalf. Almost every “which VPN should I use” argument is muddled because people compare a protocol to a managed product as if they were the same kind of thing.
Once you see that structure, the decisions get clear. The protocol question — WireGuard or OpenVPN — is mostly settled in WireGuard’s favor on performance and auditability, with OpenVPN retaining a few genuine advantages around flexibility and firewall evasion that still matter in specific situations. The control-plane question — raw config or a coordinator like Tailscale — is the one most people actually face, and it is a trade between operational simplicity and depending on (and trusting) a coordination service. This post works through the cryptography, the NAT-traversal mechanics, and the threat models, then gives a decision framework.
The protocols at the cryptographic level
WireGuard and OpenVPN embody opposite design philosophies, and the philosophies explain almost every practical difference.
OpenVPN is cryptographically agile. It runs a TLS handshake (it is essentially TLS-over-a-tunnel) and negotiates from a menu: you pick the cipher (AES-256-GCM, ChaCha20-Poly1305, historically Blowfish), the auth digest, the TLS version, the key exchange. This is the same design as TLS itself, and it carries the same baggage. Agility means OpenVPN can adapt to new ciphers and interoperate widely, but it also means a large configuration surface, a large codebase (OpenVPN links against OpenSSL — hundreds of thousands of lines between them), and the classic agility failure mode: downgrade attacks and misconfiguration. An OpenVPN deployment can be perfectly secure or quietly weak depending on a dozen config directives, and telling which from the outside is hard.
WireGuard takes the opposite stance: no agility at all. There is exactly one key exchange (Curve25519 ECDH via the Noise IK handshake pattern), one cipher (ChaCha20-Poly1305 for data, with Poly1305 for authentication), one hash (BLAKE2s), one KDF (HKDF). You cannot negotiate, downgrade, or misconfigure the crypto because there is nothing to choose. If the chosen primitives are ever broken, WireGuard versions the whole protocol and you upgrade — there is no in-band negotiation to attack. The entire kernel implementation is around 4,000 lines of code, small enough to actually audit, versus OpenVPN’s sprawl. This is the single biggest reason WireGuard won mindshare: the attack surface is a rounding error by comparison, and there are no knobs to get wrong.
HANDSHAKE SHAPE
OpenVPN (TLS-based):
ClientHello --> negotiate version, cipher suite, TLS params
Cert exchange / key exchange (RSA or ECDHE)
TLS established --> control channel --> derive data-channel keys
[ many round trips, large state machine, cipher menu ]
WireGuard (Noise IK, fixed):
Initiator -> Responder : handshake initiation (ephemeral + static, Curve25519)
Responder -> Initiator : handshake response
[ 1-RTT, no negotiation, both sides know each other's static pubkey a priori ]
-> transport keys derived, data flows as authenticated ChaCha20-Poly1305
The handshake difference has a security consequence beyond simplicity. WireGuard’s Noise IK pattern requires each peer to already know the other’s static public key before the handshake — there is no certificate authority, no in-band identity presentation. This makes WireGuard silent to unauthenticated scanners: a WireGuard endpoint does not respond at all to a packet that is not a valid handshake from a known key, so a port scan sees nothing. OpenVPN, like any TLS service, will respond to a connection attempt (it has a handshake to begin), which makes it discoverable and gives an attacker something to probe. WireGuard’s “stealth” is a real property that falls directly out of its key model, not an add-on.
| Property | WireGuard | OpenVPN |
|---|---|---|
| Design philosophy | Fixed crypto, no negotiation | Agile, TLS-style negotiation |
| Key exchange | Curve25519 (Noise IK) | RSA / ECDHE via TLS |
| Data cipher | ChaCha20-Poly1305 (only) | AES-GCM, ChaCha20, others |
| Codebase size | ~4,000 LOC (kernel) | OpenSSL + ~100Ks LOC |
| Config surface | Tiny (keys, IPs, endpoints) | Large (dozens of directives) |
| Transport | UDP only | UDP or TCP |
| Responds to scanners | No (silent) | Yes (TLS handshake) |
| Roaming | Built-in (endpoint re-bind) | Reconnect/renegotiate |
| Downgrade attacks | Impossible (no negotiation) | A real configuration concern |
The one place OpenVPN’s flexibility is a genuine advantage is transport. WireGuard is UDP-only, by design and without exception. OpenVPN can run over TCP, and specifically over TCP port 443, where it is very hard to distinguish from ordinary HTTPS. In hostile networks that block UDP or do deep-packet-inspection to kill VPNs — restrictive corporate firewalls, censored national networks — OpenVPN-over-TCP-443 (or OpenVPN wrapped in stunnel/obfsproxy) gets through where WireGuard’s UDP simply cannot. WireGuard’s answer is to be tunneled inside something else (udp2raw, or a separate obfuscation layer), which is exactly the kind of bolt-on the protocol otherwise avoids. If your threat is censorship and DPI, OpenVPN’s agility stops being baggage and becomes the feature.
A second OpenVPN edge: TCP mode gives you reliable, in-order delivery, which matters if you are tunneling a protocol that behaves badly over lossy UDP. The catch is TCP-over-TCP meltdown — running TCP traffic inside a TCP tunnel stacks two congestion-control loops that fight each other under loss, producing catastrophic latency collapse. So OpenVPN-over-TCP is for firewall evasion, not for performance; for throughput you want UDP, where WireGuard’s lean datapath simply wins, often by a wide margin in both throughput and latency.
Why WireGuard’s purity creates an operations problem
WireGuard’s minimalism is a gift to security and a burden to operations, and this burden is the entire reason Tailscale exists. The protocol deliberately does nothing about three things every real deployment needs:
- Key distribution. Every peer must be configured with every other peer’s public key and allowed IPs. For two endpoints this is trivial. For fifty laptops, phones, and servers in a mesh, it is N-squared manual configuration, and every new device means editing config on every existing peer.
- NAT traversal and roaming endpoints. WireGuard can follow a roaming peer (when an authenticated packet arrives from a new source address, it updates the endpoint), but it has no mechanism to discover how to reach a peer behind NAT in the first place. Both peers behind NAT with no public endpoint simply cannot connect without help.
- Access control and identity. WireGuard authorizes by key and by the
AllowedIPslist — that is the entire authorization model. There is no concept of users, groups, device posture, expiry, or policy. A key is valid until you manually remove it from every peer.
The minimalism is visible in the config itself. A complete WireGuard peer is a dozen lines, and every public key in the [Peer] blocks has to be hand-placed on every other node:
|
|
That AllowedIPs line is the entire routing and authorization model — it is both the crypto-key-routing table (which keys are allowed which source IPs) and the access policy. There is no expiry, no user, no group. A static WireGuard config like this is perfect for a fixed topology: a handful of servers, a home router with a public endpoint, a site-to-site link. The moment the topology is dynamic — devices that roam, come and go, sit behind CGNAT, and need group-based access — the manual N-squared model collapses, and you either build a coordination layer yourself or adopt one. That coordination layer is the actual product category Tailscale occupies.
Tailscale: a control plane over WireGuard
Tailscale is not a third VPN protocol. Its data plane is WireGuard — the same ChaCha20-Poly1305 tunnels, the same kernel module where available. What Tailscale adds is a coordination server (the control plane) that solves exactly the three things raw WireGuard ignores. Devices authenticate to the coordinator using your existing identity provider (Google, Okta, GitHub via OIDC), the coordinator distributes everyone’s public keys and the current network map to every node, and it brokers NAT traversal. Crucially, the coordinator never sees your traffic or your private keys — those stay on the devices, and the WireGuard tunnels are end-to-end between peers. The coordinator is a key-exchange and policy directory, not a relay for your data (with one exception, DERP, below).
TAILSCALE: DATA PLANE vs CONTROL PLANE
control plane (sees keys + policy, NOT traffic):
+-------------------------+
| Coordination server | <- OIDC login, key directory,
| (Tailscale or self- | ACL policy, network map push
| hosted Headscale) |
+-------------------------+
^ ^
| (control) | (control)
Laptop Server phone
\ / |
\ direct / WireGuard |
+========+ (data plane)====+
end-to-end encrypted, peer-to-peer
coordinator never on this path
The NAT-traversal magic is the part that feels like cheating. Tailscale uses STUN to discover each node’s public ip:port mapping, then performs UDP hole punching: both peers, learning each other’s mappings via the coordinator, fire packets at each other simultaneously so that each side’s NAT sees an “outbound” flow and permits the “reply,” establishing a direct peer-to-peer tunnel even though neither has a public endpoint. When hole punching fails — symmetric NATs that randomize ports, strict firewalls — Tailscale falls back to DERP (Designed Encrypted Relay for Packets), a network of relay servers that forward the still-WireGuard-encrypted packets. DERP can see ciphertext and timing but not plaintext, because the WireGuard keys never leave the endpoints. The result is that a connection always works, degrading from direct-P2P to relayed rather than failing, which is the property raw WireGuard cannot offer on its own.
The honest cost of Tailscale is dependency and trust. Your network’s ability to form new connections depends on the coordination server being up and trustworthy. If Tailscale’s coordinator is unreachable, existing tunnels keep working but new device auth and network-map changes stall. And while the coordinator cannot read your traffic, it can (in principle) push a malicious network map or inject a node — the trust you place in it is real, even if narrow. This is why Headscale, an open-source reimplementation of the coordination server, exists: you get Tailscale’s ergonomics with a coordinator you run and trust yourself, at the cost of operating it. For the full setup mechanics of the managed product, see the Tailscale complete guide and the zero-trust home network walkthrough; the Funnel vs Cloudflare Tunnels comparison covers the public-exposure variant.
Threat models, honestly
The three options fail differently, and matching the failure mode to your actual threat is the whole point.
Raw WireGuard has the smallest cryptographic attack surface and no third-party dependency — you trust only the code (auditable) and your own key management. Its weaknesses are operational: keys do not expire, there is no revocation beyond manually deleting them everywhere, and a compromised device’s key stays valid until you notice and remove it from every peer. There is no central log of who connected. For a small, static, high-trust topology this is a feature (no one to trust but yourself); for a fleet it is a liability (no lifecycle management).
OpenVPN has a larger attack surface (OpenSSL CVEs, the config-misconfiguration risk) but a richer security model: it has real PKI with certificate revocation lists, per-user certificates, and TLS-auth/tls-crypt to authenticate the control channel against scanning and DoS. A mature OpenVPN deployment with proper PKI has lifecycle management WireGuard lacks natively. The price is complexity and the standing risk that one of those many directives is wrong.
Tailscale shifts the threat model to identity and the coordinator. Authorization is tied to your IdP, so you get SSO, group-based ACLs, device expiry, and an audit log — genuinely better lifecycle management than either protocol alone. But you have added the coordinator to your trust base and your dependency graph. The relevant questions become: do you trust the coordination service (or run Headscale), and what happens to your access if it is unavailable or compromised? For most organizations the IdP-integrated access control is worth the dependency; for an air-gapped or maximally-paranoid setup it is exactly the wrong trade.
ATTACK SURFACE vs OPERATIONAL CAPABILITY
small surface, manual ops large surface / external dep, rich ops
<----------------------------------------------------------------------->
raw WireGuard OpenVPN+PKI Tailscale (managed)
- 4k LOC - revocable certs - SSO + group ACLs
- no lifecycle - per-user identity - device expiry + audit log
- you trust only - you trust your - you trust the coordinator
your own keys PKI + OpenSSL (or run Headscale)
The decision framework
Strip away the tribalism and the choice falls out of two questions: is your topology static or dynamic, and what is your real threat.
- Two fixed endpoints with at least one public IP (site-to-site, server-to-server, home router to VPS): raw WireGuard. It is the fastest, leanest, most auditable option, and the manual config is trivial at this size. Reach for the WireGuard from scratch setup. Adding a coordinator here is pure overhead.
- A fleet of roaming devices, users, and group-based access (a team, a homelab with phones and laptops behind CGNAT, anything needing SSO): Tailscale, or Headscale if you want to own the coordinator. The NAT traversal and identity-based ACLs are the entire value, and rebuilding them by hand is a project you do not want. This is where most people actually are.
- You must traverse a hostile, DPI-heavy, or UDP-blocking network (censorship, restrictive corporate firewall): OpenVPN over TCP 443, possibly obfuscated. This is the one scenario where OpenVPN’s agility is decisively better, because WireGuard’s UDP-only purity is a liability you cannot configure around without bolting on a tunnel.
- Maximum auditability and zero external dependencies (air-gapped, high-assurance, regulatory): raw WireGuard with disciplined manual key management, or OpenVPN with a self-run PKI if you need certificate revocation and per-user identity. The common thread is no coordinator in your trust base.
The pattern across all four: WireGuard is the best protocol and the right default for static topologies; Tailscale/Headscale is the right system for dynamic fleets because it solves WireGuard’s operational gaps without replacing its crypto; OpenVPN survives specifically where transport flexibility and mature PKI matter more than lean performance. They are not really competitors so much as answers to different questions, and most “which is best” debates are just people who have different topologies talking past each other. For the broader access-control picture these all plug into, the zero-trust networking post covers the policy layer that sits above any of them.
Verdict
WireGuard won the protocol argument: fixed, auditable crypto in 4,000 lines, no negotiation to downgrade, silent to scanners, and faster than OpenVPN on UDP — use it as your default data plane and stop agonizing. OpenVPN is not obsolete; its TLS agility, TCP-443 transport, and mature certificate PKI are genuinely better in exactly two situations — traversing networks that block or inspect UDP, and deployments that need per-user certificate revocation more than they need lean performance. Tailscale is not a third protocol to weigh against those two; it is WireGuard’s missing control plane, solving key distribution, NAT traversal via hole punching with DERP fallback, and identity-based access control, at the cost of trusting (or self-hosting, via Headscale) a coordination server. So the real decision is two steps: pick WireGuard unless you specifically need OpenVPN’s firewall evasion or PKI, then decide whether your topology is static enough to manage WireGuard by hand or dynamic enough to want a coordinator doing it for you. Match the tool to the topology and the threat, not to the benchmark everyone quotes.
Sources
- Donenfeld JA. “WireGuard: Next Generation Kernel Network Tunnel.” NDSS 2017. https://www.wireguard.com/papers/wireguard.pdf
- WireGuard protocol and cryptography documentation. https://www.wireguard.com/protocol/
- “The Noise Protocol Framework.” https://noiseprotocol.org/noise.html
- OpenVPN protocol and security overview. https://openvpn.net/community-resources/how-to/
- Tailscale. “How Tailscale works.” https://tailscale.com/blog/how-tailscale-works
- Tailscale. “How NAT traversal works.” https://tailscale.com/blog/how-nat-traversal-works
- “DERP servers” — Tailscale documentation. https://tailscale.com/kb/1232/derp-servers
- Headscale: an open-source Tailscale control server. https://github.com/juanfont/headscale
- RFC 8489 — “Session Traversal Utilities for NAT (STUN).” https://datatracker.ietf.org/doc/html/rfc8489
Comments