Vivian Voss

WireGuard: The VPN That Fits in Your Head

wireguard security unix

Technical Beauty ■ Episode 5

“Can I just once again state my love for it and hope it gets merged soon? Maybe the code isn’t perfect, but I’ve skimmed it, and compared to the horrors that are OpenVPN and IPSec, it’s a work of art.”

Linus Torvalds, Linux Kernel Mailing List, 2018

Linus Torvalds does not hand out compliments. He hands out opinions, frequently at volume, occasionally with vocabulary that would make a docker sailor reconsider his career choices. When Torvalds describes something as “a work of art,” it is worth understanding precisely what earned that phrase.

The Man

Jason A. Donenfeld is a security researcher and cryptographer. He built WireGuard in 2015 not because the world lacked VPN protocols (it had two) but because both of them were, to use the technical term, appalling. OpenVPN was a sprawling userspace daemon with over 100,000 lines of code. IPsec was a committee-designed protocol suite with a configuration surface area roughly the size of Belgium. Both worked. Neither could be audited by a single human in a reasonable timeframe. For security software, that is not an inconvenience. It is a structural defect.

Donenfeld’s response was not to improve either protocol. It was to start from scratch with a question that the VPN industry had apparently never thought to ask: what if a VPN were simple enough to be correct?

The Numbers

WireGuard is approximately 4,000 lines of code. OpenVPN exceeds 100,000. The IPsec implementation in the Linux kernel (StrongSwan plus the kernel modules) runs to several hundred thousand. Four thousand lines. You can read the entire codebase in an afternoon. You can audit it in a week. You can hold the complete mental model in your head while drinking a cup of tea, and the tea will still be warm when you finish.

Lines of Code: VPN Implementations Kernel module + userspace tooling WireGuard 4,000 Readable in an afternoon OpenVPN 100,000+ Requires a sabbatical IPsec (StrongSwan) 400,000+ Requires a committee Every line of code is an attack surface. WireGuard has 96% fewer lines to exploit.

This is not merely an aesthetic preference for small codebases. In cryptographic software, every line of code is a potential attack surface. Every conditional branch is a potential timing side-channel. Every configuration option is a potential misconfiguration. OpenVPN supports so many cipher suites that a non-trivial portion of its security advisories amount to “you chose the wrong one.” IPsec offers so many negotiation modes that entire books exist solely to explain the handshake. WireGuard supports one cipher suite. One handshake. One key exchange. The correct one.

The Cryptography

WireGuard’s cryptographic choices are not configurable, and this is the design’s single most radical decision. Curve25519 for key exchange. ChaCha20-Poly1305 for symmetric encryption. BLAKE2s for hashing. SipHash for hashtable keys. Noise protocol framework for the handshake. That is the entire cryptographic specification. It fits on a napkin.

The absence of cipher negotiation eliminates an entire class of downgrade attacks. There is no option to fall back to DES. There is no option to negotiate a weaker key exchange. There is no option to do the wrong thing, because the protocol does not contain the wrong thing. If the cryptographic primitives are ever broken, the protocol version increments. This is how SSH should have worked. It is how TLS should have worked. It is how nothing in the industry worked until Donenfeld decided to ignore thirty years of “flexibility” that had achieved nothing except a longer CVE list.

The Performance

The benchmark data is not subtle. WireGuard achieves over 1 Gbps throughput on commodity hardware where OpenVPN struggles to reach 100 Mbps. In direct comparisons, WireGuard is 57 per cent faster than IPsec and comfortably exceeds 10 Gbps on modern hardware. The latency figures tell a similar story: WireGuard adds roughly 0.4 milliseconds of overhead. OpenVPN adds between 1.5 and 3 milliseconds. On a mobile device, the difference between “the VPN is invisible” and “the VPN is annoying” lives in those milliseconds.

Performance: Throughput & Latency Throughput (Gbps, higher is better) WireGuard 10+ Gbps IPsec 6.4 Gbps OpenVPN 0.1 Gbps Userspace. Context switches. Copies. Latency overhead (ms, lower is better) WireGuard 0.4 ms IPsec 1.0 ms OpenVPN 1.5-3 ms Kernel-space processing. Zero context switches. Zero unnecessary copies.

The performance advantage is not a consequence of clever optimisation. It is a consequence of architecture. WireGuard runs as a kernel module. Packets never leave kernel space. There are no context switches between user and kernel mode. There are no buffer copies between layers. There is no TLS library spawning threads to negotiate a cipher suite that was already decided at compile time. The packet enters the network stack, hits the WireGuard module, gets encrypted, and leaves. The path from ingress to egress is as short as the protocol itself.

OpenVPN, by contrast, operates entirely in userspace. Every packet crosses the kernel-userspace boundary twice: once on the way in, once on the way out. Each crossing costs a context switch. Each context switch costs microseconds. At 10 Gbps, microseconds become the bottleneck. OpenVPN does not have a performance problem. It has an architecture problem. The performance is a symptom.

The Configuration

An OpenVPN configuration file is typically between 30 and 80 lines, not counting the certificate management infrastructure required to make it function. An IPsec configuration, depending on which of the seventeen available IKE modes one selects, can extend to several hundred lines, plus a certificate authority, plus a key management daemon, plus the existential dread of realising one has chosen IKEv1 aggressive mode in production.

A complete WireGuard configuration:

[Interface]
PrivateKey = gI6EdUSYvn8...
Address = 10.0.0.1/24
ListenPort = 51820

[Peer]
PublicKey = xTIBA5rboUv...
AllowedIPs = 10.0.0.2/32

Seven lines. No certificate authority. No negotiation parameters. No cipher selection. No pre-shared secret distribution mechanism that is itself a security vulnerability. Public keys are exchanged out of band, the same model as SSH. If you can copy a string, you can configure WireGuard. The protocol does not require a deployment guide. It requires a wg-quick up.

The Kernel

WireGuard was merged into the Linux kernel in version 5.6, released March 2020. Torvalds had been advocating for its inclusion since 2018. The merge was not controversial. When the maintainer of the world’s most widely deployed kernel says “it’s a work of art” and “I hope it gets merged soon,” the patch queue tends to move briskly.

Today WireGuard ships natively in Linux, FreeBSD, OpenBSD, NetBSD, Windows, macOS, iOS, and Android. The FreeBSD implementation was contributed by the community and integrated into the base system. The OpenBSD implementation was rewritten from scratch by the OpenBSD team, because the OpenBSD team rewrites everything from scratch, and the result was still compact enough to audit in a week. When your protocol is simple enough that even OpenBSD’s famously exacting security team can implement it quickly, you have achieved something rather special.

The Attack Surface

Security is not a feature that is added to software. It is a property that emerges from the absence of places where things can go wrong. Every line of code is a potential vulnerability. Every configuration option is a potential mistake. Every protocol negotiation is a potential downgrade. WireGuard minimises all three simultaneously.

The entire protocol produces a single type of packet: an encrypted UDP datagram. There is no handshake visible to a network observer. There is no response to unauthenticated packets. A WireGuard endpoint that receives a packet from an unknown source does precisely nothing. No error message. No reset. No indication that the service exists at all. The endpoint is, from the perspective of a port scanner, indistinguishable from a closed port. This is not stealth by configuration. It is stealth by design. The protocol literally has no mechanism for responding to strangers.

The Philosophy

WireGuard belongs to a specific lineage of software, the lineage that understands security as a function of simplicity, not of features. qmail belongs to this lineage. OpenSSH aspires to it. The Noise protocol framework that WireGuard’s handshake is built upon was designed with the same conviction: that the most dangerous words in cryptographic engineering are “let’s add an option for that.”

Every cipher suite in OpenVPN exists because someone, at some point, said “but what if the customer needs RC4?” Every IKE negotiation mode in IPsec exists because a committee member said “but what about this edge case?” Every one of those accommodations is now a line item in a CVE database. Flexibility, in cryptographic software, is not a virtue. It is a threat model.

Donenfeld understood this. He built a protocol that does one thing, with one set of cryptographic primitives, in one way. If the primitives are ever compromised, the entire protocol versions forward. There is no negotiation. There is no fallback. There is no “legacy mode.” There is only the current version, and it is either secure or it is replaced. This is how cryptographic software should work. It is how almost none of it does.

The Lesson

WireGuard did not win by being faster, though it is. It did not win by being easier to configure, though it is. It did not win by getting Torvalds’s endorsement, though that certainly helped. It won by being simple enough to be correct. Four thousand lines can be audited. Four thousand lines can be held in a single engineer’s mental model. Four thousand lines can be reviewed by a security team that does not require a six-month budget allocation for the engagement.

The VPN industry spent two decades adding features, options, modes, and configuration parameters. Donenfeld spent 2015 removing them. The result runs in every major operating system kernel on earth. It handles 10 Gbps without breaking a sweat. It configures in seven lines. It responds to strangers with silence.

Four thousand lines. One cipher suite. Zero negotiation. The correct answer is not a choice between options. The correct answer is the absence of the wrong ones.