Wireguard in WSL (including IPv6)

Ever wanted to run Wireguard in Windows Subsystem for Linux, or wsl2, to be precise? Even with IPv6? As of today (May 2021, 20H2 19042.985) it doesn’t work. Mainly because of the wireguard.ko module and some netfilter functions are missing. But you can fix this. You only need to compile some stuff and a Linux kernel. That doesn’t scare you? Here you go!

I am running this on Ubuntu 20.04 LTS (from the Microsoft Store). First of all, we need Microsoft’s version of the Linux kernel. The running version is missing a few modules to handle multiple tables and packet tagging in netfilter. If you want to route IPv6 over your Wireguard tunnel, you will need multiple netfilter tables for IPv6 too.

Luckily the code for the (running) kernel and Wireguard is at Github. Let’s fetch everything we need:


$ sudo apt-get install libelf-dev build-essential pkg-config git bison flex libssl-dev bc

$ mkdir -p ~/build
$ cd ~/build

$ git clone --branch $(uname -r) --depth 1 https://github.com/microsoft/WSL2-Linux-Kernel.git
$ git clone --depth 1 https://github.com/WireGuard/wireguard-tools.git
$ git clone --depth 1 https://github.com/WireGuard/wireguard-linux-compat.git

Since the running kernel is mostly fine, copy the running config to the build directory:


$ zcat /proc/config.gz >~/build/WSL2-Linux-Kernel/.config
$ cd ~/build/WSL2-Linux-Kernel/

Open the ~/build/WSL2-Linux-Kernel/.config file and add or uncomment the following lines:


CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_NETFILTER_XT_CONNMARK=y
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y

After that, build the kernel, drink a tea and install (the not yet existing) modules:


$ make -j $(nproc)
$ sudo make -j $(nproc) modules_install

It will create a /lib/modules/$(uname -r) for you, where the Wireguard module will be installed. After compiling the new kernel, copy it to your windows system, e.g.:


$ cp arch/x86/boot/bzImage /mnt/c/kernel

Open two explorer Windows, one with C:\ and one with C:\Windows\System32\lxss\tools. In this directory you will find a file called “kernel” and it is exactly what you think it is. Copy the original file and keep it as a backup. Close all your WSL sessions and Windows, open a Powershell and shutdown your Linux Containers:

PS C:\Windows\System32\lxss\tools> wsl --shutdown

After that, replace the kernel file with the version you copied to C:\ and restart your Ubuntu session. If everything went well, you are running the new kernel.

YES, you have to do that every time Microsoft updates your WSL kernel

Do yourself a favor, keep the build directory and bookmark this site. You will need it after a Windows Update, that upgrades your Linux kernel. We still need the Wireguard kernel module. Go back to your build directory and compile everything:


$ cd ~/build
$ 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

Now you should have a /lib/modules/$(uname -r)/extra/wireguard.ko file. That’s the kernel module we need to run Wireguard. Load it and you are done:


$ sudo modprobe wireguard

From here on, fire up your wg-quick sessions or go to the Wireguard Quick Start Guide and enjoy your IPv6 transport.


[wasp ~]$ uname -a
Linux wasp 4.19.128-microsoft-standard #5 SMP Thu May 13 11:12:48 CEST 2021 x86_64 x86_64 x86_64 GNU/Linux
[wasp ~]$ ping6 2600::
PING 2600::(2600::) 56 data bytes
64 bytes from 2600::: icmp_seq=1 ttl=51 time=134 ms
64 bytes from 2600::: icmp_seq=2 ttl=51 time=145 ms
64 bytes from 2600::: icmp_seq=3 ttl=51 time=138 ms
64 bytes from 2600::: icmp_seq=4 ttl=51 time=134 ms

--- 2600:: ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 133.580/137.482/144.917/4.572 ms

Yes, you need to fiddle around with revolv.confs. Thanks to Cerebrate for the hints.

 

[itgaertner.net]

Words from a network guy


Wireguard in WSL2 (including IPv6)

2021-05-13