WSL连不上网解决方案(包含WSL虚拟交换机不正常以及WSL网络配置不正常两种解决方案)
一、前言
WSL更新后就连不上网络,遂记录解决方法以便后续查找。
二、问题描述
目前总结下来,WSL访问不了网络的问题就两点,第一点是WSL的虚拟交换机不正常工作了 :
也就是如图的虚拟交换机显示媒体已断开连接,如图的显示肯定是很正常的。第二点就是WSL的网卡配置与这个虚拟交换机的网络配置不同,导致WSL无法访问宿主机,因为WSL默认是NAT模式,需要通过WSL本身的网卡与这个虚拟交换机进行连接,这个虚拟交换机连接的是宿主机本身,也就是说在NAT模式下WSL的网络IP应该是属于这个虚拟交换机子网的。类似于下图:
通过如下命令查看当前路由表:
└─$ ip route
default via 172.28.96.1 dev eth0 proto kernel
172.28.96.0/20 dev eth0 proto kernel scope link src 172.28.108.21
上面第一行表示默认路由通过 IP 地址为 172.28.96.1 的设备,设备名为 eth0,使用内核协议。第二行表示IP 地址范围为 172.28.96.0/20 的网络通过设备 eth0 连接,使用内核协议,连接范围为本地链路,源 IP 地址为 172.28.108.21。
这个IP地址为172.28.96.1的设备就是WSL网卡连接的路由器,也就是WSL的虚拟交换机,也表明了这个地址应该为这个虚拟交换机的IP地址,但根据上图发现这两个地址是不同的,说明WSL的流量就没走这个虚拟交换机,通过ipconfig查看主机的网络设备,我也没找出这个IP地址是谁的IP。
通过ip addr或者ifconfig可以看到WSL自身的网络设备信息:
└─$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet 10.255.255.254/32 brd 10.255.255.254 scope global lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 00:15:5d:57:72:cf brd ff:ff:ff:ff:ff:ffinet 172.28.108.21/20 brd 172.28.111.255 scope global eth0valid_lft forever preferred_lft foreverinet6 fe80::215:5dff:fe57:72cf/64 scope linkvalid_lft forever preferred_lft forever
通过上面发现eth0的网络地址也并不在虚拟交换机的网络范围。这两个现象都指明了一个问题,WSL当前的网络配置不对。
三、解决方案
对于第一点是WSL的虚拟交换机不正常工作的问题直接执行下面的命令就好了:
netsh winsock reset
netsh int ip reset all
netsh winhttp reset proxy
ipconfig /flushdns
最后重启电脑
下面是对这几个命令的解释:
netsh winsock reset:这个命令重置Winsock目录。Winsock是Windows用于数据通信的API(应用程序编程接口)。如果Winsock目录被错误配置或损坏,可能会导致网络连接问题。执行这个命令后,可能需要重新启动计算机以完成重置。
netsh int ip reset all:这个命令重置所有的网络接口卡(NIC)到初始状态,包括IP地址、DNS和WINS服务器的设置等。这个命令可以帮助解决TCP/IP协议栈的问题。同样,执行后可能需要重新启动计算机。
netsh winhttp reset proxy:这个命令重置WinHTTP的代理服务器设置。WinHTTP是Windows HTTP Services的缩写,用于Windows应用程序中的HTTP通信。如果代理服务器设置不正确,可能会导致应用程序无法访问互联网。重置后,WinHTTP将使用默认的代理设置。
ipconfig /flushdns:这个命令刷新DNS解析缓存。DNS(域名系统)将域名(如www.example.com)解析为IP地址(如192.0.2.1)。当DNS缓存中的信息过时或错误时,可能会导致网站无法访问或访问到错误的网站。刷新DNS缓存可以解决这个问题。
对于第二个问题可以通过手动配置WSL的网络信息进行解决,例如:
$ sudo ifconfig eth0 192.168.95.91 netmask 255.255.240.0
上面的方法需要你自己去算子网IP和掩码,另一种方法是通过重置网络的方式进行解决:
Get-NetAdapter -Name "vEthernet (WSL)" | Restart-NetAdapter //重置网络交换机,可以结合下面的方法再试试
或
wsl --shutdown
Restart-Service vmms -Force # 重启 Hyper-V 虚拟机管理服务
Restart-Service hns # 重启 Host Network Service
然后重启wsl,理论上这时wsl就已经自动被配置为正确的信息了,但是有一种特殊的情况:
网络终结点通常是指网络中的一个设备或服务的连接点。这种情况下问题就变成了这个WSL并没有连接现有的虚拟交换机,而是又创建了新的临时虚拟交换机(WSL理论上只能有唯一的虚拟交换机设备,多余的设备通常为临时设备,在电脑重启或者退出虚拟机后就应该被自动销毁,微软将其称为幽灵适配器,或称虚拟即插即用 (PnP) 设备,指在系统中显示但未物理连接的硬件组件。 这些“幽灵”设备可能会导致系统设置中的混乱和杂乱。 如果在虚拟机 (VM) 中运行 WSL 时看到幽灵适配器,最好在设备管理器中将其手动删除)步骤如下:
对于这种情况,我目前研究出的方法如下,大致思路就是删除现有的虚拟交换机,然后让系统再自动创建出一个新的虚拟交换机:
Restart-Service vmms -Force # 重启 Hyper-V 虚拟机管理服务
Restart-Service hns # 重启 Host Network Service
Get-VMSwitch -Name "WSL" | Remove-VMSwitch -Force # 删除Hyper-V 虚拟交换机
此时一般会报错:
Remove-VMSwitch: 删除虚拟以太网交换机时失败。
删除交换机失败,交换机 =“B95D0C5E-57D4-412B-B571-18A81A16E005”: 拒绝访问。 (0x80070005)。
但是在网络连接的页面你应该是能够看到这个虚拟交换机被拔出了,此时我们再执行下面的命令重置网络:
Restart-Service vmms -Force
Restart-Service hns -Force
此时你应该能看到这个虚拟交换机已经彻底消失了,此时系统上已经没有了名为WSL的虚拟交换机,此时我们再次进入WSL(注意,此时不要打开Hyper-V的管理器,有可能会又给你自动创建一个WSL的虚拟交换机,而这个虚拟交换机会占用WSL自己创建的虚拟交换机,虽然WSL依赖于Hyper-V,但是这俩好像又有点玄学,不是互通的),然后应该就会没有任何报错的进入了。
在删除虚拟交换机那步你也可以尝试下面的方法:
Get-VM | Stop-VM -Force //强制关闭所有虚拟机
Get-VMSwitch -Id "B95D0C5E-57D4-412B-B571-18A81A16E005" | Disconnect-VMNetworkAdapter -Force //释放虚拟机交换资源
Remove-VMSwitch -Id "B95D0C5E-57D4-412B-B571-18A81A16E005" -Force //强制删除
$switchPath = "C:\ProgramData\Microsoft\Windows\Hyper-V\Virtual Switches\"
Remove-Item -Path "$switchPath\B95D0C5E*" -Force -Recurse//删除交换机关联的虚拟网络配置文件
Restart-Service vmms -Force
Restart-Service hns -Force
查看网络配置信息:
这次我们发现这个网络配置信息和WSL虚拟交换机的信息就完全匹配的上了,此时WSL是连接到了虚拟交换机上的,通过访问网络也能验证这一点。
四、总结
问题到这也就解决完了,下面还有一个更加硬核的方法,如果这些都没用,你也可以试试:
如果你是Ping不通主机的话,在执行下面的方法前先尝试一下:
New-NetFirewallRule -DisplayName "WSL" -Direction Inbound -InterfaceAlias "vEthernet (WSL)" -Action Allow //设置防火墙规则,防止WSL是被Windows防火墙阻挡了
如果不行且毫无其他办法了(你也可以试试通过桥接模式(现在叫镜像模式)直接连接物理网卡来访问外部网络,但是治标不治本),尝试下面直接重置整个WSL,重装解决99%的问题:
wsl --shutdown
Get-Process -Name "wslservice" | Stop-Process -Force
Remove-Item "$env:USERPROFILE\AppData\Local\Packages\*WSL*\LocalState\*.vhdx" -Force
wsl --install -d Ubuntu # 重新安装发行版(保留数据)
如果对于WSL网络配置不熟悉的可以看看我另一篇关于WSL网络配置的文章,这个文章在计算机网络专栏下。