众所周知,wsl2 是 windows 下的 linux 子系统,并且采用类似于虚拟机 NAT 的管理方式。一般情况下,外部网络很难直接访问到 wsl 上的服务,除非使用端口转发。而现在,微软更新了 wsl 2.0.0,采用镜像网络配置,完美解决了所有网络上的问题。
研究起因 ¶
由于在编译他人代码时需要 linux 环境,我就放在了 wsl 下编译运行,然后在本地,我就尝试用ifconfig得到的虚拟机 ip,成功连接上了 wsl 服务器。但是,当我试图用局域网下其他设备连接时,很显然,根本不可能连接上。**这是因为 wsl2 采用了类似于 NAT 的网络模式,windows 作为宿主机,隔离了局域网下其他设备和 wsl 的连接。**为了外部访问 wsl,我也试过一些方法。
旧版本端口转发方案 ¶
在旧版本,常用的方法是端口转发,根据官方文档,在有管理员权限的 powershell 下,输入如下指令:
netsh interface portproxy add v4tov4 listenport=<yourPortToForward> listenaddress=0.0.0.0 connectport=<yourPortToConnectToInWSL> connectaddress=(wsl hostname -I)
在此示例中,需要更新 <yourPortToForward> 到端口号,例如 listenport=4000。 listenaddress=0.0.0.0 表示将接受来自任何 IP 地址的传入请求。 侦听地址指定要侦听的 IPv4 地址,可以更改为以下值:IP 地址、计算机 NetBIOS 名称或计算机 DNS 名称。 如果未指定地址,则默认值为本地计算机。 需要将 <yourPortToConnectToInWSL> 值更新为希望 WSL 连接的端口号,例如 connectport=4000。 最后,connectaddress 值必须是通过 WSL 2 安装的 Linux 分发版的 IP 地址(WSL 2 VM 地址),可通过输入命令:wsl.exe hostname -I 找到。
--- 官方文档
然后,我将 wsl 中的8303端口映射在了 windows 下的8304端口下,我看到,在 wsl 中,服务器照常运行。
netstat -ano | findstr 8304
也能看到 8304 端口正常监听。但是,在我访问 wsl 运行的游戏服务器~(游戏名:DDraceNetwork)~,客户端显示 “udp 疑似被拦截”。本来我认为这是端口转发失败了,但是我忽然注意到本地 8304 端口只有 tcp。于是查询了有关资料,得到了netsh只支持 tcp 的结论。因此,netsh 方案失败。
旧版本桥接模式方案 ¶
后来,我希望用 hyper-v 创建一个虚拟交换机,相当于一个可通外网的虚拟网卡,并让 wsl 连接。结果,出现了许多问题。
- 当前版本下,wsl2 已不支持更改连接方式为
bridge桥接模式,从根本上杜绝了这一方法 - 当我创建了虚拟交换机后并将其接入网桥,他直接把我 Windows 下的网络干废了。
试图用 Vmware 创建交换机,结果根本找不到选项
最后,我发现了官网给出了新方案!
新版本镜像网络模式方案 ¶
由于本人入坑 wsl 时间晚,在此之前,我对 wsl1 只是道听途说。据我了解,wsl1 建立在兼容层上,与 windows 共存,因此 wsl1 的网络配置与 windows 一致,外部网络也可以很轻松地接入 wsl。而 wsl2 则是基于 hyper-v 的虚拟机,采用的是新一套的 NAT 方案,较为独立。所以对于 wsl2 也要用和普通虚拟机一样的网络方案,如 NAT 转发和桥接。
而现在,在 Windows23H2更新中,或是22H2中的 insider,wsl2 更新了镜像网络解决方案,这个方案将会解决几乎一切 wsl 上的网络问题。而此方法,也将随着时间推移,成为 wsl2 的默认解决方案。
在此贴出微软官方文档:
使用 WSL 访问网络应用程序 | Microsoft Learn
wsl 版本检测 ¶
要启用镜像网络模式,首先要保证你的 windows 系统是 23H2 以上,或是加入了 windows 体验计划。除此之外,由于版本更新已有一段时间,如果你不确定是否可以使用,可以在 cmd 输入wsl --version查看 wsl 版本是否是2.0.0以上。如果是,那就可以。
配置 wsl 文件 ¶
在 windows 用户根目录下,新建个名为.wslconfig的文件,选择合适的编辑器打开它。
如果不知道自己的用户根目录,可以在 cmd 下输入echo %USERPROFILE,即可看到路径
经过实验,我甚至发现上面的命令只能在 cmd 命令提示符下执行,powershell 还不行!!!
在文件中输入如下内容:
[experimental]
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true
然后,执行wsl --shutdown,等待大约 8 秒后重新启动 wsl,即可成功改变网络策略。
你可以通过在 wsl 虚拟机内执行ifconfig,看到原本有的 IP 地址现在没了,即可证明 mirrored 模式启用成功。现在你可以用 phpstudy 等软件在 windows 下建立一个网站,然后用 linux 访问,会发现 linux 可以访问 windows 的服务。
比如说:我在 windows 下用 80 端口建立的网站,在 linux 下执行curl localhost,显示的是 windows 的网站。
再比如说:我在 linux 下用 apache 在 81 端口建立了个网站,在 windows 下用浏览器访问http://localhost:81,可以看到 linux 的网站。
那么,wsl 的新版本网络配置也就成功了…………
…………
吗?
解决遗留的坑 ¶
很遗憾地告诉大家,我上面给出的配置文件少了一句话,而这句话才是本文的重点。为什么会单独拿出来讲,这是因为我在 20 分钟查找资料的过程,没有一篇文章讲到这个。现在我们先来看看问题在哪里。
首先,我们要先知道 windows 的 IP 地址,不要求上百度看公网 IP,只要一个局域网内的外部 IP,也就是你电脑直连路由器分配给你的 IP,假设是 192.168.1.101,那么我现在在浏览器访问http://192.168.1.101,可以成功看到宿主机创建的网站。
现在在让我们访问http://192.168.1.101:81,也就是 linux 下的网站端口,结果发现,无法访问!
也就是说:
- localhost:81 可以!
- 192.168.1.101:81 不行!
那就奇了怪了,我也是成功在官网找到响应的配置选项,只要在最后加上那么一行:hostAddressLoopback=true就行了。
最后的配置文件:
[experimental]
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true
hostAddressLoopback=true
重启 wsl,问题解决,我的游戏服务器也能进入了,只是服务器列表不显示 [滑稽]
尾声 ¶
我在这里贴出 wsl2 关于 mirrored 模式的一些其他配置选项,可以更好的帮助各位配置 wsl。
具有 path 值的条目必须是带有转义反斜杠的 Windows 路径,例如:C:\\Temp\\myCustomKernel
具有 size 值的条目后面必须跟上大小的单位,例如 8GB 或 512MB。
值类型后带有 * 的条目仅在 Windows 11 中可用。
值类型后显示 ** 的条目需要 Windows 版本 22H2 或更高版本。
作者:Sxrhhh
博客园:Sxrhhh - 博客园 (cnblogs.com)
转载请注明出处.
在个人网站持续更新中……
文章热度:0 次阅读