Search code examples
node.jswindows-subsystem-for-linuxwsl-2

How can you make a node server running on WSL2 forward over LAN so that it can be accessed by a phone?


I've tried the following:

https://www.youtube.com/watch?v=yCK3easuYm4

https://medium.com/codemonday/access-wsl-localhost-from-lan-for-mobile-testing-8635697f008

https://superuser.com/questions/1679757/how-to-access-windows-localhost-from-wsl2

https://superuser.com/questions/1131874/how-to-access-localhost-of-linux-subsystem-from-windows

https://superuser.com/questions/1732399/cannot-communicate-with-windows-localhost-from-wsl2

https://superuser.com/questions/1594420/cant-access-127-0-0-180-outside-of-wsl2-ubuntu-20-04

https://www.reddit.com/r/vscode/comments/11bp9oo/how_do_i_access_live_server_from_phone_i_tried/

https://www.reddit.com/r/bashonubuntuonwindows/comments/m1eb49/cant_access_web_server_from_wsl2_on_my_home/

https://learn.microsoft.com/en-us/windows/wsl/networking#accessing-a-wsl-2-distribution-from-your-local-area-network-lan

They all share a common procedure:

  • Create firewall exceptions for relevant ports
  • in Admin PowerShell run: netsh interface portproxy add v4tov4 listenport=3001 listenaddress=0.0.0.0 connectport=3001 connectaddress=(wsl hostname -I)
  • Find windows IPv4 address in PowerShell with ipconfig
  • on mobile phone, connect to same wifi network
  • go to <windows_IPv4_address>:3001
  • For good measure, in the Node.js Express app, I run:
server.listen(PORT, '0.0.0.0', ()=> {
    console.log(`⚡️ listening on ${PORT}`);
})

What happens:

  • Accessing <windows_IPv4_address>:3001, localhost:3001, 0.0.0.0:3001 and 127.0.0.1 on my phone times out
  • Can only view as localhost on local computer, not 0.0.0.0 or 127.0.0.1 despite setting '0.0.0.0' as a parameter to server.listen

So these instructions don't work. I am wondering if the advice is maybe outdated, I am not sure what I'm missing. I wish to access wsl2 localhost from LAN to test on mobile. Thanks


Solution

  • If localhost works (from the PC itself) and 127.0.0.1 and the hosts own IP address (eg. 192.168.1.110) does not - then something basic is wrong, and should be troubleshooted first. Here is a screenshot of a simple python http.server running and listening on 0.0.0.0 inside WSL:

    sample IPs

    0.0.0.0 is a placeholder and basically means "any IP address that the server has". As has been stated in the comments, the WSL is essentially a container inside the computer, which also means that the host computer may have an IP hidden from you which is the one it communicates with the container on.
    Setting 0.0.0.0 inside the WSL container does NOT mean that ANY ip address the host PC has will forward traffic to WSL You will need to add something to the configuration, so that the host computer will forward traffic on its external IP to the WSL container.

    Just as an example, here is a screenshot of the same windows as above, but the exact same command is run on the host pc: Host http

    Note that this time the external IP 192.168.1.110 responds with the same response as localhost and 127.0.0.1.

    Reading on https://jwstanly.com/blog/article/Port+Forwarding+WSL+2+to+Your+LAN/ you have to do some port forwarding.

    In your WSL2 execute ip addr and copy that (not for lo). In my case it was 172.20.204.41.

    On your host PC open an administrative powershell window and execute netsh interface portproxy add v4tov4 listenport=3001 listenaddress=0.0.0.0 connectport=3001 connectaddress=172.20.204.41
    in that same PS console, execute netsh interface portproxy show v4tov4 to verify your change.

    Working working on phone

    If it doesn't work, you have to open the port in your firewall.

    In the PS window on the Host execute New-NetFirewallRule -DisplayName "WSL2 Port Bridge" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 3001

    This will open the port in your Windows Defender firewall: firewal screenshot

    Note all my screenshots are with port 8000 because I didn't want to spend too much time on this - but all the commands are with the port in your question (3001).