When using the Cisco AnyConnect client and WSL2 you may find that your WSL environment loses network connectivity. Here is a work around.
We use the Cisco AnyConnect client to connect to our work VPN. We have split tunneling enabled where all traffic for specific subnets gets sent over the VPN connection. This includes the 172.16.x.x subnets (Class B). WSL 2 puts it's Linux distributions on a random part of that network, it changes during every reboot. One thing you could do is create a virtual NIC through Hyper-V and assign it an address in that subnet with a really big subnet mask, but that is dumb and breaks anything else you may have sitting in that network. Doing that will tell the subsystem to use a random 192.168.x.x/24 subnet. Also, not ideal.
The underlying issue is that when the client creates the VPN tunnel it assigns an interface metric of 1. Meaning, that all network traffic flows through it before it goes through any other interface. You can either manually change that metric every time you connect to the VPN or set up a scheduled task to do it. Since I like automatic, I'll go the task route. Here's everything you need to do it.
First, let's create the PowerShell script to do the work. I'm going to store this in c:\tools\anyconnectworkaround.ps1
It is a simple one-line script. All it does is find the adapters a description with Cisco
in the name. You can adjust that to be more specific if you need. It then sets the interface metric to 6000. Which is higher than the other interfaces on your system. You can adjust higher or lower as necessary.
Get-NetAdapter | ? {$_.InterfaceDescription -like "*Cisco*" } |Set-NetIPInterface -InterfaceMetric 6000
Now that we have the script, we will create the task that will run whenever the VPN client establishes a connection.
In summary, the task will run as system with elevated privileges. It will trigger on a specific event in the Cisco AnyConnect Secure Mobility Client
log looking for Event ID 3020
. The action will be to start powershell.exe
and execute the c:\tools\anyconnectworkaround.ps1
script.
Here are the detailed steps on creating that task:
- Open
Scheduled Tasks
- In the right-hand pane, under
Actions
clickCreate Task...
- In the name put something descriptive, like
AnyConnect Work Around
- Click the
Change User or Group...
button - Type in
system
and click OK - Check the
Run with highest privileges
- Click the
Triggers
tab - Click
New...
- Change the
Begin the task
drop down toOn an event
- Change the
Log
drop down toCisco AnyConnect Secure Mobility Client
- Put
3020
in theEvent ID
box - Click
OK
to close the trigger dialog - Click the
Actions
tab - Click
New...
- Put
powershell.exe
in theProgram/script
box - Put the path to your script in the
Add arguments (optional)
box. Example:c:\tools\anyconnectworkaround.ps1
- Click
OK
to close the action dialog - Click
OK
to close the event dialog - Now, if you are connected to the VPN, disconnect.
- Connect to the VPN
- Validate that you can get to the internet from your WSL2 installation.
ping 8.8.8.8
Conclusion
AnyConnect is great. WSL2 is great. Combined, not so great. But with this workaround I am able to connect to the VPN and still use my WSL2 distributions and, more importantly, Docker (which sits in a WSL2 distribution). If I find that the metric is configurable in the AnyConnect client, I'll update this post. But as of now I do not know anyway of changing the metric through configuration.