Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WSL2 cannot connect to localhost when the service is running on Windows #5211

Closed
bingzhangdai opened this issue May 14, 2020 · 86 comments
Closed
Labels

Comments

@bingzhangdai
Copy link

Please fill out the below information:

  • Your Windows build number: (Type ver at a Windows Command Prompt)
    Microsoft Windows [Version 10.0.19041.264]

  • What you're doing and what's happening: (Copy&paste the full set of specific command-line steps necessary to reproduce the behavior, and their output. Include screenshots if that helps demonstrate the problem.)
    I am using an HTTP proxy (ShadowSocks) on windows which is listening on localhost port 1080. Then, I want the command in WSL2 to go through that proxy.
    image

  • What's wrong / what should be happening instead:
    curl: (7) Failed to connect to 127.0.0.1 port 1080: Connection refused

  • Strace of the failing command, if applicable: (If some_command is failing, then run strace -o some_command.strace -f some_command some_args, and link the contents of some_command.strace in a gist here).

  • For WSL launch issues, please collect detailed logs.

In WSL1, all things are fine. In WSL2 I could connect to the HTTP proxy through my Windows IP. I believe it is caused by WSL2 running in a separate VM.

@bingzhangdai
Copy link
Author

To simplify the issue, I will show the telnet result, 172.21.80.1 is the Windows IP on WSL switch.
image

@nunix
Copy link

nunix commented May 14, 2020

hi,
the issue here is that while Windows can see the localhost ports of WSL, the inverse in not true by default.
The ports forwarding are from WSL to Windows. If you do a netstat -an | grep 1080 on WSL, it should return nothing.
However, when you pass it trough the Gateway (WSL switch), it will reach it.

Going forward, you can create a tunnel from Windows to WSL if you need/want to use localhost in your proxy (see: netsh interface portproxy command)

Hope this helps.
WSL Corsair

@bplasmeijer
Copy link

See also #5131
@nunix do you see this as default behavior with the portproxy on WSL?

@bingzhangdai
Copy link
Author

Thanks for the reply. I notice that many related issues are all about the network between the two systems. I can create a tunnel or proxy for this. But may I know if the WSL team has a specific plan or eta for the network improvement? Thanks.

@nunix
Copy link

nunix commented May 15, 2020

let's wait for Build (and here I really am like you, I'm waiting on news) and see if something will done.
@bplasmeijer I remember the SSH, actually right now, netsh is what I use for many of my demos.

still, I do agree with you that the "reverse forwarding" from Windows to WSL2 would be a great improvement

@bplasmeijer
Copy link

let's wait for Build (and here I really am like you, I'm waiting on news) and see if something will done.
@bplasmeijer I remember the SSH, actually right now, netsh is what I use for many of my demos.

still, I do agree with you that the "reverse forwarding" from Windows to WSL2 would be a great improvement

cc: @craigloewen-msft @benhillis @sirredbeard

@gencer
Copy link

gencer commented May 18, 2020

hi,
the issue here is that while Windows can see the localhost ports of WSL, the inverse in not true by default.
The ports forwarding are from WSL to Windows. If you do a netstat -an | grep 1080 on WSL, it should return nothing.
However, when you pass it trough the Gateway (WSL switch), it will reach it.

Going forward, you can create a tunnel from Windows to WSL if you need/want to use localhost in your proxy (see: netsh interface portproxy command)

Hope this helps.
WSL Corsair

@nunix can you give us an example? For example; I am trying to access 10134 port from WSL. 10134 port is on Windows assigned by Logitech Options application. I would like to access this port from inside WSL.

Is it possible to do with the portproxy? Currently my WSL IP is: 172.27.80.1

@eromoe
Copy link

eromoe commented May 19, 2020

same problem , we need to use proxy on windows localhost

@fatichar
Copy link

fatichar commented May 27, 2020

In my case, I am unable to connect to a service running on windows on ANY IP. Always the response is:

~/tcc/network-info$ telnet  172.17.0.1 5432
Trying 172.17.0.1...
telnet: Unable to connect to remote host: Connection refused

@eromoe
Copy link

eromoe commented May 28, 2020

@fatichar turn off your firewall , it cost me serveral hours to get it out . This is difinitely another big problem

@bingzhangdai
Copy link
Author

bingzhangdai commented May 28, 2020

Actually, what I am looking for is something even more about proxy between WSL2 and Windows. I am expecting similar experiences like WSL1, where WSL and Windows are using the same address (at least users should not be bothered if services on WSL and Windows are listening on different addresses) and follow the same firewall rules.

If the network is not unified, why not use VM directly and using Samba to share the filesystem? WSL1 provide grate convenience compared with VM. 🤔

Am I too greedy? 😂

@nunix
Copy link

nunix commented May 28, 2020

hi,
the issue here is that while Windows can see the localhost ports of WSL, the inverse in not true by default.
The ports forwarding are from WSL to Windows. If you do a netstat -an | grep 1080 on WSL, it should return nothing.
However, when you pass it trough the Gateway (WSL switch), it will reach it.
Going forward, you can create a tunnel from Windows to WSL if you need/want to use localhost in your proxy (see: netsh interface portproxy command)
Hope this helps.
WSL Corsair

@nunix can you give us an example? For example; I am trying to access 10134 port from WSL. 10134 port is on Windows assigned by Logitech Options application. I would like to access this port from inside WSL.

Is it possible to do with the portproxy? Currently my WSL IP is: 172.27.80.1

hi @gencer I would suppose it's possible indeed, but on powershell if you do a netstat -an, on which interface is port 10134 mapped?
if it's localhost, then WSL2 cannot reach it indeed, if it's bound to 0.0.0.0 then from WSL2 distro, try connecting to the :10134

Let me know the output of netstat and I will provide you the command

@gencer
Copy link

gencer commented May 28, 2020

@nunix, Unfortunately it binds on localhost as follow:

  TCP    127.0.0.1:10134        0.0.0.0:0              LISTENING
  TCP    127.0.0.1:10134        127.0.0.1:50456        ESTABLISHED
  TCP    127.0.0.1:10134        127.0.0.1:50833        ESTABLISHED
  TCP    127.0.0.1:10134        127.0.0.1:56123        ESTABLISHED
  ... and vice-versa
  TCP    127.0.0.1:56123        127.0.0.1:10134        ESTABLISHED
  TCP    127.0.0.1:50456        127.0.0.1:10134        ESTABLISHED

However, we make it work on SSH/WSL by making vscode extension runing on UI side. This makes us to access localhost port and data.

@djfos
Copy link

djfos commented Oct 11, 2020

you can access Windows port from WSL2 using your local IP like 192.168.31.66 instead of localhost, though is not elegant

@toryano0820
Copy link

I also have experienced this issue when accessing my Windows' Redis instance from my project running in WSL2. End up mapping Nameserver to localhost in /etc/hosts.

You can find Nameserver from /etc/resolv.conf, it looks like: nameserver 172.18.144.1
Then you can add line in /etc/hosts like: 172.18.144.1 localhost

Created a shell script to make life simpler: https://gist.github.com/toryano0820/6ee3bff2474cdf13e70d972da710996a

Not sure yet if there's a downside with this method. But it works!

@bsplosion
Copy link

This is a complete duplicate of #4619, and all details there are applicable here. For those not wanting to scroll through everything there, there doesn't seem to be any indication that WSL2 will go back to handling networking in a similar manner to WSL1. Your two options are 1: Put together some hacks and maybe it'll work, or 2: Revert to WSL1 and hope WSL2 maybe someday changes its approach back to that of WSL1.

@itsakt
Copy link

itsakt commented Nov 20, 2020

I was having similar issues. For me it's a hit or miss scenario. Sometimes it works sometimes it doesn't. I started webpack dev server (0.0.0.0:500) and accessed it through 127.0.0.1:500, usually browser will wait for bundles to load but today it loaded html page then just disconnected. Reloading no longer loads the page.

I had to disable my vpn before starting local server. After that turning on VPN seems to have no impact on server. I tried shutting down wsl instance (VPN still connected) and starting it again and everything seems to work fine. 🤔

@hasan-hasanov
Copy link

I can confirm that I can connect to the WSL2's localhost using VPN but are unable to do so when I am disconnected.

@troll-os
Copy link

troll-os commented Dec 3, 2020

I personally ended up running containers with the WSL2 integration for services that can run on Docker (Mongo for example)

@medmin
Copy link

medmin commented Dec 29, 2020

This is so frustrating

@pgwilliams
Copy link

When I upgraded my distro I started having all sorts of DNS problems (even with McAfee firewall turned off) and then today hit this issue of not being able to connect to a port of a process running in Windows from my Ubuntu command line.

I've reverted the distro to WSL 1: wsl.exe --set-version Ubuntu 1 and things seem to be back to normal now.

@DachuanZhao
Copy link

DachuanZhao commented Mar 12, 2021

@fatichar turn off your firewall , it cost me serveral hours to get it out . This is difinitely another big problem

It works . But I want to know why . I have added advanced rule in windows firewall , but it doesn't work .

@jorgeorpinel
Copy link

jorgeorpinel commented Mar 20, 2021

So you can't run SSH or any daemons (#994 (comment)) and you can't connect to servers run as Windows services (e.g. #3173). 😢

@spyro2000
Copy link

spyro2000 commented May 5, 2021

This is just a nightmare when doing software development. Was expecting to work this just out of the box after all those years. Can't believe it doesn't. Non-Windows-Users laughing at me. Again. Great job.

@gpotter2
Copy link

gpotter2 commented Aug 20, 2022

@helgatheviking It did not ! But maybe back it up to be safe, or make sure you have the normal version installed as well..

@kiot389
Copy link

kiot389 commented Aug 20, 2022

I found an old article about localhost and bind 0.0.0.0. I'm posting it in case it can lead anyone who's troubleshooting to something new. https://www.bleepingcomputer.com/news/security/wsl2-now-supports-localhost-connections-from-windows-10-apps/

@githubkuyaya
Copy link

I found an old article about localhost and bind 0.0.0.0. I'm posting it in case it can lead anyone who's troubleshooting to something new. https://www.bleepingcomputer.com/news/security/wsl2-now-supports-localhost-connections-from-windows-10-apps/

Thanks for the input. However, being able to access a listener/server started in WSL is not the problem, it's the other way around. You can't access servers started in Windows with WSL.
This here is what the issue is about:
image

@doctorchuks
Copy link

This Microsoft page helped solve the problem on my end

https://docs.microsoft.com/en-us/windows/wsl/networking

Check in the "Accessing Windows networking apps from Linux (host IP)" section

Works pretty fine👌

@githubkuyaya
Copy link

This Microsoft page helped solve the problem on my end

https://docs.microsoft.com/en-us/windows/wsl/networking

Check in the "Accessing Windows networking apps from Linux (host IP)" section

Works pretty fine👌

Yes, this was already mentioned in this thread a few times (e.g. #5211 (comment))
Not a fix for the problem though, the issue is that one should be able to access it through localhost, not the IP.

@bodinsamuel
Copy link

Did anyone got around "connection refused" issue even when using the nameserver ip?

I tried: disabled firewall, fast startup, allowed localhostForwarding, rebooted everything...
Still can't reach windows from WSL2 :(

cat /etc/resolv.conf
> nameserver 172.24.176.1

curl -XGET http://172.24.176.1:4040/inspect/http -I -v
*   Trying 172.24.176.1:4040...
* TCP_NODELAY set
* connect to 172.24.176.1 port 4040 failed: Connection refused
* Failed to connect to 172.24.176.1 port 4040: Connection refused
* Closing connection 0
curl: (7) Failed to connect to 172.24.176.1 port 4040: Connection refused

@kiot389
Copy link

kiot389 commented Sep 30, 2022

@bodinsamuel does your windows host use a proxy lan setting or .pac script? if so, any recent changes?

@JuryA
Copy link

JuryA commented Oct 29, 2022

I also need some kind of localhost proxy from WSL2 to Windows host - in case I want to execute Windows binaries (that´s why WSL to Windows Interop exists), I cannot use IP Address. For example, if I Packer starts VirtualBox VM with port forwarding, it works until the moment when starts waiting for localhost:port. Boom! It ends in a never-ending loop...

Better solution would be to utilize some kind of proxy - not workaround which is useless. No offense. All threads around the WEB repeats the same: “You cannot use localhost - you have to use IP address of the host!” Well... so what to solve it with “some kind” of iptables hack and redirect traffic to localhost (for specific ports of course - maybe higher than 1024? To avoid problems with accessing WSL’s own localhost)?

UPDATE
My proposal - will test later (I'm on phone now) - is to use socat:

socat tcp-listen:{port},bind=127.0.0.1,fork tcp:{ip of windows host}:{port}

@lalilaloe
Copy link

lalilaloe commented Jan 25, 2023

I basically avoided this issue by using WSL1 for the past years, but I found a solution that works for me; If you don't encounter this issue often just use $(hostname).local 😒

TLDR; This changes localhost to point to your Windows IP, 127.0.0.1 is still available for wsl. In windows you can access WSL via localhost as usual, because windows listens for exposed ports on WSL. Exposes your set windows port(s) via portproxies.

  1. Add this to your /etc/wsl.conf,
[boot]
command="sed -i \"s/127.0.0.1$(printf '\t')localhost/$(tail -1 /etc/resolv.conf | cut -d' ' -f2)$(printf '\t')localhost/g\" /etc/hosts 2>&1"

This command replaces the default localhost in /etc/hosts to point to your Windows IP, 127.0.0.1 is still available for wsl. This might require setting the host in your code to 127.0.0.1 for example in vite add server: { host: "127.0.0.1" } . Services running on Windows might need to be bind to 0.0.0.0 or it's local ip to be accessible in WSL.
From windows you can access WSL via localhost as usual, because windows listens for exposed ports on WSL.

  1. a. And use this powershell script to configure portproxies fix-wsl2-port-forwading-to-windows-localhost. The firewall rules, might not be necessary but can be helpful if you encounter issues.

    b. While the above script also helps you set the firewall rules. You can also execute the following command to set the portproxies manually in (admin) Powershell. In this example ports 8080,27017. (credits above)

$addr='0.0.0.0'; $ports=@(8080,27017); # set ports according to your use case, what ports from windows should be exposed.
$remoteport = (wsl hostname -I).Trim(); for( $i = 0; $i -lt $ports.length; $i++ ){ $port = $ports[$i]; echo "added portproxy ${addr}:${port} to ${remoteport}:${port}"; iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr"; iex "netsh interface portproxy add    v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport"; }

You can reset these proxies anytime using netsh interface portproxy reset

Because the WSL2 ip address changes every restart you need to add two scheduled tasks;
3. netsh with arguments interface portproxy reset to trigger 'On an event', Log 'Security' and Event ID '4647' (log off).
4. The above powershell command, you can save it to a .ps1 file and execute with powershell with arguments c:\path_to_script.ps1 to trigger 'At log on'
5. You can test the automated scheduled tasks manually, by simulating a restart using wsl --shutdown you'll see the ip has changed wsl.exe hostname -I.

This for me solves many of the main issues why I didn't switch, it's not the same as using WSL1. But does the job since you don't have to change localhost host configurations for any of your projects. Which is frustrating when using WSL2. Bonus you can enjoy the latest features such as WSLg and better performance 😀.

@korneel
Copy link

korneel commented Jan 30, 2023

As a workaround, I added the following to my .zshenv file to set the IP address of the Windows host to an environment variable:

if [[ -n "$IS_WSL" || -n "$WSL_DISTRO_NAME" ]]; then
  if [[ -z "$WINDOWS_HOST_IP_ADDRESS" ]]; then
    export WINDOWS_HOST_IP_ADDRESS="$(powershell.exe -Command '(Get-NetIPConfiguration | Where-Object { $_.IPv4DefaultGateway -ne $null -and $_.NetAdapter.Status -ne "Disconnected"}).IPv4Address.IPAddress' | tr -d '\r')"
  fi
fi

This way I can use the WINDOWS_HOST_IP_ADDRESS environment variable to proxy requests from WSL2 to the Windows host. For example, I run the Vite development server in WSL and proxy API requests to a .NET web application running on the Windows host.

@osmial
Copy link

osmial commented Feb 14, 2023

Had the same issue, mentioned workarounds relying only on IPs from /etc/resolv.conf or /etc/hosts are close but not enough, at least for me. Anyone who have this problem should try finding correct IP, for me it was one of those printed by nslookup $(hostname).

@refond
Copy link

refond commented May 22, 2023

For my use case, testing Akka HTTP micro framework, disabling IPv6 in Ubuntu Linux WSL2 allowed seamless access to URL such as http://localhost:8888/
See instructions at: https://itsfoss.com/disable-ipv6-ubuntu-linux/

@mfwhatever
Copy link

mfwhatever commented Aug 1, 2023

Posting my solution to a similar (although possibly reverse) problem.

I was trying to find a way to access RStudio Server (running on WSL2 Ubuntu) from another computer on my local network. RStudio Server is accessible on the Windows Host at localhost:8787. I needed to do both of these:

  1. Create an inbound rule on Windows Defender Firewall for port 8787

  2. Create a forwarding rule for incoming connections to port 8787 to be directed to localhost
    Adapted from here. The guide suggests forwarding to the local windows address for the WSL2 VM (wsl hostname -i), which may be the right thing for other people, but in my case RStudio Server is already forwarded to localhost:8787, so that didn't work. I used 127.0.0.1 instead and now it works.

@pwang2
Copy link

pwang2 commented Aug 9, 2023

This is a frustrating topic. Exposing all the interfaces from windows via 0.0.0.0 is INSECURE. it would be great and makes most sense to just keep it behave the same as a loopback interface in WSL..

@ludobegins
Copy link

That moment when you scroll the whole thread since 2020 hoping at this point someone would have a good fix but nope 😂😕

@MarcLongoria
Copy link

That moment when you scroll the whole thread since 2020 hoping at this point someone would have a good fix but nope 😂😕

No joke. I've been following this thread since it was opened, hoping someone far more intelligent than me would have solved this by now. Yet here we are lol

@obedm503
Copy link

obedm503 commented Oct 27, 2023

This was fixed in #4619

@dons20
Copy link

dons20 commented Oct 28, 2023

Update since Major Version 2.0.9

For step 2, you can just do wsl --update only, no need to do the pre-release anymore.


Original

@obedm503 Thanks for pointing it out. Would have never known it was actually being addressed all this time.

Had to take a few steps to get it working on my local environment. Just thought I'd share. The changes are on a pre-release of WSL so it won't be available through regular update paths.

  1. Update Windows to at least the October 10th build. See more info here: [WSL 2] WSL 2 cannot access windows service via localhost:port #4619 (comment)
  2. Update your WSL to the latest pre-release by running this in CMD or Powershell wsl --update; wsl --update --pre-release. You can view the changes of the pre-release versions here: https://github.com/microsoft/WSL/releases
  3. Update (or create) your .wslconfig file which is located at %USERPROFILE% in explorer. Add the following:
    [wsl2]
    networkingMode=mirrored # add this line if file already exists
    
  4. (Optional) Shutdown and restart your WSL (after a few seconds) so that the config changes apply.

Since getting it enabled, I haven't had a single issue with my localhost being inaccessible. I could safely enable IPV6 again too.

Side note, pre-release v2.0.5 https://github.com/microsoft/WSL/releases/tag/2.0.5 moved the networkingMode setting from [experimental] to [wsl2].

@seri0zha
Copy link

@dons20 thank you so much, it works fine for me. I have spent a lot of time trying to resolve this problem

@MarcLongoria
Copy link

Awesome to hear! The release mentions it's a window 11 fix. Anyone on Windows 10 to confirm it works for them as well?

@Jacksonmills
Copy link

@obedm503 Thanks for pointing it out. Would have never known it was actually being addressed all this time.

Had to take a few steps to get it working on my local environment. Just thought I'd share. The changes are on a pre-release of WSL so it won't be available through regular update paths.

1. Update Windows to at least the October 10th build. See more info here: [[WSL 2] WSL 2 cannot access windows service via localhost:port #4619 (comment)](https://github.com/microsoft/WSL/issues/4619#issuecomment-1778054020)

2. Update your WSL to the latest pre-release by running this in CMD or Powershell `wsl --update; wsl --update --pre-release`. You can view the changes of the pre-release versions here: https://github.com/microsoft/WSL/releases

3. Update (or create) your `.wslconfig` file which is located at `%USERPROFILE%` in explorer. Add the following:
   ```
   [wsl2]
   networkingMode=mirrored # add this line if file already exists
   ```

4. (Optional) Shutdown and restart your WSL (after a few seconds) so that the config changes apply.

Since getting it enabled, I haven't had a single issue with my localhost being inaccessible. I could safely enable IPV6 again too.

Side note, pre-release v2.0.5 https://github.com/microsoft/WSL/releases/tag/2.0.5 moved the networkingMode setting from [experimental] to [wsl2].

This worked for me!

@teapot2
Copy link

teapot2 commented Nov 16, 2023

@dons20

This worked for me too on Windows 11. Thank you!

@derharry
Copy link

@dons20 Thanks! Works for me on W11.

This issue, WSL cannot connect to remote localhost, on my side had to do when the connected WiFi or LAN was set to "public network". On "private network" everything was fine.
With this fix WSL also connects to localhost while in public network. :-)

@Vividious
Copy link

@dons20 cheers mate!
For real, over a year of struggle

@mamlzy
Copy link

mamlzy commented May 11, 2024

Update since Major Version 2.0.9

For step 2, you can just do wsl --update only, no need to do the pre-release anymore.

Original

@obedm503 Thanks for pointing it out. Would have never known it was actually being addressed all this time.

Had to take a few steps to get it working on my local environment. Just thought I'd share. The changes are on a pre-release of WSL so it won't be available through regular update paths.

  1. Update Windows to at least the October 10th build. See more info here: [WSL 2] WSL 2 cannot access windows service via localhost:port #4619 (comment)
  2. Update your WSL to the latest pre-release by running this in CMD or Powershell wsl --update; wsl --update --pre-release. You can view the changes of the pre-release versions here: https://github.com/microsoft/WSL/releases
  3. Update (or create) your .wslconfig file which is located at %USERPROFILE% in explorer. Add the following:
    [wsl2]
    networkingMode=mirrored # add this line if file already exists
    
  4. (Optional) Shutdown and restart your WSL (after a few seconds) so that the config changes apply.

Since getting it enabled, I haven't had a single issue with my localhost being inaccessible. I could safely enable IPV6 again too.

Side note, pre-release v2.0.5 https://github.com/microsoft/WSL/releases/tag/2.0.5 moved the networkingMode setting from [experimental] to [wsl2].

Works! thank you so much!

@ghost
Copy link

ghost commented May 28, 2024

As mentioned by this comment: #5211 (comment) fixed by mirrored mode.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests