IPv6 Connectivity in WSL2
I am a big fan of WSL. One of my biggest complaints about WSL2 (mainly on principle) is that it does not support IPv6. But with a bit of tweaking, we can make it work.
Approach 1: WireGuard
We will use an IPv6 tunnelbroker. WireGuard makes this easy.
-
Check the kernel. In WSL, run
uname -srm
to check the kernel version. Kernels since 5.6 include WireGuard. If you have an older kernel, see how to replace the kernel below. -
Install WireGuard. Run
sudo apt install wireguard
. -
Create a tunnel. Create an account at route48.org. Create a new IPv6 tunnel. Set the tunnel type to WireGuard and pick a server location near you. Click the config icon and copy the configuration into
/etc/wireguard/wg0.conf
. Runsudo wg-quick up wg0
to start the tunnel. -
Connect. Test your connection with
ping6 google.com
. It should work now. -
Start automatically. Edit
/etc/wsl.conf
to contain[boot] command="wg-quick up wg0"
This will start the tunnel every time the WSL instance starts. The
[boot]
option is new in Windows 11.
Approach 2: Tailscale
Tailscale is magic. We can share another device’s IPv6 connection with Tailscale.
-
Create an exit node. Install Tailscale on a device with an IPv6 connection. This might even be your Windows machine. Configure it as an exit node. Save its Tailscale IP address (
100.x.y.z
) for later. - Start Tailscale automatically.
Install Tailscale in WSL.
Edit
/etc/wsl.conf
to contain[boot] command="PATH=$PATH tailscaled"
This will start
tailscaled
every time the WSL instance starts. - Update the kernel.
Tailscale needs
CONFIG_IPV6_MULTIPLE_TABLES
, so we have to build the kernel. (If you trust me, you can download my kernel.) Clone the WSL2 kernel. Add a lineCONFIG_IPV6_MULTIPLE_TABLES=y
toMicrosoft/config-wsl
, and edit theCONFIG_LOCALVERSION
line with a name you will recognize later. Follow the build instructions in the README. Download/copyvmlinux
toC:\vmlinux
. Create a file%UserProfile%\.wslconfig
containing[wsl2] kernel=C:\\vmlinux
(Note the double backslashes in the path.)
-
Restart WSL. Run
wsl.exe --shutdown
. Check that no WSL2 distros are running withwsl.exe -l -v
. Then restart WSL and rununame -srm
to check that the new kernel is running. It should have the version string you set in the config file. -
Route traffic through the exit node. Check that
tailscaled
is running withps aux
. Runsudo tailscale up --exit-node=100.x.y.z --exit-node-allow-lan-access
, replacing100.x.y.z
with the exit node’s IP address from above. - Connect.
Test your connection with
ping6 google.com
. It should work now.
Update 2022-10-21:
WSL supports systemd starting in version 0.67.6.
Enable systemd by adding systemd=true
in the [boot]
section of /etc/wsl.conf
instead of specifying boot commands.
Configure systemd to start the WireGuard interface with sudo systemctl enable wg-quick@wg0
.
Tailscale should start automatically when systemd is enabled.
IPv6 requires at least MTU 1280, but wg-quick
now sets the MTU to 1200 on my system.
To configure the WireGuard interface MTU, add a line MTU = 1280
in the [Interface]
section of /etc/wireguard/wg0.conf
.
Update 2023-03-30:
Route48 is no longer providing tunnels. route64.org is an alternative.