WSL2-网络镜像模式本机无法IP访问排查记录

WSL2 镜像模式下本机无法通过本机 IP 访问服务 —— 排查与解决全记录

环境:Windows 11 Dev Channel (Build 26200) · WSL 2.7.10 · 镜像网络模式


现象

WSL2 中启动了一个 HTTP 服务(例如 python3 -m http.server 8000 --bind 0.0.0.0),然后:

访问方式 结果
http://localhost:8000/(本机浏览器) ✅ 正常
http://192.168.0.118:8000/其他电脑 ✅ 正常
http://192.168.0.118:8000/本机 ❌ 无法访问

服务地址 192.168.0.118 是本机 Wi-Fi 网卡的 IP。在镜像模式下,WSL 共享这个 IP,服务在 WSL 中绑定了 0.0.0.0:8000,外部可访问,自己反而访问不了。


环境确认

# WSL 版本
wsl --version
# → WSL 版本: 2.7.10.0
# → 内核版本: 6.18.33.2-2
# → Windows: 10.0.26200.8655

# .wslconfig 配置
# 文件位置: %UserProfile%\.wslconfig
[wsl2]
networkingMode=mirrored
hostAddressLoopback=true
dnsTunneling=true
autoProxy=true
memory=24GB
swap=12GB

排查过程

第一步:确认服务是否正常

在 WSL 内测试:

curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8000/
# → 404(正常返回,服务运行中)

第二步:从 Windows 侧测试连通性

# localhost 测试 - ✅ 正常
Invoke-WebRequest http://127.0.0.1:8000/
# → 404

# 本机 IP 测试 - ❌ 失败
Invoke-WebRequest http://192.168.0.118:8000/
# → WebException: 操作超时

第三步:检查网络拓扑

# Windows 网卡列表
Get-NetAdapter | Select-Object Name, Status, LinkSpeed

# Windows IP 地址
Get-NetIPAddress -InterfaceAlias "WLAN"
# → 192.168.0.118/24

# WSL 内网络
ip addr show eth3
# → 192.168.0.118/24  ← 镜像模式下与 Windows 共享同一 IP

# 路由表
Get-NetRoute -DestinationPrefix "192.168.0.0/24"
# → ifIndex 10 (WLAN), 默认网关 192.168.0.1

结论:镜像模式正常工作,Windows 和 WSL 共享 192.168.0.118

第四步:尝试 netsh portproxy

# 添加转发规则(管理员终端)
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8000 connectaddress=127.0.0.1 connectport=8000

# 验证规则
netsh interface portproxy show all
# → 0.0.0.0:8000 → 127.0.0.1:8000

结果:无效。继续超时。

第五步:深入排查 portproxy 是否正常

怀疑 portproxy 本身可能失效,用两个测试验证:

测试 A:纯 Windows 环境测试

用 PowerShell 在 Windows 侧启动一个 TCP 监听(127.0.0.1:18888),添加 portproxy 规则 0.0.0.0:18888 → 127.0.0.1:18888,从本机测试 192.168.0.118:18888

结果:❌ 仍然失败 → 说明 portproxy 在此 Windows 版本上整体不可用

测试 B:绑定冲突测试

# 镜像模式下测试能否绑定 192.168.0.118:8000
$s = [System.Net.Sockets.Socket]::new([System.Net.Sockets.SocketType]::Stream, [System.Net.Sockets.ProtocolType]::Tcp)
$s.Bind([System.Net.IPEndPoint]::new([System.Net.IPAddress]::Parse("192.168.0.118"), 8000))
# → BIND_FAIL: 通常每个套接字地址(协议/网络地址/端口)只允许使用一次

镜像模式下,WSL 的 0.0.0.0:8000 占用了共享网络栈上的 所有接口 的 8000 端口,Windows 无法再绑定同一个端口。

第六步:查证社区

上网搜索发现这是 WSL2 镜像模式的已知问题

GitHub Issue 描述
#11600 镜像模式下宿主机和 WSL 无法双向访问
#40343 TCP 环回 SYN-ACK 端口错乱 Bug
#13868 镜像模式下 loopback 接口不可达

根因分析

镜像模式下网络架构

┌─────────────────────────────────────────────────────┐
│                    Windows 主机                       │
│                                                      │
│  Wi-Fi: 192.168.0.118/24                             │
│  ┌─────────────────────────────────────┐             │
│  │       WSL 镜像网络命名空间            │             │
│  │                                     │             │
│  │  eth3: 192.168.0.118/24 (共享)      │             │
│  │  服务: 0.0.0.0:8000                │             │
│  └─────────────────────────────────────┘             │
└─────────────────────────────────────────────────────┘

镜像模式下 WSL 和 Windows 共享同一个网络命名空间。服务在 WSL 内绑定 0.0.0.0:8000,相当于在整个共享栈上占用了 8000 端口。

为什么本机访问不了?

当本机请求 192.168.0.118:8000 时,Windows TCP/IP 栈检测到目标 IP 是自己的 IP,走内部环回路径。但这个环回路径并没有到达 WSL 里的服务,而是寻找 Windows 本身上有没有监听 8000 的进程——没有,于是连接失败。

本机 → 192.168.0.118:8000
       ↓
  Windows 内核: "发给自己"
       ↓
  走 loopback 本地投递(绕过了物理网卡和镜像转发路径)
       ↓
  Windows 自身无 8000 监听 ❌

从其他电脑访问时:

其他电脑 → 192.168.0.118:8000
               ↓
        物理网卡进入
               ↓
        镜像转发到 WSL 命名空间
               ↓
        WSL 服务响应 ✅

localhost:8000 能工作是因为 hostAddressLoopback=true 在 Windows 环回接口上做了显式转发。

为什么 portproxy 无效?

netsh portproxy 在 Windows TCP/IP 栈的"将发往自身 IP 的包短路到环回"这个决策点之前拦截流量。但在镜像模式下:

  1. 0.0.0.0:8000 已经被 WSL 在共享栈上占用
  2. portproxy 无法绑定到同一个地址端口
  3. 即使配置了规则也无法生效

此外,在 Windows Dev Channel Build 26200 上,portproxy 在纯 Windows 场景下也失效,可能是系统版本的 Bug。


解决方案

最终方案:切回 NAT 模式 + portproxy(确定有效)

既然镜像模式有环回访问的死结,而 portproxy 又在这个 Windows 版本上不可用,最可靠的方案是切回 WSL2 默认的 NAT 模式,然后手动配置端口转发。

步骤 1:修改 .wslconfig

# 文件位置: %UserProfile%\.wslconfig
[wsl2]
# networkingMode=mirrored    ← 注释掉,回到默认 NAT 模式
hostAddressLoopback=true
memory=24GB
swap=12GB

步骤 2:重启 WSL

wsl --shutdown

重新打开 WSL 终端。

步骤 3:获取 WSL IP

hostname -I
# → 172.29.212.65

步骤 4:添加端口转发(管理员终端)

netsh interface portproxy add v4tov4 `
    listenaddress=0.0.0.0 `
    listenport=8000 `
    connectaddress=172.29.212.65 `
    connectport=8000

步骤 5:验证

Invoke-WebRequest http://192.168.0.118:8000/
# → 404(成功到达 WSL 服务)

NAT 模式下网络架构:

┌────────────────────────────────────┐
│         Windows 主机                │
│                                     │
│  Wi-Fi: 192.168.0.118/24           │
│  Portproxy: 0.0.0.0:8000 ───┐      │
│                              │      │
│  vEthernet (默认交换机)        │      │
│  172.26.192.1/20             │      │
│       │                      │      │
└───────┼──────────────────────┘      │
        │ NAT                         │
  ┌─────┴────────────────────┐         │
  │   WSL 命名空间            │        │
  │                          │        │
  │  eth0: 172.29.212.65/20  │        │
  │  服务: 0.0.0.0:8000 ◄────┘────────┘
  └──────────────────────────┘

自动化脚本

每次都手动敲命令太麻烦,写了一个批处理脚本 wsl-port.bat

:: 用法(管理员终端)
wsl-port 8000        # 添加端口转发
wsl-port 8000 /d     # 删除端口转发

脚本会自动获取 WSL IP、添加/删除 portproxy 规则。


其他的尝试(不成功但值得记录)

尝试 结果
使用 hostAddressLoopback=true 只对 localhost 有效
netsh portproxy(镜像模式) portproxy 在此 Windows 版本上整体失效
Set-NetFirewallHyperVVMSetting 本机无此命令
firewall=false(.wslconfig) 无效
添加特定 IP 路由 需要路由器支持 hairpin NAT
iptables DNAT(WSL 内) 流量未进入 WSL 命名空间就短路了
安装 Npcap / 开启 WiFi 热点 社区报告有效,但非正规方案

总结

要点 内容
问题性质 WSL2 镜像模式的已知内核级 Bug,非操作失误
根因 本机访问自身 IP 时,Windows TCP/IP 栈将流量短路到环回,不经过 WSL 命名空间
最佳方案 切回 NAT 模式 + 手动 portproxy
长期建议 等微软修复镜像模式的环回问题后再切回去
参考链接 Issue #11600 · Issue #40343

记录于 2026-07-09

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容