进阶配置 预计阅读 11 分钟

Clash 自定义规则

拆解规则条目的三段式语法,讲清自上而下逐条匹配的顺序逻辑,以及规则集、MATCH 兜底与常见写错位置的排查方法。

规则优先级:先匹配,后选出口

Clash 规则不是按域名精确程度自动排序,而是按配置中的顺序从上到下匹配,命中后停止。精确域名、域名后缀和规则集之间,没有“精确规则天然优先”的隐藏等级。因此,例外规则放前面,通用规则放后面,MATCH 放最后,是最容易维护的排列方式。

还要区分两个阶段:规则决定连接交给哪个策略,策略组再决定使用哪个出口。如果规则命中了“业务策略”,但这个组当前选中 DIRECT,连接仍然直连。这不是规则失效,而是策略组的实际选择与预期不同。

顺序颠倒会发生什么

rules:
  - DOMAIN-SUFFIX,example.org,业务策略
  - DOMAIN,login.example.org,DIRECT
  - MATCH,业务策略

访问 login.example.org 时,第一条后缀规则已经命中,第二条精确直连规则没有执行机会。把两条交换后,登录子域才会先命中 DIRECT。这里的“更精确”只是维护配置时的排序依据,不是内核替用户执行的排序算法。

三段式语法与域名匹配边界

常见规则采用 类型,匹配内容,目标策略 的形式。逗号分隔的是规则字段,行首的短横线则是 YAML 列表语法,两者不要混淆。目标可以是内置策略 DIRECT、REJECT,也可以是配置中已经定义的节点或策略组名称。

常见规则的写法与匹配范围
类型示例含义
DOMAINDOMAIN,login.example.org,DIRECT只匹配这个完整域名,不包含其他子域。
DOMAIN-SUFFIXDOMAIN-SUFFIX,example.org,业务策略匹配根域名及其子域,不匹配 notexample.org。
DOMAIN-KEYWORDDOMAIN-KEYWORD,example,业务策略按域名中的字符串匹配,范围通常比后缀规则更宽。
IP-CIDRIP-CIDR,192.168.0.0/16,DIRECT,no-resolve匹配目标 IPv4 地址所属网段,末尾可附解析控制参数。
RULE-SETRULE-SET,work-domains,业务策略引用已定义的规则提供器,命中其中任一适用条目即交给指定策略。
MATCHMATCH,业务策略无需匹配内容,作为未被前面规则接住的兜底。

不要把网址直接填进域名规则

DOMAIN-SUFFIX 后面应写 example.org,而不是 https://example.org/path。协议头、端口、路径和查询参数都不是域名的一部分。普通域名规则也不能只让同一网站的 /video 路径走代理,而让 /account 直连;HTTPS 加密下,常规分流并不以完整 URL 路径为依据。

后缀匹配具有域名标签边界。example.org 和 api.example.org 都能命中上述后缀规则,但 example.org.other.net 不能。若只是希望一个域名家族统一走相同策略,优先用后缀规则,避免宽泛关键词误伤名称相似的站点。

RULE-SET:引用位置就是优先级

rule-providers 负责声明规则来源,rules 中的 RULE-SET 才负责把它接入匹配流程。只下载了规则文件,却没有在主规则列表引用它,不会自动产生分流效果。反过来,引用了不存在的提供器名称,也会造成配置加载或规则初始化错误。

mihomo 本地 domain 规则集示例

下面展示一个文件型规则提供器。路径相对于内核工作目录解析,不一定相对于编辑器里打开的配置文件;使用桌面客户端时,应先确认它实际使用的工作目录。示例中的“业务策略”必须已经存在于当前配置的 proxy-groups 或节点列表中。

rule-providers:
  work-domains:
    type: file
    behavior: domain
    path: ./rules/work-domains.yaml

rules:
  - DOMAIN,login.example.org,DIRECT
  - RULE-SET,work-domains,业务策略
  - MATCH,业务策略

对应文件 rules/work-domains.yaml 的内容为:

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

在这种 domain 规则集格式下,+.example.org 覆盖根域及其子域,api.example.net 表示一个精确域名。第一个登录域名例外仍然优先,因为它位于 RULE-SET 前面。把规则文件中的两项换个位置,并不会改变这条外部直连例外的优先级。

behavior 与文件内容要对应

  • behavior: domain:内容是域名匹配条目,不能把完整的 DOMAIN-SUFFIX,example.org,业务策略 三段式行直接搬进去。
  • behavior: ipcidr:内容是 IP 网段,例如 192.168.0.0/16,不是域名列表。
  • behavior: classical:可写 DOMAIN-SUFFIX,example.org 等规则表达式;出口策略由外层 RULE-SET 指定,不在每条 payload 后重复添加。

远程提供器还需要正确的下载地址、更新设置和可写的本地存储位置。更新成功仅表示来源可获取,不保证内容格式与 behavior 一致。排查时要同时查看提供器加载日志与匹配记录,而不是只看“更新时间”是否变化。

配置排列:例外、通用规则、兜底

下面是一段主规则列表示例,不是完整订阅文件。它假设上文的 work-domains 提供器和“业务策略”已经定义。合并到现有配置时应修改原来的 rules 列表,不要在文件末尾再建立第二个同名顶层键。

mode: rule

rules:
  - DOMAIN,login.example.org,DIRECT
  - DOMAIN-SUFFIX,example.net,业务策略
  - RULE-SET,work-domains,业务策略
  - 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
  - MATCH,业务策略

这个示例把域名策略放在私网 IP 规则之前,表示已识别的业务域名优先使用业务策略。如果目标是“任何私网地址都先直连”,应把私网规则前移;但还要考虑目标 IP 当时是否已知,以及 DNS 是否会被允许触发。规则排序表达的是实际政策取舍,不存在适合所有网络的一张固定清单。

no-resolve 不是关闭全部 DNS

IP-CIDR 末尾的 no-resolve,表示不为了匹配这一条 IP 规则而主动发起域名解析。连接已有目标 IP 时仍可进行网段判断;若只有域名且没有可用的目标 IP,这条规则不会为自身匹配额外解析。它不会禁止浏览器解析,也不会关闭 mihomo 的 DNS 模块。

上述 IPv4 私网示例也不等于覆盖所有局域网场景。IPv6 目标需要考虑 IP-CIDR6;局域网单标签主机名还涉及本地 DNS。TUN 排除路由又属于接管层设置,不能仅凭几条 DIRECT 规则推断所有本地流量都绕过虚拟网卡。

MATCH 提前会截断后续规则

MATCH 没有筛选条件,放到列表第一行就会接住所有进入这份列表的连接。后面的规则即使语法正确也不会得到机会。通常只保留一个末尾兜底,并明确它交给哪个策略;不要依赖缺少兜底时的隐式行为判断配置是否符合预期。

自定义规则不生效的排查顺序

  1. 确认流量进入内核。只有被系统代理、应用代理或 TUN 接管的连接才有机会匹配规则。系统代理没有接管的程序,不会因为增加一条域名规则就自动进入 Clash。
  2. 确认当前使用的配置。在客户端的“订阅”或“配置”页面核对选中项,再确认运行模式为规则模式。菜单名称随客户端变化,不能把某个客户端的设置路径套用到全部产品。
  3. 检查实际加载的规则顺序。订阅合并、覆写或脚本可能将自定义规则追加到 MATCH 后面。编辑界面的位置不一定等于最终运行配置的位置。
  4. 检查名称与缩进。业务策略 与 业务代理 是两个不同名称;提供器键名也必须逐字对应。YAML 使用空格缩进,不要混入制表符。
  5. 新建连接后再观察。已经建立的 HTTP/2、HTTP/3 或 WebSocket 连接可能继续复用原出口。应用配置后,关闭对应连接或重启目标应用,再发起测试。
  6. 对照命中规则与实际出口。连接详情中同时查看目标主机、规则类型、规则内容和策略链。只看到出口节点变化,不能证明命中了预想中的那条规则。

先做一次明确经过代理端口的测试

如果当前配置明确设置 mixed-port: 7890,可以用下面的命令让请求经过该 HTTP 代理入口。7890 是此处的示例端口,不是所有客户端的固定值;应以实际配置为准。-q 用于忽略用户的 curl 配置文件,--noproxy "" 避免环境中的绕过列表干扰测试。

curl -q --noproxy "" --proxy http://127.0.0.1:7890 \
  --connect-timeout 10 --max-time 20 \
  --head https://example.org/

这个命令只是建立一条便于定位的测试连接,不是性能实测数据。请求失败时,先区分代理端口拒绝连接、DNS 错误、出口连接失败与远端 HTTP 响应;不能仅凭一个超时结论认定规则语法有误。返回页面状态也不能替代规则命中记录。

如果 curl 命中正确,而浏览器访问同一域名的连接没有出现,应先检查浏览器是否使用了代理、是否复用了旧连接,以及相关流量是否被其他扩展接管。DNS 缓存可以影响目标地址,但“清空缓存”不应取代对接管方式和运行配置的检查。

订阅更新与规则维护

直接修改订阅生成的配置,下一次更新时可能被远端内容覆盖。更稳妥的方式是使用客户端支持的覆写、合并或脚本机制,把少量例外规则保存在本地。具体机制由客户端决定,核心验收点只有两个:自定义规则是否还在,以及它们是否排在通用规则和 MATCH 之前。

每次修改只验证一个目标

  • 先加精确域名:用一条 DOMAIN 确认规则入口和策略名称都有效,再按需要扩大为后缀规则。
  • 再迁移到规则集:单条规则验证成功后,再放入与 behavior 对应的文件,便于分离语法问题和来源问题。
  • 最后处理例外:把登录、办公内网等例外放在会覆盖它们的通用规则之前,不以不断追加重复规则代替整理顺序。
  • 更新后复查:重新打开最终规则列表,针对一个例外域名和一个普通域名分别新建连接,核对命中规则及出口。

Clash 自定义规则的关键不在数量,而在匹配范围、列表顺序与出口含义一致。先确认流量进入内核,再看最终规则位置,最后看策略组选择,通常比反复切换节点更容易定位问题。涉及具体客户端的接管与配置导入,可继续参考客户端使用教程;规则类型与内核能力则可查阅协议手册。

下载Clash按平台选择客户端