为什么把自定义规则拆成 rule-providers

如果把所有分流条件都写在主配置的 rules 中,刚开始看起来很直接:域名、IP 段和策略组一目了然。但规则一多,主配置就会变得难以审阅;想在两台设备间复用同一份清单,也只能复制整段 YAML。更麻烦的是,新增一条规则可能改变已有规则的匹配结果,排错时很难判断问题来自策略组、规则顺序,还是某个被复制后遗忘维护的域名。

rule-providers 可以把规则内容放到独立文件,由主配置通过规则集名称引用。主配置负责说明规则集从哪里来、按什么类型解析、多久检查一次;规则集文件则专门保存需要匹配的条目。这样能把「规则维护」和「策略选择」拆开:你可以在 GitHub 上审阅修改记录、回滚错误提交,并让多份 Clash 配置引用同一套规则,而不必每次都改动庞大的主 YAML。

这并不意味着 provider 会自动替你判断流量应该代理还是直连。规则集只负责列出匹配条件,最终出站仍由主配置中的 rules 决定。使用前还要确认客户端运行的内核支持相应字段;如今常见的 Mihomo 通常支持多种远程规则集写法,但旧版 Clash 核心或某些客户端内置核心,可能不认识 rule-providers、format 等字段。若日志提示配置字段未知,应先核对内核版本,而不是反复修改 YAML 缩进。

ℹ 先分清两层:rule-providers 定义和加载规则集;rules 中的 RULE-SET 条目负责引用它,并指定命中后的策略组。只有定义 provider、没有引用它,规则集不会自动参与分流。

先定规则类型,再编写独立 YAML 文件

开始托管前,先按规则内容选择 behavior。如果文件只保存域名后缀或域名条目,使用 domain;如果保存 IP 地址段,使用 ipcidr;如果需要混合多种经典规则类型,例如域名、进程名或网络类型,则使用 classical。类型必须与文件里的条目格式匹配,不能因为某个示例能加载,就把所有规则都塞进同一种 provider。

下面以域名规则为例。许多 Mihomo 版本接受带有 payload 根键的 YAML 规则文件,域名项可使用 +.example.com 这类写法表达域名及其子域。若使用 classical,则应按照对应核心支持的规则语法编写,例如 DOMAIN-SUFFIX,example.com。对于 IP 段,使用 ipcidr 类型并提供 CIDR 条目;不要把域名后缀字符串误放进 IP 规则集中。发布前应以目标 Mihomo 版本的文档和实际加载结果为准,因为客户端壳层的版本并不必然等于内核版本。

主配置中的 provider 与规则引用示例

rule-providers:
  MY-DOMAINS:
    type: http
    behavior: domain
    format: yaml
    path: ./ruleset/my-domains.yaml
    url: https://raw.githubusercontent.com/your-name/clash-rules/main/my-domains.yaml
    interval: 86400

rules:
  - DOMAIN,login.example.net,Proxy
  - RULE-SET,MY-DOMAINS,Proxy
  - MATCH,DIRECT

GitHub 仓库中的 my-domains.yaml 示例

payload:
  - '+.example.com'
  - '+.example.org'

这里的 type: http 表示核心从 URL 获取规则文件;path 是核心用于保存或读取该 provider 内容的本地路径,建议使用单独的 ruleset 目录,并为每个 provider 设置不重复的文件名。interval: 86400 表示按秒设定更新间隔,示例为一天检查一次。format: yaml 用来声明文件格式;若你使用的是不需要 YAML 包装结构的纯文本规则,必须根据内核版本和文件格式调整声明,不能把示例中的字段和值机械套用到所有规则集。

为规则集取名时,优先采用能表达用途的名称,例如 MY-DOMAINS、WORK-IP-CIDR,并确保 rules 中引用的名称与 rule-providers 下的键完全一致。名称中的大小写、连字符都应保持一致。初次搭建时尽量只增加一个 provider,确认能加载、能命中后再拆分为多个集合;一次引入许多规则集,发生问题时会增加定位成本。

把规则托管到 GitHub 并配置自动更新

可以新建一个专门保存代理规则的公开 GitHub 仓库,也可以在已有配置仓库中建立规则目录。对单个规则文件而言,关键是获得核心能够直接访问的文件 URL。常用做法是使用 raw.githubusercontent.com 下的原始文件地址,并将用户名、仓库名、分支名和文件路径填写完整。浏览器打开该 URL 时,应直接显示文件内容,而不是 GitHub 的网页界面、登录页面或仓库文件列表。将普通仓库页面地址粘到 url 中,通常不会得到可解析的规则文件。

一种易于维护的目录安排是把主配置、说明文档和不同类型的规则分开。例如域名规则放在独立 YAML 文件,IP 段使用另一个文件,更新记录写入 README。这样做不是为了让仓库目录越复杂越好,而是为了让变更范围清楚:审阅者能看出某次提交只是新增了一个域名,还是替换了整份 IP 列表。规则来源若由第三方生成,也应记录上游链接、生成时间和用途,避免以后只剩一个看不出来源的清单。

自动更新依赖 Clash 内核能够访问规则 URL,并按照 provider 的 interval 检查新内容。更新间隔不宜设置得过短:频繁轮询对日常分流通常没有明显收益,反而会增加远程请求和故障排查变量。面向个人使用的规则集可以先从每天或每几天检查一次开始;若规则变化有明确的业务时效要求,再根据维护频率调整。需要立即验证修改时,可在客户端中手动更新规则集,或重启核心触发重新加载,具体入口会随 Clash Verge、Clash Verge Rev、Mihomo Party 等客户端版本而变化。

公开仓库便于核心直接读取,但不要把订阅链接、访问令牌、私人网络清单或其他敏感资料一并提交。私有仓库的原始文件通常需要身份验证,不能假设把私有 URL 写进配置后 Mihomo 就能自动通过 GitHub 登录。若规则确实不能公开,应使用受支持的认证分发方式或自有可访问的 HTTPS 服务,并验证实际请求是否成功;不要将访问令牌直接写入会被分享或同步到公共位置的主配置。

规则顺序、命中验证与版本管理

Clash 规则通常按配置中的顺序逐条匹配,命中后采用该条规则指定的策略。因此,provider 文件写得正确,不代表流量一定会按预想处理。如果一条宽泛的 RULE-SET 放在特定例外之前,例外可能永远没有机会生效;如果通用规则集放在 MATCH 之后,它也不会被匹配。实践中应将明确的单域名例外放在前面,再放较窄用途的规则集,之后才放范围更广的 provider,最后保留兜底规则。具体顺序仍应依据配置目的安排,并通过连接记录确认结果。

验证时不要只看客户端是否显示「核心运行」。先检查配置解析日志,确认 provider 没有 URL 错误、格式错误或字段不兼容;再打开规则集更新状态,确认文件成功取得;随后访问一项确定属于该集合的测试域名,在连接面板查看最终匹配规则与策略组。测试对象应是你自己明确维护的条目,而不是凭印象推测某个大站一定在集合里。若请求命中了其他规则,逐条检查前置规则、域名解析结果和实际连接的 Host,再判断是排序问题还是规则内容遗漏。

GitHub 的提交历史提供了基础版本管理能力。修改前可先查看当前文件并在本地保留副本;修改后通过差异对比确认只改变预期条目,再提交到仓库。重要规则集可以使用固定分支或带版本号的发布路径:日常分支便于快速更新,但一次误提交也会立即影响所有引用该地址的设备;固定版本更容易复现配置和回滚,不过需要你主动更新 URL 或发布版本。无论选择哪种方式,都应保留最近一次可用版本,避免仓库内容损坏时只能从记忆中重建规则。

多台设备共用规则集时,建议让它们引用同一个仓库文件,但不要因此忽略核心差异。桌面端、Android 客户端和不同版本的 Mihomo 可能有不同的更新入口、缓存状态与字段兼容性。若一台设备已更新、另一台仍显示旧规则,应分别查看各自的 provider 状态和核心日志;不要只因为 GitHub 文件已经变更,就认定所有运行中的内核都会立刻完成下载并切换到新内容。

更新失败与规则不生效的排查方法

provider 无法更新时,先把问题分成「无法取得文件」和「取得后无法解析」两类。前者常见于 URL 拼写错误、仓库或分支路径不存在、网络无法访问 GitHub、TLS 连接失败,或者私有仓库要求认证;后者则更常见于 YAML 缩进不正确、缺少预期的 payload 结构、文件内容与 behavior 不匹配,以及当前核心不支持所写字段。日志中的 HTTP 状态码、URL 和解析错误提示通常比客户端弹出的「更新失败」更有诊断价值。先确认 URL 能直接访问,再检查返回内容确实是规则文件,而不是 404 页面或 HTML。

若文件能更新但访问目标没有命中规则集,按顺序检查四处:主配置里的 provider 键名是否与 RULE-SET 引用相同;该 provider 的 behavior 是否符合文件内容;规则集条目是否包含目标域名或地址;是否有更靠前的规则已经匹配。域名类规则还要区分精确域名与后缀匹配的意图,避免为了覆盖一个主机名而无意中扩大到整个无关域名范围。不要以添加更多泛化规则作为第一反应,否则短期看似「修好了」,长期却更难解释误分流。

如果更新看似成功但设备仍使用旧内容,可以手动触发 provider 更新,并查看更新时间与核心日志;必要时确认 path 是否指向预期缓存文件、客户端实际使用的是哪一份配置,以及是否有多个同名配置同时运行。修改 GitHub 文件后,浏览器能看到新内容不等于每个核心都已刷新缓存。定位过程中每次只改一个因素:先验证 URL,再验证格式,再验证规则顺序,这样才能知道修复究竟解决了哪个问题。

与把规则全部堆在主配置里的方式相比,GitHub 托管的 rule-providers 更适合需要跨设备复用、查看改动和回滚的用户;但它并不能替代字段校验、版本兼容测试与连接日志分析。部分旧客户端只提供有限的规则管理界面,而 Clash V.CORE 可作为整理配置、检查分流与管理客户端使用流程的入口,减少在多个工具之间反复寻找设置的成本。如果你希望按本文方法建立可维护的规则集,可以先整理一份小型规则文件,再前往下载 Clash V.CORE,在实际运行环境中逐项验证 provider 更新与规则命中。