一、典型现象:Windows 能翻墙,WSL2 里命令行却不行?
常见描述包括:Edge 或 Chrome 访问海外站点正常,Clash 连接列表里也有活跃会话;但在 WSL 终端执行 curl https://www.google.com 或 sudo apt update 时长时间卡住,最后报连接超时或 TLS 握手失败。也有人发现 npm、pip、go mod 在宿主机开了全局规则后依旧走直连,Docker pull 同样失败。
这类问题往往不是订阅失效,而是WSL 代理路径没有打通:WSL2 使用虚拟化网络,子系统内的 127.0.0.1 指向的是Linux 实例自身,而不是 Windows 上监听在回环地址的 Clash 入站端口。除非使用较新版本 Windows 提供的「WSL 访问 Windows localhost」特性,否则把代理环境变量写成 http://127.0.0.1:7890 通常连的是「空端口」。因此,第一步永远是:在 WSL 内解析出当前可用的 Windows 主机地址,并把 Clash 配置为能接受来自该网段的连接(必要时配合《Clash 局域网代理》中的 allow-lan 思路,把 WSL 虚拟网卡视作另一类「邻接客户端」)。
二、原理简述:WSL2、宿主机与 localhost
WSL2 的 Linux 内核跑在轻量虚拟机中,通过虚拟交换机与 Windows 互通。默认情况下,Windows 侧为 WSL 分配的默认网关地址,往往就是子系统视角下的宿主机 IP——这也是多数教程让你执行 ip route show default 或查看 /etc/resolv.conf 里 nameserver 的原因:在经典 NAT 布局下,该地址通常与 Windows 在「WSL 专用网段」上的接口对应。
另一方面,从 Windows 11 及配套 WSL 更新起,部分环境支持从 WSL 直接访问 Windows 上的 localhost 服务,相当于做了localhost 端口转发。若你确认系统已启用该行为,理论上可以把代理写成 http://127.0.0.1:混合端口;但若实测仍失败,请回退到「显式宿主机 IP + 端口」方案,兼容性更好。下文以宿主机 IP为主线,并在排错节补充与 localhost 相关的对照。
三、在 WSL 内获取 Windows 宿主机地址
推荐先尝试从路由表读取默认网关(多数 Ubuntu 镜像可用):
ip route show | grep -i default | awk '{ print $3}'
将输出记为 WIN_HOST(示例可能是 172.x.x.1)。另一常见写法是查看解析用 DNS 指向的地址:
grep -m1 nameserver /etc/resolv.conf | awk '{ print $2 }'
在部分公司网络或自定义 WSL 配置下,两者可能不一致;以能 ping 通且 curl 能连上代理端口的为准。也可在 Windows PowerShell 中查看 WSL 虚拟网卡 IP,与子系统内互相印证。若 DHCP 或休眠恢复后地址变化,shell 启动脚本里可每次动态解析,避免写死旧 IP。
四、Windows 侧 Clash:端口、allow-lan 与防火墙
确认 Clash 实际监听的混合端口或 HTTP 端口(界面或 config.yaml 中的 mixed-port / port,常见为 7890)。若 Clash 仅绑定 127.0.0.1,来自 WSL 虚拟网段的入站连接会被拒绝,表现为连接超时。请在客户端中开启「允许局域网连接」或等价选项,使配置中出现 allow-lan: true,并将 bind-address 设为可接受外部接口的形式(如 '*' 或 0.0.0.0,具体以你所用内核文档为准)。
随后必须在 Windows 防火墙中为该 TCP 端口添加入站放行规则(专用网络配置文件即可),否则即使 Clash 已监听 0.0.0.0,数据包仍可能被系统拦截。完成后再在 WSL 内执行(将主机与端口替换为你的实际值):
curl -x http://<WIN_HOST>:7890 -I https://www.google.com/generate_204
若此处仍失败,先不要改 apt,回到 Windows 核对端口、防火墙与 Clash 日志。更通用的端口与报错流程可参考《Clash 常见报错解决方案》。
五、Shell 环境变量:http_proxy、HTTPS_PROXY 与 no_proxy
在 ~/.bashrc 或 ~/.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 HTTP_PROXY="$http_proxy"
export HTTPS_PROXY="$https_proxy"
export ALL_PROXY="$http_proxy"
export no_proxy="localhost,127.0.0.1,::1"
export NO_PROXY="$no_proxy"
执行 source ~/.bashrc 后,用 curl -I https://example.com 验证。若使用需要 SOCKS5 的工具,可将 ALL_PROXY 改为 socks5://... 并对应 Clash 的 SOCKS 端口。内网仓库、公司 Git 域名应加入 no_proxy,以免误走代理。
六、apt 与系统级代理配置
sudo 默认会清除部分环境变量,因此仅改用户 shell 可能不足以让 sudo apt 走代理。常见做法是在 /etc/apt/apt.conf.d/ 下新建文件(需 root),例如 95proxies:
Acquire::http::Proxy "http://<WIN_HOST>:7890/";
Acquire::https::Proxy "http://<WIN_HOST>:7890/";
将 <WIN_HOST> 换成上一步得到的 IP。保存后执行 sudo apt update。若使用公司镜像源,确认镜像主机名已按需列入直连或规则组。完成后如不再需要,可删除该文件避免长期依赖宿主机在线。
七、git 与 npm(以及其它工具链)
Git 可单独指定,以免与全局环境变量冲突:
git config --global http.proxy http://<WIN_HOST>:7890
git config --global https.proxy http://<WIN_HOST>:7890
取消时使用 git config --global --unset http.proxy 等。npm 常用:
npm config set proxy http://<WIN_HOST>:7890
npm config set https-proxy http://<WIN_HOST>:7890
yarn、pnpm、Rust、Go 等工具各自有配置入口,但底层都是 HTTP/SOCKS 代理语义;保持与 Clash 端口、协议一致即可。
八、Docker Desktop 与 WSL2 后端
使用 Docker Desktop 且开启 WSL2 集成时,镜像拉取可能发生在 Windows 侧守护进程或集成发行版中,排错要分清「你在哪个环境执行 docker pull」。常见配置路径包括:Docker Desktop 设置中的 Proxy(HTTP/HTTPS 与绕过列表),或在 Docker Engine JSON 中配置 proxies 字段(不同版本界面略有差异,以当前文档为准)。
若在 WSL 内使用 Docker CLI 与守护进程通信,仍需保证拉取镜像时的出站路径能到达代理:有时需让 Docker 守护进程本身感知代理,而不仅仅是 shell 里的 http_proxy。可结合 Docker 官方说明中的 ~/.docker/config.json 与守护进程配置,逐项验证 docker pull hello-world 是否出现 Clash 连接记录。构建镜像时若 Dockerfile 内需要访问外网,可能还要设置 buildkit 相关代理环境变量,这与「仅配置交互式 shell」又是不同一层,需要按构建日志中的失败域名对症补规则。
九、localhost 端口转发与何时可省略宿主机 IP
在支持「WSL 访问 Windows localhost」的环境下,部分用户可直接使用 127.0.0.1:7890 作为代理地址,简化脚本。但若你遇到间歇性失败、或 WSL 版本较旧,仍建议统一使用第三节得到的 WIN_HOST。可在 Windows 侧用 netstat 确认 Clash 监听地址为 0.0.0.0:端口 或至少包含 WSL 可达接口。
十、验证顺序与排错清单
建议严格按序排查:① Windows 本机浏览器已确认节点可用;② WSL 内 curl -x http://WIN_HOST:端口 访问海外 URL 成功;③ 再测 apt / git / docker pull。若①成②败,检查 allow-lan、bind-address、防火墙与 IP 是否漂移;若②成③败,检查 sudo 环境、apt 独立配置或 Docker 守护进程代理。Clash 的连接日志是否出现来自 WSL 网段的入站,是判断流量是否打到核心的直观依据。
十一、小结
WSL2 Clash的本质,是在理解子系统网络边界的前提下,把 Linux 里的工具链显式指向Windows 主机代理:先取对宿主机 IP,再保证 Clash 对 WSL 网段开放入站并放行防火墙,最后用环境变量、apt 代理与 Docker 各自机制落实出站。与「只在 Windows 勾选系统代理」或「在 Linux 单机跑 Mihomo」相比,这条路径更贴近日常开发机场景,也便于和团队文档对齐。若你希望用图形界面统一管理规则、端口与局域网选项,可从本站获取 Windows 客户端安装包:→ 立即免费下载 Clash,开启流畅上网新体验