43

After installing Ubuntu as WSL(Windows Subsystem for Linux) I've run:

root@teclast:~# python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 ...

and try to access to this web server from my windows machine http://0.0.0.0:8000 or http://192.168.1.178:8000 but no success, web server available only by the address http://127.0.0.1:8000 or http://localhost:8000 it means that I can't connect to this web server from another pc in my network. Is it possible to getting an access to WSL from outside?

Roman
  • 703
  • 1
  • 6
  • 11
  • 2
    Maybe [this](https://www.nextofwindows.com/allow-server-running-inside-wsl-to-be-accessible-outside-windows-10-host) can help you. – ErazerBrecht May 01 '18 at 20:51
  • Thanks for help but server still available through the localhost only. And no ability to connect from another PC to this server. – Roman Jul 14 '18 at 08:47

8 Answers8

21

None of the existing answers work for me, as WSL2 is running in its own VM and has its own network adapter. You need some sort of bridge or port forwarding for non-localhost requests to work (i.e. from another host on the same network).

I found a script in https://github.com/microsoft/WSL/issues/4150 that worked to resolve the issue:

$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';

if( $found ){
  $remoteport = $matches[0];
} else{
  echo "The Script Exited, the ip address of WSL 2 cannot be found";
  exit;
}

#[Ports]

#All the ports you want to forward separated by coma
$ports=@(80,443,10000,3000,5000);


#[Static ip]
#You can change the addr to your ip config to listen to a specific address
$addr='0.0.0.0';
$ports_a = $ports -join ",";


#Remove Firewall Exception Rules
iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' ";

#adding Exception Rules for inbound and outbound Rules
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $ports_a -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $ports_a -Action Allow -Protocol TCP";

for( $i = 0; $i -lt $ports.length; $i++ ){
  $port = $ports[$i];
  iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
  iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport";
}

Running this script from an elevated/admin Powershell session did the trick for me. This allows accessing the WSL2 service running on a port to be accessible from the Windows host IP at that same port.

mlibby
  • 6,106
  • 1
  • 29
  • 41
  • 2
    Worked really well for me -- make sure you have `ifconfig` installed on your WSL2 distro. This can also be added to Task Scheduler on login as `powershell -executionpolicy bypass -f path\to\script.ps1` with a delay of at least 10 seeconds to allow WSL2 to launch first (making your Linux instance available to fetch the machine's IP from). – Andy Merskin Jul 18 '21 at 20:51
  • It does not help :( Do I need to restart my computer after that or anything? – Alexey Mar 03 '22 at 11:51
18

In your VM, execute ifconfig

You will see your IP in the first section (eth0:) inet x.x.x.x

This x.x.x.x is the IP you have to put in your browser.

countach
  • 267
  • 4
  • 4
12

Please follow the steps mentioned in the link shared by @erazerbrecht and run your HTTP server by providing your ip address (instead of using localhost) and port number.

example:
root@teclast:~# python3 -m http.server -b 192.168.1.178 8000 Serving HTTP on 192.168.1.178 port 8000 (http://192.168.1.178 :8000/) ...

Otherwise you can also do this instead of following the link:
1. Goto Windows defender firewall
2. select inbound
3. create new rule; next
4. select Program as a rule type; next
5. select All Program; next
6. select allow the connection; next
7. check all 3 (Domain, Private, Public); next
8. provide rule a name
9. finish
10. Your are good to go

Toran Sahu
  • 131
  • 2
  • 5
  • 1
    These are the instructions Microsoft provides. Windows firewall is blocking connections exposed by WSL. – Drew May 29 '19 at 19:16
  • 1
    It does work. Ensure you replace IP with your local windows IP. Also while accessing the webpage use IP:PORT to access. – Guru Jul 29 '19 at 19:01
  • I can confirm that following all of these instructions does not work. For me viewing my IP at port 8000 shows the document tree of the Windows user profile directory in the browser. The Linux HTTP server does see and log the request however. – Sienile Oct 17 '19 at 21:30
  • 1
    Neither suggestion in this answer worked for me on WSL2. Service can't bind to the Windows IP address because WSL2 has its own network adapter. Same for the firewall. The ports were already working when running the service in Windows, so no use allowing them again. – mlibby Mar 31 '21 at 14:58
  • @mlibby Have you found the solution? – JohnyL Apr 03 '21 at 20:42
  • @JohnyL I found one solution, I posted it as an answer here. https://stackoverflow.com/a/66890232/13468 – mlibby Apr 06 '21 at 16:11
  • @mlibby Thank you for your effort. Actually, it was working from the start, but the https protocol error distracted me, and I thought that page isn't reachable. Anyway, thanks for answer!! – JohnyL Apr 06 '21 at 18:22
1

I followed the answer by @toran-sahu about adding an inbound rule to Windows Defender Firewall but recently (after adding a 2nd wsl2 instance) it stopped working again. I came across this issue thread and running the following in cmd prompt got it working again for me.

wsl --shutdown

update: it seems this issue comes from having Fast Startup enabled https://stackoverflow.com/a/66793101/8917310

momargoh
  • 66
  • 4
  • 1
    To be honest, this question probably wouldn't have been solved by the `wsl --shutdown`. When it's the Fast Startup issue, that makes even localhost forwarding break, so the original poster wouldn't have been able to the server via `localhost` in Windows. Since they say that worked, it's unlikely to be the issue you are thinking of. – NotTheDr01ds Jul 09 '21 at 21:58
  • `wsl --shutdown` by itself, without adding any firewall rules, actually worked for me. – 0x5453 Jan 01 '22 at 19:18
1

Similar to @countach 's answer:

If using Ubuntu type ip address in the WSL terminal. Look for the entry that says #: eth0 ... where # is some small number. There is an ip address there. Use that.

Adam V. Steele
  • 429
  • 2
  • 14
1

To anyone coming new to this post have a look at Microsoft doc https://docs.microsoft.com/en-us/windows/wsl/networking#accessing-linux-networking-apps-from-windows-localhost.

According to the docs if you are running an older version of Windows (Build 18945 or less), you will need to get the IP address of the Linux host VM

This should be a non-issue post the Windows Build 18945.

Hiten Rastogi
  • 102
  • 3
  • 15
0

For now (03.2022) to access from outside an app running on WSL 2, we need to do the following:

  • Make rules in the firewall for accepting incoming (and maybe also outgoing) connexions on the protocol and port on which the app is running (e.g. TCP/80)

  • Get WSL's vm IP: hostname -I

  • As said on this page (Accessing a WSL 2 distribution from your local area network (LAN)), use this IP address to add, in Windows, a proxy that listens on the port and redirects to WSL's vm. This is done by the following command in a PowerShell running as administrator:

netsh interface portproxy add v4tov4 listenport=80 listenaddress=0.0.0.0 connectport=80 connectaddress=192.168.101.100

Where 192.168.101.100 is vm's IP from hostname -I and 80 the port we want to open to the outside.

As WSL's IP changes when rebooted, this should be automated in a PowerShell script, where the previous proxy is removed and a new one is set to the current IP. All credit goes to Edwindijas on Github from who's script this one is heavily inspired:

$ports=@(80,21,22) # the ports you want to open
$addr='0.0.0.0';

$wslIP = bash.exe -c "hostname -I"
$found = $wslIP -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';

if(! $wslIP -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') {
  echo "WSL's IP cannot be found. Aborting";
  exit;
}

$portsStr = $ports -join ",";
iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' ";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $portsStr -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $portsStr -Action Allow -Protocol TCP";

for ($i = 0; $i -lt $ports.length; $i++) {
  $port = $ports[$i];
  iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
  iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$wslIP";
}
renardesque
  • 168
  • 9
-4

I've tested on Update for Microsoft Windows(KB4532132) with reinstalled WSL and it works as expected. Seems the issue was related to old windows version or old WSL version.

Roman
  • 703
  • 1
  • 6
  • 11