先确认内核、规则模式与策略组

“大陆直连、境外代理”不是一个自动判断服务所在地的开关,而是逐条匹配连接的规则集合。Clash 从 rules 的第一行向下检查,遇到首条命中规则就采用其出站策略,不会继续寻找更具体的规则。因此,同一个域名写在不同位置,可能得到不同的路由结果。

本文以 Clash Meta 后续使用的 mihomo 内核为主要配置环境。客户端是管理界面,内核才负责解析规则;客户端名称相近,不代表支持的字段相同。旧版 Clash 内核不能直接照搬包含 GEOSITE 的示例。先在客户端的内核信息中确认实际内核,再检查日志有没有“未知规则类型”或数据文件加载失败。

修改前核对三件事

  1. 模式为 Rule:配置中的字段是 mode: rule。Global 模式使用全局策略,Direct 模式直连,均不按本文的规则列表分流。
  2. 代理组真实存在:本文用 境外代理 表示已有的策略组名称。必须把它替换成当前配置中实际存在的组名,并在代理页面为该组选择可用节点;仅修改规则不会创建节点。
  3. 保留原配置:先复制当前配置,再在副本中测试。订阅更新可能覆盖直接编辑的内容,长期使用应通过客户端支持的覆写或合并功能维护,并检查最终生效配置。

四类规则:域名、地理数据与规则集

类型匹配对象适用位置
DOMAIN-SUFFIX指定域名及其子域名少量站点的明确例外
GEOSITE域名分类数据大陆域名、境外服务分类
GEOIP目标 IP 所属区域已有目标 IP 时补充分流
RULE-SET外部或本地规则提供器独立维护一批站点规则

DOMAIN-SUFFIX:适合精确修正

DOMAIN-SUFFIX,github.com,境外代理 同时匹配 github.com 和 api.github.com,但不会匹配 githubusercontent.com。后者是独立域名,需要另一条规则。需要只匹配一个主机时,使用 DOMAIN,api.github.com,境外代理,避免把整个域名下的服务都归入相同出口。

GEOSITE:分类取决于数据文件

GEOSITE,cn,DIRECT 使用地理域名数据中的 cn 分类,不是“所有以 .cn 结尾的域名”。同样,常见数据集中的 geolocation-!cn 是一份境外域名分类,不等于数学意义上 cn 集合的完整补集。分类是否存在、覆盖哪些站点,取决于实际加载的数据文件及其更新时间。

使用本例前,确认 mihomo 已成功加载包含 cn 和 geolocation-!cn 的 geosite.dat,以及可用于 GEOIP 的地理 IP 数据。配置为 geodata-mode: true 时使用 geoip.dat;常见默认模式使用 MMDB 数据。不同客户端的数据更新入口不同,应以日志中的成功加载结果为准。

GEOIP:判断 IP,不判断网站归属

GEOIP,CN,DIRECT 判断目标 IP 是否属于中国大陆地址范围。境外服务使用大陆 CDN 时,它的 IP 也可能命中 CN;大陆服务使用境外云资源时,反过来也可能不命中。将域名分类放在 IP 分类之前,能够优先表达服务层面的访问意图。

规则尾部的 no-resolve 表示不为这条 IP 规则主动触发域名解析,不表示“禁止 DNS”。连接已有真实目标 IP 时仍可匹配;只有域名而没有可用真实 IP 时,这条规则可能被跳过。因此,加上它能减少规则匹配触发的解析,但不能保证所有未收录的大陆域名都直连。

规则顺序:局域网、明确例外、分类与兜底

下面的片段适合“大陆常用站点直连,其他流量默认代理”的需求。顺序是:局域网绕行、手动指定的境外站点、大陆域名分类、境外域名分类、大陆 IP、最终兜底。这里的 MATCH 无条件匹配剩余连接,必须放在最后。

# mihomo 配置片段;境外代理必须是已有策略组
mode: rule

rules:
  - DOMAIN,localhost,DIRECT
  - DOMAIN-SUFFIX,lan,DIRECT
  - IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - IP-CIDR,169.254.0.0/16,DIRECT,no-resolve
  - IP-CIDR6,::1/128,DIRECT,no-resolve
  - IP-CIDR6,fc00::/7,DIRECT,no-resolve
  - IP-CIDR6,fe80::/10,DIRECT,no-resolve

  - DOMAIN-SUFFIX,github.com,境外代理
  - DOMAIN-SUFFIX,githubusercontent.com,境外代理
  - DOMAIN-SUFFIX,githubassets.com,境外代理

  - GEOSITE,cn,DIRECT
  - GEOSITE,geolocation-!cn,境外代理
  - GEOIP,CN,DIRECT,no-resolve
  - MATCH,境外代理

为什么局域网规则要放最前面

路由器管理页、NAS 和公司内部服务通常使用私有地址。以 192.168.1.1 为例,送进远端代理并不能到达当前网络里的路由器。先直连私有地址,可以避免它们被最后的代理兜底接走。172.16.0.0/12 的范围是 172.16 到 172.31,不要误写成只覆盖一个小网段的 172.16.0.0/16。

域名规则只决定出站,不保证名称能解析。公司内部域名可能需要企业 DNS;.local 常用于 mDNS,也不能仅靠加一条域名直连规则解决。开启 TUN 时,还要检查内部网段的路由与 DNS 接管设置。规则命中 DIRECT 和系统能够访问局域网,是两个需要分别验证的条件。

兜底选代理还是直连

这里的“境外代理”是访问策略,不是对网络质量的承诺。策略组若选中了 DIRECT,规则虽然命中该组,最终仍然直连。排查时需要同时查看命中规则与最终出站链路。

RULE-SET:把常用站点独立维护

当手工域名规则逐渐增多,可以把它们迁移到规则提供器。下面采用本地 YAML 文件,不依赖远程规则下载;文件需要放在内核可读取的工作目录中。相对路径的基准通常是内核工作目录,不一定是当前订阅文件所在目录。

第一步:创建本地规则文件

保存为 rules/overseas.yaml。这是规则集文件,不是客户端主配置;根键必须是 payload。以下采用 classical 格式,条目包含规则类型,但不包含出站策略。

payload:
  - DOMAIN-SUFFIX,github.com
  - DOMAIN-SUFFIX,githubusercontent.com
  - DOMAIN-SUFFIX,githubassets.com

第二步:在主配置中声明并引用

把下面的提供器合并进已有 rule-providers,再用 RULE-SET 替换上一节三条 GitHub 域名规则。引用应位于局域网规则之后、GEOSITE 规则之前;下面只展示这个位置附近的片段,省略的既有规则应保留在实际配置中。

# 主配置片段:声明本地提供器
rule-providers:
  overseas-manual:
    type: file
    behavior: classical
    format: yaml
    path: ./rules/overseas.yaml
# rules 列表中对应位置的片段,不是完整列表
  - RULE-SET,overseas-manual,境外代理
  - GEOSITE,cn,DIRECT
  - GEOSITE,geolocation-!cn,境外代理
  - GEOIP,CN,DIRECT,no-resolve
  - MATCH,境外代理

behavior: domain、ipcidr 与 classical 对应不同条目格式,不能只改字段而继续使用原文件内容。若切换成 HTTP 提供器,还需要配置真实来源、缓存路径与更新间隔,并验证下载成功。规则列表里出现 RULE-SET 不代表规则文件已成功加载,应检查提供器状态和内核日志。

验证分流:看新连接,不只看网页是否打开

网页能打开,只能说明某条访问链路可用,不能证明走了预期出口。保存并重载配置后,在客户端的“连接”页面查看目标域名、目标 IP、命中规则和策略链;在“日志”页面检查规则文件加载错误。页面名称因客户端不同可能变化,重点是找到这四个字段,而不是只看代理开关。

可重复的检查步骤

  1. 确认配置中的 mode: rule 已生效,暂时使用 log-level: info。需要分析解析过程时再改为 debug,完成后恢复,避免长期产生大量日志。
  2. 关闭当前测试连接,再发起新请求。浏览器的连接复用可能继续使用原出口;修改规则后仍看到旧连接,不一定是新规则失效。
  3. 访问 github.com,预期命中手动域名规则或 overseas-manual,最终链路包含所选代理节点。
  4. 访问一个实际使用的大陆站点,检查是否命中 GEOSITE,cn;若落入 MATCH,先核对域名分类和 DNS 结果。
  5. 访问当前网络里真实存在的局域网设备,预期命中对应私有网段并使用 DIRECT。没有该设备时,不要把连接超时当作规则故障。

用指定代理入口测试

若实际生效配置设置了 mixed-port: 7890,可用下面的命令明确经过本地 HTTP 代理入口,排除系统代理没有应用到终端的问题。端口不是固定标准;实际端口不同就修改命令中的数字。

curl --proxy http://127.0.0.1:7890 --head --max-time 15 https://github.com

--max-time 15 将整个请求的最长等待时间设为 15 秒,不是对访问速度的实测结论。HTTP 状态码和响应时间不能单独证明规则命中,应与连接页面中的路由记录对应查看。这个命令测试的是显式代理入口,不等于验证全部 TUN 流量已被接管。

常见误写与 DNS、TUN 边界

现象优先检查修正方法
所有连接都走同一出口模式不是 Rule,或 MATCH 位于顶部启用规则模式,把兜底移到末尾
配置无法载入策略组名称、YAML 缩进、内核支持按日志定位,确认组名逐字一致
GEOIP 看起来没有生效no-resolve 与目标真实 IP 是否可用先确认 DNS 与域名规则命中情况
订阅更新后规则消失修改发生在生成文件而非覆写来源通过受支持的覆写机制维护并复查最终配置
境外服务部分资源加载失败资源域名与主页域名不同从失败连接记录补充独立域名规则
局域网域名无法打开内部 DNS、TUN 路由、目标可达性先确认能解析到正确地址,再检查直连规则

DNS 分流不等于连接分流

nameserver-policy 选择域名解析使用的 DNS 服务器,rules 选择应用连接的出口,两者职责不同。给大陆域名配置了本地 DNS,不会自动让它的连接直连;反过来,DIRECT 规则也不保证查询使用本地 DNS。需要控制解析链路时,应单独检查 dns 配置。

在支持相关字段的 mihomo 中,respect-rules 可以让 DNS 上游连接遵循路由规则,但启用前要正确设置 proxy-server-nameserver 等引导解析项,防止代理服务器域名解析又依赖代理本身。它不是添加到任意配置就能解决全部 DNS 问题的开关。

Fake-IP 与 TUN 不改变首条命中原则

Fake-IP 的作用是将映射地址与域名关联,供后续连接处理使用;它不会把所有站点自动分为大陆和境外。看到目标地址属于常用的 198.18.0.0/16 映射范围时,不应把整个范围加成 DIRECT 来“修复分流”,而应确认域名映射和规则匹配是否正常。

TUN 扩大的是接管范围,不是把规则模式变成全局代理。系统代理只影响遵循代理设置的应用,TUN 则可接管更多 IP 流量,但仍受权限、路由和排除项影响。只有进入内核的连接才会应用这些规则;其他 VPN、系统路由或应用自行建立的连接,都需要分别确认。