先区分:内核运行、系统代理与应用请求

客户端显示“运行中”,通常只说明代理内核已经启动,不代表浏览器正在使用它。节点延迟测试成功,也只能说明该次测试所走的链路可用,不能证明网页请求命中了同一个节点。排查时需要把三个环节拆开:本地端口有没有监听,应用有没有把请求交给端口,内核收到请求后如何转发。

Clash 及 Clash Meta(现称 mihomo)内核负责接收和转发连接;桌面客户端的“系统代理”开关通常负责修改操作系统代理设置。两者不是同一个开关。Chrome、Edge 一般读取系统代理,Firefox 可以单独设置代理,终端程序则经常读取环境变量或自己的配置。

  1. 记录客户端名称、内核名称、当前模式和本地监听端口。
  2. 使用一个固定测试地址,例如 https://example.com/,避免每次更换目标。
  3. 打开客户端连接列表和日志,再发起一次请求,核对时间、域名、规则与出口策略。
  4. 一次只改一项。测试后恢复临时设置,保留修改前后的结果。

第一步:确认本地代理端口能够接收连接

分清 HTTP、SOCKS 与混合端口

在客户端的设置或运行配置中查找 port、socks-port、mixed-port。菜单名称随客户端变化,以实际运行配置为准。下面是字段含义示例,不需要把三个端口全部加入现有配置,更不要覆盖订阅中的节点和规则。

# 字段示例:以当前内核实际生效的配置为准
port: 7890
socks-port: 7891
mixed-port: 7892
allow-lan: false
  • port:HTTP 代理入口,HTTPS 网站通常通过 HTTP CONNECT 建立隧道。
  • socks-port:SOCKS 代理入口,不能直接当作 HTTP 代理端口填写。
  • mixed-port:同一个入口接受 HTTP 和 SOCKS 代理连接。

只在本机使用时,地址优先填写 127.0.0.1。系统代理指向 7890,内核却只在 7892 监听,是常见的端口错配。不要为了修复本机连接而开启“允许局域网连接”,这个选项不负责让本机端口启动。

检查监听状态和占用进程

Windows 打开 PowerShell,先测试端口,再查询监听进程。TCP 测试通过只代表有程序接收连接,还要确认监听者确实是当前使用的代理内核。

Test-NetConnection 127.0.0.1 -Port 7890
Get-NetTCPConnection -LocalPort 7890 -State Listen |
  Select-Object LocalAddress, LocalPort, OwningProcess
# 将查询到的进程号代入;以下 1234 仅为演示
Get-Process -Id 1234

macOS 可使用下面的命令;Linux 可执行 ss -lntp 后查找对应端口。部分进程信息需要适当权限才能显示。

lsof -nP -iTCP:7890 -sTCP:LISTEN

如果日志出现 address already in use,先退出其他代理客户端,再重启当前内核。若调整了监听端口,需要同步更新系统代理、浏览器手动代理和终端变量。不要直接结束用途不明的进程,也不要同时运行两个客户端争抢同一个端口。

第二步:用显式代理测试划分故障范围

先绕过系统代理设置,明确告诉 curl 使用哪个本地端口。这样可以把“应用没有使用代理”与“代理本身转发失败”分开。Windows 使用 curl.exe,避免 Windows PowerShell 5.1 中 curl 别名带来的参数差异;macOS 和 Linux 使用 curl。

# Windows PowerShell:显式使用 HTTP 或混合代理端口
curl.exe -v --connect-timeout 5 --max-time 20 --noproxy "" --proxy http://127.0.0.1:7890 https://example.com/

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

# 只有实际 SOCKS 端口为 7891 时才使用这一条
curl -v --connect-timeout 5 --max-time 20 --noproxy "" --proxy socks5h://127.0.0.1:7891 https://example.com/

--noproxy "" 用于清空本次请求的绕过列表,避免已有 NO_PROXY 干扰。socks5h 将目标主机名交给代理解析;socks5 则通常由本机先解析。两者结果不同,可以作为 DNS 排查线索,但不能仅凭一次差异就认定某个 DNS 服务故障。

测试结果说明与下一步
连接 127.0.0.1 被拒绝先查地址、端口、内核运行状态,不必急着更换节点。
本地端口连接成功,随后超时查看该请求的策略组、节点、DNS 与远端连接日志。
显式代理成功,浏览器失败优先检查系统代理设置、浏览器代理模式及扩展。
浏览器成功,终端普通请求失败优先检查环境变量、工具独立设置及进程启动时间。
只对部分域名失败核对命中规则、绕过列表、目标站点响应和 DNS 路径。

HTTPS 测试中看到 200 Connection established,通常只说明 CONNECT 隧道已建立,仍要继续看后续 TLS 和网页响应。出现 403 也不等于系统代理失效:它可能来自目标网站的访问策略。完整结果比单个状态码更有用。

第三步:浏览器不走代理,按系统与扩展分开查

Windows:检查当前系统代理,而不是只看客户端开关

  1. Windows 11 进入「设置」→「网络和 Internet」→「代理」→「手动设置代理」。Windows 10 对应「设置」→「网络和 Internet」→「代理」。
  2. 检查代理地址是否为当前本机入口,例如 127.0.0.1,端口是否与内核一致。
  3. 检查“使用设置脚本”是否启用。脚本地址属于 PAC 配置,可能按规则让部分域名直连,不应与手动代理混在一起凭感觉判断。
  4. 检查代理例外列表。目标域名若在例外中,浏览器可能绕过代理。

先关闭另一个代理工具的自动接管,再切换一次当前客户端的系统代理开关,观察系统设置是否跟着变化。公司管理的设备可能受组织策略控制,遇到设置被自动恢复的情况,应联系管理员,不要反复改注册表。

netsh winhttp show proxy 显示的是 WinHTTP 代理配置,不等于 Chrome、Edge 正在使用的系统代理状态。看到 WinHTTP 为直连,不能据此断言浏览器代理没有启用,也不需要为了浏览器访问而盲目执行导入或重置命令。

macOS:检查当前正在使用的网络服务

macOS 13 及以后可进入「系统设置」→「网络」→当前连接的 Wi-Fi 或以太网→「详细信息」→「代理」。确认修改的是正在使用的网络服务,而不是已经断开的接口。HTTP 网页代理与 HTTPS 安全网页代理都要核对;若两项均指向本机 HTTP 入口,端口应与客户端一致。

HTTPS 网站使用本机 HTTP 代理入口是正常情况,地址不必改成 https://127.0.0.1。对于常见 Clash 本地 HTTP 入口,客户端与本机代理之间通常不是 TLS 连接,HTTPS 加密发生在隧道内部。

Firefox 与代理扩展:一次只保留一个配置来源

Firefox 进入「设置」→「常规」→「网络设置」→「设置」,检查是否选择“使用系统代理设置”。如果使用手动代理,就直接核对地址、端口和“不使用代理”列表。Chrome、Edge 还需要检查代理切换扩展的当前情景模式,以及扩展是否被企业策略管理。

  • 临时停用代理切换扩展后重新测试;隐私窗口并不必然停用所有扩展。
  • 彻底退出浏览器后重开,避免旧连接复用掩盖配置变化。
  • 发起测试请求时观察客户端连接列表。没有记录是入口或绕过问题的线索,但也要排除页面缓存、请求未发出和记录筛选。
  • Linux 桌面代理不是所有应用都遵循;显式代理测试成功后,再按应用实际支持的方式配置。

第四步:终端不走代理,检查环境变量与工具配置

系统代理不是给所有进程强制加上的转发层。终端里的 curl、Git、包管理器可能读取环境变量,也可能使用各自的代理配置。已经打开的终端或 IDE 不一定能获得后来新增的环境变量,因此测试先限定在当前会话,不要一开始就写入全局配置。

macOS 与 Linux:当前 shell 设置

# 查看已有代理变量,注意不要把含凭据的输出公开
env | grep -iE '^(http|https|all|no)_proxy='

# 当前终端有效,端口按实际配置修改
export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890

# 这次请求应读取上面的变量
curl -v --connect-timeout 5 --max-time 20 https://example.com/

# 排查结束后,移除本次添加的变量
unset http_proxy https_proxy

https_proxy 的值使用 http:// 并不矛盾:变量名说明目标 URL 使用 HTTPS,变量值说明如何连接代理服务器。curl 对 HTTP 代理变量有大小写规则,优先使用这里的小写写法;其他工具支持哪些变量,应查看对应工具文档。

Windows PowerShell:使用进程级变量

# 查看当前进程中已有的代理环境变量
Get-ChildItem Env: | Where-Object Name -Match '^(HTTP|HTTPS|ALL|NO)_PROXY$'

# 当前 PowerShell 会话及其后续子进程有效
$env:http_proxy = "http://127.0.0.1:7890"
$env:https_proxy = "http://127.0.0.1:7890"
curl.exe -v --connect-timeout 5 --max-time 20 https://example.com/

# 仅在这些变量是本次临时新增时删除
Remove-Item Env:http_proxy, Env:https_proxy -ErrorAction SilentlyContinue

如果变量原先已有值,应记录并在测试后恢复,而不是直接删除。特别检查 NO_PROXY 是否包含目标域名,或被设置为 *;通配绕过可能让支持它的工具对全部目标直连。设置了 ALL_PROXY 时,也要核对是否残留旧的 SOCKS 端口。

Git、WSL 与容器:不要假定共享同一个入口

Git 可用下面两条命令查看代理值及其来源。来源可能是系统、用户或仓库配置,修复时应修改对应层级,避免只删除用户配置却遗漏当前仓库设置。输出若含用户名、口令或内部地址,分享前需要遮盖。

git config --show-origin --get-regexp 'http\..*proxy'
git config --show-origin --get-regexp 'remote\..*proxy'

WSL、容器和虚拟机内的 127.0.0.1 不一定指向宿主系统。WSL 的 NAT 与镜像网络行为不同,容器通常也有独立网络空间。应先确认运行环境和宿主机可达地址,再判断是否需要调整监听地址与防火墙;不要直接把代理暴露到所有网卡。SSH 形式的 Git 远程地址也不会因为设置了 HTTP 代理,就自动改走同一条链路。

第五步:请求已进入 Clash,再查规则、DNS 与 TUN

连接列表有记录:检查实际命中的出口

当客户端已经记录目标域名,排查重点就应从“系统代理开关”移到转发路径。规则模式按顺序匹配,命中 DIRECT 就会直连;策略组也可能实际选中了直连项,而不是预期的代理节点。检查连接详情中的规则、策略链和目标地址,比反复切换开关更直接。

  1. 保持目标地址不变,记录当前规则和最终选中的出口。
  2. 短暂切换全局模式,并明确选择一个代理节点,再请求同一地址。
  3. 若只有全局模式成功,回到规则模式检查具体域名规则、规则集与兜底项。
  4. 测试完成恢复原模式。全局模式是对照手段,不是所有问题的长期修复方案。

可以把日志级别临时调到 debug,复现一次后恢复为 info。connection refused 要看被拒绝的是本地入口还是远端服务;i/o timeout 要看超时发生在 DNS、节点拨号还是目标连接。不要只截取报错最后两个单词。

DNS 和 TUN:分别验证,不一起改动

显式 HTTP 代理、SOCKS、本机直连、浏览器安全 DNS 与 TUN DNS 接管可能使用不同解析路径。nslookup 成功只证明该命令所用路径能解析,不能证明内核正在使用相同结果。若请求出现域名解析错误,结合内核日志检查 dns 配置,参考 DNS 配置说明,不要一次替换全部上游服务器。

TUN 用虚拟网络接口接管匹配的流量,适合处理不读取显式代理设置的程序,但并非“系统代理开关的加强版”。它还涉及权限、路由、DNS 和其他 VPN 的兼容。系统代理与 TUN 同时开启时,测试结果可能来自另一条入口。

收尾:保留证据,恢复临时配置

提交问题时,提供可复现的最小记录:操作系统、客户端与内核版本、HTTP/混合端口、是否启用 TUN、浏览器名称、显式 curl 测试结果,以及同一时刻的连接详情。版本号应从实际客户端读取,不要只写“最新版”。

  • 记录“显式代理成功、浏览器失败”这类对照结论,而不是只写“连不上”。
  • 注明具体时间和目标域名,便于从日志找到同一次请求。
  • 遮盖订阅链接、节点口令、请求中的 Cookie、授权头与敏感查询参数。
  • 恢复临时修改的模式、日志级别、浏览器扩展状态和环境变量。

最终判断顺序保持不变:端口监听正常,再验证显式代理;显式代理成功,再分别配置浏览器与终端;请求进入内核后,再查规则、节点与解析。这样每一步都有可观察的结果,不需要把重装客户端作为第一项操作。