故障排查 预计阅读 12 分钟

Clash 系统代理已开启却不生效:浏览器与终端分开排查

浏览器走不走系统代理、终端为何默认绕过,分两条线逐项检查:扩展冲突、PAC 与例外列表,以及 http_proxy 环境变量与 TUN 模式的取舍。

先区分:未进入客户端,还是进入后出站失败

“系统代理已开启”只说明客户端尝试修改了操作系统的代理设置,不代表每个应用都会读取这些设置。浏览器可能被扩展接管,终端工具可能只读取环境变量;请求即使进入 Clash,也可能被规则分配到 DIRECT,或因节点连接失败而无法完成。

本文以 Windows、macOS 和 Linux 桌面端为主。Clash 是代理内核及相关客户端生态的常用称呼,Clash Meta 后续使用 mihomo 名称;具体开关位置取决于客户端,内核名称并不决定界面菜单。Android、iOS 的 VPN 接管路径与桌面系统代理不同,不宜直接套用本文的系统设置步骤。

  1. 在客户端确认配置已加载,出站模式先使用“规则”,并记录当前策略组选择的节点。
  2. 打开客户端的“连接”页面,同时查看“日志”;必要时临时把日志级别调到 info。
  3. 对一个明确的目标域名发起新请求,核对连接时间、目标地址、命中规则和出站链路。
  4. 没有记录,先查应用入口;有记录且走 DIRECT,先查规则;有记录但连接超时,再查节点、DNS 与远端服务。

本地入口:确认地址、端口与内核状态

下面统一用 127.0.0.1:7890 举例。7890 是常见配置值,不是所有客户端的固定端口。先在客户端“设置”中的“端口”或“混合端口”项目查看实际数值,再替换命令中的端口。不要把控制器端口、仪表盘地址误填成代理端口。

配置字段用途检查重点
mixed-port同一端口接受 HTTP 与 SOCKS 代理请求可作为下文 HTTP 代理测试入口
portHTTP 代理监听端口不要向它发送 SOCKS 握手
socks-portSOCKS 代理监听端口测试时使用 SOCKS 协议地址
external-controller内核控制 API不能用作浏览器代理入口

Windows:检查端口监听与所属进程

netstat -ano | findstr :7890

在输出中找本地地址为 127.0.0.1:7890 或相应监听地址、状态为 LISTENING 的行。记下末列 PID,再到“任务管理器”→“详细信息”核对进程。端口被其他客户端占用时,当前客户端可能启动界面成功,但内核未能绑定端口。

macOS、Linux:检查 TCP 监听

lsof -nP -iTCP:7890 -sTCP:LISTEN

若系统未安装 lsof,Linux 可使用 ss -lntp 查看监听列表。没有监听时,先检查内核启动日志、配置解析错误和端口冲突,不要继续调整浏览器。只供本机使用时,通常无需启用“允许局域网连接”,也不必把监听地址扩大到所有网卡。

浏览器路线:系统设置、扩展、PAC 与例外列表

检查操作系统实际保存的代理地址

  • Windows 11:打开“设置”→“网络和 Internet”→“代理”。查看“手动设置代理”中的服务器与端口,并检查“使用设置脚本”是否仍指向旧 PAC 地址。
  • macOS 13 及以后:打开“系统设置”→“网络”→当前使用的网络服务→“详细信息”→“代理”。核对“网页代理(HTTP)”“安全网页代理(HTTPS)”以及“自动代理配置”。切换 Wi-Fi 或有线网络后需重新核对对应服务。
  • GNOME 桌面:通常在“设置”→“网络”→“网络代理”中查看。不同桌面环境的系统代理设置并不统一,应用也未必读取同一套配置。

HTTP 代理地址通常写 127.0.0.1,端口单独填 7890。HTTPS 网站通过 HTTP 代理的 CONNECT 隧道访问,不意味着必须填入一个以 https:// 开头的代理服务器地址。具体输入框是否需要协议前缀,以系统界面要求为准。

Chrome、Edge:检查扩展和策略覆盖

Chrome 可在地址栏打开 chrome://settings/system,Edge 可打开 edge://settings/system,再进入系统代理设置。随后分别检查 chrome://extensions 或 edge://extensions,临时停用代理切换类扩展,完全退出浏览器后重开。

无痕窗口不是充分的隔离测试:部分扩展被允许在无痕模式运行,系统代理和企业策略也仍然生效。受管理设备还应查看 chrome://policy 或 edge://policy;若代理由组织策略固定,应联系管理员,不要反复覆盖设置。

Firefox:核对独立的网络设置

Firefox 打开“设置”→“常规”→页面底部“网络设置”→“设置”。选择“使用系统代理设置”,才会按系统配置连接;若选择“手动配置代理”,则核对 HTTP 代理、端口以及是否对 HTTPS 使用同一代理。“不使用代理”与“自动检测此网络的代理设置”都不等同于读取当前客户端写入的手动代理。

PAC 与绕过列表:按域名分流可能发生在客户端之前

PAC 脚本可以针对不同 URL 返回 DIRECT 或代理地址。如果 PAC 对目标域名返回 DIRECT,请求就不会进入 Clash,本地规则也无从接管。排查时记录原配置,暂时只保留一种代理入口,例如关闭自动脚本后使用手动 HTTP 代理,再对同一目标复测。

还要检查 Windows 的代理例外、macOS 的“忽略这些主机与域的代理设置”、Firefox 的“不使用代理”列表。localhost、127.0.0.1 和内部域名常被绕过,不能用访问本机页面来判断外部流量是否进入代理。测试时使用新请求,并查看客户端是否出现对应域名的连接,避免被浏览器缓存误导。

终端路线:先显式指定代理,再检查环境变量

终端是进程启动环境,不是浏览器。curl、Git、包管理器与脚本运行时各有代理读取方式;桌面系统代理开关不能保证这些工具自动使用代理。先让单次请求显式连接本地入口,可以绕开大部分环境变量与应用配置的干扰。

用 curl 建立最小测试

macOS 或 Linux 执行下面的命令。Windows PowerShell 使用同样参数,但把命令名写成 curl.exe,避免 Windows PowerShell 5.1 中的 curl 别名指向其他命令。

curl -v --noproxy "" --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 https://example.com/

--noproxy "" 用于清空本次请求的绕过列表,--connect-timeout 10 和 --max-time 20 分别设置连接阶段与整个请求的超时秒数。目标为 HTTPS 时,日志通常先显示连接本地代理,再显示 CONNECT 隧道过程。200 Connection established 只表示隧道建立,不代表后续 TLS 与网页请求一定完成。

  • Connection refused:优先检查本地端口、监听地址和内核是否运行。
  • 已连接本地端口,但 CONNECT 或后续请求超时:结合客户端日志检查策略组、节点和目标服务。
  • 显式代理成功,普通 curl 失败:重点检查环境变量和工具自身设置。
  • 证书错误:检查系统时间、证书信任链和受管理网络;不要把关闭证书验证当作长期修复。

macOS、Linux:在当前 shell 设置变量

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 --connect-timeout 10 --max-time 20 https://example.com/

https_proxy 表示访问 HTTPS 目标时选用的代理,变量值仍可使用 http://。curl 对 HTTP 代理变量只接受小写 http_proxy,不接受大写 HTTP_PROXY;其他工具的大小写支持也有差异,不能假定所有程序行为一致。

这些 export 只影响当前 shell 及其后续子进程,不会修改已经启动的程序。测试通过后,再按实际 shell 写入 ~/.zshrc 或 ~/.bashrc 等启动文件。IDE 内嵌终端可能继承 IDE 启动时的旧环境,需关闭并重新启动相关进程。

Windows 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 --connect-timeout 10 --max-time 20 https://example.com/

当前窗口关闭后,这些赋值不会自动保留。Windows 的桌面代理、WinHTTP 代理和进程环境变量是不同入口;netsh winhttp show proxy 显示的结果不能代表浏览器或 curl 的全部行为。只有确认目标程序使用 WinHTTP 时,才继续检查那条路径。

清理遗留变量与应用级代理

macOS、Linux 可运行 env | grep -i proxy;PowerShell 可运行 Get-ChildItem Env:*proxy*。重点检查指向旧端口的 ALL_PROXY、大写变量,以及范围过宽的 NO_PROXY。对 curl 而言,匹配的协议代理变量通常优先于 ALL_PROXY,绕过列表则可能让请求直接连接。

若只有 Git 失败,可用 git config --show-origin --get-regexp '.*proxy.*' 查看配置来源。包管理器也可能维护独立代理配置,应针对实际工具检查,不要同时改动所有全局配置。退出测试后,Unix shell 可用下面的命令移除当前会话的常见代理变量:

unset http_proxy https_proxy all_proxy no_proxy
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY

请求已进入 Clash:检查规则、DNS 与出站链路

如果浏览器与 curl 的目标都出现在客户端连接列表中,入口已经打通。此时继续切换系统代理通常没有帮助。打开对应连接详情,依次核对目标域名、命中规则、策略组和最终节点。

  1. 规则命中 DIRECT:确认是否符合预期。规则通常从上到下匹配,前面的直连规则可能先于后面的代理规则生效;同时检查规则集是否成功加载。
  2. 策略组选择 DIRECT:即使命中了代理策略组,组内手动选择仍可能是 DIRECT。检查实际选择,不只看组名。
  3. 节点连接失败:换用同组另一节点,对同一目标重试。延迟测试成功只说明测试目标可达,不能保证所有网站可达。
  4. DNS 报错:结合日志判断是目标域名解析失败、代理服务器域名解析失败,还是连接到解析服务器失败。不要在未区分原因时同时替换 DNS、规则和节点。

为验证是否是规则问题,可以短暂切换“全局”模式,并明确选择一个代理节点,完成单次测试后恢复“规则”。全局模式只改变进入内核后的出站选择,不会强制未使用代理的应用进入客户端。

TUN 模式的取舍:用于不读取代理设置的应用

当浏览器和显式代理测试均正常,而某些应用完全不读取系统代理或环境变量时,可考虑 TUN 模式。TUN 通过虚拟网卡与路由接管流量,适合需要统一处理更多 TCP、UDP 流量的场景;实际覆盖范围取决于路由、排除项、内核配置和平台权限,并非打开后所有连接都必然走远端节点。

  • Windows:按客户端要求安装服务模式或授予管理员权限,再开启 TUN,检查虚拟网卡和路由创建是否成功。
  • macOS:按客户端要求安装辅助服务、授权相关网络能力;如果启动失败,先看权限与路由日志。
  • Linux:确认 TUN 设备可用,并按客户端部署方式授予网络管理所需权限。容器或受限环境可能无法创建虚拟网卡。

mihomo 常见 TUN 配置会涉及 enable、stack、auto-route 和 dns-hijack 等字段,但不同版本与客户端可能由界面生成配置。优先使用当前客户端提供的开关,不要把其他平台的完整配置直接覆盖到现有订阅。

排查 TUN 时,先退出其他 VPN 或同类路由接管客户端,再按顺序测试 DNS、网页、终端和局域网服务。公司 VPN、虚拟机网卡和容器网络可能与自动路由发生冲突。开启后若本地服务不可达,应检查排除网段与路由,而不是盲目删除所有例外。

仅需要让 curl、Git 等少量工具使用代理时,显式参数或环境变量通常更容易定位问题;需要覆盖不支持代理设置的应用时,再引入 TUN。若 TUN 一开启就断网,先关闭它恢复网络,再检查权限、DNS 与路由日志。

复测清单:同一目标,分别验证三条路径

测试结果优先检查下一步操作
显式 curl 失败,连接被拒绝本地监听入口核对实际端口、进程与内核启动日志
显式 curl 成功,浏览器无连接记录浏览器代理来源检查扩展、PAC、例外与独立网络设置
浏览器成功,普通终端请求失败终端环境与应用配置检查代理变量、绕过列表和工具配置
两者都有连接记录但目标失败规则与远端出站核对 DIRECT、策略组、节点与 DNS 日志
仅 TUN 开启后失败权限、路由与网络冲突恢复原模式,逐项排查虚拟网卡和 DNS

最后固定一个目标域名,依次测试显式代理 curl、浏览器、未带显式参数的终端请求。每次记录客户端是否收到连接、命中哪条规则、最终使用哪个出站。三条路径都确认后,再恢复所需的 PAC、扩展或 TUN 设置,并把临时日志级别调回日常使用值。

下载Clash