WSL服务器外网访问
实现的基本方法(分步骤)
一、核心原理
通过 Windows 的 netsh
工具建立端口转发规则,并配合防火墙设置,实现外部设备访问 WSL 中运行的服务。
二、操作步骤
-
获取 WSL IP 地址
# 在 WSL 终端执行 ip addr show eth0 | grep 'inet\b' | awk '{print $2}' | cut -d/ -f1
-
创建端口转发规则
# 在 PowerShell 管理员模式执行 $WSL_IP = "替换为WSL实际IP" $port = "目标端口" netsh interface portproxy add v4tov4 listenport=$port listenaddress=0.0.0.0 connectport=$port connectaddress=$WSL_IP
-
配置防火墙规则
New-NetFirewallRule -DisplayName "Allow WSL Port $port" ` -Direction Inbound -Action Allow ` -Protocol TCP -LocalPort $port
-
验证访问
浏览器访问
http://[Windows_IP]:[端口]
三、规则管理
-
🔍 查看所有转发规则
netsh interface portproxy show all
-
🗑️ 删除转发规则
netsh interface portproxy delete v4tov4 listenport=端口 listenaddress=0.0.0.0
-
🔧 防火墙规则管理
# 查看特定端口规则 Get-NetFirewallPortFilter | Where-Object { $_.LocalPort -eq 3000 } # 启用/禁用规则 Enable-NetFirewallRule -DisplayName "Allow WSL Port 3000" Disable-NetFirewallRule -DisplayName "Allow WSL Port 3000"
四、注意事项
- 需使用 管理员权限 运行 PowerShell
- WSL IP 可能在每次重启后变化,建议通过脚本自动获取:
$WSL_IP = wsl hostname -I
- 开放 0.0.0.0 监听适用于开发环境,生产环境建议更严格的地址限制
- 若遇到连接问题,按顺序检查:
- 端口转发规则是否存在
- 防火墙是否放行
- WSL 内部服务是否正常监听
自动化脚本
一、PowerShell 主脚本 Configure-WSL-Port.ps1
注意以
gb2312
编码保存
<#
.SYNOPSIS
自动化配置WSL端口转发和防火墙规则
.DESCRIPTION
功能包括:
1. 自动获取WSL2 IP地址
2. 创建端口转发规则
3. 配置Windows防火墙
4. 支持多端口批量操作
5. 清理旧规则功能
.PARAMETER Ports
需要转发的端口号(支持逗号分隔多个端口)
.PARAMETER Cleanup
清理模式(删除指定端口规则)
.EXAMPLE
.\Configure-WSL-Port.ps1 -Ports 3000,8080
.\Configure-WSL-Port.ps1 -Ports 3000 -Cleanup
#>
param(
[Parameter(Mandatory=$true)]
[string]$Ports,
[switch]$Cleanup
)
# 管理员权限检查
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Host "正在请求管理员权限..." -ForegroundColor Yellow
Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" -Ports `"$Ports`" $(if($Cleanup){'-Cleanup'})" -Verb RunAs
exit
}
# 解析端口列表
$portArray = $Ports -split ',' | ForEach-Object { $_.Trim() }
try {
# 获取WSL IP(自动处理多IP情况)
$wslIP = (wsl hostname -I) -split '\s+' | Where-Object { $_ -match '\d+\.\d+\.\d+\.\d+' } | Select-Object -First 1
if (-not $wslIP) {
throw "无法获取WSL IP地址,请确认WSL正在运行"
}
Write-Host "`n=== WSL 配置信息 ===" -ForegroundColor Cyan
Write-Host "检测到 WSL IP: $wslIP" -ForegroundColor Green
Write-Host "操作模式: $(if($Cleanup){'清理'}else{'配置'})" -ForegroundColor Green
Write-Host "目标端口: $($portArray -join ', ')`n" -ForegroundColor Green
foreach ($port in $portArray) {
if (-not ($port -match '^\d+$' -and [int]$port -ge 1 -and [int]$port -le 65535)) {
Write-Host "无效端口号: $port" -ForegroundColor Red
continue
}
if ($Cleanup) {
# 清理模式
Write-Host "`n正在清理端口 $port ..." -ForegroundColor Yellow
# 删除端口转发
netsh interface portproxy delete v4tov4 listenport=$port listenaddress=0.0.0.0 2>&1 | Out-Null
# 删除防火墙规则
$ruleName = "Allow WSL Port $port"
if (Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue) {
Remove-NetFirewallRule -DisplayName $ruleName
Write-Host "已删除防火墙规则: $ruleName" -ForegroundColor Magenta
}
} else {
# 配置模式
Write-Host "`n正在配置端口 $port ..." -ForegroundColor Cyan
# 创建端口转发
netsh interface portproxy add v4tov4 listenport=$port listenaddress=0.0.0.0 connectport=$port connectaddress=$wslIP
# 创建防火墙规则(如果不存在)
$ruleName = "Allow WSL Port $port"
if (-not (Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue)) {
New-NetFirewallRule -DisplayName $ruleName `
-Direction Inbound -Action Allow `
-Protocol TCP -LocalPort $port | Out-Null
Write-Host "已创建防火墙规则: $ruleName" -ForegroundColor Magenta
}
}
}
# 显示最终配置
Write-Host "`n=== 当前端口转发规则 ===" -ForegroundColor Cyan
netsh interface portproxy show v4tov4
Write-Host "`n=== 相关防火墙规则 ===" -ForegroundColor Cyan
Get-NetFirewallRule -DisplayName "Allow WSL Port*" | Format-Table DisplayName,Enabled,Direction,Action
} catch {
Write-Host "`n错误发生: $_" -ForegroundColor Red
exit 1
}
# 显示访问提示(仅配置模式)
if (-not $Cleanup) {
$localIP = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -notmatch 'Loopback' }).IPAddress | Select-Object -First 1
Write-Host "`n=== 访问提示 ===" -ForegroundColor Cyan
Write-Host "本地访问: http://localhost:$($portArray[0])"
Write-Host "网络访问: http://${localIP}:$($portArray[0])"
Write-Host "`n请在WSL中运行以下命令验证服务状态:"
Write-Host "wsl ./check_wsl_port.sh $($portArray[0])" -ForegroundColor Green
# 在退出提示部分可改为:
}
$countdown = 5
while ($countdown -gt 0) {
Write-Host "`r自动退出倒计时 ${countdown} 秒 (按任意键立即退出)..." -NoNewline -ForegroundColor DarkGray
if ([Console]::KeyAvailable) { break }
Start-Sleep -Seconds 1
$countdown--
}
二、使用指南
1. 保存脚本
将PowerShell脚本保存为 Configure-WSL-Port.ps1
2. 配置端口转发(PowerShell)
# 开放单个端口
.\Configure-WSL-Port.ps1 -Ports 3000
# 批量开放多个端口
.\Configure-WSL-Port.ps1 -Ports "3000, 8080, 8888"
# 清理端口配置
.\Configure-WSL-Port.ps1 -Ports 3000 -Cleanup
3. 检验是否可以连通
略,自行验证即可😁
最后修改于 2025-04-29