Windows Subsystem for Linux (WSL) is fantastic. It is probably the very best news that Linux geeks that are forced to run Windows due to corporate policy had ever received.
We were given Linux, while running Windows on the desktop without having to boot up a VM.
What it didn’t offer, was a full Linux kernel.
Along came WSL2, bringing with it full Linux kernel by way of a Hyper-V VM that is accessible from the same familiar terminal. But it does bring a glaring issue: It doesn’t play nicely over VPN.
The reason for this appears to primarily be in the way that WSL2 interfaces with the host system’s network stack. With WSL1, the Linux networking component shared the hardware with Windows. All of the network interfaces were mapped 1:1 with the same IP and MAC addresses. So when we connect to VPN, that connection is passed through as well.
Now with WSL2 running as a complete managed virtual machine, we use a Hyper-V virtual switch for the job. This virtual switch is set to Private by default, meaning that only the virtual machine(s) can use the virtual switch. Network traffic to the LAN is performed by a NAT layer, which I don’t fully understand the implementation of just yet. The subnet and IP range for this VM changes with every WSL reboot cycle as well.
There are loads of writeups on the web that talks about changing the virtual switch to an external network – That works for one or two use cases. Switching it to an Internal network helps with other issues. More articles talk about configuring the Windows Firewall to allow inbound traffic on the WSL virtual switch’s network adapter. This is useless for VPN connections though, because we’re wanting to talk OUT on the VPN connection so that we can use a WSL based distribution to do our actual jobs.
So the answer is as follows: Either set the Virtual Switch to External Network and point it to the VPN adapter, which disappears when we disconnect from the VPN….
OR
Go back to using WSL1. This is what I ended up doing.
And it’s really simple to do.
To set WSL1 as the default, run this command from the command prompt:
wsl –set-default-version 1
To set the WSL version for only a specific distro:
wsl –set-version <distro name> 1
I chose to set the WSL version for only the distro I was using primarily, which is Ubuntu. I like apt, sue me.
wsl –set-version ubuntu 1
The command took some time to complete while the distro was converted from a pure VM to the older way of doing things. And now, everything works the way I need it to. If you want to switch back to WSL2, the command to revert is just as simple. If I have to type that out here, you might as well just give up…