The WireGuard VPN project today announced an important milestone for its Windows users: an all-new kernel-mode implementation of the VPN protocol called WireGuardNT. The new implementation provides vastly improved throughput on 10 Gbps LAN connections, as well as on many Wi-Fi connections.
WireGuard (on Windows) and Wintun
WireGuard’s original implementation on Windows uses wireguard-go – a userspace implementation of WireGuard written in Google’s Go programming language. Wireguard-go is then linked to a virtual network device, the majority of which also live in the user space. Donenfeld didn’t like tap-windows, the virtual network interface of the OpenVPN project, so he implemented his own replacement called Wintun.
Wintun is a definite improvement over tap windows – the OpenVPN project itself has implemented Wintun support, with impressive results (414Mbps over tap windows vs 737Mbps over Wintun). But while using Wintun is an improvement over tap windows, it doesn’t change the need for constant context changes of kernel space (where the “real” network stack lives) and user space (where OpenVPN and wireguard-go are both live).
To get rid of the remaining performance bottlenecks, the entire stack – virtual adapter, cryptography, and all – has to be pulled into the kernel. On Linux, that means it’s a DLKM (Dynamically-Loadable Kernel Module). On Windows, this means it is a good in-kernel device driver.
WireGuardNT and the NT kernel
Getting rid of userspace components from the WireGuard stack on Windows and keeping everything in the kernel means changing WireGuard to work on Windows the way it already works on Linux. In fact, WireGuardNT started out as a direct port of the Linux in-kernel WireGuard implementation.
According to WireGuard creator Jason Donenfeld, “The NT codebase wandered quickly to fit well with native NTisms and NDIS APIs.” of the full range of NT kernel and NDIS capabilities.”
Of course, this also means getting rid of a lot of context changes. The end results are solid: more than three times the peak performance measured with Ethr on a pair of Equinix Metal (formerly packet.net) c3.small instances.
However, the benefits of less context switching extend beyond Xeon servers with 10 Gbps interfaces – Donenfeld said some early testers reported that WireGuardNT sometimes resolved huge performance hits seen when using their VPN connection over Wi-Fi.
We tested the difference directly with an HP EliteBook with an Intel AX201 Wi-Fi 6 card connected to the router node of a Plume Wi-Fi 6 Superpods test kit. While our results weren’t as dramatic as some early testers, they do confirm a significant performance improvement. Using the same hardware and configurations, we measured WireGuardNT iperf3 to be 10 to 25 percent faster than wireguard-go and Wintun.
Testing WireGuardNT today
WireGuardNT is now available for testing in the general Windows download for WireGuard, as of version 0.4. But since it is still classified as experimental, you need to manually add a registry key and a DWORD to use it. to unlock
regedit as an administrator, then browse to HKLM–>Software. Next, create a key called WireGuard and inside that key a DWORD called ExperimentalKernelDriver.
If ExperimentalKernelDriver is set to 1, your tunnels will use the new WireGuardNT code. Without this code (or if it is set to 0), they use the default behavior, which is the old wireguard-go/wintun code. In order for your change to take effect, you need to right-click on the WireGuard icon in the system tray and click “exit”. When you open the WireGuard app again, it will respect your ExperimentalKernelDriver setting.
Going forward, WireGuardNT will be enabled by default and you’ll need to set a registry flag instead if you want the old code. Furthermore, the project plans to eventually remove wireguard-go/wintun completely into the general binary. The projects themselves, on the other hand, will stay, as they have broad utility beyond the standard WireGuard client.