Cisco AnyConnect breaks network connectivity in Ubuntu running under WSL

Despite being primarily a Windows admin, I like to use my WSL Ubuntu instance to access Unixy-networking commands, but establishing AnyConnect VPN sessions breaks network connectivity within the Ubuntu instance. It seems that the fix for this is to open a PowerShell session as administrator and run the following commands:
Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 4000
Get-NetIPInterface -InterfaceAlias "vEthernet (WSL)" | Set-NetIPInterface -InterfaceMetric 1
It is sometimes also necessary to modify /etc/resolv.conf within Ubuntu to contain the desired resolver entries.
Unfortunately, this has to be done EVERY TIME an AnyConnect VPN session is used concurrently with WSL/Ubuntu.  Apparently, AnyConnect in some manner monkeys around with the HyperV network endpoints and routing in a way that WSL doesn’t like. I hope that they get this fixed SOMEDAY.

Update

I recently encountered issues with modifying, moving, or deleting the /etc/resolv.conf file, getting an error saying “Operation not permitted” because somehow the immutable attribute of the file had been set. The fix for this is to modify the attributes of the file with the following command:
sudo chattr -a -i /etc/resolv.conf

I have also found a forum discussion that describes how to automatically handle all of this when a WSL/Ubuntu session is started:

  1. Make sure that auto generation of resolv.conf is enabled (Some instructions for fixing the file involve disabling auto-generation of the file.)This can be done by commented the disable commands in wsl.conf with #.
    sudo nano /etc/wsl.conf

    #[network]
    #generateResolvConf = false
  2. Create a script for implementing the fixes
    sudo nano /bin/vpn-dns.sh
    
    #!/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
    Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 6000
    ' | \ awk 'BEGIN { print "# Generated by vpn fix function", strftime("%c"); print } { print "nameserver", $1 }' | \ tr -d '\r' > /etc/resolv.conf clear
  3. Make the script executable and able to be run as sudo without having to enter a password
    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
  4. Add the script to the profile script to make it run automatically upon wsl startup
    echo "/bin/vpn-dns.sh" | sudo tee /etc/profile.d/vpn-dns.sh

The script can also be invoked on demand with

sudo /bin/vpn-dns.sh

Leave a Reply