WireGuard - The VPN That's About to Change Everything
WireGuard is, line for line, the most consequential piece of networking software written this decade. Jason Donenfeld began working on it in 2015. The first public release was December 2016. By August of this year, after three years of careful design and implementation, Donenfeld submitted the kernel module for inclusion in the Linux mainline. Linus Torvalds publicly endorsed the submission, calling it "a work of art" compared to OpenVPN and IPsec. As of November, the merge has not landed in mainline yet — review is ongoing — but the path is clear and the merge is expected within the next year.
In the meantime, WireGuard is fully usable in production. It ships as a DKMS-built kernel module on every major distribution, has stable userspace implementations for non-Linux platforms, and is in active deployment by individuals, businesses, and at least one major commercial VPN provider. This post is about what WireGuard actually is, why the design choices matter, and how to deploy it on Debian today.
The structural claim
Existing VPN solutions are large. OpenVPN is roughly 100,000 lines of C, plus a substantial portion of the OpenSSL library. IPsec, in its various Linux implementations (StrongSwan, Libreswan, the in-kernel XFRM stack), is around 400,000 lines once you count the userspace tooling. Both have decades of accumulated complexity, configuration surface, and security-relevant code that is difficult to audit and even more difficult to formally reason about.
WireGuard is approximately four thousand lines of kernel code, plus a small userspace tool of about a thousand lines. The total codebase is small enough that a competent reader can read all of it in a weekend. It uses a fixed, modern cipher suite — no negotiation, no algorithm agility, no flexibility to misconfigure — and a fixed, simple wire format that is documented in a paper short enough to read in an evening.
The structural claim is that this is not a coincidence. Donenfeld argues, and the design demonstrates, that VPN protocols do not need to be as complex as OpenVPN or IPsec. The complexity in those systems was accumulated for historical reasons (algorithm agility for a future where AES might be broken; key exchange flexibility because nobody could agree on a single mechanism in 1998; certificate-based authentication because PKI was the political solution of the era) that have not aged well. WireGuard rebuilds the VPN from first principles with the assumption that we now know what good cryptography looks like.
The cryptography
WireGuard uses, by design, exactly one cipher suite. There is no negotiation:
- ChaCha20 for symmetric encryption
- Poly1305 for authentication (combined with ChaCha20 as ChaCha20-Poly1305, an AEAD construction)
- Curve25519 for elliptic curve Diffie-Hellman key exchange
- BLAKE2s for hashing
- HKDF for key derivation
- SipHash24 for hash-table keys
- The Noise Protocol Framework (specifically Noise_IK) for the handshake
These are the modern primitives you would choose today if you were designing a protocol from scratch. They are fast on modern CPUs, resistant to side-channel attacks, and have been thoroughly analyzed. None of them are negotiable; if any of them are ever broken, WireGuard will release a new version with new primitives and you will upgrade. This is the design choice — protocol agility instead of algorithm agility — and it is the right one. The complexity of in-protocol negotiation is not free; it is the source of the majority of TLS-era cryptographic vulnerabilities.
The handshake
The handshake uses Noise_IK, a one-round-trip pattern from the Noise Protocol Framework. Each peer is identified by a Curve25519 public key. The handshake authenticates both peers, derives ephemeral session keys, and provides forward secrecy and identity hiding. It completes in 1.5 round trips of small UDP packets — fast even on high-latency mobile connections.
The crucial property: WireGuard is connectionless at the packet level. There is no "session" the way OpenVPN has sessions. A handshake produces a transient set of keys; data packets are sent under those keys; the keys are renegotiated periodically. If a peer's IP address changes mid-session — because a phone moved between WiFi networks, or a laptop went from ethernet to mobile — the existing keys continue working, and the data packets simply arrive from a new source IP. WireGuard learns the new source IP from the first authenticated packet and starts replying there. This is roaming, and it is built into the protocol rather than bolted on.
The configuration model
WireGuard's configuration is peer-based. Each interface has a private key. Each peer is identified by a public key, an allowed IP range, and optionally an endpoint (hostname or IP and port). That is the entire model.
A typical configuration file:
1[Interface]
2PrivateKey = oK56DE9Ue9zK76rAc8pBl6opph1Z5m82YbWhnq3fnFI=
3Address = 10.0.0.1/24
4ListenPort = 51820
5
6[Peer]
7PublicKey = GtL7fZc/bLnqZldpVofMCD6hDjrK28SsdLxevJ+qtKU=
8AllowedIPs = 10.0.0.2/32
9
10[Peer]
11PublicKey = MlctomZmF8r5wW2Tj2vLqhCNjnvGLnJqNwS7+xWyhhE=
12AllowedIPs = 10.0.0.3/32
There are no certificates. There is no PKI. There is no separate authentication database. The public key is the identity. To add a new peer, you generate a new keypair, give the public key to the server administrator, and they add a [Peer] block. To revoke a peer, you delete the [Peer] block. The simplicity is shocking the first time you see it after years of OpenVPN.
The AllowedIPs directive serves a dual purpose. On the server, it controls which source IPs are accepted from this peer (cryptographically — a packet claiming to be from this peer but with a source IP outside the AllowedIPs is dropped). On the client, it controls which destination IPs are routed through this peer. Setting AllowedIPs = 0.0.0.0/0 on a client routes all traffic through the VPN; setting AllowedIPs = 10.0.0.0/24 routes only traffic to that subnet.
Deploying on Debian Stretch
WireGuard is not in Debian Stretch's main repository — it is in stretch-backports. Add the backports source if you have not already:
1echo "deb http://deb.debian.org/debian stretch-backports main" | \
2 sudo tee /etc/apt/sources.list.d/stretch-backports.list
3sudo apt-get update
4sudo apt-get install -t stretch-backports wireguard
This installs both the kernel module (built via DKMS for your current kernel) and the userspace tools (wg, wg-quick).
Generate a key pair:
1umask 077
2wg genkey | tee privatekey | wg pubkey > publickey
Create a configuration at /etc/wireguard/wg0.conf following the model above. Bring the interface up:
1sudo wg-quick up wg0
Verify:
1sudo wg show
For persistence across reboots:
1sudo systemctl enable --now wg-quick@wg0
That is the entire deployment. From package install to working VPN, allow fifteen minutes if you have done it before, an hour if you are setting up your first peer relationships and figuring out the IP allocation.
Performance
WireGuard is faster than OpenVPN and IPsec on essentially every benchmark. Donenfeld's published numbers from 2017 showed roughly 1 Gbps throughput on commodity hardware, against 250–400 Mbps for OpenVPN and 700–800 Mbps for IPsec. The reasons are structural:
- The protocol is implemented entirely in the kernel. No userspace context-switching per packet.
- The cipher suite (ChaCha20-Poly1305) is fast in software and benefits from AVX2 optimizations on modern CPUs.
- The packet format is minimal. A 4-byte type, 4-byte sender index, 8-byte counter, then the encrypted payload. No padding, no negotiation, no complex framing.
- The handshake is rare relative to data flow. Once established, the data plane is essentially symmetric encryption plus authentication, both of which are fast.
For a home connection over residential broadband, WireGuard is unlikely to be the bottleneck. For a data-center deployment moving large volumes between regions, it is the right choice for performance reasons alone.
What WireGuard does not do
Deliberate omissions, all of them justified:
- No DNS configuration in the protocol. Use
wg-quick'sDNS =directive in the config file, which sets/etc/resolv.confwhile the interface is up, or handle DNS via the system resolver. - No address assignment. Static configuration, peer-by-peer. There is no DHCP equivalent. For dynamic allocation in larger deployments, you orchestrate at a higher layer — Tailscale (a commercial product built on WireGuard) does this; for self-hosted setups, scripts or a small management server fill the gap.
- No NAT traversal magic. WireGuard runs over UDP. If both peers are behind NAT, you need at least one peer with a public IP, or a STUN-equivalent rendezvous mechanism that you implement yourself.
- No HTTP-style obfuscation. WireGuard packets are recognizably WireGuard. If you are deploying in an environment where the VPN traffic itself is being blocked (state-level censorship, hostile network operators), you need to tunnel WireGuard through something else — an SSH tunnel, a TLS-tunneling tool like
wstunnel, or a dedicated obfuscation layer.
These omissions are deliberate. WireGuard is the data-plane protocol; the higher-level concerns (address allocation, NAT traversal, obfuscation, federation) are left to other tools that compose with it.
Should you deploy now or wait for mainline
The kernel mainline merge, when it happens, will not change the deployed protocol. Configurations written today will continue to work. The merge will eliminate the DKMS build (the module will simply be in the kernel) and will accelerate adoption by removing the "out-of-tree module" friction. For a careful operator, neither of these is a meaningful reason to wait.
Deploy now. The only argument for waiting is if you have a specific institutional policy against out-of-tree kernel modules, in which case you wait until your distribution ships a kernel that has WireGuard merged. For everyone else, the protocol is stable, the userspace tools are stable, and the security review has been thorough.
The summary
WireGuard is what a VPN looks like when designed with a decade of cryptographic and protocol-design lessons applied without the constraint of legacy compatibility. Four thousand lines of kernel code, one fixed cipher suite, peer-based configuration, no PKI, fast roaming, and performance that beats OpenVPN by a factor of two to four.
The kernel merge is pending but not necessary. The protocol is production-ready. If you operate any system that needs an encrypted point-to-point or point-to-multipoint tunnel — between data centers, between a laptop and a home server, between a phone and a personal subnet — WireGuard is the right tool, and the alternative tools are increasingly difficult to justify.
In two years, this will be obvious. The interesting question now is what becomes possible when secure, fast, simple VPNs are something you deploy in fifteen minutes rather than a week. The answer, I suspect, is "more interesting infrastructure than we have built so far."