microsoft / WSL

Issues found on WSL
https://docs.microsoft.com/windows/wsl
MIT License
17.43k stars 824 forks source link

WSL2 , problem with network connection when VPN used (PulseSecure) #5068

Open fibu79 opened 4 years ago

fibu79 commented 4 years ago

I'm using MS v. 2004 (build 19041) with UBUNTU linux on WSL2. When I don't use VPN on windows , everything is fine - I have internet connection on windows and wsl2 ubuntu. But when established connection via VPN (on windows) then on windows still is OK - I have both internet and vpn connection , but on Ubuntu there is no network connection at all (no internet , no vpn access). I suspect there is a problem with NAT (on Hyper-V default switch) Any idea what could be wrong ? Additionally: on wsl1 everything worked fine (also when VPN enabled)

Currently on wsl2 it looks like this : fibu@DESKTOP-3N4US3P:/mnt/c/Users/fibu2$ ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.30.123.209 netmask 255.255.240.0 broadcast 172.30.127.255 inet6 fe80::215:5dff:fe41:b550 prefixlen 64 scopeid 0x20 ether 00:15:5d:41:b5:50 txqueuelen 1000 (Ethernet) RX packets 263 bytes 27705 (27.7 KB) RX errors 0 dropped 1 overruns 0 frame 0 TX packets 223 bytes 34352 (34.3 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 2 bytes 56 (56.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 2 bytes 56 (56.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

fibu@DESKTOP-3N4US3P:/mnt/c/Users/fibu2$ fibu@DESKTOP-3N4US3P:/mnt/c/Users/fibu2$ ping google.com ping: google.com: Temporary failure in name resolution fibu@DESKTOP-3N4US3P:/mnt/c/Users/fibu2$ fibu@DESKTOP-3N4US3P:/mnt/c/Users/fibu2$ netstat -rn Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 172.30.112.1 0.0.0.0 UG 0 0 0 eth0 172.30.112.0 0.0.0.0 255.255.240.0 U 0 0 0 eth0 fibu@DESKTOP-3N4US3P:/mnt/c/Users/fibu2$ cat /etc/resolv.conf nameserver 172.30.112.1 fibu@DESKTOP-3N4US3P:/mnt/c/Users/fibu2$

luvwagn commented 4 years ago

@David Copenhaver - i ended up skipping WSL 1 or 2 on my 2nd box and just using Hyper-V + a full Ubuntu GUI environment, and then from inside there works fine (although the host Windows environment is not VPN'd) - using AnyConnect Linux client.

dcopenhaver commented 4 years ago

hi @luvwagn - thanks for the info - I currently have an ubuntu 20.04 hyper-v VM and its networking is working fine, not experiencing the same issue as in WSL - and my host machine is running the same anyconnect vpn client, which is connected. I have all expected network functionality with the VM (as in a full GUI installed ubuntu on hyper V). Now if that stops working also that will be the last straw for me lol - I will abandon all hyper-v related anything. Note: it was a complete nightmare getting "enhanced session mode" working on this ubuntu VM, and there is a pull request sitting in a github issue with the fix and for some reason it is just not being merged in... I don't know, I hope MS is not changing its "we love linux" stance, because I think its great how they are embracing open source and trying to integrate all these things together in Windows. Anyway, thanks again, I don't want to derail this issue any further with my rambling... I hope this is all taken care of.

trevor-viljoen commented 4 years ago

From what I can tell, Pulse Secure adds a route that sends traffic over the VPN that is intended for the Hyper-V Switch. I can add the correct route and manipulate the metric on the VPN route and see traffic start going to WSL 2's VM. This same thing happens for any VM (Hyper-V), so for me it is not specific to WSL2. Pulse Secure then removes my manual route and adds back its preset route within a couple seconds. Interestingly, Docker containers work correctly with my VPN.

VPN Passthrough
Docker Desktop networking can work when attached to a VPN. To do this, Docker Desktop intercepts traffic from the containers and injects it into Windows as if it originated from the Docker application.

Can WSL2 implement a similar solution?

None of the other solutions have worked for me. So, I'm really not sure where to go from here other than to ditch WSL2.

arcsector commented 4 years ago

@trevor-viljoen has my exact situation; using the Pulse Secure app, Docker works through VPN but WSL2 VMs do not. I am also moving back to WSL1 for my VMs for now.

ianichitei commented 4 years ago

From what I can tell, Pulse Secure adds a route that sends traffic over the VPN that is intended for the Hyper-V Switch. I can add the correct route and manipulate the metric on the VPN route and see traffic start going to WSL 2's VM. This same thing happens for any VM (Hyper-V), so for me it is not specific to WSL2. Pulse Secure then removes my manual route and adds back its preset route within a couple seconds. Interestingly, Docker containers work correctly with my VPN.

VPN Passthrough
Docker Desktop networking can work when attached to a VPN. To do this, Docker Desktop intercepts traffic from the containers and injects it into Windows as if it originated from the Docker application.

Can WSL2 implement a similar solution?

None of the other solutions have worked for me. So, I'm really not sure where to go from here other than to ditch WSL2.

I think that this is the same issue that I havr with CISCO AnyConnect. When WSL2 can't connect to the internet the same thing is true for any Hyper-V VM I have.

markko1-pro commented 4 years ago

@trevor-viljoen my desperate solution (because I would rather ditch Windows than WSL2) was to install PulseSecure Linux client on WSL2. As well as tinyproxy and configure my Windows browser to use WSL2 as a proxy.

adam-zielonka commented 4 years ago

I used proxy server in docker (base on WSL2) to connect WSL2 to network, and it works for me :-)

If you want to try:

  1. Write conf in /etc/squid/squid.conf
acl all src all

http_access allow all
http_port 3128

# access to the internet inside vpn network
cache_peer my-proxy-server-in-vpn-network.com parent 80 0 no-query no-digest
never_direct allow all

# access to internal network
acl local-servers dst 10.1.1.0/8
acl local-servers dst 192.168.1.12
always_direct allow local-servers
  1. Run docker
$ docker run --name squid -d --restart=always \
  --publish 3128:3128 \
  --volume /etc/squid/squid.conf:/etc/squid/squid.conf \
  sameersbn/squid:3.5.27-2
  1. Write script wslproxy.
#!/bin/bash

if [[ $1 == on ]] ; then

cat > /etc/apt/apt.conf.d/apt-proxy.conf <<- EOM
Acquire::http::Proxy "http://localhost:3128";
Acquire::https::Proxy "http://localhost:3128";
EOM

cat > /root/.ssh/config <<- EOM
Host git.on-my-internal-network.com
  User git
  ProxyCommand nc -x localhost:3128 -Xconnect %h %p
EOM

export http_proxy=http://localhost:3128
export https_proxy=http://localhost:3128
git config --global http.proxy http://localhost:3128
git config --global https.proxy http://localhost:3128

elif [[ $1 == off ]] ; then

unset https_proxy
unset http_proxy
rm /etc/apt/apt.conf.d/apt-proxy.conf
rm /root/.ssh/config
git config --global --unset http.proxy
git config --global --unset https.proxy

else

echo "source wslproxy [on|off]"
echo ". wslproxy [on|off]"

fi
  1. Run script
$ chmod +x ./wslproxy
$ . ./wslproxy on
  1. When you back to the office, remember to run:
$ . ./wslproxy off

Edit:

  1. For React development, you need setup proxy to consider corporate proxy (😃) in file src/setupProxy.js:
const HttpsProxyAgent = require('https-proxy-agent')
const { createProxyMiddleware } = require('http-proxy-middleware')

module.exports = function (app) {
  const proxyServer = process.env.https_proxy || process.env.http_proxy

  app.use(createProxyMiddleware('/api', {
    target: `http://my.internal.service.com/`,
    agent: proxyServer && new HttpsProxyAgent(proxyServer),
  }))
}
axway-dpal commented 4 years ago

I have similar issue with wsl-2 distro.

for some reason, wsl-2 distro is unable to update ip routes & DNS Settings. -------------------- wsl2 ------------------------------------

 $cat /etc/resolv.conf
nameserver 172.30.208.1
$ ip route
default via 172.30.208.1 dev eth0
172.30.208.0/20 dev eth0 proto kernel scope link src 172.30.219.136
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 06:32:a9:f6:c0:bb brd ff:ff:ff:ff:ff:ff
3: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 86:6c:d3:b0:46:c1 brd ff:ff:ff:ff:ff:ff
4: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:ae:78:6c brd ff:ff:ff:ff:ff:ff
    inet 172.30.219.136/20 brd 172.30.223.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::215:5dff:feae:786c/64 scope link
       valid_lft forever preferred_lft forever
5: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/sit 0.0.0.0 brd 0.0.0.0
$ cat /etc/wsl.conf
# Enable extra metadata options by default
[automount]
enabled = true
options = "metadata,umask=22,fmask=11"
mountFsTab = false

# Enable DNS – even though these are turned on by default, we'll specify here just to be explicit.
[network]
generateHosts = true
generateResolvConf = true

------------------------------------------- wsl1--------------------------------

$ cat /etc/resolv.conf
nameserver 192.168.0.1
nameserver 10.253.253.253
nameserver 10.252.252.252
$ ip a
11: eth0: <BROADCAST,MULTICAST,UP> mtu 1350 group default qlen 1
    link/ether 54:96:9b:20:ad:06
    inet 10.134.35.99/24 brd 10.134.35.255 scope global dynamic
       valid_lft forever preferred_lft forever
    inet6 fe80::2ce8:b7bc:497f:6c9a/64 scope link dynamic
       valid_lft forever preferred_lft forever
14: eth1: <BROADCAST,MULTICAST,UP> mtu 1500 group default qlen 1
    link/ether 00:15:5d:13:ad:54
    inet 172.23.112.1/20 brd 172.23.127.255 scope global dynamic
       valid_lft forever preferred_lft forever
    inet6 fe80::4c99:e5a4:a751:8767/64 scope link dynamic
       valid_lft forever preferred_lft forever
59: eth2: <BROADCAST,MULTICAST,UP> mtu 1500 group default qlen 1
    link/ether 00:15:5d:f5:cf:bc
    inet 172.30.208.1/20 brd 172.30.223.255 scope global dynamic
       valid_lft forever preferred_lft forever
    inet6 fe80::698e:b926:17ba:e451/64 scope link dynamic
       valid_lft forever preferred_lft forever
1: lo: <LOOPBACK,UP> mtu 1500 group default qlen 1
    link/loopback 00:00:00:00:00:00
    inet 127.0.0.1/8 brd 127.255.255.255 scope global dynamic
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host dynamic
       valid_lft forever preferred_lft forever
4: wifi0: <BROADCAST,MULTICAST,UP> mtu 1500 group default qlen 1
    link/ieee802.11 fc:77:74:22:b1:63
    inet 192.168.0.119/24 brd 192.168.0.255 scope global dynamic
       valid_lft 4244sec preferred_lft 4244sec
    inet6 fe80::d485:a562:4c16:5c63/64 scope link dynamic
       valid_lft forever preferred_lft forever
22: wifi1: <> mtu 1500 group default qlen 1
    link/ieee802.11 fc:77:74:22:b1:64
    inet 169.254.11.17/16 brd 169.254.255.255 scope global dynamic
       valid_lft forever preferred_lft forever
    inet6 fe80::58db:af76:7ba9:b11/64 scope link dynamic
       valid_lft forever preferred_lft forever
10: wifi2: <> mtu 1500 group default qlen 1
    link/ieee802.11 fe:77:74:22:b1:63
    inet 169.254.66.129/16 brd 169.254.255.255 scope global dynamic
       valid_lft forever preferred_lft forever
    inet6 fe80::9c4c:6753:c9d2:4281/64 scope link dynamic
       valid_lft forever preferred_lft forever
$ ip route
none 1.0.0.94 via 10.134.35.98 dev eth0 proto unspec metric 1
none 1.0.0.99 via 10.134.35.98 dev eth0 proto unspec metric 1
none 10.56.0.0/16 via 10.134.35.98 dev eth0 proto unspec metric 1
......................... very long list
$ cat /etc/wsl.conf
# Enable extra metadata options by default
[automount]
enabled = true
options = "metadata,umask=22,fmask=11"
mountFsTab = false

# Enable DNS – even though these are turned on by default, we'll specify here just to be explicit.
[network]
generateHosts = true
generateResolvConf = true

------------------------------- windows settings --------------------------

C:\Users\dpal>ipconfig

Windows IP Configuration

Ethernet adapter Ethernet 2:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::2ce8:b7bc:497f:6c9a%11
   IPv4 Address. . . . . . . . . . . : 10.134.35.99
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . :

Ethernet adapter vEthernet (Default Switch):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::4c99:e5a4:a751:8767%14
   IPv4 Address. . . . . . . . . . . : 172.23.112.1
   Subnet Mask . . . . . . . . . . . : 255.255.240.0
   Default Gateway . . . . . . . . . :

Wireless LAN adapter Local Area Connection* 1:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :

Wireless LAN adapter Local Area Connection* 2:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :

Wireless LAN adapter Wi-Fi:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::d485:a562:4c16:5c63%4
   IPv4 Address. . . . . . . . . . . : 192.168.0.119
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.0.1

Ethernet adapter vEthernet (WSL):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::698e:b926:17ba:e451%59
   IPv4 Address. . . . . . . . . . . : 172.30.208.1
   Subnet Mask . . . . . . . . . . . : 255.255.240.0
   Default Gateway . . . . . . . . . :

Current working solution for me is to downgrade distro to WSL-1 wsl --set-version 1

folkvir commented 4 years ago

Confirmed, PulseSecure is blocking connections between my Debian distribution and Windows. Can't ping at all the IP address of WSL2 while under VPN, and everything is working while the VPN is off. Proxy settings and routing tables are set and good. I managed to sometimes ping my WSL IP when I shutdown WSl, reboot, shutdown WSL again, starting VPN, starting wsl, but it is not 100% a workaround and a pain to do it everytime I need to reboot (aka everyday !).... Downgrading to version 1 is working... wsl --set-version Debian 1

butgit commented 4 years ago

os build: WIN10 18363.1139 vpn client: softether vpn client, connection type: direct TCP/IP connection distro: Ubuntu 20.24 on WSL2 problem description: I have Emacs27 installed in Ubuntu 20.24 which in turn runs in Windows 10 via WSL 2. In addition, I use X410, an X-Windows server app, which allows me to use Emacs GUI as if it was an Windows 10 app. With the internet connection on, but VPN off, I launch Emacs by typing emacs & at a shell prompt. The problem is that, when I turn on VPN connection, Emacs suddenly shuts down with the following error message:

Connection lost to X server '172.x.x.x:0.0' When compiled with GTK, Emacs cannot recover from X disconnects. This is a GTK bug: https://gitlab.gnome.org/GNOME/gtk/issues/221 For details, see etc/PROBLEMS.

devonkinghorn commented 3 years ago

I have an issue with GlobalProtect. Turns out the issue can be solved by updating the route tables. So I wrote a script to fix it. The issue is that the ip cidr that's supposed to go to WSL ends up going to the vpn network interface So I update the priorities of the different routs. A similar approach might work for other vpn types.

$wslIfIndex = $(Get-NetIPInterface -InterfaceAlias "vEthernet (WSL)" )[0].ifIndex
$pangpIfIndex = $(Get-NetAdapter | Where-Object {​​​​​​$_.InterfaceDescription -Match "PANGP Virtual Ethernet Adapter"}​​​​​​)[0].ifIndex
$destinationPrefix = $(Get-NetRoute -InterfaceIndex $wslIfIndex | where DestinationPrefix -like "*.0/20")[0].DestinationPrefix
Get-NetRoute -InterfaceIndex $wslIfIndex -DestinationPrefix $destinationPrefix | Set-NetRoute -RouteMetric 0
Get-NetRoute -InterfaceIndex $pangpIfIndex -DestinationPrefix $destinationPrefix | Set-NetRoute -RouteMetric 256
Get-NetIPInterface -InterfaceAlias "vEthernet (WSL)" | Set-NetIPInterface -InterfaceMetric 1

Please excuse my PowerShell, I'm coming from a Mac and just learning to use PS

Techdread commented 3 years ago

If you are using Cisco AnyConnect VPN, Open a PowerShell with Administrator rights after connecting to the VPN. Run the command Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 6000

WSL2 Internet connection will now be restored.

lpuglia commented 3 years ago

If you are using Cisco AnyConnect VPN, Open a PowerShell with Administrator rights after connecting to the VPN. Run the command Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 6000

WSL2 Internet connection will now be restored.

i had no luck with this

ronald-willems commented 3 years ago

@Techdread thanks for the suggestion. I tried it but it didn't work for me, unfortunately

NiklasBr commented 3 years ago

@Techdread didn't work for me either

machuu commented 3 years ago

If you are using Cisco AnyConnect VPN, Open a PowerShell with Administrator rights after connecting to the VPN. Run the command Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 6000

WSL2 Internet connection will now be restored.

I played around with these settings to see what reproduced/fixed this behavior.

By default, the Interface Metrics for AnyConnect are:

Changing the Interface Metrics for AnyConnect to:

I turned off generateResolvConf in /etc/wsl.conf, then manually added the corportate DNS Server as the first nameserver in /etc/resolv.conf.

/etc/wsl.conf

[network]
generateResolvConf = false

/etc/resolv.conf

nameserver <corporateDNS1>
nameserver <corporateDNS2>
nameserver 1.1.1.1

Network appears to behave correctly for Internet and Internal domains.

ronald-willems commented 3 years ago

@machuu Great. This works for me also. I used this Powershell statement to get the corporate DNS: Get-DnsClientServerAddress | Select-Object -ExpandProperty ServerAddresses

I can't get my Xming to work by the way. Can't ping my local machine anymore after starting VPN. I was using Xming to get a linux desktop.

AlbesK commented 3 years ago

@machuu Great stuff. Works for me as well along with the commands given by @Techdread and @ronaldwillems74 for Cisco AnyConnect (Internal one even in my case).

For full solution I did the following:

  1. Connect to Cisco AnyConnect VPN.

  2. To find your Corporate DNS nameservers run in cmd the following: ipconfig/all (quicker, no need for administrator privileges) and check the first Ethernet adapter Ethernet 2:, or whichever ethernet number table, under the DNS Servers row section.

Or use @ronaldwillems74 command in PS, run as administrator: Get-DnsClientServerAddress | Select-Object -ExpandProperty ServerAddresses, the two first results will be the two Cisco AnyConnect DNS nameservers.

  1. Go to /etc/wsl.conf and add the following lines as @machuu shows:

    [network]
    generateResolvConf = false
  2. Now you might see that if you changed /etc/resolv.conf after closing the wsl shell it will be again changed to a random nameserver and with the same comment pointing to change the /etc/wsl.conf file as shown in these issues: 5420, 3928. To stop this reset and have the correct DNS set up do the following commands in order in your ~ home directory:

    1. First remove the file: sudo rm /etc/resolv.conf
    2. Then create a new one with the same name, quickest way using touch: sudo touch /etc/resolv.conf
    3. Then put in your DNS nameservers wither using nano, vi etc to your liking inside /etc/resolv.conf
      nameserver <corporateDNS1>
      nameserver <corporateDNS2>
  3. Then run this command:

    sudo chattr +i /etc/resolv.conf

The chattr command is used to make it read protected and it stops the next time you start the shell to override the /etc/resolv.conf file. Based on the solution in issue 5420.

Also here, if you messed up like me first time for this step and can't edit the file, to re-edit the file just do sudo chattr -i /etc/resolv.conf. Edit the file. And then redo the same command with +i to not let it be deleted by wsl in the next shell run thereafter!

  1. Now open PS in administrator mode and put @Techdread 's command:
    Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 6000

(Assuming before all steps you have wsl2 as well with a linux distro already installed, Ubuntu (20.04 LTS) in my case)

And you are done!

Hope this helps 😃 !!

Update: Still works, but when you restart your laptop/PC just re-run Step 5's command above. The /etc/resolv.conf file should have the Corporate DNS and in read mode they should not have been reset. Might make a power shell file for this in the future.

Docker however, as shown in other issues it seems wsl again generates the /etc/hosts/ file in which some people try and put the registries for docker to enable pulling images (see issues 4884, 1317 for example). I have not had yet success but will update if I configure something out soon.

machuu commented 3 years ago

@ronaldwillems74

I can't get my Xming to work by the way. Can't ping my local machine anymore after starting VPN. I was using Xming to get a linux desktop.

I was trying to use Docker Desktop, but when Anyconnect is active WSL can't reach the Docker Desktop IP. I haven't found a workaround for this yet.

TBG-FR commented 3 years ago

@machuu Great stuff. Works for me as well along with the commands given by @Techdread and @ronaldwillems74 for Cisco AnyConnect (Internal one even in my case).

For full solution I did the following:

[...]

Thank you for you detailed solution, will definitely try ! If I understand right, this will set DNS on corporate ones to work with VPN, but it will not work anymore when disconnected from the VPN, right ? I have to switch frequently my VPN on and off, so I'm searching for a flexible solution, but tell me if I'm wrong !

machuu commented 3 years ago

@TBG-FR

@machuu Great stuff. Works for me as well along with the commands given by @Techdread and @ronaldwillems74 for Cisco AnyConnect (Internal one even in my case). For full solution I did the following:

[...]

Thank you for you detailed solution, will definitely try ! If I understand right, this will set DNS on corporate ones to work with VPN, but it will not work anymore when disconnected from the VPN, right ? I have to switch frequently my VPN on and off, so I'm searching for a flexible solution, but tell me if I'm wrong !

The DNS updates should work with and without the VPN. In the list of nameservers the first entry is tried, and if it is not responsive, the next one is tried. I put nameserver 1.1.1.1 at the bottom, so when my VPN is disconnected, and corporate DNS is unavailable, WSL will use the public DNS.

eliezerben commented 3 years ago

I am using a linux distro in VirtualBox in headless mode and connecting to it via ssh for now until the issues with VPNs are solved in WSL2. I have setup some aliases in my powershell profile(notepad $profile) to make things easier.

function vboxon { VBoxManage.exe startvm <machine_name> --type headless }
function vboxoff { VBoxManage.exe controlvm <machine_name> acpipowerbutton }
function vboxssh { ssh <username>@<vbox_host_name> }
machuu commented 3 years ago

I wrote instructions to create a scheduled task to update the VPN Interface Metric:

Scheduled Task to Update VPN Interface Metric for WSL

This was written specifically for Cisco AnyConnect, so if you're using a different VPN you will have to change the -Match "Cisco AnyConnect" to the name of your VPN's Adapter Name.

Nguimjeu commented 3 years ago

@machuu Great stuff. Works for me as well along with the commands given by @Techdread and @ronaldwillems74 for Cisco AnyConnect (Internal one even in my case).

For full solution I did the following:

Thanks a lot that helped me move foward with setting up my dev. environment!

rajnathsah commented 3 years ago

I got below command from a link for cisco any connect, i run in powershell in admin mode and it worked.

Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 4000 Get-NetIPInterface -InterfaceAlias "vEthernet (WSL)" | Set-NetIPInterface -InterfaceMetric 1

NiklasBr commented 3 years ago

@rajnathsah It did not work for me with AnyConnect 4.9.04053

Timothy-Edward-Kendon commented 3 years ago

Firstly a big thanks. The recipe of @machuu, @ronaldwillems74 and @AlbesK worked for me.

The following has been mentioned in other threads (e.g. https://github.com/microsoft/WSL/issues/5611), but for completeness I wanted to add it here. Instead of using sudo chattr +i /etc/resolv.conf you can use the command wsl.exe --shutdown. This way your /etc/wsl.conf will get properly read and the /etc/resolve.conf will not get auto-generated. That is after all the point of adding the generateResolvConf = false to /etc/wsl.conf

rajnathsah commented 3 years ago

@rajnathsah It did not work for me with AnyConnect 4.9.04053

If wsl was already started and then vpn was switched on then it may not work, even i faced similar issue and looks like each time you have to run these commands.

  1. Switch off wsl - wsl -shutdown
  2. Run powershell command as admin
  3. Login to wsl and check
agrexgh commented 3 years ago

I found a workaround, but I think there will be some better ways...

The workaround is below.

  1. Before Pulse Secure connecting, disable vEthernet (WSL).
  2. Connect Pulse Secure.
  3. Enable vEthernet (WSL).

I confirmed this worked during wsl was running. This causes ping from wsl to vEthernet (WSL) can be passed.

Without this, Wireshark shows the ping request is sent to vEthernet(WSL) but the ping reply is not sent from vEthernet (WSL). I think there is something wrong with vEthernet(WSL) routing.

I hope someone invents automated way!

rajnathsah commented 3 years ago

I saw a pattern while using WSL 2 on cisco any connect vpn and tried this and looks to be working.

  1. Disconnect from VPN, if you are connected.
  2. Shutdown WSL 2
  3. Login to VPN again
  4. Run below command from powershell as administrator.
    Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 6000
    Get-NetIPInterface -InterfaceAlias "vEthernet (WSL)" | Set-NetIPInterface -InterfaceMetric 1
  5. Login to WSL 2, Hopefully you will have internet working.
  6. This steps has to be repeated every time when switched on machine.
davidshen84 commented 3 years ago

My company uses Citrix VPN. I have a Citrix Virtual Adapter on my system. I have tried all the methods above and others found online, none of them works. Interestingly, I noticed I have both vEthernet (Default Switch) and vEthernet (WSL). Should we have two vEthernet?

HanamDo-TF commented 3 years ago

Workaround I have:

Currently I have to run these commands every morning, when my WSL doesn't sync up properly with my Pulse Secure VPN:

In administrator powershell:

PS C:\Users\Me> Restart-Service -Force -Name hns
PS C:\Users\Me> Restart-Service LxssManager
PS C:\Users\Me> Restart-NetAdapter -Name "vEthernet (WSL)"

It's a bit annoying, but it works for the time being. If Santa can drop off a nice solution to this without having to install an intermediate (like the docker solution above), then it would be forever appreciated.

krishvk commented 3 years ago

It worked for me after adding the Pulse DNS servers from Windows and DNS Suffix to /etc/resolv.conf inside WSL2

It looks like below now

# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
search internal.*.com
nameserver **.***.*.*
nameserver **.***.*.*
nameserver ***.**.***.***

The *s above are wildcards

Also, you have to edit the /etc/wsl.conf as mentioned in the comments above. Else /etc/resolv.conf will be overwritten

I think I have to refresh the addresses above when those DNS servers change

jaycenet commented 3 years ago

Workaround I have:

Currently I have to run these commands every morning, when my WSL doesn't sync up properly with my Pulse Secure VPN:

In administrator powershell:

PS C:\Users\Me> Restart-Service -Force -Name hns
PS C:\Users\Me> Restart-Service LxssManager
PS C:\Users\Me> Restart-NetAdapter -Name "vEthernet (WSL)"

It's a bit annoying, but it works for the time being. If Santa can drop off a nice solution to this without having to install an intermediate (like the docker solution above), then it would be forever appreciated.

Hello, I have the same problem but with your solution it doesn't work. My WSL network adapter get an ip adress 192.168.x.x but i cannot reach oustide (ping command) I'm giving up ...

protzman commented 3 years ago

Still having an issue with this as well. I am trying to ssh to gitlab, where when doing it from Powershell I can connect successfully, but running the same command from within WSL2 (Ubuntu 18,04) I am blocked with:

ssh: Could not resolve hostname gitlabext.str.ext: Temporary failure in name resolution
fatal: Could not read from remote repository.
glenvan commented 3 years ago

I've been having similar issue with WSL2 routing over Pritunl (OpenVPN). For me I found it's down to the order in which I start WSL2 and the VPN connection after a boot - possibly because the vEthernet (WSL) adapter isn't present unless the LxssManager service is started, something you can't easily start automatically. I'm guessing that this means that my VPN client can't or won't set up routing between the WSL2 subnet and the VPN subnet when the vEthernet (WSL) adapter eventually appears.

I suspect that if I could force the LxssManager service to start automatically, things would work better.

I've found some lovely tutorials on setting up a new Group Policy to permit me to do this, since by default my admin account doesn't have permission to do so, but I'm a little hesitant... it seems like someone really wants me to keep my fingers out of this service.

HanamDo-TF commented 3 years ago

I've been having similar issue with WSL2 routing over Pritunl (OpenVPN). For me I found it's down to the order in which I start WSL2 and the VPN connection after a boot - possibly because the vEthernet (WSL) adapter isn't present unless the LxssManager service is started, something you can't easily start automatically. I'm guessing that this means that my VPN client can't or won't set up routing between the WSL2 subnet and the VPN subnet when the vEthernet (WSL) adapter eventually appears.

  • Connecting to VPN first: WSL2 can route to the internet but not to my VPN subnets.
  • Opening WSL2 (and therefore starting LxssManager and creating a vEthernet (WSL) adapter) first: WSL2 can route everywhere, including my VPN subnets.

I suspect that if I could force the LxssManager service to start automatically, things would work better.

I've found some lovely tutorials on setting up a new Group Policy to permit me to do this, since by default my admin account doesn't have permission to do so, but I'm a little hesitant... it seems like someone really wants me to keep my fingers out of this service.

That was my conclusion to it as well, hence the 3 commands above which is done after connecting to VPN.

glenvan commented 3 years ago

That was my conclusion to it as well, hence the 3 commands above which is done after connecting to VPN.

I tried your solution, but didn't work for me after connecting to my VPN. I think that's the point. If LxssManager isn't running by the time you connect over VPN, you can forget about getting a route, at least for some VPN clients.

jaycenet commented 3 years ago

Bizarly it's working with WSL1...

geiranton commented 3 years ago

If you are using Cisco AnyConnect VPN, Open a PowerShell with Administrator rights after connecting to the VPN. Run the command Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 6000 WSL2 Internet connection will now be restored.

i had no luck with this

This worked for me. Thanks!

jaycenet commented 3 years ago

If you are using Cisco AnyConnect VPN, Open a PowerShell with Administrator rights after connecting to the VPN. Run the command Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 6000 WSL2 Internet connection will now be restored.

i had no luck with this

This worked for me. Thanks!

Is this working with PulseSecure ?

rmcolbert commented 3 years ago

What I found was that the NIC in WSL has an MTU of 1500 but my PulseConnect NIC sets its MTU to 1320. If I change the MTU size in WLS to 1320, then things work. sudo ip link set dev eth0 mtu 1320

You can check the MTU of your NICs via PowerShell by executing: Get-NetIPInterface

I tried updating the WSL network interface in Windows to 1320 but that didn't change the vNIC actually attached to WSL so tweaking the MTU with the appropriate ip config command is currently required.

yamam commented 3 years ago

Pulse Secure prevents the WSL network from functioning because the routing table is rewritten by Pulse Secure. The following script solves the problem in Pulse Secure.

$ip = $(Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object{($_.IPEnabled -eq "TRUE") -and ($_.Description -match "Hyper-V") })
$wsl_ip = $ip.IPAddress[0]
$mask = $ip.IPSubnet[0]
$subnet = ([IPAddress](([IPAddress]$wsl_ip).Address -band ([IPAddress] $mask).Address)).ToString()

route delete $subnet
route add $subnet mask $mask $wsl_ip
dpalma9 commented 3 years ago

Pulse Secure prevents the WSL network from functioning because the routing table is rewritten by Pulse Secure. The following script solves the problem in Pulse Secure.

$ip = $(Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object{($_.IPEnabled -eq "TRUE") -and ($_.Description -match "Hyper-V") })
$wsl_ip = $ip.IPAddress[0]
$mask = $ip.IPSubnet[0]
$subnet = ([IPAddress](([IPAddress]$wsl_ip).Address -band ([IPAddress] $mask).Address)).ToString()

route delete $subnet
route add $subnet mask $mask $wsl_ip

This didn't work to me and broke the whole Pulse connection. I had to close the VPN and re-open it.

jaycenet commented 3 years ago

Yes not working for me also

jaycenet commented 3 years ago

Without VPN i cannot work :-)

brian316 commented 3 years ago

Without VPN I cannot work :-)

I am using the "Checkpoint Endpoint VPN". How I get it to work now is by disabling the security policy in the firewall setting of the client. I'm guessing it applies some firewall rule and disables networking capabilities. Maybe other VPNs do the same

au-rimas commented 3 years ago

you can always install cisco inside your WSL and then if you installed it in default dir just use /opt/cisco/anyconnect/bin/vpn connect

works for me haven't faced any errors

NiklasBr commented 3 years ago

you can always install cisco inside your WSL and ...

Not really, I need it for Windows apps such as RDC and OneDrive

OneBlue commented 3 years ago

Thanks for reporting the issue @fibu79.

Can you please follow these instructions and share the script output, and both wsl.etl and packets.etl so we can have a deeper look ?