microsoft / WSL

Issues found on WSL
https://docs.microsoft.com/windows/wsl
MIT License
17.4k stars 819 forks source link

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

Closed bingzhangdai closed 5 months ago

bingzhangdai commented 4 years ago

Please fill out the below information:

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.

shaopu1225 commented 2 years ago
  1. In Powershell, use ipconfig command to find the IPV4 address in vEthernet (WSL).
  2. Add the normal proxy setting command in ~/.bashrc (e.g. export http_proxy="http://172.65.25.3:1080") for http & https using the address you found in the above step.
  3. source ~/.bashrc
  4. Close the current wsl terminal and open it again. curl www.google.com should work.

    In the ssr software, use Socks5(support UDP) & Allow connections from LAN.

kiot389 commented 2 years ago

What about setting up SSH Tunneling for this? i tried to solve this last year. i had to recompile the wsl distro, because i read it pulls down network settings for apt functionality

FossPrime commented 2 years ago

No one here seems to have brought this up... so I will:

In ChromeOS's version of WSL2 called Crostini, all listening ports are automatically forwarded to the host machine and accessible at localhost:1234 or example.localhost:1234. The battery efficient Android VM doesn't support that, but it has a stable IP address.

P.S. If I don't figure this out in the next 5 minutes I'm shifting my resources to dual booting Manjaro Gnome... for context I've used ChromeOS for development primarily on my Laptop and Ubuntu on desktop. My new laptop is too fancy for stock Manjaro linux... but I found the Kernel driver that I needed to use and OLED damage will be someone else's problem. The value proposition of Windows has been so negative, I might just erase it and dual boot SteamOS/Manjaro Gnome.

Update: While flashing Linux to a USB I remembered... some linux servers do work exactly as they do on ChromeOS's Crostini with automatic port forwarding.... so this looks like a configuration issue somewhere. Linux migration temporarily halted.

fadebowaley commented 2 years ago

I can confirm that migrating to WSL1 resolves the issue entirely. For a comparison of features, see https://docs.microsoft.com/en-us/windows/wsl/compare-versions

Notably, WSL1 outperforms WSL2 for Windows File access performance. While WSL2 has the "full Linux kernel", it lacks serial device support that works for WSL1. See the link for full details.

The conversion command where "Ubuntu-20.04" may be any from the list wsl.exe -l -v:

wsl.exe --set-version Ubuntu-20.04 1

manulep commented 2 years ago

Not wanting to switch to WSL1, I put my server in a docker container. It works for me.

TSOTSI1 commented 2 years ago

Come on WSL2, 2 years already! Do something please!

pkaushal-mdsol commented 2 years ago

The application running on WSL2 was unable to access API running on windows host at localhost:5001

This worked for me. 1) Run ipconfigon windows host terminal 2) Get the IPV4 Address from Ethernet adapter vEthernet (WSL) - Eg - 172.22.176.1 3) Replace localhost:5001 with 172.22.176.1:5001

Thanks to https://github.com/sakai135/wsl-vpnkit

githubkuyaya commented 2 years ago

Why is this taking so long, this can't be that hard to fix, can it? It's just annoying having to deal with stuff like this.

gpotter2 commented 2 years ago

On my end this happened because I was using the WSL Insider Preview from the store. Uninstalling it fixed the issue.

helgatheviking commented 2 years ago

@gpotter2 I just installed that here as well. Did uninstalling it remove any of the files you had saved in your linux subsystem?

gpotter2 commented 2 years ago

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

kiot389 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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. https://github.com/microsoft/WSL/issues/5211#issuecomment-706652801) Not a fix for the problem though, the issue is that one should be able to access it through localhost, not the IP.

bodinsamuel commented 2 years ago

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 commented 2 years ago

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

JuryA commented 1 year ago

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 commented 1 year ago

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;

  1. netsh with arguments interface portproxy reset to trigger 'On an event', Log 'Security' and Event ID '4647' (log off).
  2. 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'
  3. 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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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

MarcLongoria commented 1 year ago

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 commented 1 year ago

This was fixed in #4619

dons20 commented 1 year ago

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: 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].

seri0zha commented 12 months ago

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

MarcLongoria commented 12 months ago

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 commented 11 months ago

@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 commented 11 months ago

@dons20

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

derharry commented 10 months ago

@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 commented 9 months ago

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

mamlzy commented 5 months ago

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 commented 5 months ago

As mentioned by this comment: https://github.com/microsoft/WSL/issues/5211#issuecomment-1783883702 fixed by mirrored mode.