How to Fix WSL2 & VPN Connectivity Issues
Comprehensive guide to fix WSL2 and Cisco AnyConnect VPN internet connectivity issues.
There is a known issue with DNS forwarding in WSL2 and WSL1 when using VPN (see GitHub Issue #1350). Additionally, there are specific problems with Cisco AnyConnect VPN client. This guide provides workarounds for these issues and should work for Ubuntu and Debian distributions.
The Problem - Common Symptoms
When connected to Cisco AnyConnect VPN, you may encounter the following DNS resolution failures:
- Package updates fail -
sudo apt updatedisplays errors like:
Err:1 http://archive.ubuntu.com/ubuntu focal-updates InRelease
Temporary failure resolving 'archive.ubuntu.com'
Err:2 http://archive.ubuntu.com/ubuntu focal-backports InRelease
Temporary failure resolving 'archive.ubuntu.com'
Reading package lists... Done
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal/InRelease Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal-updates/InRelease Temporary failure resolving 'archive.ubuntu.com'
- Git operations fail -
git pulldisplays errors like:
// code-block-error-line
fatal: unable to access 'https://github.com/actionanand/wiki.git/': Could not resolve host: github.com
- Network connectivity fails -
ping google.comdisplays:
ping: google.com: Temporary failure in name resolution
Root Cause: When you connect to Cisco AnyConnect VPN, WSL2 fails to resolve DNS names correctly. Commands like sudo apt update, ping google.com, and git pull work fine without VPN but fail when the VPN connection is active. The issue stems from WSL's inability to properly resolve DNS when the VPN modifies the Windows network configuration.
Solution 1: Automatic DNS Configuration (Recommended)
This automated solution was created by EdwardCooke and automatically updates resolv.conf when starting WSL.
Step 1: Re-enable Auto-Generation of resolv.conf
If you previously disabled it, re-enable auto-generation by commenting out the configuration:
sudo nano /etc/wsl.conf
Ensure these lines are commented out (prefixed with #):
#[network]
#generateResolvConf = false
Step 2: Create the DNS Update Script
Create a script that automatically fetches and configures DNS servers:
sudo nano /bin/vpn-dns.sh
Add the following content:
#!/bin/bash
echo "Getting current DNS servers, this takes a couple of seconds"
/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -Command '
$ErrorActionPreference="SilentlyContinue"
Get-NetAdapter -InterfaceDescription "Cisco AnyConnect*" | Get-DnsClientServerAddress | Select -ExpandProperty ServerAddresses
Get-NetAdapter | ?{-not ($_.InterfaceDescription -like "Cisco AnyConnect*") } | Get-DnsClientServerAddress | Select -ExpandProperty ServerAddresses
' | \
awk 'BEGIN { print "# Generated by vpn fix func on", strftime("%c"); print } { print "nameserver", $1 }' | \
tr -d '\r' > /etc/resolv.conf
clear
Step 3: Make the Script Executable
Grant execution permissions and configure sudo access:
sudo chmod +x /bin/vpn-dns.sh
echo "$(whoami) ALL=(ALL) NOPASSWD: /bin/vpn-dns.sh" | sudo tee /etc/sudoers.d/010-$(whoami)-vpn-dns
Step 4: Configure Automatic Execution on Startup
Make the script run automatically when WSL starts:
echo "sudo /bin/vpn-dns.sh" | sudo tee /etc/profile.d/vpn-dns.sh
Now restart WSL and test with wget google.com or ping google.com.
Step 5: Manual Execution (Optional)
If you prefer not to run the script automatically (skip Step 4), you can execute it manually each time:
sudo /bin/vpn-dns.sh
Reference: StackOverflow Solution
Solution 2: Manual DNS Configuration
Internet connection and DNS routing break from WSL2 instances when certain VPNs are active. This manual workaround involves two main steps: DNS resolution and network connection configuration.
Part A: DNS Resolution
Step 1: Get DNS Servers from VPN
With Cisco AnyConnect VPN connected, open PowerShell as Administrator and run:
Get-DnsClientServerAddress -AddressFamily IPv4 | Select-Object -ExpandProperty ServerAddresses
Note down all the DNS/nameserver addresses - you'll need them later.
Step 2: Get Search Domains
Run this command to get all available search domains:
Get-DnsClientGlobalSetting | Select-Object -ExpandProperty SuffixSearchList
Step 3: Disable Auto-Generated resolv.conf
When VPN is active, the auto-generated /etc/resolv.conf doesn't work correctly. You need to manually configure the nameservers.
First, unlink the default resolv.conf file:
sudo unlink /etc/resolv.conf
Then, disable automatic generation by configuring WSL:
cat <<EOF | sudo tee -a /etc/wsl.conf
[network]
generateResolvConf = false
EOF
Step 4: Create Custom resolv.conf
Manually add your corporate DNS servers as the first nameservers in /etc/resolv.conf:
cat <<EOF | sudo tee -a /etc/resolv.conf
nameserver 10.50.xxx.xxx # Corporate DNS from Step 1
nameserver 10.50.xxx.xxx # Corporate DNS from Step 1
nameserver 8.8.8.8 # Google Public DNS (fallback)
nameserver 8.8.4.4 # Google Public DNS (fallback)
search your.searchdomain.com # Search domain from Step 2
EOF
Step 5: Prevent File Overwriting
To prevent the system from rewriting your /etc/resolv.conf on WSL startup:
sudo chattr +i /etc/resolv.conf
This makes the file immutable.
Additional Information: Finding Corporate DNS
To get <corporateDNS> addresses, use ipconfig /all from CMD or PowerShell prompt, and check the details of the VPN adapter:
Description . . . . . . . . . . . : Cisco AnyConnect Secure Mobility Client Virtual Miniport Adapter for Windows x64
Physical Address. . . . . . . . . : XX-XX-XX-XX-XX-XX
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
IPv6 Address. . . . . . . . . . . : xxxx:xxxx:xxxx:xxxx(Preferred)
Link-local IPv6 Address . . . . . : xxxx:xxxx:xxxx:xxxx(Preferred)
IPv4 Address. . . . . . . . . . . : 10.20.30.40(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.255.255
Default Gateway . . . . . . . . . : ::
0.0.0.0
DHCPv6 IAID . . . . . . . . . . . :
DHCPv6 Client DUID. . . . . . . . :
DNS Servers . . . . . . . . . . . : 123.45.67.89 ← Corporate DNS 1
123.45.67.90 ← Corporate DNS 2
Primary WINS Server . . . . . . . : xxx.xx.xxx.xx
NetBIOS over Tcpip. . . . . . . . : Enabled
Part B: Network Connection Configuration
When the VPN connection is active, network traffic from WSL2 may not be passed to the internet correctly.
Solution: Change the Interface Metric from 1 to 6000 for the AnyConnect VPN Adapter. This must be done each time after the VPN connection is established.
Default Interface Metrics for AnyConnect:
- IPv6: 6000
- IPv4: 1
Without this change, ping times out from WSL Shell.
After changing Interface Metric to 6000:
- IPv6: 6000
- IPv4: 6000
Step 1: Change Interface Metric
Run this command in PowerShell (as Administrator):
Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 6000
This PowerShell command (with admin rights) must be run each time after the VPN connection is established.
Step 2: Restart WSL (Optional)
Restart WSL2 from PowerShell using:
Restart-Service LxssManager
Alternatively, you can close the WSL2 window and reopen it.
Reference: GitHub Gist by machuu
Solution 3: Simplified WSL1 Configuration
For WSL1 users, here's a streamlined approach:
Step 1: Get DNS Nameservers
After connecting to Cisco VPN Client (and optionally before connecting), get all available DNS nameservers using PowerShell:
Get-DnsClientServerAddress -AddressFamily IPv4 | Select-Object -ExpandProperty ServerAddresses
Note: Nameservers visible before connecting to the Cisco client may change frequently. You can either update them as needed or omit pre-VPN nameservers.
Step 2: Disable systemd-resolved Service
sudo systemctl disable systemd-resolved.service
Step 3: Stop the Service
sudo systemctl stop systemd-resolved.service
Step 4: Remove Existing resolv.conf
sudo rm /etc/resolv.conf
Step 5: Create Custom resolv.conf
Create a new resolv.conf file:
sudo vim /etc/resolv.conf
Step 6: Add DNS Servers
Add your preferred DNS servers to resolv.conf:
nameserver 8.8.8.8
nameserver 1.1.1.1
nameserver 8.8.4.4
# Add nameservers obtained after connecting to Cisco client
nameserver 10.**.**.***
Step 7: Disable Auto-Generation of resolv.conf
Edit WSL configuration:
sudo vim /etc/wsl.conf
Find and uncomment these lines (remove # prefix):
#[network]
#generateResolvConf = false
Change to:
[network]
generateResolvConf = false
Vi/Vim Editor Quick Reference
When editing configuration files, you'll often use Vi or Vim. Here's a quick reference:
Command Mode (Default)
Press Esc to enter Command mode. Then type : to launch the prompt bar.
Essential commands:
:w- Save changes to the file without exiting:wq- Write (save) and quit the editor:wq- Write (save) and quit the editor, but forcefully:w newfilename- Save as a new file (e.g.,:w testfile2):q!- Quit without saving changes (forcefully)
Other Useful Commands
- Command Mode is the default mode when launching Vi or Vim. Use it for navigation, searching, replacing, deleting, copying, and pasting
- Text manipulation:
- Press
xto delete a character - Press
ddto delete an entire line - Press
yyto copy (yank) a line - Press
pto paste
- Press
- Insert Mode: Press
ikey (lowercase) to enter Insert Mode from Command Mode - Exit Insert Mode: Press
Escto return to Command Mode
Hot Reload Not Working in WSL2
Fix for Angular/React/JavaScript Projects Running on WSL2
The issue occurs because inotify, the Linux API used by hot reload, is not supported in WSL2 on 9P filesystem drives (e.g., Windows drives mounted into WSL2).
Solutions:
- Move your files inside the
/home/your_linux_user_name/directory within WSL (Linux filesystem) - Switch from WSL2 to WSL1
- Use the polling workaround described below
Enabling Polling for Hot Reload
This fix works for all JavaScript projects including React, Vue, and Angular.
Method 1: Environment Variable
- Open a terminal window
- Navigate to your project directory
- Set the
CHOKIDAR_USEPOLLINGenvironment variable totruein your.envfile - Start the development server
Method 2: Command Line (Angular Example)
You can also set the environment variable directly when starting the server:
export CHOKIDAR_USEPOLLING=true
ng serve
For other frameworks:
export CHOKIDAR_USEPOLLING=true
npm start
Understanding CHOKIDAR_USEPOLLING
CHOKIDAR_USEPOLLING is an environment variable that enables a polling mechanism for file watching. This is useful when the default file watching mechanism doesn't work properly, such as when using:
- Docker containers
- WSL/WSL2
- Network file systems
- Virtual machines
How it works:
- When set to
true, your application uses a polling mechanism to watch for file changes - It periodically checks for file changes rather than relying on the operating system's file system events
Performance Considerations:
- ✅ Improves reliability of hot reloading
- ⚠️ May have a negative impact on performance (higher CPU usage)
- 📌 Only recommended if you experience hot reload problems
- 💡 Requires Node.js version 10 or above
Bonus: Unable to Download RAW Files from GitHub
The Problem
If you're in India using Jio network (or certain other ISPs), you may encounter this error:
wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
--2022-12-28 13:02:52-- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
Resolving raw.githubusercontent.com (raw.githubusercontent.com)… 49.44.79.236, 2405:200:1607:2820:41::36
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|49.44.79.236|:443… failed: Connection timed out.
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|2405:200:1607:2820:41::36|:443… failed: Network is unreachable.
Root Cause: Some ISPs block raw.githubusercontent.com at the DNS level.
The Solution
Update the /etc/hosts file in Linux and Windows, change DNS, or connect to VPN. Here we'll focus on updating the hosts file.
For Windows
- Open Notepad as Administrator
- Click File → Open (or press
Ctrl+O) - Navigate to:
%SystemRoot%\System32\drivers\etc\hostsC:\Windows\System32\drivers\etc\hosts - At the end of the file, add:
185.199.110.133 raw.githubusercontent.com - Save the file
For Linux and macOS
Open the /etc/hosts file with any editor:
sudo nano /etc/hosts
Add this line at the end:
185.199.110.133 raw.githubusercontent.com
Save and exit (in nano: Ctrl+X, then Y, then Enter).
Test the fix: Try downloading from raw.githubusercontent.com again.
Summary
This guide covered three main solutions for WSL2/WSL1 VPN connectivity issues:
- Automatic DNS Configuration (Recommended) - Script-based solution that auto-updates DNS
- Manual DNS Configuration - Full control over DNS and network settings
- WSL1 Simplified Solution - Streamlined approach for WSL1 users
Additional topics covered:
- Vi/Vim editor basics
- Hot reload fixes for JavaScript frameworks
- GitHub raw file download issues
Choose the solution that best fits your workflow and technical requirements. The automatic solution (Solution 1) is recommended for most users as it requires minimal maintenance.
