In case you wondered: Yes, there is a way to run Wireguard in Windows Subsystem for Linux without replacing the kernel. You still need the kernel and compile the Wireguard module as described in in this article. But it comes with a price: You can not use wq-quick, and you have to configure all the networking for yourself. We will use Linux’s Network Namespaces to get this running, as described at Wireguard’s netns page.
We will make some assumptions about the whole system: The WSL network is usually randomly generated. In my case, I always have an IP address from the 172.23.32.0/20 prefix with 172.23.32.1 as the default gateway. You can use any IP address in this range - the system will NAT anything. In this example, I chose to use 172.23.32.2 as my fixed address to make things easier.
You can not use the ‘Address’ and ‘DNS’ features of the Wireguard configuration in this scenario. You have to set everything manually. First of all we move the eth0 interface to a separate namespace ‘physical’. I know it’s not physical, but it makes it easier to understand the idea. Then, we will add a wg0 interface of type “wireguard” with one end in the physical namespace, and one end in the initial system namespace (1):
$ modprobe wireguard
$ ip netns add physical
$ ip link set eth0 netns physical
$ ip -n physical link add wg0 type wireguard
$ ip -n physical link set wg0 netns 1
Now the old interface eth0 in the namespace physical lost all of its configurations and is down. Configure it with a static IP, set the default route to the Windows host, and set the link status to up:
$ ip -n physical link set up eth0
$ ip -n physical addr add 172.23.32.2/20 dev eth0
$ ip -n physical route add default via 172.23.32.1 dev eth0
You should be able to communicate with the outside world from this point. Try to ping something on the internet, using the physical namespace, e.g.: ip netns exec physical ping google.com
The default namespace (1) only has the wg0 interface right now, but it is still unconfigured. Add the IP configuration for your Wireguard connection, in my case it is:
$ wg setconf wg0 /etc/wireguard/wg0.conf
$ ip addr add 172.19.23.7/32 dev wg0
$ ip -6 addr add fd86:ea04:1115:23::7/128 dev wg0
$ ip link set wg0 up
$ ip route add default dev wg0
$ ip -6 route add default dev wg0
And that’ it. The default system networking namespace is now connecting to your Wireguard endpoint, and EVERY traffic is routed through it. Do not forget to set some valid nameservers in your /etc/resolv.conf. They must be reachable over the VPN.
Conclusion: Yes, it is possible to run Wireguard in Windows Subsystem for Linux without replacing the kernel, but it lacks comfort. Scripting all the necessary steps is highly recommended. You will find examples at the Wireguard site. The good thing is: In this configuration, you can connect to other VPNs (like Forti, Cisco) over your Wireguard connection. Stacking VPNs is tricky tho, check your MTUs.