Internet connection and DNS routing are broken from WSL2 instances, when some VPNs are active. The workaround breaks down into two problems:
- Network connection to internet
- DNS in WSL2
This problem is tracked in multiple microsoft/WSL issues including, but not limited to:
When the VPN connection is active, network traffic out of WSL2 is not passed to the internet.
Changing the Interface Metric 1 -> 6000 for AnyConnect VPN Adapter resolves the connection issue, but this has to be done after each time the VPN connects.
By default, the Interface Metrics for AnyConnect are:
- IPv6: 6000
- IPv4: 1
ping times out from WSL Shell.
Changing the Interface Metrics for AnyConnect to:
- IPv6: 6000
- IPv4: 6000
ping to IP Addresses succeed, but still no DNS Resolution.
When the VPN is active, the autogenerated /etc/resolv.conf does not work. The list of nameservers must be manually built to include some sane default DNS Name Servers and the DNS from the VPN.
First, disable automatically generating /etc/resolv.conf.
Add the following configuration, or create the file if it doesn't exist. The path to this file is from the shell prompt of your WSL2 instance.
/etc/wsl.conf
[network]
generateResolvConf = false
Next, manually add the corportate DNS Server as the first nameserver in /etc/resolv.conf.
/etc/resolv.conf
nameserver <corporateDNS1>
nameserver <corporateDNS2>
nameserver 1.1.1.1
To automate this, I put the PS command in a script and created a Task to run every time there is a network change.
First, create the script. I have a 'scripts' directory in my user home, so I put it at:
%HOMEPATH%\scripts\UpdateAnyConnectInterfaceMetric.ps1
Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 6000
You can save it where you want, just make sure to use that path in step 13 below.
- Open 'Task Scheduler'
- Click "Create Task" on Right Sidebar
- Name: Update Anyconnect Adapter Interface Metric for WSL2
- Set Security Options
- Check box: 'Run with highest priveleges'
- Select 'Triggers' Tab
- Click 'New' at bottom of Window
- Open 'Begin the task' drop-down
- Select 'On an Event'
- Configure Event:
- Log: 'Microsoft-Windows-NetworkProfile/Operational'
- Source: 'NetworkProfile'
- Event ID: '10000'
- Click 'OK'
- Select 'Actions' Tab
- Click 'New'
- Configure Action:
- Action: 'Start a Program'
- Program/script: 'Powershell.exe'
- Add arguments: '-ExecutionPolicy Bypass -File %HOMEPATH%\scripts\UpdateAnyConnectInterfaceMetric.ps1'
- Click 'OK'
- Select 'Conditions' Tab
- Uncheck box:
- Power -> Start the task only if the computer is on AC Power
- (optional) Check box:
- Network -> Start only if the following network connection is available
- Select your corporate network name (e.g. cisco.com)
- This will avoid running the script unnecessarily (startup, connect to new wifi, VPN not active)
- Click 'OK'
When AnyConnect finishes connecting, a Powershell window pops up for a couple seconds and WSL can reach the network.