WireGuard is a security-focused virtual private network (VPN) known for its simplicity and ease of use. It uses proven cryptography protocols and algorithms to protect data. Originally developed for the Linux kernel, it is now deployable on Windows, macOS, BSD, iOS and Android.
Virtual private networks (VPNs) are indispensable to businesses. They link remote office branches to the main corporate network, they allow roaming employees to use internal company applications and enable cloud servers to be part of the same network as on-premises ones.
Most VPN solutions that exist today were designed a long time ago, so they’re quite slow and are overly engineered. Enter WireGuard, a project that puts security and simplicity first.
Security researcher and kernel developer Jason Donenfeld got the idea for WireGuard in 2017 while in need of a stealthy traffic tunneling solution that could be used during penetration testing engagements. The more he looked at the existing options, the more he realized that VPN tunnels like IPsec and OpenVPN did not perform well and were difficult to configure and manage properly.
So, he set out to create an entirely new VPN protocol and implementation that would avoid some of the design decisions that transformed other tunneling technologies into monster projects with huge code bases and countless knobs and switches.
How WireGuard’s cryptography works
For one, the WireGuard protocol does away with cryptographic agility -- the concept of offering choices among different encryption, key exchange and hashing algorithms -- as this has resulted in insecure deployments with other technologies. Instead the protocol uses a selection of modern, thoroughly tested and peer-reviewed cryptographic primitives that result in strong default cryptographic choices that users cannot change or misconfigure. If any serious vulnerability is ever discovered in the used crypto primitives, a new version of the protocol is released and there’s a mechanism of negotiating protocol version between peers.
WireGuard uses ChaCha20 for symmetric encryption with Poly1305 for message authentication, a combination that’s more performant than AES on embedded CPU architectures that don’t have cryptographic hardware acceleration; Curve25519 for elliptic-curve Diffie-Hellman (ECDH) key agreement; BLAKE2s for hashing, which is faster than SHA-3; and a 1.5 Round Trip Time (1.5-RTT) handshake that’s based on the Noise framework and provides forward secrecy. It also includes built-in protection against key impersonation, denial-of-service and replay attacks, as well as some post-quantum cryptographic resistance.
In the WireGuard protocol, each peer is identified to others through short public keys in a similar way to how key-based authentication works in OpenSSH. The public keys are also used to establish which IP addresses are assigned to each peer inside the tunnel as part of a new concept that WireGuard developers call cryptokey routing.
The protocol is also stealthy, as it does not respond to any packets from peers it doesn’t recognize, so a network scan will not reveal that WireGuard is running on a machine. Furthermore, the connection between peers, which can act as both clients and servers at the same time, go silent when there’s no exchange of data.
The WireGuard protocol has been reviewed by multiple teams of security researchers from the private sector and academia and has been formally verified in different computational models.
The main WireGuard implementation is for Linux and comes in the form of a kernel module. The code is intended to be easily auditable, with Donenfeld saying it can be read in an afternoon.
Compared to OpenVPN which has over 100,000 lines of code and depends on OpenSSL -- another huge codebase -- the WireGuard kernel module has around 4,000 lines of code and the crypto code is built into it. This means that it has a smaller attack surface compared to other VPN projects and, since it doesn’t respond to unauthenticated packets, it’s much harder to attack.
How well does WireGuard perform?
On Linux, WireGuard operates exclusively in kernel space, so its performance is much better than OpenVPN, which lives in userspace and uses a virtual network interface driver. Many of WireGuard benchmarks -- including on the project’s own website -- show up to four times better performance and connection speeds than OpenVPN and better speeds than IPsec-based VPNs on the same hardware.
However, WireGuard implementations for Android, iOS, macOS, OpenBSD and Windows are written in the Go memory-safe programming language. Aside from some community-supported Android firmware projects that integrated the WireGuard kernel module, the non-Linux WireGuard implementations run in userspace and don’t benefit from the same performance as the kernel implementation. That said, they still manage to match or outperform OpenVPN in most cases.
How WireGuard integrates into the Linux kernel
The WireGuard kernel module is available in the package repositories of all major Linux distributions and even some specialized ones. However, Donenfeld has been working to integrate it directly into the main Linux kernel since last year. Progress has been slow because merging it requires significant changes to both the Linux kernel’s cryptographic API and the networking stack, but it has received a favorable review from Linus Torvalds.
“I see that Jason actually made the pull request to have WireGuard included in the kernel,” Torvalds said on the Linux kernel mailing list one year ago. “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.”
Donenfeld’s plans involved merging a new, simpler cryptographic API to the Linux kernel that he dubbed Zinc. According to him, Zinc would have made it easier for developers to perform cryptographic operations in their applications compared to using the kernel’s existing crypto API, which is overly complex for most use cases. In a presentation on Zinc, he described the Linux crypto API as a “super crazy ‘enterprise'” API that is very prone to failure and overwhelmingly hard to use.”
His attempts to merge a second crypto API received mixed responses from other kernel developers who raised various concerns regarding feature duplication and whether it’s needed instead of fixing the problems with the existing API. The mailing list discussion about the Zinc patch submission stopped in April, but another kernel developer recently took on the task of integrating most of the Zinc features into the existing crypto API and the changes were merged into the kernel in November. Donenfeld accepted the compromise and is mostly satisfied with the result.
“It's not called ‘Zinc’ any more, and some of the design decisions I liked aren't there, but I think the lion's share of what we were after is there, and a few other pieces should be possible to upstream one at a time,” he said in a message to the WireGuard project’s mailing list.
This was an important step that has unlocked the process of upstreaming WireGuard into the Linux networking subsystem. That might take some time as well, but once integration is achieved, WireGuard will make its way into a very large number of devices as they are updated to use new kernel versions. If everything goes to plan, WireGuard will land in Linux kernel 5.6, which is expected to be released sometime around April.
“WireGuard is probably mostly okay, but I still do anticipate review with lots of feedback to incorporate, since now there's more impetus for people to take the patch submission seriously,” Donenfeld said.
Being part of the Linux kernel itself will not make WireGuard ubiquitous immediately, because embedded devices in particular are very slow to adopt new kernel versions. However, WireGuard is already available in the OpenWRT community firmware for routers and other embedded devices and EdgeOS, which is used on Ubiquiti networking devices.
Windows and a new TUN driver
To improve WireGuard performance on Windows, Donenfeld and the other WireGuard developers have created a new, simpler open-source TUN driver called Wintun. Windows doesn’t provide a native TUN virtual device and while some drivers exist to achieve this from projects such as OpenVPN or SoftEther, they were written a long time ago and have various issues.
“These projects were written in a different age, the era of NDIS5, and then ported later to NDIS6,” Donenfeld wrote in an email in March announcing the project. “This means they haven't benefited from things like Windows 7's NdisMediumIP, which allows for native layer 3 tunneling, without having to do layer 2 emulation. Drivers like OpenVPN's tap-windows6 also do some somewhat nasty things, like emulate DHCP from inside the kernel for network configuration. The code is old and complicated. As usual, I wanted instead something tiny and dumb that we can reason about, which does things in a ‘right’ and ‘boring’ way for a narrower use case: layer 3 TUN.”
Like Zinc and WireGuard itself, Wintun seems to be developed with the same focus on simplicity, auditability and security. Developers from the OpenVPN project are also working on adding support for OpenVPN to use it as an alternative to their old driver.
When will WireGuard be enterprise ready?
Even though WireGuard has not officially reached a stable version yet, it’s already being used in production. Some commercial VPN service providers offer WireGuard servers and there are ongoing efforts to build mesh networking tools around it. It is not yet “enterprise ready” and it’s unclear if it will ever be because its developers are reluctant to add new features that are only useful to a subset of users or cover edge cases because that’s how other projects became overly complex.
However, WireGuard can be a building block on top of which more complex solutions can be created. For example, enterprises need to deploy and configure new software on a large number of computers in an automated manner, but the distribution of public keys among peers and key management are not covered by the WireGuard project itself and will have to be implemented as a separate tool.