Has anyone used WSL2 and connected to the host machine using its actual IP instead of through the WSL2 Network Adapter IP?
My situation is this:
My ip is 192.168.1.2
I start a webserver on my actual machine, it binds to 127.0.0.1, and 192.168.1.2
I want do connect to the webserver from within a docker container under WSL2.
If I ping/telnet/curl to 192.168.1.2 the call simply fails from a timeout, this happens both from my docker container as well as straight from within ubuntu under WSL2
I have verified that I can ping my router at 192.168.1.1 from within my docker container.
I cannot access 192.168.1.2 from within my WSL2 shell outside of docker.
I cannot use 127.0.0.1 as a replacement, as the end goal is to run a setup of docker inside WSL2, that calls the webserver on my machine (i.e. I want to start up 4 services and a database through docker, and then actively develop and debug a 5 service on my actual machine).
I’ve tried disabling the firewall completely to no avail.
Does anyone have an idea of what it could be?
Or if I’m even supposed to be able to access 192.168.1.2 from within WSL2.
2
Answers
A few different ways (and things you might have to do) to make this work. You may have some of this in place already:
First, as mentioned in the comments, the best name to use (in most cases) from WSL2 when accessing a service running Windows is the mDNS format
$(hostname).local
(or the equivalent from whatever language you are using). This can be hardcoded as simply the Windows "Computer Name" + (concatenated with).local
.Next, remember that the first time you try to access a network service on a port, Windows Defender Firewall will ask you for permission to create a rule. By default, this rule only applies to Private network profiles. As a result, a corresponding Block rule is created for the port on any Public network profile. I honestly just discovered this when trying this out. I don’t think I knew that a corresponding Block was generated by that GUI dialog.
Since WSL’s network is (oddly) considered Public, you’ll need to delete that Block rule if it exists.
You’ll then also need to open an Allow rule for the port from WSL. Something like:
This will open the port on both Public and Private networks, but only on the WSL virtual interface. It will still be blocked from other machines on the network (assuming that’s what you want).
Now for the bind address, you have several options:
If you really do want to bind only to the WSL virtual network, then you’ll need to either obtain (or parse somehow) the correct address, since it will after each reboot (or
wsl --shutdown
). You can see the correct address withipconfig
in PowerShell, and look for:In this case, the bind address would be
172.25.208.1
.Alternatively, I don’t believe there’s much of a reason not to just bind to
0.0.0.0
(all interfaces), since the firewall is going to block connections from other networks (assuming you specified the-InterfaceAlias "vEthernet (WSL)"
).However, from the comments, you also mention:
If you really can’t change the bind address to something else, then you won’t be able to access it directly from WSL2. However, it’s still possible to use port forwarding to get the packets to the right interface, if that’s the case.
The easiest way to do this is to install/enable the Windows OpenSSH server, and then use something like:
That will make
localhost:80
in WSL2 connect to the Windows service on port 80.If you need the server name to match some virtual host name (SNI), then you can add the hostname to your Windows host file (which is mapped into WSL2 by default) as a pointer to localhost.
In my case, when the Windows host was connected to a VPN, the only chance to connect to the host from within WSL2 was to use the external VPN IP.
From within WSL2, I got it with:
(in my case, ipconfig outputs the VPN address always first)