本文介绍 wsl2 的端口转发、网络代理等问题,不会或者少量涉及 wsl2 的安装部署,因为安装教程很容易能找到。这里着重于端口转发、网络代理等容易遇到的坑
上述问题,可以通过端口转发的方式,让 windows 把 wsl2 的端口转发暴露给局域网,因此需要搞定三件事情:
以上三个问题的对应方案如下:
============================
※ 注意,本 2.2.1 小节已经废弃,不再需要使用这种迂回的方式来映射子系统的 ip
※
※ 对于获取子系统 ip 不感兴趣的可以直接跳到文章第 2.2.2 小节端口转发
※
※ 本节不删除只用作存档,修改时间:2024/1/20
============================
.\wsl2host.exe install
192.168.82.59 ubuntu.wsl # managed by wsl2-host
ubuntu.wsl
来获取到子系统的虚拟 ip.bat
文件并以管理员权限打开):pushd "%~dp0"
dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >List.txt
dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientTools-Package~3*.mum >>List.txt
for /f %%i in ('findstr /i . List.txt 2^>nul') do dism /online /norestart /add-package:"C:\Windows\servicing\Packages\%%i"
.\wsl2host.exe debug
指令, 这样也可以手动给 hosts 添加上新的 ip, 这样需要每次开机都手动调下指令 (原因是每次开机宿主机 ip 都不一样), 挺麻烦的notepad $profile
打开 pwsh 的配置文件,接下来要写两段脚本在配置文件中添加如下代码并保存。另外下面的脚本中有 sudo
指令,这个要求你的 pwsh 要事先安装了 sudo 插件,这个是用来获取管理员权限的,请自行搜索安装方法(温馨提示:最新版本的 win11 内置 sudo 命令,但是默认关闭,自行搜索启用方法;旧的系统依然需要安装第三方的 sudo 工具,自行搜索安装方式)。对于脚本里面的 192.168.10.68
就是你需要映射的端口,一般就是你的宿主机的内网 ip,自行修改,下面是代码:
function setWslNetsh {
param (
$Port
)
sudo pwsh -c "netsh interface portproxy add v4tov4 listenport=$Port connectaddress=localhost connectport=$Port listenaddress=192.168.10.68 protocol=tcp"
Write-Output "✔ Port($Port) now is out!"
}
function unsetWslNetsh {
param (
$Port
)
sudo pwsh -c "netsh interface portproxy delete v4tov4 listenport=$Port listenaddress=192.168.10.68 protocol=tcp"
Write-Output "✔ Port($Port) now is not out!"
}
Set-Alias wsl-netsh-set setWslNetsh
Set-Alias wsl-netsh-unset unsetWslNetsh
上面这段代码就是实现端口转发的主要脚本,这时候在 pwsh 中执行:wsl-netsh-set <port>
就能让 windows 把子系统的端口转发出去。例如:wsl-netsh-set 8000
就能把子系统中端口号为 8000 的进程转发出去
wsl-netsh-unset <port>
则是取消转发pwsh wsl-netsh-set <port>
或 pwsh wsl-netsh-unset <port>
localhost
转发的宿主机,例如你在子系统起了一个 http://localhost:8000
的服务,那么你不需要做任何事情,就可以在宿主机通过 http://localhost:8000
访问到这个服务,而这个脚本就是基于这个原理,通过 netsh
进行流量转发,把特定的 <ip>:<port>
的访问流量转发到 localhost:<port>
,这样就能把子系统的端口暴露给局域网了v4tov4
你就可以看出来,如果你子系统使用的是 ivp6 服务,那么你也可以这样来设置转发和取消转发,你可以自行调整 v4tov6
这一处,看你的宿主机是想用什么 ip 协议来访问这个子系统端口sudo pwsh -c "netsh interface portproxy add v4tov6 listenport=8000 listenaddress=192.168.10.68 connectport=8000 connectaddress=::1"
sudo pwsh -c "netsh interface portproxy delete v4tov6 listenport=8000 listenaddress=192.168.10.68"
wsl-netsh-unset <port>
取消转发,然后再重新设置一下转发就行了,你可以通过 netsh interface portproxy show all
看到当前有哪些进行了流量转发的地址和端口最简单的做法其实就是在防火墙中添加出站和入站规则,添加一下需要暴露到局域网的端口即可。当然也可以把这个写成脚本,需要暴露什么端口直接执行脚本就行,同样在 pwsh 的配置文件中添加代码:
function setFWPort {
param (
$Port
)
$Port4WSL = "Port4WSL-" + $Port
$NetFirewallRule = Get-NetFirewallRule
if (-not $NetFirewallRule.DisplayName.Contains($Port4WSL)) {
# sudo pwsh -c "Remove-NetFireWallRule -DisplayName $Port4WSL"
sudo pwsh -c "New-NetFireWallRule -DisplayName $Port4WSL -Direction Outbound -LocalPort $Port -Action Allow -Protocol TCP"
sudo pwsh -c "New-NetFireWallRule -DisplayName $Port4WSL -Direction Inbound -LocalPort $Port -Action Allow -Protocol TCP"
Write-Output "✔ New rule for WSL(Port: $Port)!"
}
else {
Write-Output "✔ Rule for WSL(Port: $Port) exists!"
}
}
function unsetFWPort {
param (
$Port
)
$Port4WSL = "Port4WSL-" + $Port
$NetFirewallRule = Get-NetFirewallRule
if (-not $NetFirewallRule.DisplayName.Contains($Port4WSL)) {
Write-Output "✔ Rule for WSL(Port: $Port) not exists!"
}
else {
sudo pwsh -c "Remove-NetFireWallRule -DisplayName $Port4WSL"
Write-Output "✔ Rule for WSL(Port: $Port) removed!"
}
}
Set-Alias fw-port-set setFWPort
Set-Alias fw-port-unset unsetFWPort
然后就能用 fw-port-set <port>
来创建新的出入站规则,用 fw-port-unset <port>
移除规则。规则名称定为了 Port4WSL-<port>
,可以自行修改
完成上述步骤,就可以把子系统的进程端口暴露到局域网了,例如我在子系统起了一个服务,端口为 8000,windows 在局域网的地址为 192.168.1.215
,那么局域网下的其他设备就能通过访问 http://192.168.1.215:8000
访问我子系统下的服务
点击这里前往 Github 查看原文,交流意见~
文档信息
版权声明:自由转载 - 非商用 - 非衍生 - 保持署名(创意共享3.0许可证)