当自定义规则逐渐增多,直接把所有条目堆在主配置的 rules 里,通常会让日常维护变得吃力:规则来源不清楚,调整时容易误删;多个设备之间难以同步;服务商更新规则后,还得手动复制、合并并重新检查顺序。对于熟悉 YAML 的用户,Mihomo 内核支持的 rule-providers 可以把规则内容与主配置分开管理,再通过 RULE-SET 在规则列表中引用。本文以 GitHub 托管规则文件为例,说明如何设计规则文件、设置自动更新、区分远程与本地路径,并排查更新失败和规则未命中的情况。

这套做法适合需要维护个人规则、团队共享规则,或希望把配置纳入 Git 版本管理的用户。开始之前,请确认客户端实际使用的内核支持 rule-providers,并且当前配置由 Mihomo 或兼容内核解析;不同客户端界面名称可能不同,但配置项仍以实际运行内核的文档和日志为准。不要把订阅服务商的主配置、规则覆写和内核配置误当成同一层:有些客户端会在更新订阅时重新生成配置,直接修改生成文件可能被覆盖。更稳妥的方式是使用客户端支持的配置覆写,或在你控制的主 YAML 中维护这些字段。

先拆分配置:rule-provider 负责规则,rules 负责顺序

rule-providers 定义一个可重复引用的规则集合,包括规则来源、匹配类型、缓存文件位置和更新间隔;主配置的 rules 则决定这个集合何时参与匹配,以及命中后使用哪个策略组。两者分工不同:provider 文件本身不替你选择代理策略,也不自动排在规则列表最前面。理解这一点很重要,因为不少「规则文件已经下载,流量却没有按预期走」的问题,实际上是引用名称写错,或 RULE-SET 放在了更宽泛规则之后。

规则文件建议使用普通文本 YAML,内容采用列表形式,每行一条规则。比如要把几个自定义域名交给代理,可以把文件命名为 work-services.yaml,并提交到自己控制的 GitHub 仓库:

payload:
  - DOMAIN,api.example.com
  - DOMAIN-SUFFIX,service.example
  - DOMAIN-KEYWORD,workspace

上面的 payload 是规则集文件的外层字段,后面每一项才是规则内容。选择匹配类型时,应尽量贴近实际需求:domain 适用于域名类条目,ipcidr 适用于 IP 段,classical 则可容纳传统规则格式中的多种规则类型。不要只因为某个文件里有域名就默认它适合所有 behavior;provider 的 behavior 必须与文件中的条目类型相符。文件内容格式也要和内核支持的格式对应,常见的 YAML 文件应明确使用 format: yaml;若使用二进制规则集格式,则需按内核要求选择对应的 format 和行为类型。

然后在主配置中声明 provider,并在规则列表里引用同一个键名:

rule-providers:
  work-services:
    type: http
    behavior: domain
    format: yaml
    url: "https://raw.githubusercontent.com/your-name/clash-rules/main/work-services.yaml"
    path: ./ruleset/work-services.yaml
    interval: 86400

rules:
  - RULE-SET,work-services,PROXY
  - MATCH,DIRECT

示例中的 work-services 是本地配置里的标识符,必须与 RULE-SET 后面的名称完全一致;它不必与 GitHub 文件名相同,但使用相近名称更容易排错。path 是内核保存下载文件的本地路径,通常相对于配置文件所在位置或内核的数据目录解析,具体基准目录取决于客户端的启动方式。首次使用前应确认目录可写,避免把路径指向只读目录、临时目录或客户端升级时会清理的位置。interval: 86400 表示按秒计算的更新间隔,即约一天一次;它不是「每次启动都强制下载」的开关。

命名建议:给 provider 使用稳定、容易辨认的键名,例如 work-services 或 media-domains。如果重命名,记得同步修改 RULE-SET 引用;只改其中一处,通常会导致配置校验失败或规则集无法匹配。

用 GitHub 托管规则:选择稳定 URL 与可追溯的变更方式

对公开规则文件,常见做法是把 YAML 存在 GitHub 仓库的默认分支,并使用 raw 文件地址作为 url。仓库路径、分支名和文件名都必须准确;分支改名或文件移动后,旧地址就会返回错误。建议为规则单独建立目录,例如 rules/,并让文件名表达用途,而不是用 new.yaml、test2.yaml 这类无法长期辨认的名称。修改规则前先在 GitHub 页面检查文件原文,确认链接指向的是 YAML 内容,而不是仓库网页、登录页或错误提示页面。

如果希望规则更新更可控,可以使用固定分支并通过 Pull Request 合并改动。日常测试先在开发分支校验格式和命中结果,再把经过检查的版本合并到稳定分支。这样 provider 的自动更新仍可从同一地址拉取最新内容,同时每次变化都保留提交记录,发现误拦截时也能回滚到之前的版本。个人维护也可以采用类似流程:每次提交写清楚新增或删除了什么域名、为何修改、影响哪些策略组。规则文件越小、职责越单一,回归检查就越容易。

公开仓库意味着规则内容对所有人可见,因此不要在规则文件或提交信息中加入订阅链接、认证令牌、内网主机名、私人 IP 清单等敏感资料。若仓库是私有的,普通 raw 地址可能需要认证;直接把访问令牌放入配置 URL 会增加泄露风险,也可能被同步到其他设备或日志中。此时应优先考虑客户端支持的安全认证能力,或改用不含机密的公开规则文件;不要把 token 当作普通 URL 参数长期保存。

GitHub 托管也不等于绝对可用。网络策略、DNS、代理出口或平台限流都可能让客户端无法访问 raw 主机;分支不存在、路径大小写错误、文件未提交等问题也会产生相似的下载失败。遇到异常时先用浏览器或命令行打开准确的原始文件地址,确认返回的是预期 YAML,再检查 Clash 连接日志中该请求是否成功。不要因为某次更新失败就立即更换多项配置,否则难以判断根因。

设置自动更新与本地路径:平衡及时性和可维护性

更新间隔应根据规则变化频率设置,而不是越短越好。每天变动的服务域名可以使用较短周期;稳定的个人白名单通常一天或数天更新一次就够用。频繁轮询会增加远程请求,也可能触发托管平台的限流;如果一份规则一个月才调整一次,把间隔设为几分钟并不会提升实际效果。反过来,规则涉及经常变更的服务时,间隔过长会让客户端持续使用旧缓存。可以先从 86400 秒开始,根据提交频率和更新需求调整,并记录变更时间,避免把缓存尚未刷新误判为规则解析失败。

path 决定下载后的规则缓存保存在何处。远程 provider 的 url 是获取源,path 是本机缓存,两者不能混为一谈。多设备共享配置时,通常让各客户端分别维护本地缓存;不要假设某台电脑上的绝对路径在 Android、macOS、Windows 或路由器上都存在。使用相对路径一般更便于迁移,但仍需确认当前客户端对相对路径的解析基准。若客户端提供配置目录或数据目录设置,尽量把缓存放在它管理的目录中,并避免在多个 provider 之间复用同一个文件路径。

对于离线环境或不希望客户端访问远程源的情况,可以使用本地文件 provider。其核心思路是把 type 设为 file,并让 path 指向已经放置在设备上的规则文件;这时通常不需要远程 url 和定时更新。此方案适合手动审核、离线设备或规则变更非常少的场景,但不会自动从 GitHub 同步。若希望在本机维护一份可审阅的规则,再由脚本下载后复制到客户端目录,应确保更新过程先写入临时文件、验证成功后再替换正式文件,避免网络中断时留下半截 YAML。

修改完配置后,不要只看界面上的「更新成功」提示。先确认配置校验通过,再到客户端的规则集管理或日志页面查看 provider 状态、最后更新时间和缓存路径;不同客户端展示方式不同,字段可能不会全部出现。随后用一个确定命中该规则的域名发起请求,在连接详情中核对匹配到的规则类型、provider 名称和最终策略组。最好先用不会影响重要业务的测试域名验证,不要一上来就把宽泛的域名后缀规则指向全局代理或拒绝策略。

检查规则优先级并定位更新故障

Clash 规则按配置列表从上到下检查,先匹配到的规则通常决定后续处理。因此自定义 provider 要放在可能覆盖它的通用规则之前。例如,如果 GEOIP,CN,DIRECT、宽泛的 DOMAIN-SUFFIX 或其他规则集已经先命中,后面的 RULE-SET,work-services,PROXY 就没有机会生效。反过来,把过宽的自定义集合放在最前,也可能让本应直连的流量意外进入代理。建议从更具体的例外规则开始,再放置用途明确的 provider,最后保留兜底规则;具体顺序要结合现有配置,而不是机械照搬示例。

一次只调整一个变量,排障会更有效。若配置无法启动,先查 YAML 缩进、冒号、引号和重复键,再确认内核版本认识相关字段;若配置能启动但 provider 显示下载失败,检查 URL、网络连通性、仓库分支和返回状态;若下载成功却无规则命中,核对文件外层结构、behavior 与 format 是否匹配,并确认 provider 名称在规则列表中拼写一致;若命中但策略错误,则检查该规则所在位置及策略组名称是否存在。错误日志中的具体字段通常比客户端页面上的概括性提示更有用。

排查时还要区分「规则更新」与「配置重新加载」。某些客户端在 provider 下载后会自动载入更新,有些则需要等待内核刷新或重新载入配置;不应默认每个前端都以同样方式工作。可以通过日志确认新文件是否成功获取、缓存时间是否变化,再观察实际请求。若旧缓存持续存在,先确认网络和下载地址,之后再考虑清理缓存;删除缓存并不能修复无效 URL 或 YAML 结构错误,而且可能让故障设备暂时失去该规则集。

部署到多台设备时,建议固定一份主配置和一份规则源,记录每个 provider 的用途、匹配行为、更新周期及维护人。更新后先在一台测试设备上观察命中情况,再推广到其他客户端;如果不同设备的内核能力不一致,应使用各端都支持的格式,或为不兼容设备准备单独配置。相较于把规则塞进某个图形客户端的临时覆写界面,这种可审阅、可回滚的 GitHub 文件方案更方便复用;而比起直接复制一份庞大规则集,它也更容易追踪变化、定位误匹配。若你希望在现有规则管理基础上继续使用跨平台客户端,可根据自己的系统选择合适的 Clash 客户端。

前往下载 →