1. 日志采集:先固定请求,再提高日志级别

Clash 客户端的界面日志与内核运行日志不是同一层。界面日志可能记录订阅下载、服务启动和配置合并;内核日志主要记录监听端口、DNS、规则匹配和出站连接。网页打不开时,应先确认内核已经启动,再检查该次请求是否进入内核。只有客户端界面的报错截图,通常不足以判断节点或规则问题。

最小复现记录

  1. 记录客户端名称、客户端版本、内核名称及完整版本号。Clash 原版与 mihomo 支持的字段不同,不能只写“最新版”。
  2. 记录当前配置名称、运行模式,以及系统代理或 TUN 是否开启。排查规则时使用规则模式,避免全局模式绕过预期规则。
  3. 清空当前日志视图,记下时间,只访问一个有问题的地址。等待约 10 秒后停止重复刷新,保存同一时间窗口的日志。
  4. 同时查看连接列表中的目标、命中规则、策略组和最终节点。日志未提供的出站信息,可用连接列表补齐。

需要增加细节时,在当前客户端的日志页面调整级别;如果界面没有入口,可在其支持的配置编辑或覆写功能中设置下列字段。订阅客户端可能重新生成运行配置,应检查最终生效值,不能只修改随后会被覆盖的订阅缓存文件。

log-level: debug
级别典型用途阅读重点
debug短时复现疑难故障DNS、连接及内核提供的调试细节
info日常运行观察启动信息、规则命中与连接记录
warning筛选异常事件失败连接、资源加载异常
error关注较严重错误配置加载和关键组件错误
silent关闭常规日志输出不适合故障复现阶段

具体消息的级别由内核决定,warning 不一定代表整个代理服务停止。问题复现完成后,将级别恢复为 info。分享日志前隐藏订阅地址中的令牌、节点密码、控制接口密钥和个人访问域名,保留端口、错误类型及规则顺序。

2. dial tcp 超时:区分节点连接与目标连接

dial tcp 表示程序正在建立 TCP 连接,不等于“DNS 出错”,也不能单凭这两个词断定节点失效。关键是后面的地址属于谁:代理服务器、直连目标,还是代理链中的下一跳。以下片段仅演示错误结构,地址使用文档示例地址,不是可用节点。

dial tcp 192.0.2.10:443: i/o timeout
dial tcp 192.0.2.10:443: connect: connection refused
dial tcp [2001:db8::10]:443: connect: network is unreachable

三类错误的排查方向

  • i/o timeout:连接或读写在期限内未完成。检查该行对应的节点地址、端口、出站接口和网络路径,不要直接通过增加超时时间掩盖问题。
  • connection refused:通常收到明确拒绝。优先检查端口填写、远端服务是否监听,以及本机或中间设备的拒绝策略。
  • network is unreachable:当前网络栈没有可用路径。若目标是 IPv6 地址,先核对系统 IPv6 路由,不要立即归因于节点密码。

如果错误指向节点服务器,先切换到同一策略组内另一个已知可用节点,再复现同一目标。若只有某个节点失败,检查该节点的服务器域名、端口和协议参数;若多个节点同时失败,检查本地网络、节点域名解析和代理回环。节点测速成功只说明测速所覆盖的请求成功,不能证明所有网站或 UDP 流量正常。

如果连接列表显示 DIRECT,失败的可能是目标网站的直连路径。此时先核对命中的规则,不要在没有证据时重装客户端。规则按顺序匹配,较靠前的 DOMAIN-SUFFIX 或规则集可能已经决定出站,后面的 MATCH 不会再改变结果。

3. DNS 解析失败:沿解析链逐层确认

no such host 常见于名称不存在或解析链返回了否定结果;lookup ... i/o timeout 更接近 DNS 请求未及时获得响应;SERVFAIL 表示解析服务未能完成查询。它们是不同信号,不能统一用更换代理节点处理。

先确定正在解析哪个域名

  1. 目标网站域名:检查内核 DNS 是否启用、应用是否使用系统 DNS,以及 Fake-IP 请求是否确实进入内核。
  2. 节点服务器域名:检查节点域名的解析路径。mihomo 可使用 proxy-server-nameserver 指定节点域名解析器,具体行为以当前内核版本文档为准。
  3. 加密 DNS 服务器域名:检查用于启动解析的 default-nameserver。上游解析器自身的域名无法解析时,会出现解析链无法启动的问题。

下面是监听本机 1053 端口的最小 DNS 诊断片段。应合并到现有的唯一一个 dns 映射中,保留与当前环境相关的其他字段。它使用普通 DNS 作为定位工具,不是所有网络环境通用的最终配置,也不会自动修改系统 DNS。

dns:
  enable: true
  listen: 127.0.0.1:1053
  enhanced-mode: redir-host
  nameserver:
    - 223.5.5.5

安装了 dig 的环境可直接测试这个监听端口。下面两条命令分别查询 IPv4 和 IPv6 记录;没有 AAAA 记录不等于 A 记录解析失败。

dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com AAAA

如果本机监听端口查询成功,而应用仍报解析失败,应检查应用自带的安全 DNS、浏览器 DNS 缓存和实际接管路径。如果监听端口也失败,再查看上游 DNS 是否可达,以及启用 respect-rules 等功能后是否形成解析依赖环。不要一次同时更改上游、Fake-IP 和路由规则,否则难以确定哪个改动有效。

4. 端口占用:定位监听者与实际代理端口

启动时出现 bind: address already in use,通常意味着监听地址与端口发生冲突。Windows 也可能显示“通常每个套接字地址只允许使用一次”。permission denied 则需要另外检查权限、安全策略或端口保留,不能全部归类为已有进程占用。

先从错误行读出具体端口,再查配置字段。例如 mixed-port: 7890 同时提供 HTTP 与 SOCKS 代理入口,external-controller: 127.0.0.1:9090 是管理接口,二者用途不同。以下端口仅为诊断示例,客户端实际端口以运行配置为准。

Windows:查看 7890 的监听进程

netstat -ano | findstr :7890
tasklist /FI "PID eq 1234"

第一条命令也可能匹配远端端口,应查看本地地址列及 LISTENING 状态。第二条命令中的 1234 是示例 PID,执行时替换为第一条输出中的实际进程号。优先从客户端正常退出重复运行的实例,不要直接结束不明系统进程。

macOS 与 Linux:只看 TCP 监听者

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

# Linux
ss -ltnp 'sport = :7890'

Linux 显示其他用户的进程信息时可能需要管理员权限。若改用 7891,必须同步修改系统代理、浏览器手动代理或终端环境变量;只改内核端口会导致应用继续连接旧端口。allow-lan 影响局域网访问范围,不是修复本机端口冲突的开关。

5. 配置解析错误:语法、字段、引用分开检查

配置无法加载时,应先处理启动错误,再讨论网络。yaml: line ... 通常指向 YAML 解析问题;proxy ... not found 一类信息通常涉及引用名称;协议类型不支持或字段无法识别,则可能是内核兼容性问题。错误行是定位起点,真正的缩进错误也可能发生在前一段。

  • 缩进:使用空格,不使用 Tab。同级键保持同一缩进,列表项保留 - 后的空格。
  • 重复键:不要在同一层再加第二个 dns、rules 或 proxy-groups。不同解析器可能报错或覆盖内容,结果不可靠。
  • 名称引用:规则引用的策略组、策略组引用的节点,以及 RULE-SET 引用的规则提供者,必须与定义名称一致。
  • 内核能力:VLESS、Hysteria2 等配置不能假设原版 Clash 均可读取。先核对实际运行的内核,而不是仅看客户端名称。
  • 远程资源:规则集下载失败属于资源加载问题,不一定是 YAML 语法错误。继续检查对应提供者的 URL、文件格式、缓存路径及下载时使用的网络路径。

直接运行 mihomo 内核时,可以先进行配置测试。以下命令要求当前目录存在对应可执行文件及配置;测试用的配置应尽量与客户端实际生成的运行配置一致。

# macOS / Linux
./mihomo -t -f ./config.yaml

# Windows PowerShell
.\mihomo.exe -t -f .\config.yaml

配置测试通过只说明该次检查未发现阻止加载的问题,不保证节点可达或所有规则集都能按预期工作。如果订阅原文通过测试、客户端启动仍失败,应检查覆写、脚本合并和客户端生成配置的差异。修改前保存副本,每次只修复一种错误,再重新测试。

6. 系统代理与 TUN:用同一请求比较接管路径

“浏览器能打开,终端不能”通常需要检查应用是否遵循系统代理。系统代理并不会自动接管所有程序;TUN 则涉及虚拟网卡、路由与 DNS 接管,排查面更大。不要在缺少对照结果时同时打开多个代理工具和多个 TUN 实例。

先验证显式代理入口

假设运行配置的混合端口确实为 7890,可通过以下请求绕开应用是否读取系统代理的差异。Windows PowerShell 使用 curl.exe,避免旧版环境中的命令别名影响结果;macOS、Linux 可将命令名改为 curl。

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

这条命令把连接阶段上限设为 10 秒、总时间上限设为 20 秒,便于对齐日志时间,并非实测延迟。立即无法连接 127.0.0.1:7890 时先查监听;已建立代理隧道但 TLS 失败时检查后续握手;出现 HTTP 响应后再判断状态码,403 等响应不能简单等同于代理入口故障。

再比较 TUN 接管

如果显式代理成功、普通应用请求失败,重点检查系统代理设置、应用独立代理与 TUN 路由。启用 TUN 后出现故障时,可在保留配置副本的前提下暂时关闭 TUN,以显式代理结果作对照。需要检查的字段包括 tun.enable、auto-route 和 dns-hijack,但实际支持与权限要求取决于内核、客户端和操作系统。

不要把 dns-hijack 理解为能拦截所有加密 DNS:常规 DNS 劫持配置主要处理匹配的 DNS 流量,应用自己的 HTTPS DNS 请求仍可能走独立路径。若日志完全没有对应连接,先确认请求是否进入内核;若已经进入,再沿规则、出站、解析和握手阶段逐层定位。

7. 修复验收:保留可复现证据

故障关闭前,用原先失败的同一个地址重复测试,并确认日志中的命中规则和出站节点符合预期。只看到首页打开一次,不能证明订阅更新、DNS 与后台应用都已恢复。

  1. 启动验收:内核完成加载,代理入口正常监听,没有重复的端口绑定错误。
  2. 请求验收:原始请求成功,日志中不再出现该请求对应的重复超时或解析错误。
  3. 路径验收:直连与代理规则分别命中预期策略,TUN 开关状态与使用需求一致。
  4. 配置持久化:重启客户端或更新订阅后,修改仍然生效,没有被配置生成流程覆盖。

仍需反馈问题时,整理“客户端与内核版本、系统版本、复现时间、目标类型、相关配置片段、前后连续日志、已做的单项测试”。这些信息比单独截取最后一行 timeout 更容易定位。字段含义可查阅协议参考;规则、DNS 与 TUN 的概念区别可查阅概念速查。