我已经修补 WSL-2 一段时间了,并不完全了解流量如何在主机和 WSL-2 dist 之间路由。
在某些源中,似乎 WSL-2 使用的所有端口都自动可供主机使用。例如在本教程中由Microsoft。 同样,我设法托管了一个Jupyter实例,该实例可通过localhost:8888
直接在我的主机上使用。
但是,当尝试其他服务时,例如 ssh(也在非标准端口上尝试),该端口不会通过本地主机自动可用,我必须使用分配给我的 WSL 发行版的 IP 地址(来自wsl hostname -I
的
为了通过本地主机提供服务,我找到了这个端口转发脚本,它有效。但我想了解为什么需要它。
为什么某些服务需要端口转发,而不是全部?
当您运行 WSL-2 时,一台机器(如 Vitural machin)会在您的窗口设备上运行。Windows 将创建一个本地网络,与您的 LAN 相同,并将 WLS-2 连接到此网络。
- 在 WSL2 上,可以运行ip a | grep eth0,结果如下所示:
5:eth0:<广播,组播,UP,LOWER_UP> MTU 1500 QDISC MQ 状态 UP 组默认 QLEN 1000 inet 172.27.5.124/20 BRD 172.27.15.255 范围 全局 ETH0
- 在窗口上的终端(或PowerShell)上,运行ipconfig,在结果中找到,如下所示:
Ethernet adapter vEthernet (WSL):
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::1532:a8ea:6b34:8df2%73
IPv4 Address. . . . . . . . . . . : 172.27.0.1
Subnet Mask . . . . . . . . . . . : 255.255.240.0
Default Gateway . . . . . . . . . :
WSL-2 和 Windows 设备位于同一网络上,并且 WSL-2 未连接到局域网。
我的解决方案(在 Windows 上使用端口转发)
在Windows上使用Admin打开终端,然后运行脚本:
netsh interface portproxy set v4tov4 listenport=8888 listenaddress=0.0.0.0 connectport=8888 connectaddress=$(wsl hostname -I)
我的困惑来自 WSL-2 的防火墙问题。
我发现的是:
- 侦听 WSL-2 中端口的服务可作为
localhost:<port>
从主机访问 - 无法从主机外部访问 WSL-2 端口
- WSL-2 端口可以使用 WSL 实例的 IP 地址通过
netstat interface portproxy
或其他端口转发工具提供。
防火墙不允许仅通过列出端口来访问 WSL 端口。我必须在防火墙规则中指定选择iphlpsv
服务(IP 帮助程序服务),以允许流量通过 WSL 实例。
按照以下步骤帮助我在 Windows 上本地连接到我的端口:
- 使用此处的脚本并将端口更改为需要转发的端口。将此文件保存到路径。
- 在 wsl,
sudo apt install net-tools
- 在电源外壳(管理员模式)中,
type ".script.ps1" | powershell.exe -c -
.这是运行文件。右键单击文件以"使用Powershell运行"将不起作用。 - 若要测试它是否正常工作,请在 powershell 中键入
netsh interface portproxy show v4tov4
根据netstat -an | findstr ":PORT_NUMBER"
的输出,尝试在同一 (TCP) 端口上开始侦听的netsh interface portproxy
和 WSL"魔术"端口转发器之间可能存在冲突。
假设一个 Linux 服务已启动。 它侦听 TCP 端口 443。WSL 将 Windows 的localhost:443
连接到 Linux 服务的端口 443。 这在显示未连接localhost:443
上的侦听器netstat
可见。
PS C:WINDOWSsystem32> netstat -an | findstr ":443"
[...]
TCP 127.0.0.1:443 0.0.0.0:0 LISTENING
尝试从任何其他网络接口的端口 443 转发到localhost:443
withnetsh
不会显示错误,但在netstat
中被视为不同 TCP 端口上的意外侦听器。 我认为这是netsh interface portproxy
的错误.
PS C:WINDOWSsystem32> netsh interface portproxy set v4tov4 listenport=443 listenaddress=0.0.0.0 connectport=443 connectaddress=127.0.0.1
PS C:WINDOWSsystem32> curl.exe -iskS https://10.X.Y.Z/
curl: (7) Failed to connect to 10.X.Y.Z port 443 after 2022 ms: Connection refused
PS C:WINDOWSsystem32> netsh interface portproxy show v4tov4
Listen on ipv4: Connect to ipv4:
Address Port Address Port
--------------- ---------- --------------- ----------
[...]
0.0.0.0 443 127.0.0.1 443
我相信在意外接口127.0.0.1
127.0.0.1:443
看到来自意外随机TCP端口的TCP连接后,我当场抓住了netsh interface portproxy
,
PS C:WINDOWSsystem32> netstat -an | findstr ":443"
[...]
TCP 127.0.0.1:443 0.0.0.0:0 LISTENING
TCP 127.0.0.1:63916 127.0.0.1:443 TIME_WAIT
如果上述关于netsh
错误理论是正确的,我就可以理解为什么我之前直观的端口号分离有效。 也就是说,可以将Linux服务配置为侦听不同的端口号,例如10443,然后可以将Windows端设置为从端口443转发到localhost:10443
。
我想如果在启动 Linux 服务之前设置了netsh interface portproxy
转发,同样的冲突可能会导致原始帖子的情况。
更新。看来我目前的困境是由于我的笔记本电脑上强制实施的防火墙管理器造成的。 我上面的回答是不可信的。