跳到主要内容

WSL2下,Mirrored网络下无法从外部访问

· 阅读需 3 分钟
RibomBalt
CTF enthusiastist, GeoPhysics PhD, Amateur coder

TL;DR

  • 本文讨论WSL2下的服务被外部访问的问题。这里的外部包括宿主机、与宿主机同一局域网的其他设备、可以访问到共同网关(路由器)的“广域网”设备。
  • 解决方案来自CSDN,但文中会展示微软官方说明。

22H2之前 - 桥接

WSL2默认采用NAT模式,即WSL2是宿主机内部的一个子网(通常为B类或C类地址),且子网IP会随重启而变化,不利于WSL内服务被外部访问。Win11 22H2之前,可以通过桥接网络的方法缓解,其%WIN_HOME%/.wslconfig类似于:

[wsl2]
networkingMode=bridged
vmSwitch=WSL

这时WSL会和宿主机桥接在同一网络中。对于我的网络构型,可以通过路由器的虚拟服务器(端口转发)功能,可以实现外部访问。局域网内仍然可以通过不同的子网IP分别访问WSL和宿主机。

22H2之后 - Mirrored

镜像网络是最近WSL2的新特性,可以让WSL2和WSL1对外表现为同一IP地址。以下为镜像模式的完整配置,也可看微软文档

[wsl2]
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true

Mirrored下,WSL2内服务无法被外部访问

第一个问题是:Mirrored模式下,宿主机可以用localhost回环地址访问WSL服务,但不能用外部地址(如C类192.168地址)访问。这个的解决方案是启用hostAddressLoopback配置,如微软文档所示,目前hostAddressLoopback仍然是实验性设置,示例如下。

[wsl2]
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true

[experimental]
hostAddressLoopback=true

第二个问题是:即使本机能够访问WSL2内的服务,局域网内其他设备仍然不能访问WSL2内的服务。这个问题需要打开Hyper-V防火墙,如文档所示:

# 二选一即可
# 开放全部端口
Set-NetFirewallHyperVVMSetting -Name '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}' -DefaultInboundAction Allow
# 仅开放特定端口(推荐)
New-NetFirewallHyperVRule -Name "MyWebServer" -DisplayName "My Web Server" -Direction Inbound -VMCreatorId '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}' -Protocol TCP -LocalPorts 80

目前Hyper-V防火墙似乎还不能被GUI管理。

Docker访问

TODO: Docker的问题还没研究清楚

CSDN博客宣称,需要在/etc/docker/daemon.json中加入下列设置以使得docker -p 80:80等方式运行的容器被外部访问:

{
"iptables": false
}

然而我本机测试后,这个反而是不需要加的,加了就无法访问。这个问题之前在纯Linux系统遇到过类似的,docker确实会修改iptables导致无视ufw等防火墙规则,造成安全问题。这里反而是需要它暴露。