WSL2 里执行 apt update、curl、git clone 全部超时,但 Windows 浏览器正常上网?这是快连 TUN 模式与 Hyper-V 虚拟交换机路由冲突的典型症状。根因是 WSL2 通过 Hyper-V 虚拟交换机 NAT 共享 Windows 网络,而快连开启 TUN 后会接管路由表,把 WSL2 的返回包送进死胡同。
本文给出 3 种修复方案,按推荐顺序排列:方案 A 在 WSL2 内配置代理指向 Windows 主机,方案 B 重置 Hyper-V 虚拟交换机,方案 C 切换快连到系统代理模式。所有命令都在 Windows PowerShell 或 WSL2 终端里执行,无需改注册表或重装系统。
一、为什么 WSL2 会和快连冲突
WSL2 不是虚拟机,而是跑在 Hyper-V 轻量虚拟机里的 Linux 环境。它通过 Hyper-V 虚拟交换机(vEthernet (WSL))做 NAT:WSL2 看到的网关是 Windows 主机的内部 IP(通常是 172.x.x.1),所有出站流量先到 Windows,再由 Windows 转发到物理网卡。
快连开启 TUN 模式后,会创建一块虚拟网卡接管系统路由表,把默认路由指向快连隧道。问题在于:WSL2 的返回包走 Hyper-V 虚拟交换机到 Windows 后,Windows 的路由表已经被快连改写,属于 WSL2 网段的回包不知道该从哪个接口送回去,于是丢包。表现就是 WSL2 里任何网络操作都超时,但 Windows 本身一切正常。
快速判断:在 WSL2 里执行 curl -I https://www.baidu.com --max-time 5。如果超时,但 Windows 浏览器能打开百度,基本就是这个冲突。
二、先做两步临时恢复
步骤 1:彻底重启 WSL2
以管理员身份打开 PowerShell,执行:
wsl --shutdown
等 5 秒后再打开 WSL2 终端。这会清空 Hyper-V 的 NAT 会话,多数临时路由错乱会自动恢复。
步骤 2:确认快连当前模式
打开快连客户端 → 设置 → 网络模式。如果显示"TUN 模式",先切到"系统代理模式",再回 WSL2 测试。如果系统代理模式下 WSL2 能通,说明就是 TUN 与 Hyper-V 的冲突。
三、方案 A:在 WSL2 里配置 Windows 代理(推荐)
这是最稳的长期方案。WSL2 不需要感知快连的 TUN 网卡,只要在 Linux 环境变量里把 HTTP/HTTPS 代理指向 Windows 主机的快连端口即可。
步骤 1:拿到 Windows 主机在 WSL2 里的 IP
在 WSL2 终端里执行:
ip route show | grep -i default | awk '{ print $3}'
输出类似 172.27.192.1,这就是 Windows 主机在 WSL2 虚拟网络里的地址。
步骤 2:在 WSL2 里写入代理环境变量
把下面三行加到 ~/.bashrc(如果用 zsh 就加到 ~/.zshrc):
export host_ip=$(ip route show | grep -i default | awk '{ print $3}')
export http_proxy="http://$host_ip:7890"
export https_proxy="http://$host_ip:7890"
export all_proxy="socks5://$host_ip:7890"
执行 source ~/.bashrc 生效。
步骤 3:在 Windows 防火墙放行
默认情况下快连只监听 127.0.0.1,WSL2 访问不到。需要在快连设置里开启"允许局域网连接"(或"允许来自局域网的连接"),让快连监听 0.0.0.0:7890。Windows Defender 防火墙首次会弹窗,选"允许"。
步骤 4:验证
在 WSL2 里执行:
curl -I https://www.baidu.com --max-time 5
看到 HTTP/2 200 或 HTTP/1.1 200 OK 就说明通了。再跑一次 sudo apt update,应该能正常拉取包列表。
对 Git/npm/pip 单独配置:命令行工具会读 http_proxy 环境变量,但 Git 和 Docker 需要单独配置。Git 执行 git config --global http.proxy http://$host_ip:7890;Docker 在 ~/.docker/config.json 里加 "proxies": {"default": {"httpProxy": "http://$host_ip:7890", "httpsProxy": "http://$host_ip:7890"}}。
四、方案 B:重置 Hyper-V 虚拟交换机
如果方案 A 配好代理后 WSL2 还是不通,可能是 Hyper-V 虚拟交换机本身状态异常。在管理员 PowerShell 里执行:
# 查看现有虚拟交换机
Get-VMSwitch
# 如果输出为空或 WSL 网卡消失,重建
wsl --shutdown
Get-NetAdapter | Where-Object {$_.Name -like "*WSL*"} | Disable-NetAdapter -Confirm:$false
Get-NetAdapter | Where-Object {$_.Name -like "*WSL*"} | Enable-NetAdapter
# 重启 WSL
wsl
这会重置 WSL2 的虚拟网卡,但不会影响 Windows 物理网卡或快连配置。
五、方案 C:切换快连到系统代理模式
如果不想在 WSL2 里配环境变量,最省事的办法是把快连从 TUN 模式切到系统代理模式:
- 打开快连 → 设置 → 网络模式
- 选择"系统代理"(不要选 TUN)
- 重启快连客户端
系统代理模式下,快连只改 Windows 的 IE/系统代理设置,不动路由表。WSL2 的 Hyper-V 虚拟交换机不会被影响,容器内流量按原 NAT 路径走,由 Windows 系统代理转发到快连。缺点是只支持 HTTP/HTTPS 代理,不支持 UDP 隧道。
六、常见错误码对照表
| 症状 | 可能原因 | 首选修复 |
|---|---|---|
| curl: (28) Connection timed out | TUN 模式劫持了 WSL2 路由 | 方案 A 配代理,或方案 C 切系统代理 |
| Could not resolve host | WSL2 DNS 没指向 Windows | 编辑 /etc/resolv.conf,nameserver 改为 $host_ip |
| Connection refused (端口 7890) | 快连没开"允许局域网连接" | 快连设置 → 允许局域网连接 |
| apt update: Temporary failure resolving | DNS 解析失败 | 方案 A 配好代理后,DNS 走代理自动恢复 |
| WSL2 完全启动不了 | Hyper-V 服务停了 | 管理员 PowerShell: Start-Service vmcompute |
七、验证步骤清单
修复完成后,按下面顺序逐项验证,全部通过才算解决:
- WSL2 里
curl -I https://www.baidu.com --max-time 5返回 200 - WSL2 里
sudo apt update能拉到包列表,无超时 - WSL2 里
git clone https://github.com/...(任意小仓库)成功 - Windows 浏览器打开任意网页正常(确认没影响主机网络)
- 重启 WSL2 后(
wsl --shutdown再开),代理配置依然生效
八、常见问题 FAQ
Q1:需要关闭快连才能用 WSL2 吗?
不需要。按方案 A 在 WSL2 里配好代理指向 Windows 主机,快连保持开启即可。容器内流量会经 Windows 主机的快连端口出网,和 Windows 浏览器共用同一条隧道。
Q2:WSL2 里 ping 不通外网是快连的问题吗?
不一定。ICMP(ping)默认不被 HTTP 代理转发,这是正常的。判断网络是否通,用 curl -I https://www.baidu.com,不要用 ping。
Q3:Docker Desktop 里的容器也受影响吗?
Docker Desktop on Windows 同样基于 Hyper-V,会遇到一样的问题。按方案 A 配代理后,Docker 容器在 ~/.docker/config.json 里单独配 proxies 段即可。
Q4:每次重启 WSL2 都要重新配代理吗?
不需要。把环境变量写进 ~/.bashrc 或 ~/.zshrc,每次开 WSL2 终端自动生效。如果用的是 systemd 管理的发行版,可以在 /etc/profile.d/ 里放脚本。
快连