如何从 WSL2 访问主机上运行的服务(连接被拒绝)

jus*_*dev 3 windows-subsystem-for-linux

我的主机上正在运行 selenium,我的应用程序位于 docker 容器内(在 WSL2 内)。

我正在尝试让应用程序连接到 selenium,它正在监听端口 4445。几个月前它曾经工作过,我认为 WSL 中发生了一些变化。

主机正在监听 4445:

PS> netstat -ano | findstr :4445
  TCP    0.0.0.0:4445           0.0.0.0:0              LISTENING       11604
  TCP    [::]:4445              [::]:0                 LISTENING       11604

Run Code Online (Sandbox Code Playgroud)

我可以从Windows主机访问selenium:

>curl -X POST http://DESKTOP-HED9HVG:4445/wd/hub
{"state":".....}
Run Code Online (Sandbox Code Playgroud)

但不是来自 WSL2:

$ curl -X POST http://172.22.241.214:4445/wd/hub
curl: (7) Failed to connect to 172.22.241.214 port 4445: Connection refused
Run Code Online (Sandbox Code Playgroud)

我尝试了在curl中使用的ip的几个选项:

  • ip addreth0 ip
  • $(hostname)
  • ip 地址的结果ipconfig /all | findstr IPv4
  • ip地址结果route -n | grep UG | head -n1 | awk '{print $2}'

我在 WSL 上安装了 tcptraceroute 并运行它。这是输出:

$ tcptraceroute $(hostname) 4445
Selected device lo, address 127.0.0.1, port 53915 for outgoing packets
Tracing the path to DESKTOP-WXYZ1 (127.0.1.1) on TCP port 4445, 30 hops max
 1  DESKTOP-WXYZ1.localdomain (127.0.1.1) [closed]  0.075 ms  0.082 ms  0.074 ms
Run Code Online (Sandbox Code Playgroud)

顺便说一句,从 WSL 到主机的 ping 操作确实有效:

$ ping $(hostname)
PING DESKTOP-WXYZ1.localdomain (127.0.1.1) 56(84) bytes of data.
64 bytes from DESKTOP-WXYZ1.localdomain (127.0.1.1): icmp_seq=1 ttl=64 time=0.053 ms
Run Code Online (Sandbox Code Playgroud)

我尝试完全禁用Windows防火墙,但没有帮助。我还在“Windows Defender 防火墙”中添加了一条规则,专门启用端口 4445。仍然没有帮助

WSL的相关资料:

>wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu-20.04           Running         2
  docker-desktop         Running         2
  docker-desktop-data    Running         2
Run Code Online (Sandbox Code Playgroud)

知道如何解决这个问题吗?

jus*_*dev 5

经过多次尝试,解决方案来自github问题中的一个晦涩评论: https: //github.com/Microsoft/WSL/issues/1032#issuecomment-891618766

基本上:

if you also use Docker Desktop, you can access your Windows host with host.docker.internal
Run Code Online (Sandbox Code Playgroud)


小智 5

其实我自己在工作做的一个项目中也遇到过这个问题,而且无法使用docker Desktop。

我所要做的就是建立防火墙和端口代理规则来绕过 wsl 和 windows 防火墙。您需要主机以太网适配器的 IP,因此在 Windows 中运行 ipconfig 来获取它。您还需要 Windows 上服务的侦听端口和 WSL IP(wsl 中的 ifconfig,查找 eth0 的 ivp4 inet 值)。

主机上 powershell 的防火墙规则命令:

New-NetFireWallRule -DisplayName 'WSL firewall unlock' -Direction Outbound -LocalPort your_port_here -Action Allow -Protocol TCP

New-NetFireWallRule -DisplayName 'WSL firewall unlock' -Direction Inbound -LocalPort your_port_here -Action Allow -Protocol TCP
Run Code Online (Sandbox Code Playgroud)

绕过 Windows 防火墙后,您还可以从 Windows 提示符将端口“转发”到 wsl:

netsh interface portproxy add v4tov4 listenport=your_port_here listenaddress=host_ip_here connectport=your_port_here connectaddress=wsl_ip_here
Run Code Online (Sandbox Code Playgroud)

运行所有命令后,您应该能够通过容器中的 <host_ip>:<host_port> 访问主机服务。