系统代理不生效排查:浏览器走代理而终端不走的原因与验证

系统代理只是环境变量与设置项,浏览器遵循而终端命令未必读取。分两条路径给出验证命令与修复方法,并说明何时应改用 TUN 模式接管全局流量。

先区分系统代理与实际流量路径

Clash 客户端里的「系统代理」通常不是一条覆盖所有程序的全局隧道。它做的是把操作系统的 HTTP 与 HTTPS 代理地址写成 127.0.0.1,端口指向 Clash 正在监听的本地端口。浏览器读取这项设置后,把请求交给 Clash;终端程序是否读取,取决于程序本身、启动环境和代理协议。

常见默认值是 HTTP 端口 7890、SOCKS5 端口 7891,或者由一个 mixed-port: 7890 同时接收 HTTP 与 SOCKS5。端口不是固定规范。配置文件、客户端版本或用户覆写都可能修改它。排查前应以客户端「设置」→「端口设置」或当前配置中的字段为准。

mixed-port: 7890
allow-lan: false
mode: rule

dns:
  enable: true
  enhanced-mode: fake-ip

当网页可以打开,而 curlgitnpm 或某个命令行下载器仍然直连时,通常不是节点整体失效。更准确的判断是:浏览器路径已经进入 Clash,终端路径没有进入,或者终端进入后采用了不同的 DNS、协议和规则。

第一条路径:浏览器如何读取系统代理

确认 Clash 本地端口正在监听

系统代理指向一个没有监听的端口时,浏览器通常显示连接被拒绝。Windows PowerShell 可检查 7890,macOS 与 Linux 可查看对应进程。若实际端口不是 7890,应替换命令中的数字。

# Windows PowerShell
Get-NetTCPConnection -LocalPort 7890 -State Listen

# macOS
lsof -nP -iTCP:7890 -sTCP:LISTEN

# Linux
ss -lntp | grep 7890

预期结果应包含本地监听地址,例如 127.0.0.1:78900.0.0.0:7890。没有结果时,返回客户端检查配置是否已启动、代理开关是否已开启,以及端口是否被其他程序占用。若端口冲突,可临时改为 7897,随后同步更新系统代理和终端变量。

检查操作系统代理地址

  • Windows 11:进入「设置」→「网络和 Internet」→「代理」→「手动设置代理」。地址应为 127.0.0.1,端口应与 Clash 的 HTTP 或 mixed 端口一致。
  • macOS:进入「系统设置」→「网络」→当前网络接口→「详细信息」→「代理」。检查网页代理 HTTP 与安全网页代理 HTTPS。
  • Firefox:进入「设置」→「常规」→「网络设置」。若选用了「手动代理配置」,它会覆盖系统代理;希望跟随操作系统时应选择「使用系统代理设置」。
  • Chrome 与 Edge 通常读取操作系统代理,但扩展程序、企业策略和浏览器启动参数仍可改写该路径。

浏览器验证应同时查看页面结果与 Clash 连接记录。打开一个此前未访问的站点,然后在客户端的连接页面按域名筛选。若能看到目标域名、命中的规则和出口节点,说明请求已经进入内核。只看网页能否打开无法区分代理访问、缓存命中和直连访问。

检查规则是否让浏览器直连

系统代理开启只代表流量进入 Clash,不代表必然使用代理节点。在 mode: rule 下,请求还要经过规则匹配。连接记录若显示 DIRECT,应检查域名规则、规则集与最终规则。临时切换到全局模式可用于对照,但完成验证后应恢复规则模式。

rules:
  - DOMAIN-SUFFIX,example.com,Proxy
  - GEOIP,CN,DIRECT
  - MATCH,Proxy

如果全局模式可用、规则模式不可用,问题集中在规则顺序、策略组选择或订阅生成内容,而不是系统代理开关。Clash 规则从上到下匹配,第一条命中后即停止。宽泛的 DIRECT 规则放在前面,可能提前截获后续域名规则。

第二条路径:终端程序为什么没有跟随

终端窗口本身不会自动转发网络。真正发起请求的是 curl、Git、Node.js、Python 包管理器或其他命令。每个程序都有自己的代理读取逻辑。部分程序读取 HTTP_PROXYHTTPS_PROXY,部分读取小写变量,部分只接受命令参数,还有一些使用独立配置文件。

用 curl 显式指定代理做基准测试

先绕过环境变量,直接让 curl 连接 Clash 的 HTTP 端口。这一步可以把“终端未读取系统设置”和“Clash 本地代理不可用”分开。

curl -v -x http://127.0.0.1:7890 https://api.ipify.org

curl -v --connect-timeout 10 \
  -x http://127.0.0.1:7890 \
  https://www.example.com/

输出中应先出现到 127.0.0.1:7890 的连接,再出现 HTTPS 的 CONNECT 过程。若显式指定代理成功,而不带 -x 时失败,节点、端口和 Clash 内核基本正常,后续只需处理终端配置。

SOCKS5 测试可使用 socks5h。末尾的 h 表示域名解析交给代理端处理,适合排除本地 DNS 解析异常。若使用 socks5,域名通常先在本地解析,再把 IP 交给代理。

curl -v --proxy socks5h://127.0.0.1:7891 \
  https://api.ipify.org

为当前终端设置环境变量

macOS、Linux、Git Bash 与多数类 Unix shell 可在当前会话中导出变量。建议同时写入大写和小写形式,以兼容读取规则不同的工具。关闭终端窗口后,这组临时变量会失效。

export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export NO_PROXY=localhost,127.0.0.1,::1

curl -v https://api.ipify.org

PowerShell 可写入当前进程环境。执行后只影响该 PowerShell 窗口及从它启动的子进程,不会自动修改已经打开的编辑器或其他终端。

$env:HTTP_PROXY="http://127.0.0.1:7890"
$env:HTTPS_PROXY="http://127.0.0.1:7890"
$env:NO_PROXY="localhost,127.0.0.1,::1"

curl.exe -v https://api.ipify.org

验证完成后应清理测试变量,避免 Clash 退出后程序继续访问失效的本地端口。

# bash / zsh
unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY NO_PROXY

# PowerShell
Remove-Item Env:HTTP_PROXY
Remove-Item Env:HTTPS_PROXY
Remove-Item Env:NO_PROXY

Git、npm 与 Python 的独立配置

环境变量适合一次性排查。长期使用时,还要确认工具是否保存过旧端口。Git 可分别读取全局配置和仓库配置;仓库内的局部项优先级更高。

git config --global --get http.proxy
git config --global --get https.proxy
git config --local --get http.proxy

git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

# 删除全局代理
git config --global --unset http.proxy
git config --global --unset https.proxy

npm 可用 npm config get proxynpm config get https-proxy 检查。值显示为 null 时,npm 才可能继续参考环境变量。旧配置若仍指向 127.0.0.1:7897,即使系统代理已经改成 7890,npm 仍会访问旧端口。

npm config get proxy
npm config get https-proxy

npm config set proxy http://127.0.0.1:7890
npm config set https-proxy http://127.0.0.1:7890

npm config delete proxy
npm config delete https-proxy

Python 的 pip 可读取环境变量,也可通过命令参数测试。仅为单次安装添加代理时,使用参数比永久写入配置更容易回退。

python -m pip install --proxy http://127.0.0.1:7890 package-name

python -m pip config list
python -m pip config debug

DNS、IPv6 与 UDP:进入代理后仍可能失败

区分解析失败与连接失败

终端报错中的关键词可以缩小范围。Could not resolve host 指向域名解析阶段;Connection refused 通常表示本地代理端口未监听;Operation timed out 可能是节点链路、规则出口、防火墙或目标站响应超时;TLS 证书错误则需要检查系统时间、证书存储与程序使用的 TLS 后端。

使用 HTTP 代理访问 HTTPS 站点时,客户端一般先向代理发送 CONNECT。使用 SOCKS5 时,socks5hsocks5 的解析位置不同。若普通 socks5 失败而 socks5h 成功,应优先检查本地 DNS,不要直接更换订阅。

检查 IPv4 与 IPv6 结果

部分终端程序优先连接 IPv6,而当前网络的 IPv6 路由不完整。可分别执行 curl -4curl -6 对照。若 IPv4 在 2 秒内返回、IPv6 在 10 秒后超时,问题位于 IPv6 路径,而不是 HTTP 代理变量。

curl -4 -I --connect-timeout 10 https://www.example.com/
curl -6 -I --connect-timeout 10 https://www.example.com/

curl -4 -I -x http://127.0.0.1:7890 https://www.example.com/
curl -6 -I -x http://127.0.0.1:7890 https://www.example.com/

还要注意,传统 HTTP 系统代理主要处理 TCP 上的 HTTP 与 HTTPS。基于 UDP 的 QUIC、游戏流量、语音应用和自定义协议不一定经过该入口。浏览器可能在代理环境下回退到 TCP,但其他应用未必执行相同回退,因此会出现网页正常、特定应用超时的差异。

何时改用 TUN 模式

TUN 模式通过虚拟网络接口和系统路由接管更多 IP 流量。它不要求每个应用理解 HTTP 代理,也不依赖程序读取 HTTP_PROXY。当需要覆盖多个终端工具、UDP 应用、无法配置代理的软件,或者希望减少逐项维护代理变量时,TUN 通常比系统代理更合适。

适合切换 TUN 的场景

  • 浏览器稳定进入 Clash,但多个命令行工具都忽略系统代理。
  • 应用使用自定义 TCP 或 UDP 协议,没有 HTTP、HTTPS 或 SOCKS5 代理设置。
  • 开发环境包含容器、包管理器和后台进程,逐个配置环境变量成本较高。
  • 需要让 DNS 查询与连接流量遵循同一套规则,减少本地解析路径差异。
  • 系统代理关闭后仍希望由规则决定 DIRECT、代理组和最终出口。

mihomo 内核的常见配置包含 tun.enablestack、自动路由与 DNS 劫持。具体可用值取决于客户端打包的内核版本和操作系统权限。修改前应保留当前可工作的 Profile,并通过客户端提供的设置入口启用,不要同时手工创建第二套系统路由。

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53

tun.enable: true · stack: mixed · auto-route: true

启用后先关闭系统代理做一次对照测试,避免同一请求先进入系统代理、再被 TUN 路由重复接管。多数内核会处理这种组合,但排障阶段保留单一路径更容易判断。随后分别测试浏览器、curl、Git 和目标应用,并在连接记录中确认命中规则。

Android 上的系统代理与 VPN 路径

Android 客户端通常通过系统 VpnService 建立本地 VPN 接口,而不是依赖桌面系统常见的 HTTP 代理设置。首次启动时出现的连接请求属于 Android 系统授权。确认后,应用才能创建 VPN 接口并接收被路由到该接口的流量。

如果 Android 浏览器可用而 Termux 中的命令不可用,先检查客户端是否启用了按应用代理、应用绕过或仅代理选中应用。精确菜单名称因客户端不同而变化,常见入口为「设置」→「网络」→「访问控制」或「设置」→「参数设置」→「按应用代理」。Termux 若未包含在代理应用列表中,其流量可能直接走物理网络。

  • 在连接记录中搜索 Termux 请求的目标域名。
  • 检查访问控制当前采用「仅代理所选应用」还是「绕过所选应用」。
  • 关闭私有 DNS做一次短时对照,再恢复原设置并记录结果。
  • 确认省电策略没有在熄屏后终止 VPN 服务。
  • 检查当前 Profile 的 DNS、TUN 与规则组是否实际生效。

Termux 仍可使用 export HTTPS_PROXY=http://127.0.0.1:端口,但这里的回环地址和端口必须确实由 Android 客户端开放给本机应用。若客户端主要通过 VPN 接口工作,没有开放本地 HTTP 监听,设置该变量不会产生有效连接。此时应优先修正 VPN 的应用范围,而不是照搬桌面端口。

按顺序执行的最终检查表

  1. 在 Clash 客户端确认 Profile 已启动,策略组已选择可用节点。
  2. 读取当前 mixed-portportsocks-port,不要假定一定是 7890
  3. 用监听命令确认本地端口存在,并排除端口冲突。
  4. 在浏览器打开新页面,同时查看 Clash 连接记录与命中规则。
  5. 执行带 -xcurl,建立显式代理基准。
  6. 显式代理成功后,再设置当前终端的代理环境变量。
  7. 检查 Git、npm、pip 等工具保存的独立代理配置和旧端口。
  8. 使用 socks5h-4-6 区分 DNS 和 IP 路径。
  9. 需要接管非 HTTP、UDP 或大量后台程序时,切换到 TUN 做单路径验证。
  10. 验证完成后清理临时变量,恢复规则模式与原有 DNS 设置。

最关键的判断不是“代理开关是否亮着”,而是请求实际经过哪一条路径。浏览器路径看系统代理与规则,终端路径看程序参数、环境变量和独立配置,复杂应用路径再看 TUN、路由与 DNS。按照监听端口、显式代理、环境变量、工具配置、TUN 的顺序检查,通常可以在不改动订阅的前提下定位问题。

客户端与排查入口

选择对应平台的 Clash 客户端,或继续查看首次配置、系统授权与连接步骤。

下载Clash