Clash 自定义规则写法详解:DOMAIN-SUFFIX、IP-CIDR、GEOIP 与自上而下匹配顺序

逐类拆解常用规则类型的书写格式与适用场景,说明规则自上而下匹配、命中即停的机制,以及 rule-providers 与 MATCH 兜底规则的放置位置。

规则格式:类型、匹配内容与出口策略

Clash 自定义规则写在 YAML 配置的 rules: 列表中。客户端运行在规则模式时,内核按照这个列表决定连接使用哪个出口。本文以 Clash 通用规则语法为基础;涉及规则集加载时,以 mihomo 支持的配置为准。图形客户端提供的是编辑入口,真正执行规则的是当前启用的内核。

mode: rule
rules:
  - DOMAIN,example.com,DIRECT
  - DOMAIN-SUFFIX,example.org,节点选择
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - MATCH,节点选择

这是需要合并到现有配置的片段,不是完整订阅。示例中的 节点选择 必须是现有 proxy-groups 中的策略组名称,也可以替换成配置中已有的节点名称。名称需要逐字一致,包括空格与大小写;不存在的策略可能导致配置加载失败。

  • DOMAIN:规则类型,决定如何解释第二个字段。
  • example.com:匹配内容,这里是完整域名,不包含协议、路径与端口。
  • DIRECT:内置直连策略,由本机网络直接连接目标。
  • REJECT:内置拒绝策略,用于阻止命中的连接。
  • no-resolve:部分 IP 类规则支持的附加参数,不是出口名称。

DOMAIN-SUFFIX:域名后缀与精确域名的区别

只处理一个主机名时用 DOMAIN;处理一个域名及其全部子域名时用 DOMAIN-SUFFIX。后缀匹配以域名标签边界为准,不是随意寻找一段字符串。

规则示例能够匹配不能匹配
DOMAIN,example.com,DIRECTexample.comwww.example.com
DOMAIN-SUFFIX,example.com,DIRECTexample.com、api.example.comnotexample.com
DOMAIN-KEYWORD,example,DIRECT域名中含有 example 的主机不含该字符串的域名

例外规则放在后缀规则之前

假设整个 example.com 需要直连,只有 api.example.com 需要代理。先写精确域名,再写覆盖范围更大的后缀规则:

rules:
  - DOMAIN,api.example.com,节点选择
  - DOMAIN-SUFFIX,example.com,DIRECT
  - MATCH,节点选择

如果交换前两行,API 域名会先命中后缀规则并直连。内核不会因为后面还有一条更精确的规则就重新选择。DOMAIN-KEYWORD 的范围更宽,容易把不相关域名一起匹配进去;能够用精确域名或后缀表达时,优先选择范围明确的规则。

域名规则不识别网页路径

不要把 https://example.com/video 写进 DOMAIN。这里的匹配对象是主机名,不是完整 URL。同一域名下的 /video 与 /docs 不能用上述域名规则区分。对于 HTTPS,内核也不能仅凭这些规则读取加密后的网页路径。

IP-CIDR 与 GEOIP:地址范围、数据库和 no-resolve

IP-CIDR 按目标 IPv4 网段匹配,IP-CIDR6 用于 IPv6。斜杠后的数字表示前缀长度,不是端口。单个 IPv4 地址可写成 /32,单个 IPv6 地址可写成 /128。

rules:
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
  - IP-CIDR6,fc00::/7,DIRECT,no-resolve
  - GEOIP,CN,DIRECT
  - MATCH,节点选择

前三条覆盖常见 IPv4 私有地址范围,第四条覆盖 IPv6 唯一本地地址范围。它们是内核内的分流规则,并不意味着所有局域网连接都会进入内核。系统代理的绕过列表、TUN 的路由排除项,仍可能让相关连接直接绕过客户端。

GEOIP 不是网站所属国家判断

GEOIP,CN,DIRECT 根据内核使用的 IP 地理数据匹配目标地址。它不检查域名后缀、公司注册地或用户账号地区。CDN 地址变化、DNS 返回结果差异、地理数据库版本差异,都可能影响最终命中。需要固定处理某个服务时,应把明确的域名规则放在 GEOIP 之前。

no-resolve 只限制当前规则触发解析

当连接只有域名信息、尚无可用真实目标 IP 时,IP 类规则可能触发 DNS 解析以判断地址。加上 no-resolve 后,该规则不会主动为匹配而解析域名;如果连接已有可用 IP,仍然可以进行地址匹配。

  • 私有网段规则加 no-resolve,常用于减少仅为判断私网地址而发生的解析。
  • 给 GEOIP 加上该参数后,仅有域名且没有可用 IP 的连接可能跳过这一条,继续落到后续规则。
  • 前面的规则已经触发解析时,后面的 no-resolve 不会撤销已经得到的结果。

匹配顺序:从上到下,第一条命中后停止

规则列表没有自动的“精确优先”排序,也不会按照规则类型自动把 DOMAIN 提到 GEOIP 前面。正常分流流程是读取第一条规则,未命中则检查下一条,命中后把连接交给对应策略,不再继续寻找更合适的规则。

  1. 最前面放明确例外。例如某个 API 必须代理、某个测试域名必须拒绝。
  2. 随后放域名与业务规则集。在处理 IP 归属之前,先表达确定的服务策略。
  3. 再放私有网段与地区 IP 规则。具体先后取决于是否允许域名策略覆盖地址策略。
  4. 最后放 MATCH。给所有尚未命中的连接提供明确出口。

上述顺序是一种常用组织方式,不是内核强制要求。如果业务要求“任何私网目标都必须直连”,就应把私网规则移到可能覆盖它的业务规则之前。判断顺序是否正确,要先明确哪个策略具有更高的业务优先级。

rules:
  - DOMAIN,blocked.example.com,REJECT
  - DOMAIN,api.example.com,节点选择
  - DOMAIN-SUFFIX,example.com,DIRECT
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - GEOIP,CN,DIRECT
  - MATCH,节点选择

在这个列表中,blocked.example.com 被拒绝;api.example.com 交给节点选择;www.example.com 直连。即使 API 解析到的地址符合后面的 GEOIP 条件,也不会再检查那一条,因为域名规则已经命中。

MATCH 后面的普通规则不会执行

MATCH,节点选择 没有匹配内容字段,它对所有到达这一行的连接成立。把它放到列表中间,会使后续普通规则失去作用。也不要写成 MATCH,*,节点选择;这里的出口就是第二个字段。

规则命中后的连接失败通常也不会让内核回头尝试下一条规则。需要节点故障切换时,应在策略组中配置相应选择机制,而不是在 rules 中重复书写相同域名并指向多个出口。

rule-providers:定义规则集,再用 RULE-SET 引用

rule-providers 用于声明规则集来源,RULE-SET 用于把规则集接入匹配列表。声明本身不会自动参与分流。下面以 mihomo 的本地文件规则集为例,规则文件按经典规则格式组织:

rule-providers:
  office-services:
    type: file
    behavior: classical
    format: yaml
    path: ./rules/office-services.yaml

rules:
  - DOMAIN,api.example.com,节点选择
  - RULE-SET,office-services,DIRECT
  - GEOIP,CN,DIRECT
  - MATCH,节点选择

将下面内容保存到内核工作目录对应的 rules/office-services.yaml。相对路径的基准由客户端启动内核时使用的工作目录决定,不一定是下载目录;文件还需要位于该客户端允许内核访问的位置。

payload:
  - DOMAIN-SUFFIX,example.org
  - DOMAIN,intranet.example.com
  - IP-CIDR,10.20.0.0/16

这里的 payload 条目不写 DIRECT 或策略组名,出口由引用处的 RULE-SET,office-services,DIRECT 统一指定。普通配置的 rules 与规则集文件的 payload 不是同一种文件结构,不能直接互换。

behavior内容形式使用边界
classicalDOMAIN-SUFFIX,example.org 等带类型条目适合混合域名与 IP 条件
domain专用域名匹配条目不要粘贴带 DOMAIN-SUFFIX, 前缀的经典条目
ipcidr10.20.0.0/16 等地址段不要混入域名或出口策略

RULE-SET 在 rules 中的位置就是它的优先级。把它放到 MATCH 后面不会生效;把它放在精确例外之前,则可能先吞掉例外连接。顶层 rule-providers 写在 rules 前面还是后面,不决定匹配优先级。

如果使用远程 HTTP 规则集,interval: 86400 表示该 provider 的更新间隔为 86400 秒,即 24 小时。它与订阅配置的更新周期、代理节点列表的更新周期是不同设置。本文采用本地文件示例,因此不配置 HTTP 更新参数。

客户端落地:覆写、重新载入与连接验证

订阅文件直接编辑后,下一次订阅更新可能恢复原内容。长期保留自定义规则时,应优先使用客户端的覆写、合并配置或脚本功能,并确认最终生成的 rules 顺序。不同客户端对数组的处理可能是整体替换,也可能提供前置、后置插入,不能仅凭编辑框内容判断最终结果。

按最终配置检查,不只看编辑内容

  1. 记录当前客户端和内核版本。在客户端的「设置」或「关于」页面确认运行的是 mihomo 还是其他内核,避免把新语法直接用于旧内核。
  2. 在「配置」页面选择当前订阅,再进入该配置的编辑或覆写入口。菜单名称随客户端版本变化,保存后还要执行重新载入或应用配置。
  3. 检查最终生效配置中只有一个顶层 rules:,并确认新增例外在订阅生成的 MATCH 之前。
  4. 切到「规则 / Rule」模式,在「连接 / Connections」打开目标连接详情,查看命中规则、规则内容和策略链。

用一次新连接验证规则

已有 TCP 连接通常继续使用建立时的出口。修改规则后,应关闭相关旧连接,或退出应用后重新发起请求,避免浏览器连接复用导致误判。下面的命令仅适用于最终配置实际监听 mixed-port: 7890,且监听地址允许本机访问的情况:

curl.exe -I --proxy http://127.0.0.1:7890 https://example.com/

Windows 下使用 curl.exe 可以明确调用 curl 程序。这里显式指定 HTTP 代理,不依赖浏览器是否读取系统代理;7890 是测试示例端口,不是所有客户端的统一出厂值。运行后在连接页面查找 example.com,以命中规则和策略链为准,不能只凭页面能否打开判断分流是否正确。

常见报错与修正方向

  • 配置解析失败:检查缩进是否使用空格、列表项是否带 - 、是否误用了中文逗号。不要重复添加同名顶层键。
  • 找不到策略:将规则第三字段与实际策略组名称逐字对照,尤其检查订阅更新后策略组是否改名。
  • 规则集加载失败:核对 provider 名称、文件路径、behavior 与文件内容,确认 payload 缩进正确。
  • 一直命中 MATCH:检查连接详情是否有域名信息、目标是否已经变成另一个主机名,以及规则是否真的进入最终配置。
  • 连接页面没有记录:先检查应用是否使用代理或被 TUN 接管;尚未进入内核的流量无法靠调整规则顺序解决。

需要核对配置字段时,可查看协议参考;不确定策略组、系统代理与 TUN 的区别时,可先阅读名词解释。规则维护的重点是保持例外清晰、出口有效,并让 MATCH 始终位于兜底位置。

下载Clash按系统选择安装包