40

I have Windows 11 with WSL2 (Ubuntu) installed on it.

I've setup a gdb listener server on my Windows localhost and want to access it from Wsl2, but it seems my Windows machine and WSL are using different network adapters.

>ipconfig

Windows IP Configuration


Ethernet adapter vEthernet (Default Switch):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::1114:bb:d0ad:93f8%18
   IPv4 Address. . . . . . . . . . . : 172.29.192.1
   Subnet Mask . . . . . . . . . . . : 255.255.240.0
   Default Gateway . . . . . . . . . :

Ethernet adapter vEthernet (WSL):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::897:849a:5fed:1c6e%52
   IPv4 Address. . . . . . . . . . . : 172.21.128.1
   Subnet Mask . . . . . . . . . . . : 255.255.240.0
   Default Gateway . . . . . . . . . :

My server is actively listening on the 8888 port and is accessible on Windows but not on Ubuntu/WSL.

I've opened the 8888 port both from the Windows firewall and Ubuntu firewall

What is the solution?

1
  • The accepted answer is ubiquitous on the internet and probably works in most cases. However, it did not for me. I found a workaround for my own problem of accessing a server on the windows host from WSL2: I setup the server running on WSL2 instead, mounting the relevant host directories into the WSL, and became happy bidirectionally. Note, that it is no problem to access the WSL2 from the Windows host. Only WSL2 to host is difficult. This is no general answer but a workaround for some of those whose problem is not solved by the accepted answer. Aug 11, 2022 at 11:57

5 Answers 5

48

localhost doesn't work because WSL2 is running with a virtual network (vNIC) created by the Windows Virtual Machine Platform (a subset of Hyper-V). Inside WSL2, localhost is the address of the vNIC.

WSL2 does set up a virtual router on the Windows host to allow connectivity to both the outside world as well as the Windows host. You can see this via:

ip route

The "default via" address is the address to use for the Windows host.

You could parse it from the above, or from /etc/resolv.conf, but WSL also sets up a convenience mDNS, the .local domain, using the Windows "computer name", which is also used as the hostname of the WSL instance.

Accessing it is by concatenating $(hostname) with .local.

Try:

ping "$(hostname).local"

Or, if ICMP is blocked (seems so on new Windows 11 installs), use netcat. It's available by default in the WSL Ubuntu installation, but may need to be installed in other distributions like openSUSE:

nc -zv "$(hostname).local" <portnumber>

Reference: Access a localhost running in Windows from inside WSL2? answer by NotTheDr01ds.

8
  • 13
    That looks suspiciously like my Stack Overflow answer of a few days ago :-). Please remember to add a reference/attribution when copying/pasting from another answer. Oct 4, 2021 at 18:20
  • @NotTheDr01ds: Sorry, I forgot to add the reference. Feel free to add here your answer; let me know and I'll delete mine.
    – harrymc
    Oct 4, 2021 at 18:26
  • No worries - I just try to link people back to the original source so that they can upvote there as well. I don't ask for upvotes for the original source, but I hope folks will do so if they find it useful. Oct 4, 2021 at 18:27
  • Also, funny thing - You accidentally linked back to this answer (yours, here) instead of the SO one. I'll edit and fix. Oct 4, 2021 at 18:28
  • 1
    But yeah, as an aside, I don't usually ask for upvotes, but if you found my SO answer useful enough to copy/paste from, you could have at least thrown an upvote on it while you were at it! :-) Oct 4, 2021 at 18:29
5

"Localhost" always refers to system itself. When you're running a host OS and a virtualized OS, you're running 2 systems, both of which refer to themselves as "localhost". So you can never access "localhost" of another system, you need to use its external IP.

In your case if you want to access from the Ubuntu system a service that's running on your host Windows listening to port 8888, you have to access 172.29.192.1:8888. Only the system that's actually offering the service must listen to the port and allow new incoming connections through that port.

Because the Ubuntu is a separate system, you won't have anything there listening to port 8888 unless you install a service that listens to that port.

4
  • 3
    But won't that 172.29.192.1 address change every time you restart the computer? So if you bookmark a page under that 172.29.192.1:8888 address the bookmark will be broken each time the IP changes. How do you get around that?
    – luisdev
    Feb 16, 2022 at 6:03
  • Upvoted, but "never say never" ;-). As of release 2.0.0 of WSL2, localhost can now refer to the host Windows loopback from inside WSL2. Mar 15 at 16:49
  • @luisdev That is (was, at the time, at least) a good point. However, it should be noted that for the last year or so (maybe more) WSL2 attempts to always reuse the same IP address. Mar 15 at 16:50
  • Thx for the update @NotTheDr01ds :-) Interesting, need to look into that, can't even imagine how that's done without breaking the system... EDIT Checking below no wonder I've no clue - I've no idea about W11 :-D Apr 3 at 20:41
5

Further elaborating on the answer from @harrymc and @NotTheDr01ds:

Generally, you can contact Windows services from wsl2 command line using "$(hostname).local" as the host name. If such connections seem to be blocked, you can try the following:

  • Check whether Windows Firewall blocks the traffic. One easy check would be to turn it off for a few seconds and repeat the test. If that works, add appropriate Firewall rules.

  • Issue nslookup "$(hostname).local". This will give you a bunch of IPs. By default, the first one will be used, but that might not be the one which works. Try the other ones as well. If you find one that works, you can tailor a short script for your own system which will always return the correct IP.

2
  • 1
    "$(hostname).local" cannot be resolved. nslookup etc. does not give me any IP for this. (WSL2 on Win11)
    – Tino
    Jun 25, 2023 at 18:28
  • @Tino hostname is a standard Linux command, and $(...) is a standard way to include the result of an external command into a command line. You either use a shell which needs a different syntax, or the hostname command is not installed. Both should be easy to fix.
    – malamut
    Jul 2, 2023 at 8:50
2

Other answers have solved this by using "$(hostname).local".

However, for my case at least (Ubuntu 23.10 on WSL 2), running the command ping "$(hostname).local" errored:

ping: <myhostname.local: Name or service not known

I managed to fix this by installing libnss-mdns, letting the ping command run normally. (Run sudo apt install libnss-mdns to install on Ubuntu)

Source for the fix: https://github.com/microsoft/WSL/issues/10077#issuecomment-1736181588

0

As of the 2.0.0 release of WSL2, there are two good options for this (and several not-as-good). Copying from my Stack Overflow answer on the topic 1:

Short(ish) answers:

  1. NAT (default) WSL2 networking with mDNS

    Concatenating your WSL2 hostname (or the equivalent command/function in your programming/language environment) with ".local" (the host mDNS name) should 2 get you access. For example, in Bash try:

    ping "$(hostname).local"
    

    Or, let's say you are trying to access MongoDB from Python, as in this question:

    import socket
    server = f'{socket.gethostname()}.local'
    host = f'mongodb://{socket.gethostname()}.local'
    
  2. Mirrored Mode WSL2 Networking

    Note: Requires Windows 11 23H2 or later

    In Mirrored mode, localhost should "just work". To enable:

    • Add the following to your <windows_user_profile>/.wslconfig:

      [wsl2]
      networkingMode=mirrored
      
    • Exit your WSL distribution

    • Run wsl --shutdown from PowerShell then restart WSL

    You should then be able to access services running in Windows via localhost.

    Note that when running in Mirrored mode, mDNS will not work.

More explanation:

Option 1: NAT with mDNS

The default network mode of WSL2 is NAT'd behind a virtual Hyper-V switch. Up until recently, this was the only networking mode for WSL2. In this mode, WSL2 is running with a virtual network (vNIC) that is created by the Windows Virtual Machine Platform (a subset of Hyper-V). Inside WSL2, localhost is the address of the vNIC rather than that of the Windows host.

In this mode, using the mDNS name for the Windows host 3 is usually the easiest solution.

mDNS has been a feature of WSL2 for a while now. Concatenating your WSL2 hostname (or the equivalent command/function in your programming/language environment) with ".local" should get you access.

As mentioned above, from Bash, try:

ping "$(hostname).local"

For instance, if your hostname is "MyComputer", then the mDNS should be MyComputer.local.

If ICMP is blocked (as it seems to be on new Windows 11 installs), or if you want to test the connection to the actual port, then use netcat instead of ping. It's available by default in the WSL Ubuntu installation, but may need to be installed in other distributions like openSUSE:

nc -zv "$(hostname).local" <portnumber>

See also "Other NAT/mDNS considerations" 2.

Option 2: Mirrored Network Mode

Release 2.0.0 of WSL2 introduced a new Mirrored networking mode that can simplify many of the network access issues.

In this mode, the Windows network interfaces are mirrored into WSL2. When you run ip addr, for example, you'll see (mostly) the same interfaces as when you run ipconfig /all from PowerShell/CMD.

Because of this, localhost is routing through the mirrored Windows loopback adapter.


Footnotes:

2 Duplicated (and new) information

  • While I hate to duplicates part of the currently accepted answer, as noted, the currently accepted answer was based on my Stack Overflow version in the first place. In fairness, @harrymc did ask in the comments if I'd like to repost it here, but I declined at the time.

  • Over the years, though, I've added new information to the SO version of this which hasn't made it over to this SU question. Given the (now) massive changes mbade, I feel the information needs to be here as well.

  • The SO version is technically off-topic and currently closed there. This SU question is on-topic and should be the canonical question where new information on the topic is posted.


2 Other NAT/mDNS considerations

  • mDNS is reliant on the Windows host to resolve the name. If you have changed your /etc/resolv.conf under WSL, then this will likely not work.

  • Remember to open any necessary firewall ports. WSL2 is considered a separate network from that of the Windows host. Windows will consider network connections from WSL2 to be coming from an external source. (Credit to @RamilGilfanov for a comment pointing this out)

    The first time a connection is made from WSL2 to a particular port, Windows Defender (if that is your firewall) will typically display a dialog asking if you want to grant access. However, in my experience, this dialog often gets buried under the main window due to timing of mouse-clicks, keyboard, etc., so it's easy to miss.

  • Remember to have your Windows service accept connections from remote hosts.

    Many servers are configured by default to bind to localhost/127.0.0.1. Because WSL2 appears to Windows as a remote network, you'll typically need to update your configuration to bind to 0.0.0.0 or a specific address.

    Note that, since the address for WSL2 changes after each reboot, it can be difficult to update your configuration each time. If at all possible, use 0.0.0.0 unless there are security concerns. Since WSL is designed for development rather than production, this shouldn't be an issue.


3 Technically, this is the IP address of the virtual switch that WSL2 uses to interface with Windows and the outside world.

You can see this via:

ip route

This is the address you need to use for the Windows host.

You could, of course, parse it from the route (or, as in an earlier answer, from /etc/resolv.conf), but since WSL sets up the convenience mDNS (the .local domain) it's easier to just use that.

You must log in to answer this question.

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