Skip to content

WSL2 & Wireguard

opustecnica edited this page Jan 16, 2021 · 10 revisions

You might have noticed that the Ubuntu instructions for the installation of Wireguard at do not work in WSL2. The first hint of an issue is conveyed to you when trying to initialize the wg0 interface:

$ sudo ip link add dev wg0 type wireguard
RTNETLINK answers: Operation not supported

First, cleanup your environment

sudo apt purge -y wireguard && sudo apt autoremove -y

Second, let's build the needed module/s

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://git.zx2c4.com/wireguard-linux-compat
git clone --depth 1 https://git.zx2c4.com/wireguard-tools
# Install required dependencies
sudo apt-get install libelf-dev build-essential pkg-config
sudo apt-get install bison build-essential flex libssl-dev libelf-dev bc
# Let's build
cd ~/build/WSL2-Linux-Kernel
zcat /proc/config.gz > .config
vim ./.config
# Make sure you change 
# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
# to 
# CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
# recompile Kernel
make -j $(nproc)
# Copy kernel to temporary location
cp ./arch/x86_64/boot/bzImage /mnt/c/Users/USER/WSL2-Kernels/kernel-new
sudo make -j $(nproc) modules_install
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
# Verify presence of module
ls -las /lib/modules/$(uname -r)/extra/
# Load the Kernel module & veriify
sudo modprobe wireguard
dmesg | tail

In PowerShell with Admin rights:

Move-Item C:\Windows\System32\lxss\tools\kernel C:\Users\USER\WSL2-Kernels\kernel-orig
New-Item -Type SymbolicLink -Path C:\Windows\System32\lxss\tools\ -Name kernel -Value C:\Users\USER\WSL2-Kernels\kernel-new

This can also be achieved by editing the %USERPROFILE%\.wslconfig:

[wsl2]
kernel=C:\\Users\\USER\\WSL2-Kernels\\kernel-new

Third, test vs demo.wireguard.com

sudo /home/user/build/wireguard-tools/contrib/ncat-client-server/client.sh default-route
curl http://192.168.4.1
ping 192.168.4.1
curl zx2c4.com/ip
sudo ip link set down dev wg0

Fourth, test your favorite client configuration

  1. Create a configuration file in /etc/wireguard/ (e.g. sudo vim /etc/wireguard/vpn-xyz.conf)
[Interface]
PrivateKey = ...Q03z8DPHr......=
Address = 192.168.0.2/32
DNS = 192.168.0.1

# PostUp = iptables -t nat -A POSTROUTING -o %i -j MASQUERADE
# PostDown = iptables -t nat -D POSTROUTING -o %i -j MASQUERADE
# Specifically add a route via gateway for the WR server address.  When using the 0.0.0.0/1, 128.0.0.0/1 AllowedIPs
# PostUp = gateway=$(/sbin/ip route | awk '/default/ { print $3 }'); endpoint="$(wg show %i endpoints | sed -n 's/.*\t\(.*\):.*/\1/p')"; ip route add $endpoint via $gateway
# Specifically set the DNS (why is the build in method not working?)
PostUp = DNS=192.168.0.1; sed -i -E "s/([[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+)/$DNS/" /etc/resolv.conf
# Restore DNS once connection is closed
PostDown = sed -i -E "s/([[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+)/$(/sbin/ip route | awk '/default/ { print $3 }')/" /etc/resolv.conf
# Add multiple DNS?
# PreDown = gateway=$(/sbin/ip route | awk '/default/ { print $3 }'); echo "nameserver $gateway" >> /etc/resolv.conf;
# Specifically remove a route via gateway for the WR server address.  When using the 0.0.0.0/1, 128.0.0.0/1 AllowedIPs
# PreDown = endpoint="$(wg show %i endpoints | sed -n 's/.*\t\(.*\):.*/\1/p')"; ip route del $endpoint

[Peer]
PublicKey = ...y28TWojCa...=
# AllowedIPs = 0.0.0.0/1, 128.0.0.0/1
AllowedIPs = 0.0.0.0/0
Endpoint = wr.somedomain.com:51820
  1. Test it all:
sudo modprobe wireguard && sudo wg-quick up vpn-xyz
# To shutdown the connection
sudo wg-quick down vpn-xyz

  1. https://www.wireguard.com/quickstart/
  2. https://github.com/pirate/wireguard-docs#Interface