Port Forwarding WSL 2 to Your LAN

Run a public server from WSL thats accessible on your local network
WSL
PowerShell
Networking
Picture of John Wright Stanly, author of this blog article
John Wright Stanly
Jun 25, 2021

-

-

image

The Windows Subsystem for Linux (WSL) is great for development. WSL gives you the functionality of UNIX with only a fraction of the resources required for a traditional VM. It also runs alongside your Windows environment, allowing you to access Windows files inside Linux. Microsoft continues to improve WSL like with the release of WSL2 in 2019

WSL2 noticeably does not share an IP address with your computer. Because WSL2 was implemented with Hyper-V, it runs with a virtualized ethernet adapter. Your computer hides WSL2 behind a NAT where WSL2 has its own unique IP. Although WSL2 can be accessed on your machine through localhost thanks to recent updates, these ports will not be open on your LAN.

image

Port Forwarding

You can fix this with port forwarding. First open WSL and find its IP address. Depending on your distro, ifconfig or ip addr show or hostname -I should do the trick.

image

For every port you need to forward to your computer, run this netsh command in PowerShell. Replace [PORT] and [WSL_IP].

netsh interface portproxy add v4tov4 listenport=[PORT] listenaddress=0.0.0.0 connectport=[PORT] connectaddress=[WSL_IP]

You can view all your forwarded ports with netsh interface portprixy show v4tov4.

image

There's a chance Windows firewall blocks this. To ensure WSL ports can be reachable, you can make a new inbound rule. Open PowerShell as Administrator and run the following command. Replace -LocalPort with the list/range of ports you need.

New-NetFirewallRule -DisplayName "WSL2 Port Bridge" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 80,443,10000,3000,5000

image

Congrats! Your WSL ports are now reachable through your Windows computer's IP address.

However, there is a catch. WSL changes its IP on every Windows reboot. If you're looking for a one time solution, you'll need to automate this process.

Scripting

We can trigger a script upon login to do this for us. Save the following script as Bridge-WslPorts.ps1. If your distro doesn't have ifconfig, you will need to change line 1 to find WSL's IP another way, like with ip addr or hostname.

$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";
}

If you have multiple WSL distros, make sure to set your default so bash.exe will execute under the correct WSL. You can list and set distros with wslconfig /l and wslconfig /s <name>

image

We can now run this script every time we log in with a Windows task. Run the following commands in PowerShell. Replace [PATH_TO_SCRIPT] with the absolute directory of the script, like C:\Users\John\Documents.

$a = New-ScheduledTaskAction -Execute "powershell -ExecutionPolicy Bypass [PATH_TO_SCRIPT]\Bridge-WslPorts.ps1"
$t = New-ScheduledTaskTrigger -AtLogon
Register-ScheduledTask BridgeWslPorts -Action $a -Trigger $t

image

Now you won't have to think about WSL port forwarding every time you restart your PC.

Comments

Be the first to add a comment!

Add Comment

Post