DEV Community

WSL Port Forwarding

Vishnu on July 15, 2020

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 b...
Collapse
 
mindplay profile image
Rasmus Schultz

Almost 2 years on, and they still don't have a wsl command to open/close ports? 🤦‍♂️

I've spent a ridiculous amount of time on this and still can't get it to work. 😣

Collapse
 
mindplay profile image
Rasmus Schultz

I can't even run this script - it says it's "not digitally signed", and then sends me to an endless documentation page with absolutely nothing I can understand.

Collapse
 
mindplay profile image
Rasmus Schultz

Pardon me, it's 3 years on. 😣

Thread Thread
 
justintaddei profile image
Justin Taddei

4 years....

Collapse
 
drblack profile image
Drblack101 • Edited

Wow, what a great post, saved me lots of time and effort. I was struggling recently about exactly the port forwarding issue. Today saw your post and followed your instruction. It works perfectly. Thanks!

Collapse
 
gargamelism profile image
Gargamel

Great post, really helped me.
I would point out that I changed mine to have target port to 80, I think a common occurrence is using different ports for incoming and outgoing, maybe you can update the script to have a map from incoming to outgoing?

Collapse
 
ptraversee profile image
Pierre Traversee • Edited

That did not work for me as I have several distros and custom machines, and I do not accept to work a admin, so I adapted your script to execute the netsh part elevated and the rest as normal user. I also noted that it is not needed to install net tools if we use the command ip add, and the command bash.exe is deprecated, should use wsl.exe instead

Here is my script if it can help

$WslMachine = 'Ubuntu-20.04'
$Activity = "Forward wsl ports of $WslMachine"

$remoteip =wsl.exe -d $WslMachine /usr/sbin/ip add `| /usr/bin/grep 'eth0'

[string]$found = $remoteip -match 'inet (\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})/';

if( $found ){
$start=9
$end=$found.IndexOf("/")
$connectaddress=$found.substring($start, $end - $start)
} else{
Write-Error "The Script Exited, the ip address of $WslMachine cannot be found";
exit;
}

$ports=@(80);
$connectports=@(80)

$adminscript = "$env:programdata/wsl$env:computername/forward.ps1"

if (-not (Test-Path $adminscript)) {
New-Item -Path $adminscript -ItemType File -Force
}
Set-Content -Path $adminscript -Encoding UTF8 -Value @"

please note : replace backslashes by backticks, as backticks would not be displayed correctly here

\$connectaddress='$connectaddress'
\$ports=@($ports)
\$connectports=@($connectports)

Invoke-Expression 'netsh interface portproxy reset';

for( \$i = 0; \$i -lt \$ports.length; \$i++ ){
\$port = \$ports[\$i];
\$connectport=\$connectports[\$i];
Invoke-Expression \"netsh interface portproxy add v4tov4 listenport=\$port connectport=\$connectport connectaddress=\$connectaddress\";
}

Invoke-Expression 'netsh interface portproxy show v4tov'

start-sleep -seconds 2
"@

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{

$arguments = $adminscript
Start-Process powershell -Verb runAs -ArgumentList $arguments -Wait 
Enter fullscreen mode Exit fullscreen mode

} else {

Start-Process powershell -ArgumentList $arguments -Wait 
Enter fullscreen mode Exit fullscreen mode

}

Invoke-Expression 'netsh interface portproxy show v4tov'

Collapse
 
timhass6 profile image
Tim Hass • Edited

Great post, thank, this script is very handy until WSL finds a way to do it as built-in or at least provide a way to set "static" ip for the wsl.
after your permission if you will, I just modified your code so it would map host port to different ports on WSL
*don't forget to enable host ports on windows firewall ;)
*install net-tools on wsl , $sudo apt install net-tools

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
}

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

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

$ports=@(3388,3306);
$connectports=@(3389,3306)

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

Collapse
 
alvinlee001 profile image
Red Pill Factory

TLDR: This post is underrated AF, WSL 2 users should save this script up as a gist.

I did not know that this issue exist, spent hours if not days trying to figure why my microservices are not reachable from one app to another.. This code saved my life, now all my services between WSL 2 and windows can communicate perfectly.

Collapse
 
davidfm profile image
DavidFM

Great! Thanks

Collapse
 
arifimran5 profile image
Arif Imran

This helped me a lot to understand this. Thanks

Collapse
 
sc7639 profile image
Scott Crossan

Thank you the powershell script worked for me. Been trying to get this working for ages

Collapse
 
mjcarnaje profile image
Michael James Carnaje

Wow, Thank you so much!!!

Collapse
 
pauloch8 profile image
Paulo Henrique

Hello! Thank you for sharing this. Is there any problem in listening to port 80? I have a Gitlab docker container running on port 80. I ran your script but it is not being reached in my local network