Installing WireGuard in WSL 2
There’s been a lot of buzz about WireGuard recently, primarily because of it getting merged into the Linux Kernel for 5.6. So much so that even my friends started reaching out:
So I decided to take a look. I primarily run Windows, but most of my work is in Linux, therefore I spend a lot of time in WSL 2. Needless to say, installing WireGuard into WSL 2 was not as simple/easy as it probably should have been. I’m sure these issues will be resolved as WireGuard becomes more mainstream, but for the moment the setup is a bit more manual.
Note: This tutorial will only work for WSL 2, which at the time of this writing requires you to be running a Windows Insider build of Windows 10, and specifically enable it for your WSL instance. This is because WSL 2 runs a full Linux kernel, and so loading modules that create network interfaces is completely possible.
To check what version of WSL you’re running:
wsl --list -v
What‘s Happening
I’m using Ubuntu in WSL 2, specifically 18.04.4 LTS with the default 4.19.84-microsoft-standard Linux kernel. A few things happen that that cause the install issue:
- The custom/Microsoft kernel headers are not installed on the system by default, they also aren’t available as an apt package.
- The naming of the kernel (I suspect) tips off WireGuard that it is non-standard, and thus it opts to compile the WireGuard kernel module against linux-generic, which doesn’t work.
- For whatever reason, despite the fact that WSL 2 is currently running a 4.19 version kernel, APT wishes to install any generic things at 4.15.0–76.
Needless to say, following the Ubuntu install instructions listed on WireGuards page doesn’t work:
Text output, for screen readers and SEO:
$ sudo ip link add dev wg0 type wireguard
RTNETLINK answers: Operation not supported
$ sudo modprobe wireguard
modprobe: ERROR: ../libkmod/libkmod.c:586 kmod_search_moddep() could not open moddep file '/lib/modules/4.19.84-microsoft-standard/modules.dep.bin'
modprobe: FATAL: Module wireguard not found in directory /lib/modules/4.19.84-microsoft-standard
$ sudo modprobe wireguard
modprobe: ERROR: ../libkmod/libkmod.c:514 lookup_builtin_file() could not open builtin file '/lib/modules/4.19.84-microsoft-standard/modules.builtin.bin'
modprobe: ERROR: could not insert 'wireguard': Exec format error
Cleanup
If you’ve already attempted the install, and it failed (otherwise, why would you be reading this article?), lets first clean up the mess. We don’t need most of what was installed before:
sudo apt purge -y wireguard && sudo apt autoremove -y
And if you get the following error:
dpkg: warning: while removing linux-headers-4.15.0–76-generic, directory ‘/lib/modules/4.15.0–76-generic’ not empty so not removed
You can most likely safely manually remove this folder:
sudo rm -rf /lib/modules/4.15.0–76-generic/
The Fix
Now, onto the interesting bits! We’ll need to compile our own kernel (we won’t need to install it though), and kernel modules for WSL 2, along with compiling WireGuard and the wg(8) helper tool.
For starters, we need a clean workspace, and the code:
cd ~
mkdir workspace
cd workspace
git clone --depth 1 https://github.com/microsoft/WSL2-Linux-Kernel.git
git clone --depth 1 https://git.zx2c4.com/wireguard-linux-compat
git clone --depth 1 https://git.zx2c4.com/wireguard-tools
—
UPDATE: Microsoft is of course updating WSL regularly, and so at the time of this writing, the checkout of the repo lead to the version of the kernel that I needed to build. After the Windows Cumulative Update 2004, Windows updated the Kernel in my WSL instance too. This lead to my WireGuard breaking and having to redo these steps, but with a new Kernel version. The above kernel clone will only checkout master
but what you’ll most likely want is the version that matches what kernel you have running. To do this, try:
git clone --branch $(uname -r) --depth 1 https://github.com/microsoft/WSL2-Linux-Kernel.git
The same steps apply for the rest of the tutorial, except you’ll need to replace the kernel version that I’m using with whatever you have from running:uname -r
—
WireGuard has listed on it’s compilation page that a set of packages are needed. We need all but one: linux-headers-$(uname -r)
, as this will fail to install since it doesn’t exist.
sudo apt-get install libelf-dev build-essential pkg-config
We also need packages necessary to compile our Linux kernel and modules:
sudo apt-get install bison build-essential flex libssl-dev libelf-dev bc
Then, we need to ‘restore’ the configuration that was used to build your current kernel as the config needed for our build:
cd ~/workspace/WSL2-Linux-Kernel
zcat /proc/config.gz > .config
Followed by compiling the kernel and modules, and installing the modules:
make -j $(nproc)
sudo make -j $(nproc) modules_install
We then need to make a symlink of that install, so that WireGuard can find the right directory:
cd /lib/modules
sudo ln -s 4.19.84-microsoft-standard+/ 4.19.84-microsoft-standard
Now we can build WireGuard and it’s tool (this is more or less following the compile steps on the WireGuard compile page):
cd ~/workspace
make -C wireguard-linux-compat/src -j$(nproc)
sudo make -C wireguard-linux-compat/src install
make -C wireguard-tools/src -j$(nproc)
sudo make -C wireguard-tools/src install
Verify it’s installed (you should see a wireguard.ko file):
ls /lib/modules/4.19.84-microsoft-standard/extra/
Load the Kernel Module, and verify that it’s loaded:
sudo modprobe wireguard
dmesg | tail
If all is well, you should see this output:
[ 7834.764730] wireguard: WireGuard 0.0.20200205 loaded. See www.wireguard.com for information.
[ 7834.764734] wireguard: Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
Congrats! You now have WireGuard installed and working on your system! Hop on over to the WireGuard Quick Start page, to get using it!
One tip: After a reboot the module won’t be loaded, so you’ll have to issue the following to get it loaded again:
sudo modprobe wireguard