3

I have selenium running on my host machine, and my app is inside a docker container (inside WSL2).

I am trying to get the app connect to the selenium, that is listening on port 4445. It used to work a few months ago, I think something changed in WSL.

Host is listening on 4445:

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

I can access selenium from the windows host machine:

>curl -X POST http://DESKTOP-HED9HVG:4445/wd/hub
{"state":".....}

but not from 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

I tried several options for the ip that I used in curl:

  • ip addr eth0 ip
  • $(hostname)
  • ip addresses from the results of ipconfig /all | findstr IPv4
  • ip address result of route -n | grep UG | head -n1 | awk '{print $2}'

I installed tcptraceroute on WSL and run it. This is the output:

$ 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

By the way, pinging from WSL to host does work:

$ 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

I tried to disable completely the windows firewall, but it doesn't help. I also added a rule in "Windows Defender Firewall" to enable port 4445 specifically. It still didn't help

Info about WSL:

>wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu-20.04           Running         2
  docker-desktop         Running         2
  docker-desktop-data    Running         2

Any idea how to solve this?

4 Answers 4

5

After a lot of tries, the solution came from an obscure comment in github issues: https://github.com/Microsoft/WSL/issues/1032#issuecomment-891618766

Basically:

if you also use Docker Desktop, you can access your Windows host with host.docker.internal
5

I actually encountered this problem myself in a project I was working on for work, and couldn't use docker desktop.

What I had to do was establish firewall and portproxy rules to bypass the wsl and windows firewalls. You'll need the host ethernet adapter's ip, so run ipconfig in windows to get it. You'll also need the listening port for the service on windows, and the WSL ip (ifconfig in wsl, looking for eth0's ivp4 inet value).

The commands for the firewall rules from powershell on the host:

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

With the windows firewall bypassed, you can then "forward" the ports to wsl also from a windows prompt:

netsh interface portproxy add v4tov4 listenport=your_port_here listenaddress=host_ip_here connectport=your_port_here connectaddress=wsl_ip_here

Once you've run all the commands, you should be able to access the host service via <host_ip>:<host_port> from the container.

5

See guidance here

https://docs.microsoft.com/en-us/windows/wsl/networking#accessing-windows-networking-apps-from-linux-host-ip

If you want to access a networking app running on Windows (for example an app running on a NodeJS or SQL server) from your Linux distribution (ie Ubuntu), then you need to use the IP address of your host machine. While this is not a common scenario, you can follow these steps to make it work.

Obtain the IP address of your host machine by running this command from your Linux distribution: cat /etc/resolv.conf Copy the IP address following the term: nameserver. Connect to any Windows server using the copied IP address. The picture below shows an example of this by connecting to a Node.js server running in Windows via curl.

You will also need to allow inbound connections to that port in the host. (Through a firewall rule).

5
  • 2
    There's a catch with this. If you're running docker daemon on wsl, the resolv.conf nameserver will apparently point to the wsl gateway in wsl, and not the actual windows host ip.
    – Ryan Wood
    Commented Apr 7, 2022 at 17:07
  • You can still run your services on the host and the requests from inside WSL will get routed to them. Commented Apr 8, 2022 at 18:05
  • How would you access them? I'm assuming through host.docker.internal? That's docker desktop specific, and even when it's not (using the host-gateway workaround), then it'll look for services on WSL as the host for the daemon, not those running on windows.
    – Ryan Wood
    Commented Apr 11, 2022 at 23:38
  • You can access them through the IP directly. The dns entry is the hostname of the host. That IP exposes the services on the Windows host not WSL. This isn't related/specific to docker in anyway. Are you trying to access a service on the host from within a container? Commented Apr 12, 2022 at 12:15
  • I think you nailed the miscommunication. I'm talking about accessing the windows services from a container running on a wsl-hosted daemon. wsl requests will make it to the windows service, container requests will look for services on wsl is what I've encountered.
    – Ryan Wood
    Commented Apr 12, 2022 at 21:29
0

just use 127.0.0.1:<port> in WSL instead of hostname of Windows host - worked for me without adding firewall rules.

https://github.com/Microsoft/WSL/issues/1032#issuecomment-244160207:

Hi @netroby -- in WSL, actually there is no such thing as the "host" in the sense that you're referring to; it's all just Windows. Even your Linux environment is actually all running directly in Windows; it's just running with a wrapper library that makes it work. So, for example, if you have a service running on 127.0.0.1 on Windows, Linux programs should also connect to it at 127.0.0.1, on the same port. 0.0.0.0 is a special IP; it means "any IP address". So Linux processes can pick any IP address that's valid on the Windows host. ~aseering

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .