Skip to main content

How to Fix WSL2 & VPN Connectivity Issues

· 10 min read
Anand Raja
Senior Software Engineer

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 update displays 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 pull displays 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.com displays:
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.

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:

/etc/wsl.conf
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:

/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
Important

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.

See detailed instructions

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:

/etc/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:

  1. :w - Save changes to the file without exiting
  2. :wq - Write (save) and quit the editor
  3. :wq - Write (save) and quit the editor, but forcefully
  4. :w newfilename - Save as a new file (e.g., :w testfile2)
  5. :q! - Quit without saving changes (forcefully)

Other Useful Commands

  1. Command Mode is the default mode when launching Vi or Vim. Use it for navigation, searching, replacing, deleting, copying, and pasting
  2. Text manipulation:
    • Press x to delete a character
    • Press dd to delete an entire line
    • Press yy to copy (yank) a line
    • Press p to paste
  3. Insert Mode: Press i key (lowercase) to enter Insert Mode from Command Mode
  4. Exit Insert Mode: Press Esc to 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:

  1. Move your files inside the /home/your_linux_user_name/ directory within WSL (Linux filesystem)
  2. Switch from WSL2 to WSL1
  3. 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

  1. Open a terminal window
  2. Navigate to your project directory
  3. Set the CHOKIDAR_USEPOLLING environment variable to true in your .env file
  4. 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

  1. Open Notepad as Administrator
  2. Click File → Open (or press Ctrl+O)
  3. Navigate to: %SystemRoot%\System32\drivers\etc\hosts
    C:\Windows\System32\drivers\etc\hosts
  4. At the end of the file, add:
    185.199.110.133 raw.githubusercontent.com
  5. 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:

  1. Automatic DNS Configuration (Recommended) - Script-based solution that auto-updates DNS
  2. Manual DNS Configuration - Full control over DNS and network settings
  3. 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.