Briefly, WireGuard is a new type of VPN protocol designed from the ground up for performance and flexibility. All the juicy technical details are available in this white paper. We’ll summarize some of the important details of that paper and explain them as non-technically as possible.
What even is a VPN?
For quite a few years the two available VPN protocols were PPTP and OpenVPN, with L2TP being a sort of awkward hybrid of emerging IPSEC technology and PPTP that lurked in the background. The reasons for this state of affairs are only partially technical, but insofar as they are, they boil down to VPN having a vague definition in practical use.
Networks don’t just connect, like roads, but they also have to route, like traffic signs. Having a highway that connects major cities is less effective if each commuter has to know the way by heart--perhaps a hard thing to imagine in the days of GPS and mapping software directly in your car, but imagine these conveniences did not exist. Now also imagine that road signs, stop lights, and even maps did not exist. This is basically what a packet of information sent along the wire sees--just the dark road in front of it. So when your computer fires off a request for a web page, neither your computer nor the packet itself have any idea how it’s getting to the server that holds that page.
Enter the router--the device that tells packets where they’re going and how to get there. Now, the router is more like the directions your aunt gave you to Albuquerque than Google Maps. It knows that you need to turn left here to get there, but it has no idea where you’re going after that--you just ask at the next turn, or basically the next router, to find your way. This may seem haphazard, but the structure of the internet changes often enough that this system makes more sense. Imagine if the DOT was constantly disconnecting and reconnecting roads--possibly easier if you live in an area currently engaged in lots of road construction!
If you’re asking what this has to do with VPNs, that’s definitely understandable. It’s because VPNs at their heart often just do connection, and routing is left up to something else entirely. PPTP and OpenVPN both handle making changes to routing themselves, usually by default, and the expectation is that when you start them, your routing will change. IPSEC operates differently, in that it just establishes a connection, and with L2TP a PPP program will handle routing much like with PPTP; with IKEv2, a much newer protocol, the IPSEC program itself handles routing much more like OpenVPN. However, all these VPNs basically route according to IP addresses, which is entirely normal.
WireGuard uses many of these same mechanics, but at heart it routes using cryptographic keys: when a computer wants to send a packet out through WireGuard, it checks its destination IP against a table of public keys to find which one to encrypt the packet with, and when a packet arrives and is decrypted with a certain key, it’s only allowed if that key matches the IP range that key is approved for.
One of the benefits of this approach shows up mainly for clients connecting to a server--those clients can “roam” across locations with entirely different external IP addresses, and the WireGuard server keeps track of them using the clients’ keys. This sort of setup would break most existing VPN protocols.
To State or Not To State?
For programmers, state is a bit of a bugbear. You can think of state as a sort of mental todo list in which you might keep track of things like whether your laundry is in the washer or dryer, and whether those dishes in the dishwasher are clean yet. State is the *current* what of things, and for stateful programs, it matters immensely.
In internet terms, this usually boils down to TCP or UDP: the former stateful, the latter stateless. UDP is often used where speed is more important than order or completeness, like watching a streaming video where if you lose a packet it can be ignored and you move on to the next piece of information. This is because most users just want the video to keep playing, not to stop mid-scene and wait for all the information for that frame of the video to catch up before continuing. If a frame gets dropped or quality reduced, that’s not so jarring as for the video to stop entirely and wait. TCP is more like your field trip chaperone: count all the packets, make sure they’re all there, single file, in order, please behave yourselves. If someone’s missing--STOP THE BUS! You want TCP when every piece of information you’re downloading is important, like when downloading a program. HTTPS is implemented over TCP, for instance.
However, there are many technical gotchas here, for instance that reliable protocols can be implemented over UDP, and often are. TCP is a very specific way of ensuring delivery, and sometimes isn’t ideal. For instance, when you want clients to be able to roam. But that isn’t to say that a roaming protocol can’t be implemented using TCP either--just that it would be harder to accommodate. With networking, the devil is always in the details.
Because WireGuard is already shepherding packets, having an additional shepherd (TCP) is not especially efficient.
What’s in a Connection?
Of course, now down to the meat of what most people are after when they use a VPN: the encryption. OpenVPN is somewhat configurable, offering a number of different handshakes and encryption schemes; IPSEC is perhaps ridiculously configurable, offering so many options as to be utterly baffling to the average user. What does WireGuard bring to the table?
First, each WireGuard instance performs a TLS-style handshake that allows securely swapping encryption keys, and WireGuard’s handshake is designed specifically to mitigate well known attacks and to conform to best security practices. In particular a property known as perfect forward secrecy is important here, as well as the handshake’s resistance to denial of service attacks.
Peers receiving handshake requests are basically allowed to punt the request back to the sender with some slightly higher requirements for acceptance designed to sidestep potential MITM attacks and allow the peer some recovery from high CPU usage.
But perhaps WireGuard’s most interesting feature here is that it allows connections to remain entirely silent. Two peers with no data to exchange need no heartbeat signals or other such keep-alive messaging to retain a connection. When there’s nothing to say, nothing need be said. The only constraint on this is that a one-way message will get a simple empty reply if there is no data scheduled to be sent back within a certain time.
Now, WireGuard does keep some state behind the scenes, and its hidden mechanisms sync this state. However, to the user and in practice the system appears completely stateless, and the simplicity of its state-keeping makes it very resilient. Because of this simplicity, WireGuard is a provable system, which is unusual among VPN protocols.
Cryptographically, WireGuard uses Curve25519 Elliptic Curve Diffie-Hellman for handshakes. This is a complex mathematical structure that makes strong encryption parameters easy to agree upon for two peers, but hard to guess for outside observers of the handshake. Hard here means that you might need billions of years of computing resources to successfully guess the handshake parameters, by which time one hopes the peers have moved on with another handshake.
For bread and butter encryption, WireGuard uses the ChaCha20 steam cipher, which is both highly secure and extremely performant. Each message uses the Poly1305 message authentication code to ensure data integrity. ChaCha20Poly1305 is basically becoming industry standard at this point, and unlike AES requires no dedicated CPU instructions to be fast on non-desktop devices such as cell phones or IoT devices.
Speaking as a systems admin, I can say that WireGuard is the simplest VPN implementation I have ever deployed. But on top of this ease of use for me, the small amount of configuration required for an end user is very helpful. A small configuration file is all each user needs, and there are no complex levers or knobs to tweak. WireGuard’s reliance on easily shared public keys makes it very straightforward to deploy securely.
In Linux, its implementation is very simple, only a few thousand (<4000) lines of code. (Compare OpenVPN at 100,000+...) Room for optimizations and all sorts of clever improvements easily exists when a piece of software is this simple, whereas adding those sorts of features to something as large and complex as IPSEC is daunting.
Additionally, with so few moving parts, it’s very easy to automate WireGuard. Indeed, the default distribution of the software includes its own wg-quick tool to do just that.
But all these concerns leave aside the number one concern of most of the public--speed. WireGuard is incredibly fast, and outperforms OpenVPN and IPSEC easily. Its simplicity and ability to roam, and use of modern cryptographic systems out of the box only make it that much more appealing.