现象:浏览器正常,终端却像「没开代理」
很多 Windows 用户会遇到一种割裂感:Clash 或 Verge 类客户端已经启动,Edge / Chrome 访问外站顺畅,但一回到 PowerShell 或 Windows Terminal,git clone、npm install、curl https://... 依然慢到超时,甚至直接报连接失败。第一反应往往是「节点坏了」或「规则没命中」,于是开始疯狂换节点、清空 DNS,却忽略了一个更常见的事实:图形界面里勾选的「系统代理」并不会自动让所有命令行工具走代理。
在 Windows 上,「系统代理」主要影响遵循系统 WinHTTP / 代理发现机制的应用;而大量开发者工具(尤其是 Git、npm、部分 Python 工具链)更习惯读取进程环境变量里的 http_proxy、HTTPS_PROXY 等字段。若这些变量为空,它们就会按默认逻辑直连——与 Clash 是否在监听本地端口无关。本文专门走终端环境变量 + Clash 混合端口这条排查路径:不展开 TUN 安装与驱动细节(那属于另一条故障树,可参考站内《TUN 与防火墙排查》),而是把「端口填在哪、变量写什么、如何验证」一次说清。
系统代理 vs 终端环境变量:到底谁在管 Git / npm
可以把网络栈想成两层:系统层与进程层。Clash 客户端里「设置为系统代理」时,通常会把 Windows 的 HTTP 代理指向类似 127.0.0.1:端口 的地址,让尊重系统代理设置的应用自动走本地环回。但 Git for Windows 默认并不会因为系统代理已开启,就自动为所有子命令注入代理;它优先看自己的配置(http.proxy 等)以及当前 shell 的环境变量。npm 同理:Node 的 HTTP 客户端会读取 HTTP_PROXY / HTTPS_PROXY(大小写变体亦常见),与「系统设置里那一行代理地址」不是同一条通路。
因此,正确的排错顺序是:先确认 Clash 本地监听端口确实打开(混合端口或 HTTP 端口),再在同一个 PowerShell 会话里打印 $env:HTTPS_PROXY 等变量,看是否为空。若为空,即使系统代理已写入注册表,Git 仍可能直连海外 GitHub,表现为 TLS 握手卡住或 EOF。反过来,如果你只在「系统环境变量」里添加了用户级变量,却从未重启已打开的终端,旧会话同样读不到新值——这也是高频「我明明配了」的来源。
若公司装有安全代理或 VPN 客户端,可能改写系统代理或与本地端口冲突。排错时尽量只保留 Clash 一条链路,关闭其它「全局代理」类软件后再测 git ls-remote。
Clash 混合端口与 SOCKS 端口:终端里该填哪一个
Clash 系核心通常在配置里提供 mixed-port(或界面中的「混合端口」)以及独立的 port(HTTP)与 socks-port(SOCKS5)。混合端口的含义是:在同一监听地址上同时接受 HTTP 代理与 SOCKS5 连接,极大降低记错端口的概率。对 Git、npm、curl、wget 这类以 HTTP(S) 为主的工具,最省心的写法是统一把代理指到混合端口上的 HTTP 代理 URL,例如 http://127.0.0.1:7890(端口号以你本机 YAML 或界面为准,切勿照抄教程里的示例数字)。
若你改用 socks5://127.0.0.1:xxxx,请确认该 xxxx 真的是 SOCKS 监听端口,而不是把 SOCKS 地址错填到只提供 HTTP 的端口上——否则会出现「连接立即被拒绝」或「协议握手失败」。部分用户看到订阅里写着 7891、7892 就随手填,也容易与 Clash 本地监听混淆。以 Clash 主界面或当前生效配置里显示的本地端口为准,并用 Test-NetConnection 127.0.0.1 -Port xxxx 在 PowerShell 里验证端口可达,比盲猜更有效。
若你需要把手机或局域网设备接到这台电脑的代理上,监听地址与防火墙又是另一套检查项,可对照《局域网代理与防火墙》;本文只讨论本机当前用户的终端场景,不把问题扩张到 TUN 或整网路由。
PowerShell:为当前用户设置 http_proxy(推荐起步方式)
在不确定该永久写入用户目录还是仅本次会话调试时,建议先用当前会话临时变量验证链路。下面示例中的端口请替换为你的 Clash 混合端口。注释说明仅用于文档阅读,请勿连同注释一并复制进正式配置。
$env:HTTP_PROXY = "http://127.0.0.1:7890"
$env:HTTPS_PROXY = "http://127.0.0.1:7890"
$env:ALL_PROXY = "http://127.0.0.1:7890"
然后执行 curl -I https://www.google.com 或访问你常用的可访问测试域名,观察是否仍直连超时。若临时变量生效而永久配置不生效,多半是写入位置不对:PowerShell 5 与 PowerShell 7 的配置文件路径不同;「系统属性」图形界面里改的用户变量也需要新开终端才会注入旧进程。
对需要长期固定的开发者,可把上述 $env:... 行写入 PowerShell Profile,或写入「用户环境变量」对话框中的 HTTP_PROXY / HTTPS_PROXY。注意变量名大小写在不同工具链里兼容性不一:Git 与许多 Unix 习惯工具认 http_proxy 小写形式,Windows 上亦建议同时设置 HTTP_PROXY 与 http_proxy,减少「有的命令认、有的不认」的玄学问题。
NO_PROXY:别让内网与镜像站「误走代理」
一旦设置了全局感很强的 ALL_PROXY,常见副作用是:访问公司内网 Git、私有 npm registry、或国内镜像源时也强行走海外节点,导致变慢或证书报错。解决办法是维护 NO_PROXY(或 no_proxy)列表,把无需出国的域名或 IP 段排除出去,例如本机、内网域名、常用国内镜像主机名。列表分隔符在 Windows 与类 Unix 之间习惯不同,若一套配置要在 WSL 与 PowerShell 间共享,建议查目标工具文档确认支持的分隔符是逗号还是竖线。
若你同时为 Docker 配代理,还要警惕 Docker Desktop 的代理设置与宿主机环境变量叠加或互相覆盖;排错时同样坚持「单一变量」:先只验证宿主机 PowerShell,再进入容器内验证。
Git:环境变量与 git config 如何二选一或并用
Git 获取 http.proxy 时,会综合环境变量与仓库级 / 全局级 config。实务上更推荐:在团队脚本里统一用环境变量注入,避免把含密码的代理 URL 写进全局 config 并误提交;若只有你本机使用,也可以用 git config --global http.proxy http://127.0.0.1:7890 显式指定。对 HTTPS 仓库地址,通常设置 http.proxy 即可让 Git 通过 HTTP CONNECT 隧道访问 HTTPS 远端,但若你遇到老版本 Git 或特殊 CA 问题,需要再结合 http.sslBackend 与公司证书策略排查。
SSH 协议的 [email protected]:... 与 HTTPS 不是一条路径:SSH 不走 http_proxy,需要 core.sshCommand 挂 nc 或通过其它 SSH 代理工具。很多新手误以为设置了 HTTPS_PROXY 后 git@ 也会自动翻出去,这是典型误区。若你主要使用 SSH remote,请单独查 SSH 代理方案,本文仍以 HTTPS remote 与 npm 为主。
npm / pnpm / yarn:registry 与代理的叠加关系
npm 在下载包时会访问配置的 registry(默认或淘宝镜像等)。若只改了 registry 未配代理,在海外网络环境下仍可能极慢;若只配了代理而 registry 指向不可达的旧域名,则会报 ENOTFOUND。建议先用 npm config get registry 确认源,再在同一终端会话已设置 HTTPS_PROXY 的前提下执行 npm ping 或安装一个小包做探针。
你也可以使用 npm config set proxy / npm config set https-proxy 写入用户级 npm 配置,但与环境变量相比,缺点是工具链一多(pnpm、yarn、corepack)就要分别核对是否继承。多数团队更倾向在 CI 与本地统一用环境变量,减少「某人机器上 npm 能装、pnpm 不能装」的差异。
常见坑速查表:为什么「还是直连」
- 端口写错:把订阅里的远程端口、面板里的节点端口写进
http_proxy;正确的是本机 Clash 监听端口。 - 协议写错:对混合端口的 HTTP 代理使用了
socks5://,或反之。 - 只改系统、不改终端:浏览器走系统代理,Git 仍无环境变量。
- 变量名大小写:仅设了
HTTP_PROXY,某工具只读http_proxy。 - 会话未刷新:用图形界面改完环境变量,未关闭旧 PowerShell 窗口。
- ALL_PROXY 副作用:内网流量被拖去海外,表象为「代理开了反而更慢」。
- 与 TUN 预期混淆:未开 TUN 时,某些不走系统代理的 GUI 可能仍直连;本文刻意不引导为终端问题盲目开 TUN,先把本地端口 + 变量链路跑通。
验证与回滚:用最小命令确认「真的走了 Clash」
验证时建议打开 Clash 的连接日志或当前客户端等效视图,在终端执行一次 git ls-remote https://github.com/...,观察是否出现指向 127.0.0.1:混合端口 的本地连接,再由 Clash 转发至远端。若日志里完全看不到对应进程或域名,说明流量仍绕开了代理。确认无误后,再把临时 $env: 写入 Profile 或用户环境变量,避免一次改太多处难以回滚。
若你希望由 Clash 侧统一接管更多应用而不逐个配变量,TUN 确实是更强的一刀切方案,但涉及路由、权限与防火墙,复杂度显著高于「只给当前开发终端加变量」。在能明确区分场景的前提下,先掌握混合端口 + http_proxy这条路径,通常足以解决 Git/npm 类问题,也与你在容器、IDE、CI 里接触到的代理习惯一致。
合规提示
请在你所在地区法律法规及服务条款允许的范围内使用代理与访问目标站点。本文仅讨论本地网络参数与排错思路,不构成对任何网络限制或平台政策的规避建议。
结语
Windows 上「Clash 已开但终端仍直连」,多数时候不是玄学,而是系统代理与进程环境变量两套机制未对齐。把 Clash 混合端口写进 http_proxy / HTTPS_PROXY,为 Git 与 npm 显式提供出口,再配合 NO_PROXY 保护内网与镜像访问,往往比盲目切换节点或立刻上 TUN 更省时间。能把规则命中日志与终端变量打印结果对照起来,排错会快一个数量级。
若你希望与教程使用同一套客户端能力(连接日志、端口展示、配置编辑体验),可从客户端下载页获取适合你系统的版本;更多分流与 YAML 细节见博客索引与《YAML 配置解析》。→ 立即免费下载 Clash,开启流畅上网新体验