WSL Port Forwarding
Published: 2020-07-15 12:26:17

When you start a server in WSL, both Windows and Linux share the same local host. When using a WSL 1 distribution, if your computer was set up to be accessed by your LAN, then applications running in WSL could be accessed on your LAN as well. [This isn't the default case in WSL 2](https://docs.microsoft.com/en-us/windows/wsl/compare-versions#accessing-a-wsl-2-distribution-from-your-local-area-network-lan).

So, in order to access the server from your local devices, you need to port forward the WSL local IP using [netsh](https://docs.microsoft.com/en-us/windows-server/networking/technologies/netsh/netsh).

First, install net-tools in your linux distro.
For Ubuntu,
```bash
sudo apt install net-tools
```

Next, in Windows, create `network.ps1` PowerShell script file with the following content.
```powershell
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {   
  $arguments = "& '" + $myinvocation.mycommand.definition + "'"
  Start-Process powershell -Verb runAs -ArgumentList $arguments
  Break
}

$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 {
  Write-Output "IP address could not be found";
  exit;
}

$ports = @(5001, 19000, 19001);

for ($i = 0; $i -lt $ports.length; $i++) {
  $port = $ports[$i];
  Invoke-Expression "netsh interface portproxy delete v4tov4 listenport=$port";
  Invoke-Expression "netsh advfirewall firewall delete rule name=$port";
  
  Invoke-Expression "netsh interface portproxy add v4tov4 listenport=$port connectport=$port connectaddress=$remoteport";
  Invoke-Expression "netsh advfirewall firewall add rule name=$port dir=in action=allow protocol=TCP localport=$port";
}

Invoke-Expression "netsh interface portproxy show v4tov4";

```

This script is taken from [here](https://github.com/microsoft/WSL/issues/4150#issuecomment-504209723), I added command to automatically ask for admin permission, when opening the script, instead of right clicking and clicking run as admin every time you run the script.

_Note: The network should be a [private network](https://support.microsoft.com/en-us/windows/make-a-wi-fi-network-public-or-private-in-windows-10-0460117d-8d3e-a7ac-f003-7a0da607448d)._

The script will ask for admin access. 

The script gets the WSL IP address and then executes [netsh commands](https://docs.microsoft.com/en-us/windows-server/networking/technologies/netsh/netsh-interface-portproxy) to forward the connection to your Windows' local IP, which you can see by executing `ipconfig` in either PowerShell or Command Prompt.

The script also resets all previous forwards and at the end displays the list of ipv4 connections forwarded.

You can modify the `$ports` array with your commonly used ports.

Since WSL2 uses virtual network adapters, its IP address resets after every startup.

## For [Expo](https://expo.io/) users
- Include both ports 19000 and 19001 in the `$ports` array. (Don't include 19002 - dev tool server).

- In your Android device (connected to the same network as your PC), copy `exp://<your-windows-ip-address>:19000` to the clipboard.

- Open [Expo Go](https://play.google.com/store/apps/details?id=host.exp.exponent), "Open from Clipboard" option will appear.

## Notes
- PowerShell command to view all forwards
```powershell
netsh interface portproxy show v4tov4
```

- Have a desktop shortcut for the script. It could be handy.

- The network should be a [private network](https://support.microsoft.com/en-us/windows/make-a-wi-fi-network-public-or-private-in-windows-10-0460117d-8d3e-a7ac-f003-7a0da607448d).

- If your primary purpose is to only check your website for responsive design with your mobile, there is a simple way for that in chrome. See [Chrome remote debugging](https://developers.google.com/web/tools/chrome-devtools/remote-debugging)

## References
- [Accessing a WSL 2 distribution from your local area network (LAN)](https://docs.microsoft.com/en-us/windows/wsl/compare-versions#accessing-a-wsl-2-distribution-from-your-local-area-network-lan) - WSL Docs
- [WSL issues on Github](https://github.com/microsoft/WSL/issues)
- [Script Source](https://github.com/microsoft/WSL/issues/4150#issuecomment-504209723)
- [Running a command as Administrator using PowerShell](https://stackoverflow.com/a/11440595) - From StackOverFlow