-
-
Save composite/003e27c68b70325a049caff2b32c2ea8 to your computer and use it in GitHub Desktop.
WSL 2 TCP NETWORK FORWARDING, IMPROVED FOR TASK SCHEDULER! ALSO WORKS ON WINDOWS SERVER 2022!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# WSL2 network port forwarding script v1 | |
# for enable script, 'Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser' in Powershell, | |
# for delete exist rules and ports use 'delete' as parameter, for show ports use 'list' as parameter. | |
# written by Daehyuk Ahn, Aug-1-2020 | |
# edited by Ukjin Yang, Jun-7-2022 (Windows Server 2022 also works!) | |
# Improved features: more detailed logs for Task Scheduler, saved IP check, etc. | |
If ($Args[0] -eq "list") { | |
netsh interface portproxy show v4tov4; | |
exit; | |
} | |
# If elevation needed, start new process | |
If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) | |
{ | |
# Relaunch as an elevated process: | |
Start-Process powershell.exe "-File",('"{0}"' -f $MyInvocation.MyCommand.Path),"$Args runas" -Verb RunAs | |
exit | |
} | |
# You should modify '$Ports' for your applications | |
$Ports = (22,80,443,8080) | |
# log file and saving IP file | |
$today = [System.DateTime]::Today.ToString("yyyyMMdd") | |
$logdir = "$PSScriptRoot\logs" | |
$logfile = "$logdir\wsl2ip_$today.log" | |
$lastfile = "$logdir\wsl2ip.txt" | |
# mkdir log folder if not exists | |
if (-not (Test-Path $logdir -PathType Container)) { | |
New-Item -Path "$logdir" -ItemType "directory" | Out-Null | |
} | |
# Log helper function | |
function Log-Append { | |
[CmdletBinding()] | |
param( | |
[Parameter()] | |
[string] $Text | |
) | |
$now = [System.DateTime]::Now.ToString("yyyy-MM-dd HH:mm:ss.fff") | |
Tee-Object -FilePath "$logfile" -Append -InputObject "WSL2IP: [$now] $Text" | |
} | |
# Get WSL Interface IP, and get only first IP. (I don't know why multiple IPs registered) | |
wsl hostname -I | Set-Variable -Name "WslIp" | |
$WslIp = $WslIp.split(" ")[0] | |
$found = $WslIp -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'; | |
if (-not $found) { | |
Log-Append "WSL2 cannot be found. Terminate script." | |
exit; | |
} | |
# Get saved IP for prevent unexpected running. | |
$OldIp = "" | |
if (Test-Path $lastfile -PathType Leaf) { | |
$OldIp = Get-Content "$lastfile" | |
} | |
$OldIp = $OldIp.Trim() | |
if ($WslIp -eq $OldIp) { | |
Log-Append "WSL2 IP ($WslIp) already bound in port proxy. Terminate script." | |
exit; | |
} | |
# If you got new WSL IP, Go ahead! | |
Log-Append "Applying WSL IP to port proxy." | |
# Remove and Create NetFireWallRule | |
Log-Append "Replacing Firewall rules..." | |
Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' | Tee-Object -FilePath "$logfile" -Append; | |
if ($Args[0] -ne "delete") { | |
New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $Ports -Action Allow -Protocol TCP | Tee-Object -FilePath "$logfile" -Append; | |
New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $Ports -Action Allow -Protocol TCP | Tee-Object -FilePath "$logfile" -Append; | |
New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $Ports -Action Allow -Protocol UDP | Tee-Object -FilePath "$logfile" -Append; | |
New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $Ports -Action Allow -Protocol UDP | Tee-Object -FilePath "$logfile" -Append; | |
} | |
# Add each port into portproxy | |
Log-Append "Replacing port forwarding any to WSL2 Port..." | |
$Addr = "0.0.0.0" | |
Foreach ($Port in $Ports) { | |
iex "netsh interface portproxy delete v4tov4 listenaddress=$Addr listenport=$Port | Out-Null"; | |
if ($Args[0] -ne "delete") { | |
iex "netsh interface portproxy add v4tov4 listenaddress=$Addr listenport=$Port connectaddress=$WslIp connectport=$Port | Out-Null"; | |
} | |
} | |
# Display all portproxy information | |
Log-Append "Retrieving port forwarding table..." | |
netsh interface portproxy show v4tov4 | Tee-Object -FilePath "$logfile" -Append; | |
# Give user to chance to see above list when relaunched start | |
If ($Args[0] -eq "runas" -Or $Args[1] -eq "runas") { | |
Write-Host -NoNewLine 'Press any key to close! '; | |
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown'); | |
} | |
# Save successful WSL IP to file. | |
Log-Append "Saving successful IP $WslIp to $lastfile ..." | |
$WslIp | Out-File -FilePath "$lastfile" | |
# Preserve WSL service scripts here. | |
Log-Append "Executing WSL Startup scripts..." | |
iex "wsl sudo service ssh start" | Tee-Object -FilePath "$logfile" -Append | |
iex "wsl sudo service cron start" | Tee-Object -FilePath "$logfile" -Append | |
Log-Append "Done." | |
Add-Content "$logfile" "" |
If you want full instructions for Windows server 2022, check out my blog post.
Windows 10 also will help.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you want start service without prompt password, you should run
sudo visudo
and append a line like this:# change username to your linux default user name who can run sudo. username ALL=(ALL:ALL) NOPASSWD: ALL
If you worried about all executables security, you can just replace last
ALL
to/sbin/service, /usr/sbin/service
and sudo without password process as you want.# change username to your linux default user name who can run sudo. username ALL=(ALL:ALL) NOPASSWD: /sbin/service, /usr/sbin/service