Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save balmeida-nokia/122adf625c11c916902950e3255bd104 to your computer and use it in GitHub Desktop.
Save balmeida-nokia/122adf625c11c916902950e3255bd104 to your computer and use it in GitHub Desktop.
WSL 2 Cisco AnyConnect Networking Workaround

WSL 2 Cisco AnyConnect Networking Workaround

Overview

WSL 2 uses a Hyper-V Virtual Network adapter. Network connectivity works without any issue when a VPN is not in use. However when a Cisco AnyConnect VPN session is established Firewall Rules and Routes are added which breaks connectivity within the WSL 2 VM. This issue is tracked WSL/issues/4277

Below outline steps to automatically configure the Interface metric on VPN connect and update DNS settings (/etc/resolv.conf) on connect/disconnect.

Acknowledges

This guide is inspired by and a variation of pyther's guide for the networking workaround.

In this guide, the differences exist majorely in the automatic configuration process.
I did this guide because his version was not working for me, specially due to the missing pac proxy and the python script was not running working for me.

Manual Configuration

Set Interface Metrics

After connecting to the VPN, you'll want to modify the Interface Metric of the Cisco VPN Adapter

PS C:\Users\gyurgyik> Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 6000

Run the following command in Powershell with Administrative permission.

At this point you should have connectivity in your container (but without name resolution). You can test this by running ping 8.8.8.8.

Set DNS servers in Linux VM

Once connected the VPN determine the DNS servers that are configured:

PS C:\Users\gyurgyik> (Get-NetAdapter | Where-Object InterfaceDescription -like "Cisco AnyConnect*" | Get-DnsClientServerAddress).ServerAddresses
10.10.0.124
10.10.0.132

Update /etc/resolv.conf

M-machine:~$ cat /etc/resolv.conf
nameserver 10.10.0.124
nameserver 10.10.0.132

Verify Connectivity

ping google.com -c 4

Automatic Configuration

Create Scripts

Save the contents of the zip file you can download here below to %homepath%\wsl\scripts.
Create the directories as needed

Adjust the scripts to you

Task scheduling

The .xml files are windows task scheduler files for importing.

Here's what to keep into account while importing them all to task scheduler:

Suggestion: Create a Folder called WSL so you keep the schedules organized.

While importing each individual one

In the import window:
"General" -> "Security options" -> "When running the task, use the following user account":
Change the user to your own user

Everything else should be already correct to use as-is

Setup proxy

In setVPNON.ps1, change the first line's ip address and port to the IP address and port of the server that provides the pac file.

-> Most likely, that information will be in your browser's proxy settings. If you have a host, you may need to get the IP address that host resolves to in order to work (potential issues with alpaca this method depends on)

Warning: Due to lack of knowledge on my side, both setVPNON.ps1 and setVPNOFF.ps1 need to have the distros you own correctly set. I tried the automatic way of achieving that but the results were not to part. Fell free to propose the fix in the comments.

1st time install script

Run the install.sh script inside WSL %homepath%\wsl\scripts\wsl as root. For example, you can use Powershell like such:

cd "$Home\wsl\scripts\wsl"; wsl.exe -d 'Ubuntu-20.04' -u root "./install.sh"

Explaining: These scheduled tasks and how they work

Windows Scheduled Tasks allows you to trigger an action when a certain log event comes in. The Cisco AnyConnect VPN client generates a number of log events.

3 tasks are necessary.

  1. Will configure the interface metric when the VPN connects.
  2. Will activate the proxy and set the name servers for connections.
  3. Will execute on disconnection to setup the proxy as unconfigured (no pac file) and remove VPN nameservers.

Cisco AnyConnect Events

  • 2039: VPN Established and Passing Data
  • 2061: Network Interface for the VPN has gone down
  • 2010: VPN Termination
  • 2041: The entire VPN connection has been re-established.

Procedure in case importing the xml files does not work

Note: The preferred way of installing these tasks is by importing and adapting the scheduled tasks provided. The explanation below works just both as a fallback and explanation on how to achieve a similar result.

  1. Open Task Scheduler
  2. Create a Folder called WSL (Optional, but easier to find rules later)
  3. Create Rules
    1. Update AnyConnect Adapter Interface Metric for WSL2
      • General: Check: Run with highest privileges
      • Triggers:
        • On an Event, Log: Cisco AnyConnect Secure Mobility Client, Source: acvpnagent, Event ID: 2039
        • On an Event, Log: Cisco AnyConnect Secure Mobility Client, Source: acvpnagent, Event ID: 2041
      • Action: Start a program, Program: Powershell.exe, Add arguments: -WindowStyle Hidden -NonInteractive -ExecutionPolicy Bypass -File %HOMEPATH%\wsl\scripts\setCiscoVpnMetric.ps1
      • Condition: Uncheck: Start the task only if the computer is on AC power
    2. Start proxy for pac and set nameservers
      • General: UnCheck: Run with highest privileges
      • Triggers:
        • On an Event, Log: Cisco AnyConnect Secure Mobility Client, Source: acvpnagent, Event ID: 2039
        • On an Event, Log: Cisco AnyConnect Secure Mobility Client, Source: acvpnagent, Event ID: 2041
      • Action: Start a program, Program: Powershell.exe, Add arguments: -WindowStyle Hidden -NonInteractive -ExecutionPolicy Bypass -File %HOMEPATH%\wsl\scripts\setVPNON.ps1
      • Condition: Uncheck: Start the task only if the computer is on AC power
    3. Start proxy without pac and reset nameservers
      • Triggers:
        • On an Event, Log: Cisco AnyConnect Secure Mobility Client, Source: acvpnagent, Event ID: 2010
        • On an Event, Log: Cisco AnyConnect Secure Mobility Client, Source: acvpnagent, Event ID: 2061
        • At log on: At log on of $USER
      • Action: Start a program, Program: Powershell.exe, Add arguments: -WindowStyle Hidden -NonInteractive -ExecutionPolicy Bypass -File %HOMEPATH%\wsl\scripts\setVPNOFF.ps1
      • Condition: Uncheck: Start the task only if the computer is on AC power
  4. Test: Connect to the VPN, a powershell window should pop-up briefly
    1. Same will happen if you disconnect from VPN

FAQ

Q: Does traffic orginating from the Linux VM still route through the VPN?
A: Yes, I believe so. I did not see any leaked traffic when running a tcpdump on my router.

Q: Are VPN resources accessible from the Linux VM?
A: Yes

Q: Can the Linux VM communicate with Windows?
A: No, it appears a firewall rule is preventing traffic between Windows and the Linux VM. You can still access windows using the /mnt mount

Q: How do I revert/disable these changes?
A:

  1. Run the 3rd scheduled task
  2. Disable scheduled Tasks
  3. Remove the proxy entries from /etc/environment
  4. Reboot wsl wsl --shutdown
@ExtremeFiretop
Copy link

In setVPNON.ps1, change the first line's ip address and port to the IP address and port of the server that provides the pac file.

can u please elaborate more? can't find the IP nor the Port

What if you don't use a PAC file and instead use Transparent Proxy? Should this work?

@balmeida-nokia
Copy link
Author

balmeida-nokia commented Nov 8, 2022

In setVPNON.ps1, change the first line's ip address and port to the IP address and port of the server that provides the pac file.

can u please elaborate more? can't find the IP nor the Port

What if you don't use a PAC file and instead use Transparent Proxy? Should this work?

If it's a transparent proxy, it will just work. You don't need to do anything mentioned in this guide

@ExtremeFiretop
Copy link

In setVPNON.ps1, change the first line's ip address and port to the IP address and port of the server that provides the pac file.

can u please elaborate more? can't find the IP nor the Port

What if you don't use a PAC file and instead use Transparent Proxy? Should this work?

If it's a transparent proxy, it will just work. You don't need to do anything mentioned in this guide

Perfect. Just wanted to validate before I tried as my organization literally just moved off Pac files a few months ago to Transparent Proxy. Wanted to know if I needed to modify the script to remove the proxyIP or just leave it as is, etc.

I'll give it a try and advise! :)

@sellersj
Copy link

As an alternative, I've found this works for me:
https://github.com/sakai135/wsl-vpnkit

@ExtremeFiretop
Copy link

As an alternative, I've found this works for me: https://github.com/sakai135/wsl-vpnkit

Hey Jim :)

Joel here, this comment was when I was doing the research on the issue.

Thanks for all the help updating the guide again!

@maxjf1
Copy link

maxjf1 commented Jan 10, 2023

working great!

@avnerse3
Copy link

works!
what is the alpaca binary, can you say a bit more why it is needed?

@balmeida-nokia
Copy link
Author

what is the alpaca binary, can you say a bit more why it is needed?

Alpaca is the proxy that makes the process the same for all software. Every time internet is needed, all software connects to alpaca which then connects to the correct endpoint. This is just so all programs can be configured the same way and not have to adjust their proxy configuration depending on the connected network

@joret
Copy link

joret commented May 10, 2023

I followed the steps, and the DNS works, and also the change of metrics let's me reach the network, but after half an hour my browsers stop being able to reach the DNS/IPs of servers inside the VPN. Ping still works, but not accessing the urls inside the VPN via browsers. Anyone else has this issue?

@kheuton
Copy link

kheuton commented Aug 27, 2023

I'm unable to add the wsl proxy deactivate job to the scheduler, as it fails with "The specified account name is not valid." I've changed the user to my user, just as I did with the other tasks, and even tried running as administrator. Do you have any idea why this might happen?

Edit: The manual steps to add worked great, so this question isnt so important

@balmeida-nokia
Copy link
Author

I'm unable to add the wsl proxy deactivate job to the scheduler, as it fails with "The specified account name is not valid." I've changed the user to my user, just as I did with the other tasks, and even tried running as administrator. Do you have any idea why this might happen?

No idea at all.

@sortelyn
Copy link

sortelyn commented Oct 7, 2023

It seems to be af feature and not a flaw that you can't connect from WSL2 through AnyConnect. For what it is worth I found this checkmark - "Allow local (LAN) access when using VPN (if configured)"

The above solution also worked for me except I can't get permission to run a script, so I could not automate it.
The below is properly the (cooperate right) way, if you have that option available.

image

@ExtremeFiretop
Copy link

ExtremeFiretop commented Oct 7, 2023

It seems to be af feature and not a flaw that you can't connect from WSL2 through AnyConnect. For what it is worth I found this checkmark - "Allow local (LAN) access when using VPN (if configured)"

The above solution also worked for me except I can't get permission to run a script, so I could not automate it. The below is properly the (cooperate right) way, if you have that option available.

image

Many corporate environments, including ours, disables this feature in the profile.xml for security reasons.
So you have this option only due to less strict security in AnyConnect compared to most corporate environments.

Many corporate environments simply do not allow your local home devices to communicate with your work device directly, this introduces security risks and attack vectors, a compromised device on your home network could now attack or collect data from any device not strictly sending it's traffic through the tunnel.

I work for a Government Department and strictly handle our Cisco implementation, and we would never allow this access.

image

Source:

https://community.cisco.com/t5/security-knowledge-base/anyconnect-xml-preferences/ta-p/3157733?fbclid=IwAR3TJVa2kpfLroJW-jbkF5BDw0Q4n8FGcpC0xvQLAq3QquyfEJz-NjGQEgY

@dswhite42
Copy link

For users of Cisco AnyConnect 5.0+ (I have 5.0.03076), the Windows Event logging naming convention has changed. So instead of writing triggers based on:
Log: Cisco AnyConnect Secure Mobility Client, Source: acvpnagent
it is now:
Log: Cisco Secure Client - AnyConnect VPN, Source: csc_vpnagent

@yassine-ah
Copy link

works! what is the alpaca binary, can you say a bit more why it is needed?

Exactly, it is a huge file that can do a lot.
However, all I need is to extract the correct DNS values and place them in /etc/resolv.conf.

The GitHub repository from which this was forked appears to focus solely on this task, at least in its most recent version.

I suggest having two versions: one with the minimal setup required for most users, and another for those who need the alpaca binary!

@balmeida-nokia
Copy link
Author

@yassine-ah At this point, this process is legacy because recent versions of AnyConnect already does this correctly, specially if you also use wsl-vpnkit which didn't exist at the time.
Only who are stuck to older versions of AnyConnect need to use this process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment