WSL2和VPN

shixudong@163.com

本人使用WSL2已有一段时间,近日在学习linux5.0新内核的UDP GRO功能时,偶尔发现WSL2在NAT模式下eth0的MTU值默认只有1420,顺便检查了一下Vmware和VirtualBox虚拟机,发现其NAT模式下以太网卡的MTU默认都是1500。感觉WSL2有点怪异,NAT从不涉及数据包的二次封装,怎么会莫名其妙降低MTU呢,手工将其改为1500,似乎也没出现不良症状。好奇之下,网上搜了一下相关资料,WSL2(NAT)降低默认MTU,居然和所在Windows主机上的VPN有关。综合网上资料,最初WSL2(NAT)的MTU也是1500,后来发现不能顺利访问主机VPN网络,便将其改为1280(IPv6最小MTU),再后来考虑WSL2内部有时也需要跑VPN,导致该VPN的MTU小于1280,内部VPN上不能跑IPv6,这才把WSL2(NAT)的MTU改到了1420(wg的默认MTU),而且理论上为了让WSL2(NAT)能顺利访问主机VPN网络,WSL2(NAT)的MTU不应超过主机VPN。所以针对不同的VPN,如发现网络访问不正常,还需要进一步缩小WSL2(NAT)的MTU。我也试着在Windows主机上启用了wg(AllowedIPs = 0.0.0.0/1,128.0.0.0/1),WSL2(NAT)在MTU=1500的情况下确实会出现ssh不能连接的问题,进一步测试发现在启用wg的kill-switch功能后(AllowedIPs = 0.0.0.0/0),即使MTU=1420也必定会出现无法访问互联网现象。网上有位老外对WSL2(NAT)和主机VPN相互之间的影响分析得比较全面,网络访问异常主要由3个原因引起,分别是MTU路由DNS,但由于只考虑了WSL2的NAT,分析未免不够透彻。本人同时对比了Vmware和VirtualBox下NAT和主机VPN的互动,做了进一步的分析,有助于更深刻地了解虚拟机的NAT模式,特此记录,以免遗忘。

一、MTU问题

对于ICMP和UDP数据包,WSL2(NAT)的网关(对应主机上的vEthernet (WSL)网卡)功能太弱鸡,不能处理IP碎片包(即使数据包不带“不分段”标志)。测试发现,即使主机上没有开启VPN,由于WSL2(NAT)的默认MTU设置为1420,和主机以太网卡的MTU(1500)已经不匹配,在WSL2(NAT)内ping外部网络,当包长度超过MTU-28时,由于需要拆包导致ping不通。对于UDP数据包同样如此,使用iperf测试UDP包,因UDP包默认长度1470,已超过WSL2(NAT)的默认MTU(1420),WSL2在IP层对UDP包分片,但因网关不支持,分片后的UDP无法发送出去,实际上无法进行UDP性能测试。要使iperf能顺利测试UDP,要么修改iperf的UDP包默认长度参数不超过MTU-28,要么将WSL2的MTU重新设置为1500。

TCP数据包能够自动协商MSS,故不存在上述IP碎片包问题。但当WSL2(NAT)的MTU设置为1500,和主机VPN的MTU不匹配时,首先依赖VPN的MSS clamping机制,并将PMTU发现机制作为备用手段,如两者都不起作用,就会引发TCP不通问题。

在VPN不能提供MSS clamping机制时,PMTU发现机制尤显重要,而且双向都必须有效。如Win11防火墙没有放行“虚拟机监控(回显请求)”,WSL2(NAT)很大可能收不到网关主动发来的通告Path MTU的ICMP包,意味着本地PMTU发现机制失效,导致TCP大包发不出去,具体表现为ssh不通。如主机VPN对端VPN Server出于安全考虑,阻塞了ICMP包,将导致远端PMTU发现机制失效,对端TCP大包无法回来,具体表现为无法访问网页。鉴于这么多不利因素可能影响TCP双向通信,干脆将WSL2(NAT)的MTU设置值不超过主机VPN不失为一种简易且有效的方法。

Vmware和VirtualBox的NAT模式,在主机层面,其实质就是代理模式,主机上netstat能看到主机代理发起的相关TCP连接。虚拟机内TCP数据包通过主机VPN路由出去时,代理模式发起的TCP连接将以VPN的MTU去协商TCP的MSS,此外如发现MTU不匹配,代理模式自动对虚拟机发来的大包进行拆分合并成小包(非IP碎片包),使之适配VPN的MTU,顺利通过主机VPN发送出去。代理过程对虚拟机完全透明,虚拟机认为自己处于NAT模式,也感觉不到两者MTU不匹配这一事实。

Vmware和VirtualBox的NAT对于UDP和ICMP数据包的处理,和TCP一样也采用了代理模式,不同之处在于MTU不匹配时,代理模式对虚拟机大包的拆分合并采用了IP碎片包方式。此外,当虚拟机和主机VPN之间MTU不匹配时,VirtualBox(NAT)存在一个小缺陷,当数据包长度落在两个MTU之间时,虚拟机发出的UDP和ICMP数据包默认带“不分段”标志,但对于主机来说,数据包长度已超过VPN的MTU,认为需要进行拆包处理,此时VirtualBox(NAT)完全无能为力,数据包将无法到达主机。针对这一缺陷,可将虚拟机linux的ip_no_pmtu_disc设置为1,使得数据包默认都不带“不分段”标志,允许VirtualBox(NAT)用IP碎片包方式进行拆包处理,顺利通过主机转发出去。

前面分析了Vmware和VirtualBox的NAT,最后还得提一下WSL2的本家Hyper-v(NAT),本自同根生,因此存在的问题和分析与WSL2(NAT)完全一致。至于前文所提的WSL2(NAT)网关功能太烂,不支持IP碎片包,实际上是Win11配套Hyper-v的NAT功能太烂,无法对IP碎片包进行NAT转换(事实上,IP碎片包的转换对基于端口的NAT也确实是个挑战),而不是网关对应的虚拟网卡弱鸡。经验证,只要不使用NAT转换功能,Hyper-v虚拟网卡对IP碎片包的处理完全没有问题(原计划准备本机验证的,结果发现Win11的23H2版本突然不支持通过注册表IPEnableRouter开启路由转发功能了,尚不清楚今后是否继续支持抑或纯粹BUG)。

二、路由和DNS问题

当Windows主机启用wg的kill-switch功能后(AllowedIPs = 0.0.0.0/0),即使WSL2(NAT)的MTU已设为1420,依旧无法访问互联网,初步测试发现,是WSL2(NAT)网关作为DNS不能提供解析服务,如直接访问外部IP或换用VPN提供的DNS,就没有问题。经深入研究,WSL2(NAT)网关不能解析DNS只是表象,本质上是由wg的kill-switch机制衍生的路由问题所致。wg启用kill-switch功能后,主机和外部网络的通信数据包,只允许来自或去往wg通道,本地局域网通信则不被允许。因为WSL2(NAT)的网关就是主机上的vEthernet (WSL)网卡,WSL2(NAT)访问网关的DNS通信被视为本地局域网流量而丢弃,导致无法提供DNS解析。同理,主机和WSL2(NAT)之间也无法ping通(通过localhost地址互访则不受影响)。

新版WSL2引入了dnsTunneling开关,启用后,WSL2(NAT)不再使用网关作为DNS,新的DNS地址127.0.0.42属于loopback地址,不受kill-switch机制影响。但主机在启用kill-switch功能时如不指定VPN对应的DNS,即使主机原DNS能通过VPN通道访问,使用新的127.0.0.42仍然无法解析DNS。目前尚不清楚其内在机制,因为主机上包括浏览器在内的部分程序都能使用主机原DNS正常访问域名,nslookup也能正常查询,但在cmd下也无法ping域名。

同样,我们检查一下Vmware和VirtualBox的NAT模式在主机wg启用kill-switch功能后的表现,VirtualBox(NAT)在主机上没有对应的网卡,直接使用主机的DNS作为自己的DNS,使用末位为2的同网段IP地址作为自己的网关。Vmware(NAT)表面上类似WSL2(NAT),在主机上生成了对应的网卡(IP末位地址为1),但该网卡IP并不充当虚拟机的网关和DNS,甚至可以设置不要在主机上生成该网卡,虚拟机同样使用末位为2的同网段IP地址作为自己的网关和DNS。如同WSL2(NAT),Vmware(NAT)和末位地址为1的IP之间无法通信,但Vmware(NAT)和DNS之间的通信完全属于虚拟机内部通信,故不受kill-switch机制影响。

显然Vmware和VirtualBox在NAT模式下的DNS解析完全符合kill-switch允许通信的要求,故没有类似WSL2(NAT)的DNS解析问题。另外一方面,也完美解释了Vmware(NAT)为什么使用.2而不是.1作为网关和DNS的疑惑。

Wg的kill-switch机制比较科学,对底层网络包进行了截获,以判断其通信流量是否通过VPN来控制放行与否,但有些VPN单纯采用了路由技巧实现kill-switch机制,如前面老外在路由问题中所提到的VPN,此类VPN通过新增InterfaceMetric为1的多条路由覆盖本地局域网路由(包括虚拟机对应的局域网络),以引导流量完全指向VPN通道。由于纯粹使用路由机制实现kill-switch,导致外部网络回复WSL2(NAT)的数据包又重新路由到VPN通道,最终WSL2(NAT)彻底无法与外部网络通信。针对此类VPN,只有参照老外给出的方案,删除新增的针对虚拟机的局域网络,才能在启用kill-switch的同时解决WSL2(NAT)与外部网络的通信问题。至于Vmware和VirtualBox的NAT,虚拟机和外部网络通信时,由于采用代理模式,取消或绕过了虚拟机对应的主机网卡,同样不会受到此类VPN启用kill-switch功能的影响。

至于Hyper-v(NAT),主机wg启用kill-switch功能后,针对局域网通信,仅放开了主机作为DHCP客户端的通信,对于Hyper-v(NAT)来说,主机作为DHCP服务器,DHCP响应包发不出去,导致Hyper-v(NAT)根本无法获取DHCP。而WSL(NAT)的DHCP不是通过网络分配(虚拟机里也无需跑DHCP客户端),所以不存在无法获取DHCP问题。

三、后话

WSL2(NAT)的底层网络机制和KVM(NAT)一致,不采用代理模式,主机上netstat看不到虚拟机和外部设备的TCP连接,NAT在主机层面既不修改或重新协商虚拟机发出TCP的MSS,也不对数据包进行拆分合并操作。理论上KVM(NAT)在虚拟机和主机VPN的MTU不匹配时,也会出现同样的TCP连接问题,模拟测试(不使用MSS clamping并禁用本地PMTU)证实了这一推理,但由于linux主机防火墙行为不像Win11那样难以捉摸,而且更主要的是KVM(NAT)使用了主机iptables实现NAT功能,很容易启用MSS clamping机制,因而基本对用户无感,无需像WSL2(NAT)那样只能在虚拟机网卡层面进行MTU调优。

顺便提一下,最新版WSL2新增了mirrored模式,使用和主机完全相同的IP地址,外部网络访问WSL2(mirrored)不再需要另行配置NAT映射,相较bridged模式,主机也无需额外安装Hyper-v功能。VPN在WSL2内部被视为另一块网卡,MTU直接继承自主机VPN,压根没有前面那些破事。但经初步使用,目前发现mirrored模式存在如下不足:

1、在WSL2(mirrored)上使用tcpdump捕获进来的UDP包时,如WSL2没有事先打开相应的UDP接收端口,主机根本不会把外部网络发来的UDP包镜像到虚拟机,你将会一无所获。

2、WSL2(mirrored)号称支持multicast,但其官方内核CONFIG_IP_MULTICAST is not set,如主机使用有线网卡,问题倒是不大。然而如主机笔记本无线网卡固件具有multicast filter特性,由于WSL2内核缺失组播加入功能,导致外部发来的组播包在主机无线网卡层面就被拦截,此时WSL2的multicast receive大概率无法工作。不过,mirrored在支持multicast方面确实存在优势,譬如,使用CONFIG_IP_MULTICAST=y重新编译内核后,由于目前无线AP大都已强制启用multicast_to_unicast功能,通过主机WiFi进来的multicast包采用主机WiFi的MAC作为目标MAC,能够顺利被WSL2(mirrored)接收,但无法被WSL2(bridged)接收(Vmware和VirtualBox的无线桥接模式进一步扩展了桥接功能,可根据三层多址IP对multicast_to_unicast进行逆转换,将目标MAC恢复成标准多址MAC,故不存在无线multicast receive的瑕疵)。

3、WSL2(mirrored)尚不支持内核sockets镜像,因此,内核态udp隧道如wireguard、vxlan等都无法工作(无法接收UDP包)。经过验证,可以借助用户态socket工具(如iperf -u -s -p port)重新bind一下内核态隧道已经打开的UDP接收端口,虽然会报地址已被使用的错误,但此后上述内核态udp隧道就能正常工作,也算是一种临时解决方案吧。

  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 都是什么?它们有什么区别和联系? VM是虚拟机的缩写,是一种软件模拟的计算机系统,可以在一个物理计算机上运行多个虚拟机,每个虚拟机都可以运行不同的操作系统和应用程序。WSL2是Windows Subsystem for Linux 2的缩写,是一种在Windows 10操作系统上运行Linux二进制文件的兼容层,可以让用户在Windows系统上使用Linux命令行工具和应用程序。Docker是一种容器化技术,可以将应用程序和其依赖项打包成一个独立的容器,可以在任何支持Docker的平台上运行。 它们的区别在于,VM是一种完全虚拟化技术,需要在虚拟机中安装完整的操作系统和应用程序,相对来说比较重量级;WSL2是一种轻量级虚拟化技术,只需要安装Linux内核和用户空间工具,可以在Windows系统上运行Linux应用程序;Docker是一种容器化技术,可以将应用程序和其依赖项打包成一个独立的容器,可以在任何支持Docker的平台上运行。 它们的联系在于,都是一种虚拟化技术,可以在一个物理计算机上运行多个不同的操作系统和应用程序,提高了计算机资源的利用率和灵活性。 ### 回答2: VM(虚拟机)、WSL 2(Windows Subsystem for Linux 2)和Docker 都是常用的虚拟化技术,用于在计算机上运行不同的操作系统环境。 虚拟机(VM)是一种软件实现的计算机系统,它可以在主机操作系统上创建和运行多个虚拟的客户操作系统。通过虚拟化技术,它可以模拟硬件、网络和其他计算机资源,让多个操作系统同时运行在同一物理计算机上。虚拟机可以提供相对独立的操作系统环境,使得不同的操作系统可以在同一台计算机上互不干扰地运行。它广泛应用于软件开发、软件测试和服务器虚拟化等场景。 WSL 2 是 Windows 10 上的一个功能,允许用户在计算机上运行 Linux 内核,并与 Windows 操作系统无缝集成。WSL 2 相比于早期的 WSL 提供了更好的性能和兼容性。它使用虚拟化技术将 Linux 内核运行在 Windows 上,同时提供了与 Windows 文件系统的互通以及与 Windows 应用程序的集成。这使得开发人员可以在 Windows 操作系统上使用 Linux 工具和工作流程,无需直接使用虚拟机。 Docker 是一种容器化平台,它提供了一个容器化的运行环境。容器是一种独立且可移植的软件包,包含了运行一个特定应用程序所需的所有代码、运行时环境、系统工具和库等。Docker 在容器内部提供了与主机操作系统隔离的运行环境,使得应用程序可以在相同的软件环境中运行,并且可以在不同的计算机和操作系统间无缝迁移。Docker 在开发、测试和部署应用程序方面具有很高的效率,支持快速部署、扩展和管理各种应用。 总结来说,虚拟机(VM)、WSL 2 和 Docker 都是虚拟化技术。虚拟机可以模拟完整的操作系统环境,使得不同的操作系统可以在同一台计算机上运行。WSL 2 则是在 Windows 系统上运行 Linux 内核,并提供和 Windows 的集成。而 Docker 则是一种容器化平台,提供了一个独立的、可移植的运行环境,可以在不同的计算机和操作系统间无缝迁移应用程序。这些技术都有各自的应用场景和优势,适用于不同的开发和运行需求。 ### 回答3: VM是虚拟机(Virtual Machine)的缩写,它是一种通过在物理硬件上创建虚拟计算机环境来运行软件的技术。VM可以在主机操作系统之上运行另一个完全独立的操作系统,允许用户在不同的操作系统之间进行快速切换,提供了隔离和独立的环境,可以同时运行多个虚拟机实例。 WSL2是Windows Subsystem for Linux 2的缩写,是微软为Windows 10和Windows Server 2019引入的一个功能,可以在Windows上运行Linux子系统。相比于WSL1,WSL2采用了完整的Linux内核虚拟化技术,提供了更高的性能和更好的兼容性,用户可以在Windows上使用包管理器安装和运行Linux软件。 Docker是一种容器化技术,通过将应用程序、依赖项和配置打包在一个独立的容器中,实现了应用程序与底层操作系统之间的隔离。Docker可以在不同的操作系统上运行相同的容器,提供了便捷、可移植和可扩展的应用部署和管理方式,使开发人员能够更快速地构建、交付和运行应用程序。 三者之间存在一些相似之处和区别。VM和WSL2都是提供虚拟化环境的技术,但VM通常是在硬件层面上虚拟化整个操作系统,而WSL2是在操作系统层面上虚拟化Linux子系统。Docker则是一种更轻量级的容器化技术,它虚拟化的是应用程序及其依赖项,与操作系统相对独立。 相比于VM和WSL2,Docker具有更高的性能和更小的资源开销,容器可以快速启动和停止,并且可以共享宿主机的操作系统内核,避免了资源浪费。但VM和WSL2提供了更高的隔离性和完整的操作系统环境,可以运行各种不同的操作系统,更适合于需要完全隔离的场景。 综上所述,VM适用于在完全独立的操作系统环境中运行不同的应用程序,WSL2适用于在Windows上运行Linux子系统,而Docker适用于在不同的操作系统上轻量级部署和管理应用程序。根据具体需求和场景的不同,可以选择适合的技术来满足需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值