52

I am running a local AEM server in my Windows machine. The server is running on localhost:4502. I am using a Ubuntu distribution running in WSL 2 for my development. I want to access the localhost:4502 running in the Windows machine in my WSL 2 Ubuntu.

Is there a way to do that or is it not possible?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ganesh A.S
  • 639
  • 1
  • 5
  • 5
  • 1
    Your Windows's machine IP plus the 4502 should be enough, though you would like to check that the firewall is allowing the connection, – ronnyfm Nov 10 '20 at 12:12
  • 1
    No this is completely wrong!, I have this problem too and your answer is wrong unfortunately. I try ssh -p and the connection is immediately and always refused ! any other ideas? – SheppLogan Jul 14 '21 at 15:31
  • 1
    Please do the following steps: 1. Get IP of window by run command line on WSL Ubuntu: cat /etc/resolv.conf. It will show "nameserver ". 2. Turn of the Firewall on the Windows. 3. Connect to your windows host. – Hieu.Gi Jul 24 '22 at 10:13
  • For me, was solved after execute in PowerShell: netsh interface portproxy add v4tov4 listenport=4000 listenaddress=0.0.0.0 connectport=4000 connectaddress=192.168.101.100 .... connectaddress = nameserver in resolv.conf – dmotta Dec 29 '22 at 02:12

7 Answers7

106

Short answer for most recent Windows versions

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.

For example, 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. 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>

Why localhost doesn't work

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.

What you need

WSL2 also sets 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

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 WSL sets up a convenience mDNS (the .local domain) using the Windows "computer name", which is also used as the hostname of the WSL instance.

So concatenating $(hostname) (or it's equivalent in your programming/language environment) with ".local" should get you access.

Other 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.

NotTheDr01ds
  • 15,620
  • 5
  • 44
  • 70
  • Excellent! Why isn't this marked as the answer? You can wrap this idea with a convenient script which you call, instead of curl directly. – automorphic Apr 15 '22 at 22:41
  • 1
    and open ports in windows firewall – Ramil Gilfanov Jul 04 '22 at 21:37
  • @RamilGilfanov Great point! I've edited that into the answer. – NotTheDr01ds Jul 08 '22 at 20:28
  • 2
    I am able to ping windows host IP but still unable to access any opened port on windows from WSL2 (firewall closed), do you have any insights? Thanks! – nonemaw Aug 19 '22 at 10:29
  • @nonemaw I'll probably need more info. If you'd like, open a [Super User](https://superuser.com) question on it with more detail (commands, ports, firewall rules, whatever you can think of), and I can take a look. I'm a little bit unclear on what you mean by the *"opened port / (firewall closed)"* part. – NotTheDr01ds Aug 19 '22 at 19:22
  • Hi @NotTheDr01ds, I have posted a question: https://superuser.com/questions/1738265/wsl2-ubuntu-can-access-host-ip-but-is-unable-to-access-host-port, would you mind if you can take a look? Thanks! – nonemaw Aug 22 '22 at 04:35
  • What if you wanted to reach some other address within the `127.0.0.0/8` range? – leo Apr 27 '23 at 23:35
  • @leo Can you provide more details on your use-case (possibly with a new Super User question)? The simple answer is that the entire loopback subnet in *Windows* isn't accessible from *WSL2*. That's why we need the mDNS address. – NotTheDr01ds Apr 28 '23 at 01:09
  • Got an app that securely connects to some servers via ssh. When the connection is established, in the PC running said app, you ssh to an address in that space. So I wanted to ssh from WSL to one of those. I can set up an ssh server in the Windows host that runs the app, then make an ssh tunnel as a workaround. – leo Apr 28 '23 at 01:22
  • 1
    @leo Agreed - that's my typically recommendation. Having that SSH server in Windows makes a lot of WSL2 tasks easier. See [my jumphost answer here](https://superuser.com/a/1764213/1210833) for details. I've used it in quite a few other answers as well. – NotTheDr01ds Apr 28 '23 at 13:01
  • None of the top 2 answers work for me. In this answer, I got the hostname and filled it in both `nc -zv "$(hostname).local" ` and `ping "$(hostname).local"`. Both just hang. Maybe I should hang as well. – Bob the Builder Jul 19 '23 at 00:23
  • @BobtheBuilder It could be the firewall issue that RamilGilfanov pointed out. Are you sure the firewall rule got created on first access as mentioned in the answer? – NotTheDr01ds Jul 19 '23 at 00:58
  • @NotTheDr01ds I had made a rule in windows firewall that allows connections from port 4502. I also made another rule that allows ports from a range starting from and ending to a range I cannot recall at the moment, another post said these were possible ports WSL could connect from. No banana. – Bob the Builder Jul 20 '23 at 02:55
  • @BobtheBuilder You might want to post a new question on Super User (or Ask Ubuntu, if you are using Ubuntu). Reference this one, but add any specifics on what you've tried. I'll try to take a look at it. Thanks! – NotTheDr01ds Jul 20 '23 at 10:39
12

I was also looking for some solution to do this, but currently there isn't any such option available. Check out this GitHub issue:

[WSL 2] WSL 2 cannot access Windows service via localhost:port #4619

One solution can be this:

If you have the IP address of the Windows (host) then it will do the job, but the only problem is that the IP address will change every time. But, WSL 2 stores your Windows (host) IP address in the /etc/resolv.conf file. So we can modify our etc/hosts file to map winhost to the IP address dynamically.

Add the following lines at the end of the ~/.bashrc file file. This will grep the IP address and modify the etc/hosts file when you boot the WSL.

export winhost=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }')
if [ ! -n "$(grep -P "[[:space:]]winhost" /etc/hosts)" ]; then
        printf "%s\t%s\n" "$winhost" "winhost" | sudo tee -a "/etc/hosts"
fi

Then run the following command to reload the changes.

source ~/.bashrc

Now you can use winhost instead of localhost in WSL 2 (client) to access the servers running Windows (host). In your case, it will be winhost:4502, but this will work for any other use cases as well like accessing a PostgreSQL or MySQL server running on Windows, etc.

Note: Always remember to configure your firewall on Windows to allow those ports, so that WSL 2 can access it. Otherwise, your connection may get blocked by the firewall.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tarun Kumar
  • 346
  • 3
  • 8
  • 1
    Hello, I have this problem too and your answer is wrong unfortunately. I try ssh -p and the connection is immediately and always refused ! Any other ideas? – SheppLogan Jul 14 '21 at 15:30
  • @SheppLogan I am not sure what you are trying to achive. Can you elaborate more? – Tarun Kumar Jul 15 '21 at 10:32
  • 1
    This is the accepted answer but it implies that the service is not listening on localhost, but on 0.0.0.0 with a firewall... – Andrea Ratto Sep 23 '21 at 12:34
5

This is simple; you just need to do two things. Set the IP address to localhost in the hosts file and allow Windows Firewall to allow incoming connections.

Here are step-by-step instructions:

  1. Get the IP address. Open cmd.exe and type ipconfig /all. Note down the IP address 172.22.16.1

    image

  2. Open Notepad as administrator, menu Fileopen, browse to C:\Windows\System32\drivers\etc\hosts, add the line 172.22.16.1 localhost, save and close.

  3. The last option is to allow Firewall rules to accept public connections. For this, open Control Panel* → System and SecurityWindows Defender FirewallAdvanced SettingsInbound RulesNew Rule

  4. Rule Type: choose Port and click Next

  5. Protocol and Ports: type Specific local port: 4502, and click Next

  6. Action: Allow the connection and click Next

  7. Profile: check Public and click Next

  8. Name: type AEM server and click Finish

  9. Close other windows, and again open cmd. Type wsl --shutdown for shutting down the Ubuntu subsystem.

  10. Open Ubuntu again.

  11. Testing connection: type curl localhost:4502 in command prompt. If it returns something, it means you are good to go.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sorabh86
  • 457
  • 4
  • 17
  • 1
    wanted to add if it doesn't return something you can also be good to go -- just so long as it doesn't hang or give a message about connection refused. I had a test service that was just logging get requests but not returning anything :) – howard Jul 17 '23 at 06:54
  • @howard by not hanging you mean it should return and let you type another command? does not work for me then :( – Bob the Builder Jul 17 '23 at 19:54
  • @sorabh86 Isn't making port 4502 public a security risk? – Bob the Builder Jul 17 '23 at 19:58
  • @BobtheBuilder correct – howard Jul 18 '23 at 05:58
  • @BobtheBuilder - What kind of Security risk? sniffing attack or data breach? opening port is not always a security risk, we had allowed our hosted OS to access with a virtual private network created to access a virtual OS. I don't think there is any security risk. – sorabh86 Jul 19 '23 at 07:29
  • @sorabh86 Nvm chatgpt explained it. A local port isn't accessible to the internet unless we configure a port on our router to forward traffic to the port on our computer. Afaik. – Bob the Builder Jul 20 '23 at 02:47
  • @BobtheBuilder yes, you can't access private network outside of local network, if you want then setup apache, nginx server and write port forwarding. ChatGPT can give you the steps as well if you want that. Actually those are just few lines of configuration and restart. – sorabh86 Jul 20 '23 at 12:07
2

You need add an IPv6 rule in the hosts file.

Like:

127.0.0.1 example.com
::1 example.com localhost

I had a similar problem and found the solution at the page WSL 2 Linux host cannot be accessed by a custom domain name or 127.0.0.1 #5728.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
-2

The easy way:

On the Ubuntu command line, type:

ip route

Output:

default via 172.23.96.1 dev eth0
172.23.96.0/20 dev eth0 proto kernel scope link src 172.23.97.122

In your application, configure the host to: 172.23.97.122

Now you can access it using Windows Browser.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 3
    Hello and Welcome to Stack Overflow. Just a heads-up that I already covered the `ip route` command as an option to get the IP address in my existing answer. Duplicate answers should be avoided, so please make sure to read the existing answers before writing a new one. Also note that this IP address changes each time you restart WSL (or your computer), so it's not "the easy way", unfortunately. As I mentioned in my answer, it's best to use the mDNS name, since that will always resolve to the correct address (as long as mDNS is enabled). – NotTheDr01ds Nov 22 '21 at 19:59
  • What is "Windows Browser"? [File Explorer](https://en.wikipedia.org/wiki/File_Explorer)? – Peter Mortensen Jul 20 '23 at 15:09
-4

Windows 10 considers localhost as ::1. Ubuntu considers localhost as 127.0.0.1.

So solution is to create a mapping. Create a file called *.wslconfig* in C:\Users\<your_username>\.wslconfig.

Add the following to it.

[wsl2]
localhostForwarding=true

PS: I don’t know if it messes up anything else, but it helped me run Django servers which were broken after upgrading to WSL 2.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vipin Mohan
  • 1,631
  • 1
  • 12
  • 22
  • 1
    `localhostForwarding` should already [default to `true`](https://learn.microsoft.com/en-us/windows/wsl/wsl-config#wsl-2-settings) on WSL2, but sometimes it seems to break down, and I haven't been able to identify a cause. Usually just doing a `wsl --shutdown` and restarting the session will restore it for most people. – NotTheDr01ds Jan 27 '21 at 00:56
  • 3
    This answer really needs at least one correction. ::1 vs 127.0.0.1 has absolutely nothing to do with Windows 10 vs. Ubuntu. Windows 10 understands 127.0.0.1 just fine, and Ubuntu understands ::1 just fine, too. The real difference is that ::1 is the IPv6 address, and 127.0.0.1 (or any IP address starting with 127, really) is IPv4. – Kevin Keane Apr 24 '21 at 20:05
  • so please do explain exactly why this fixed my issue? because as far i'm concerned it fixed the issue. and apparently for the users as well. – Vipin Mohan Apr 26 '21 at 06:44
  • 8
    From microsoft doc, `localhostForwarding` means "ports bound to localhost in the WSL 2 VM should be connectable from the host" but **not** "ports bound to localhost in the host should be connectable from the WSL 2 VM", so this answer won't work. – ayanamist Jun 22 '21 at 03:40
-5

I suspect you could do this.

  1. Step 1. Run your AEM server on your actual IP address (or all addresses) instead of binding to just localhost.

  2. Step 2. Your Ubuntu WSL client instance won't share localhost with the host machine, but it will share the local IP address your machine actually has (e.g. 10.0.0.2). Just have your client connect to that IP address instead of localhost.

  3. I don't know anything about AEM, but you might need to secure it if you are exposing it to a larger network. Block port 4502 on the upstream firewall or use a Windows Firewall rule to only allow incoming on port 4502 from your own IP address. This certainly appears possible.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
selbie
  • 100,020
  • 15
  • 103
  • 173