WSL2 主机无法通过 IP 访问 WSL 内 HTTP 服务完整排查修复

11次阅读
没有评论

核心原理

WSL2 是独立 NAT 虚拟机,拥有172.x.x.x内网 IP;默认只监听 127.0.0.1、Windows 防火墙拦截、无端口转发是访问失败三大根源。

一、第一步:WSL 内服务必须监听 0.0.0.0(90% 人踩坑)

1. 检查当前监听端口(WSL 终端执行)

bash

运行

# 替换3000为你的http端口
ss -tulnp | grep 3000
  • 正常:0.0.0.0:3000 所有网卡可访问
  • 异常:127.0.0.1:3000 仅 WSL 内部能访问,Windows 主机直接连不通

2. 各服务修改监听地址示例

Python 内置 http 服务

bash

运行

# 正确,绑定全部网卡
python3 -m http.server 3000 --bind 0.0.0.0
# 错误(默认只127.0.0.1)
python3 -m http.server 3000

Flask/Django

python

运行

# Flask
app.run(host="0.0.0.0", port=3000, debug=True)
# Django
python manage.py runserver 0.0.0.0:3000

Node/Express

js

运行

app.listen(3000, "0.0.0.0", ()=>{})

Nginx

修改nginx.conf监听行:

nginx

listen 3000; # 等价0.0.0.0:3000,不要写127.0.0.1:3000

3. 获取 WSL 真实 IP(Windows 访问用)

bash

运行

hostname -I | awk '{print $1}'
# 输出示例:172.27.135.66

Windows 浏览器直接访问:http://172.27.135.66:3000

二、第二步:关闭 WSL 内部防火墙(Ubuntu/Debian)

WSL 内置 ufw 拦截外部请求:

bash

运行

# 临时关闭
sudo ufw disable
# 放行端口(推荐)
sudo ufw allow 3000/tcp

三、第三步:Windows 防火墙放行端口(关键)

管理员身份打开 PowerShell,放行你的端口(示例 3000):

powershell

# 创建入站规则,允许TCP 3000
New-NetFirewallRule -DisplayName "WSL HTTP 3000端口" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 3000

验证规则:

powershell

Get-NetFirewallRule -DisplayName "WSL HTTP 3000端口"

四、场景 1:仅 Windows 本机访问(172.x IP)

完成上面三步即可直接用 WSL 的172.x.x.x:端口访问。

测试连通(Windows PowerShell):

powershell

Test-NetConnection 172.27.135.66 -Port 3000

TcpTestSucceeded: True 代表通了。

五、场景 2:局域网手机 / 其他电脑访问(Windows 局域网 IP,如 192.168.x.x)

WSL 的 172 网段是虚拟机内网,局域网其他设备无法直接访问,必须配置 Windows 端口转发:

1. 一键转发命令(管理员 PowerShell)

powershell

# 替换3000为端口,自动获取WSL IP
$wslIp = (wsl hostname -I).Trim()
netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=$wslIp

2. 查看 / 删除转发规则

powershell

# 查看所有转发
netsh interface portproxy show all
# 删除转发
netsh interface portproxy delete v4tov4 listenport=3000 listenaddress=0.0.0.0

3. 访问方式

手机 / 另一台电脑打开:http://Windows主机局域网IP:3000(例:192.168.1.105:3000

六、常见报错排查清单

  1. Connection refused
    • 服务只监听 127.0.0.1 → 改成 0.0.0.0
    • 端口写错、服务未启动
  2. 超时无法连接
    • Windows 防火墙未放行端口
    • 未做 portproxy 转发(局域网访问)
    • WSL ufw 防火墙拦截
  3. 重启 WSL 后 IP 变了,端口转发失效
    • 每次重启重新执行转发命令;或写 PowerShell 开机脚本自动配置
  4. WSL1 vs WSL2 区分 powershellwsl -l -v
    • WSL1:共享 Windows 网络,直接localhost访问,无需转发
    • WSL2:独立虚拟机,必须按上面步骤操作

极简快速修复脚本(复制到管理员 PowerShell 运行)

替换端口 3000 为你自己的端口:

powershell

$port=3000
# 放行防火墙
New-NetFirewallRule -DisplayName "WSL HTTP $port" -Direction Inbound -Action Allow -Protocol TCP -LocalPort $port -ErrorAction SilentlyContinue
# 添加端口转发
$wslIp=(wsl hostname -I).Trim()
netsh interface portproxy delete v4tov4 listenport=$port listenaddress=0.0.0.0 2>&1 | Out-Null
netsh interface portproxy add v4tov4 listenport=$port listenaddress=0.0.0.0 connectport=$port connectaddress=$wslIp
Write-Host "WSL IP: $wslIp`nWindows局域网访问地址: http://$((Get-NetIPAddress | Where-Object {$_.AddressFamily -eq 'IPv4' -and $_.InterfaceAlias -notlike 'vEthernet*' -and $_.IPAddress -ne '127.0.0.1'}).IPAddress):$port"
正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 0
评论(没有评论)
验证码