分流前提:规则模式与代理策略组

国内直连、国外代理根据域名集合、目标 IP 所属地址段和规则顺序选择出口。中文页面可能使用境外接口,境外服务也可能接入中国大陆的 CDN。因此,配置目标应当是“已知国内域名直连,其余请求按明确策略处理”,而不是把域名后缀当作服务器所在地。

下文适用于使用 Mihomo 内核的客户端。开始前,将运行模式切换为 Rule,确认已经导入可用节点,并且配置中存在名为 PROXY 的策略组。DIRECT 是内核内置的直连策略,不需要自行创建;PROXY 只是本文使用的组名,不是自动存在的内置出口。

  • 如果实际组名是“节点选择”,把示例中作为规则目标的 PROXY 全部改为“节点选择”。组名必须逐字一致。
  • 先备份当前配置,再通过客户端的覆写或合并功能保存本地规则。直接修改订阅生成文件,可能在下次订阅更新时被覆盖。
  • 确认应用流量确实进入内核。启用系统代理不代表所有应用都使用代理;TUN 可以接管更多流量,但不会改变规则首条命中的顺序。

GEOSITE 方案:先域名,再 IP,最后兜底

已有可用 GeoSite 与 GeoIP 数据时,可以先用下面的规则建立基线。局域网地址放在前面,避免本地服务进入代理;域名规则先于 IP 归属规则,防止境外服务因为解析到中国大陆地址而被提前直连。

mode: rule

rules:
  - DOMAIN-SUFFIX,localhost,DIRECT
  - DOMAIN-SUFFIX,local,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-CIDR6,::1/128,DIRECT,no-resolve
  - IP-CIDR6,fc00::/7,DIRECT,no-resolve
  - IP-CIDR6,fe80::/10,DIRECT,no-resolve
  - GEOSITE,cn,DIRECT
  - GEOSITE,geolocation-!cn,PROXY
  - GEOIP,CN,DIRECT,no-resolve
  - MATCH,PROXY

每一层负责什么

规则层匹配依据处理结果
局域网例外本地域名、回环与私有地址段DIRECT
GEOSITE,cn数据文件中的 cn 域名集合DIRECT
GEOSITE,geolocation-!cn数据文件中的对应域名集合PROXY
GEOIP,CN已知目标 IP 的归属DIRECT
MATCH此前均未命中的连接PROXY

GEOSITE 匹配域名分类,不负责判断当前服务器的物理位置。geolocation-!cn 是数据集中的分类名称,不是把 cn 结果实时取反的表达式。不同数据源的收录范围不同,也可能没有这个分类;遇到分类不存在的报错,应先核对客户端使用的 GeoSite 来源。

GEOIP,CN,DIRECT,no-resolve 中的 no-resolve 表示不为了这条规则主动触发域名解析。若连接已有可用的真实目标 IP,可以据此判断;如果当前只有域名且前面的域名集合均未命中,这条规则可能被跳过,随后由 MATCH 处理。这是减少额外解析的取舍,不等于全部国内 IP 都一定直连。

Geo 数据的更新边界

GeoSite 与 GeoIP 是本地数据文件,首次加载需要可用文件或可访问的下载来源。更新订阅不一定会更新这些数据。应分别检查客户端的 Geo 数据管理项、内核加载日志和实际数据源;不要在 Geo 数据报错时只反复刷新节点订阅。

rule-providers 方案:独立更新远程规则集

需要单独维护规则来源与更新周期时,可以改用 rule-providers。提供器负责下载和解析集合,RULE-SET 负责在规则列表的具体位置引用集合。仅声明提供器不会自动分流,也不会自动把集合插到规则顶部。

下面使用 Loyalsoldier/clash-rules 的公开发布文件作为语法示例。两个文件是 YAML 域名集合,因此使用 behavior: domain 和 format: yaml。部署前应核对来源内容与当前网络的可达性;这些地址不是节点订阅地址。

rule-providers:
  overseas-domains:
    type: http
    behavior: domain
    format: yaml
    url: "https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/proxy.txt"
    path: ./ruleset/overseas-domains.yaml
    interval: 86400

  domestic-domains:
    type: http
    behavior: domain
    format: yaml
    url: "https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/direct.txt"
    path: ./ruleset/domestic-domains.yaml
    interval: 86400

rules:
  - DOMAIN-SUFFIX,localhost,DIRECT
  - DOMAIN-SUFFIX,local,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-CIDR6,::1/128,DIRECT,no-resolve
  - IP-CIDR6,fc00::/7,DIRECT,no-resolve
  - IP-CIDR6,fe80::/10,DIRECT,no-resolve
  - RULE-SET,overseas-domains,PROXY
  - RULE-SET,domestic-domains,DIRECT
  - MATCH,PROXY

这份列表可以替换上一节的 rules,不要把两份完整列表前后拼接。前一份的 MATCH 已经匹配所有剩余连接,放在它后面的任何规则都不会参与判断。这里故意不依赖 GeoIP,未收录域名和未被局域网规则匹配的 IP 连接统一由代理兜底。

  • interval: 86400 的单位是秒,即每 24 小时检查更新;它不是缓存文件的有效期承诺。
  • path 是相对于内核工作目录的本地文件路径。两个提供器使用不同路径,避免相互覆盖。
  • overseas-domains 与 domestic-domains 是自定义名称,必须与 RULE-SET 中的名称完全一致。
  • 该示例把代理集合放在直连集合之前。若两个集合重叠,先命中的代理规则获胜;不能假设不同维护者的集合绝不重叠。

规则格式:domain、ipcidr 与 classical

远程地址能打开,不代表内容格式正确。订阅服务返回的节点配置、包含登录提示的 HTML,以及单纯的域名文本,不能不加区分地交给同一种解析方式。behavior 决定条目的含义,format 决定文件的编码形式,两者要同时对应来源。

behaviorYAML payload 条目示例适用内容
domain'+ .example.com' 不正确;应写 '+\.example.com' 之外的标准形式 '+ .' 也不可用,正确条目见下方代码域名匹配集合
ipcidr'192.168.0.0/16'IP 地址段集合
classical'DOMAIN-SUFFIX,example.com'带规则类型的条目

域名集合的简洁写法如下。+.example.com 表示匹配根域名及其子域名,中间没有空格,也不需要反斜杠:

payload:
  - '+.example.com'
  - 'api.example.net'

若使用 classical,同类内容应写为以下形式。规则集条目中不写出口;出口由外层的 RULE-SET,集合名称,策略 指定。

payload:
  - DOMAIN-SUFFIX,example.com
  - DOMAIN,api.example.net

文件扩展名不是解析依据。上文的 direct.txt 虽然以 .txt 结尾,内容仍是带 payload 的 YAML,因此配置为 format: yaml。如果换成每行一个条目的纯文本来源,才应按该来源要求使用 format: text。

例外规则与 DNS:避免国内接口误走代理

把具体例外放在集合之前

若某项服务因为登录风控、内网访问或本地设备发现需要直连,先从连接记录获取实际请求域名,再添加精确规则。不要因为一个接口异常,就把整组境外域名切换为直连。下面是语法示例,example.com 是说明用途的保留域名,实际使用时应换成连接记录中的目标。

rules:
  - DOMAIN,api.example.com,DIRECT
  - DOMAIN-SUFFIX,example.com,PROXY
  - RULE-SET,overseas-domains,PROXY
  - RULE-SET,domestic-domains,DIRECT
  - MATCH,PROXY

在这个顺序中,api.example.com 先命中直连,其他 example.com 子域名再交给代理。这体现的是先具体、后宽泛,而不是 DOMAIN 天生比 DOMAIN-SUFFIX 优先;将两条交换位置,结果也会随之改变。

分流规则不等于 DNS 分流

GEOSITE,cn,DIRECT 决定连接出口,并不直接指定由哪台 DNS 服务器查询域名。DNS 上游选择需要检查 dns 中的相关设置,例如 nameserver 与 nameserver-policy。如果启用 respect-rules 让 DNS 连接遵循路由规则,还应按当前内核文档配置节点域名解析所需的 proxy-server-nameserver,避免形成解析依赖环。

Fake-IP 返回合成地址,由内核维护域名与连接的对应关系;不能看到合成 IP 就直接拿它判断真实归属。redir-host 则更依赖真实解析结果。两种模式都应先观察连接记录里的域名、命中规则和最终出口,再判断问题发生在解析阶段还是分流阶段。

验证与排障:按连接记录逐项确认

保存配置后,先确认配置校验与重新加载成功,再测试新连接。已经建立的长连接可能继续使用原出口;改变规则后,关闭相关连接或重启测试应用,比反复刷新同一个页面更有判断价值。

  1. 检查运行模式。确认当前是 Rule。在 Global 下观察全局出口,不能用来验证这份规则列表是否正确。
  2. 检查流量入口。如果客户端显示的本地混合端口确实是 7890,可用下方命令显式指定代理进行测试。若端口不同,应使用界面显示的实际值。
  3. 检查匹配结果。在客户端连接列表中分别记录目标域名、规则类型、规则载荷、策略组和实际节点。命中 PROXY 不代表最终一定使用远程节点,该组也可能选中了 DIRECT。
  4. 检查提供器状态。核对更新时间与条目数量。日志出现下载超时,优先检查远程地址和下载链路;出现解析错误,先检查文件是否返回 YAML、纯文本或 HTML。
  5. 检查最终合并配置。确认本地覆写没有被订阅规则覆盖,自定义规则位于兜底规则之前,且规则目标名称全部存在。
curl --proxy http://127.0.0.1:7890 --head https://www.baidu.com
curl --proxy http://127.0.0.1:7890 --head https://www.wikipedia.org

以上命令只用于产生便于追踪的 HTTP 代理连接,不代表这两个域名在所有来源里都必然命中某个集合。HTTP 状态码也不能单独证明分流成功:服务端可能返回重定向或拒绝访问,仍需结合内核连接记录判断出口。

常见现象与处理顺序

  • 国内网站走代理:先看是否命中 MATCH。若是,检查域名是否被直连集合收录;若不是,检查前置代理规则或集合重叠。
  • 境外网站显示直连:检查是否被前面的域名例外或 GEOIP,CN 命中,再检查代理组是否选择了直连出口。
  • 浏览器正常,其他应用异常:检查该应用是否遵循系统代理,以及是否需要 TUN 接管。不要先把问题归因于规则集缺少域名。
  • 规则更新后没有变化:确认更新的是规则提供器而不是节点订阅,再建立新连接复测,并检查客户端是否仍加载另一份配置。

维护时保留一份小而明确的本地例外列表,再选择 GeoSite 或远程规则集作为主要分类来源。每次只改一类规则,记录改动前后的命中结果。这样可以区分数据收录、规则顺序、DNS 解析与流量接管四类问题,避免靠不断叠加集合掩盖真正原因。