当机场订阅里的规则越来越多,或你需要为多个设备维护同一套分流逻辑时,把自定义规则直接塞进主配置,往往会变得难以审查、更新和回滚。更可维护的做法,是把规则单独整理成规则集,托管在 GitHub,再通过 Clash 配置中的 rule-providers 定期拉取。这样既能让主 YAML 保持简洁,也方便在仓库里查看每次改动。本文从规则集的工作方式讲起,带你编写 YAML、发布到 GitHub、接入 Mihomo 系配置,并按实际排查顺序处理更新失败和规则未命中等问题。
需要先区分两件事:规则集文件负责提供一组匹配条件,主配置中的规则负责决定这组条件命中后交给哪个策略组。规则集不会自行选择节点,也不会因为文件托管在 GitHub 就自动生效。客户端必须成功获取并解析文件,主配置还要用 RULE-SET 引用它,并且规则顺序不能被前面的宽泛规则截走。
rule-providers 如何工作:拆分规则与执行策略
在常见的 Mihomo 配置中,rule-providers 是一个命名集合。每个条目定义规则集的来源、匹配类型、文件格式、刷新间隔和本地缓存路径;rules 则通过 RULE-SET,提供器名称,策略组 将它接入规则链。客户端加载配置后,会按照当前内核支持的方式读取远程文件,并将下载内容保存在本地指定路径。之后连接请求按 rules 的排列顺序逐条匹配,命中规则集中的条件时,就进入对应策略组。
这几个环节需要同时成立。仅在 rule-providers 里声明一个名为 work-sites 的提供器,不会让它参与分流;如果 rules 中拼成了 work-site,名称对不上,规则也不会按预期套用。即使名称正确,若一条更早的 MATCH,DIRECT 已经兜底,后面的规则集永远没有机会匹配。因此排查时要依次确认:配置是否被客户端接受、提供器是否下载成功、规则集名称是否一致、规则在主链中的位置是否合理。
规则集的 behavior 表示条目的语义。常用类型包括 domain、ipcidr 和 classical。前两者分别适合域名类条目与 IP 网段;classical 可以包含完整的规则类型,例如域名、进程名或其他受内核支持的规则。不同客户端可能搭载不同版本或不同分支的内核,具体能识别哪些字段应以当前客户端和内核文档为准。不要因为某个配置字段在一款客户端中有效,就推断所有 Clash 系客户端都采用完全相同的解析行为。
| 字段或类型 | 用途 | 编写时要检查 |
|---|---|---|
behavior |
声明规则集内容的匹配类型 | 必须与文件中的条目结构相符 |
format |
指定规则集文件格式 | 远程文件是 YAML 时使用内核支持的 YAML 格式 |
url |
提供器下载地址 | 确认链接可公开访问,且指向原始文件而非网页 |
path |
本地缓存文件位置 | 确保目录可写,避免与其他提供器共用同一文件名 |
interval |
自动检查更新的间隔,单位通常为秒 | 避免设置得过短,按规则变更频率安排即可 |
先写一份可维护的 YAML 规则集
示例先采用 domain 类型,为一个自定义的工作站点规则集准备几条域名。规则集文件本身是一份独立的 YAML 文档,常见结构是以 payload 作为规则列表。域名条目应当按所用内核对 domain 规则的语法书写;以下示例用 + 前缀表示匹配域名及其子域名的写法。若你的内核文档要求不同形式,请按其规则调整,不要直接把主配置中的规则类型前缀写进 domain 列表。
payload:
- '+.docs.example.com'
- '+.packages.example.net'
- '+.status.example.org'
把文件保存为 work-sites.yaml,提交前检查缩进和标点。YAML 对空格缩进敏感,列表项需要处于 payload 的下一级,不能用 Tab 代替空格。文件应只放入预期类型的规则;如果把完整规则表达式混进 domain 列表,内核可能拒绝文件、忽略无效项,或产生与预期不同的匹配结果。用清楚的名称和有意义的注释维护规则,也能让几个月后的自己看懂每一条为何存在。
若规则需要包含多种规则类型,例如精确域名、关键词、进程匹配或 IP 网段,应考虑使用 classical,并根据内核要求在 payload 中写入完整规则。下面是结构示意;具体规则类型是否支持,仍须核对当前内核文档:
payload:
- DOMAIN,portal.example.com
- DOMAIN-SUFFIX,service.example.net
- IP-CIDR,198.51.100.0/24,no-resolve
no-resolve 等参数是否可用于某类规则,取决于相应规则类型的语义。不要为了让配置“看起来完整”而给所有条目机械添加参数。规则越精确,越容易维护;把大量无关域名或过宽的关键词规则塞进同一集合,短期内似乎省事,长期却更难定位误分流。
将规则集托管到 GitHub 并取得原始文件链接
在 GitHub 新建一个专门存放配置规则的仓库,或在现有配置仓库中创建独立目录,例如 rules/。将 work-sites.yaml 提交到默认分支,并确认仓库内容不包含节点密码、订阅地址、访问令牌或其他账户凭据。规则集通常只需要公开访问;如果仓库是私有的,客户端是否能通过认证访问,取决于内核、链接形式和客户端的支持能力,不要默认私有仓库链接可以直接使用。
Clash 配置需要获取的是文件原始内容,而不是 GitHub 的仓库页面。可在 GitHub 文件页面选择查看原始文件,再复制其 Raw 地址。使用前在浏览器中打开该链接,确认页面显示的是以 payload: 开头的 YAML 文本,而不是 GitHub 界面、登录页、404 页面或 HTML 错误内容。使用分支名称时也要检查路径大小写和文件扩展名;仓库目录名、分支名及文件名拼错,都会造成下载失败。
公共托管适合不含敏感信息、变更频率适中的规则。GitHub 或网络链路可能有访问限制、短时故障或请求频率变化,因此不要把“能在浏览器打开”视为客户端一定能稳定更新的保证。重要配置建议保留一份本地副本,并通过提交记录管理版本。这样即使远程地址暂时不可用,也能回到最近一次已知可用的规则集;如规则被意外改坏,还可以比较差异并回滚,而不是在主配置里盲目重写。
work-sites.yaml、media-sites.yaml,每份文件只承担一个清晰职责。文件名稳定后,尽量不要频繁移动目录;如果必须改路径,记得同步更新主配置中的 url,并确认本地 path 不会与其他提供器冲突。
在主配置中声明提供器并接入规则链
文件托管完成后,在主配置的顶层添加提供器定义,再在 rules 中引用它。下面示例中的代理策略组名称 PROXY 需要替换为你配置里真实存在的名称。interval: 86400 表示以一天为周期检查更新;更新间隔不会保证远程文件一定可用,也不是越短越好。path 是内核运行环境中的缓存位置,桌面客户端可能会在配置目录或受管理的数据目录中处理它;若客户端限制自定义路径,按客户端的规则填写。
rule-providers:
work-sites:
type: http
behavior: domain
format: yaml
url: "https://raw.githubusercontent.com/你的账号/你的仓库/main/rules/work-sites.yaml"
path: ./rule_providers/work-sites.yaml
interval: 86400
rules:
- RULE-SET,work-sites,PROXY
- MATCH,DIRECT
这是面向支持相应字段的 Mihomo 配置的示例,不代表旧版或分支内核一定接受全部选项。保存后先使用客户端提供的配置检查或重新加载功能。如果出现 YAML 解析错误,优先检查冒号后的空格、缩进层级、引号和列表结构;若配置可以加载但无法下载,再检查 Raw 地址、文件是否公开、网络可达性以及客户端运行时的网络环境。
规则顺序直接影响结果。将自定义规则集放在兜底规则 MATCH 之前,是常见做法;但它也必须放在会提前匹配同一流量的其他规则之前。举例来说,如果主配置较早出现了覆盖范围很广的代理规则,目标流量可能已经被它接管,你新增的 work-sites 就不会命中。查看实际连接记录中的域名、匹配规则和策略组,比只观察“客户端已开启”更可靠。若记录显示命中了预期规则集但策略组选错,检查 RULE-SET 的第三个参数;若流量先命中别的规则,则调整规则顺序或缩小前置规则的范围。
也要区分提供器刷新与主配置刷新。改变 GitHub 上的规则文件后,客户端需要等待自动更新周期,或通过提供器管理界面手动触发更新;更新提供器不一定等同于重新下载整个订阅。不同客户端的按钮名称和刷新入口可能不同,操作后应查看更新时间、提供器状态或日志,确认新内容确实被取回。不要只凭浏览器缓存中的页面内容判断客户端缓存已经刷新。
更新失败、解析异常与误分流的排查顺序
遇到规则集没有生效时,按从源头到匹配链的顺序排查,避免同时改多个地方。第一步,确认配置本身通过解析;错误信息如果指向行号,先检查对应缩进和字段名。第二步,检查远程 URL 是否返回原始 YAML,并确认仓库、分支、目录和文件名完全一致。第三步,打开客户端日志或规则提供器页面,查看下载状态、HTTP 错误和解析错误。第四步,在连接记录中核对请求域名、最终命中的规则以及策略组。这个顺序可以区分“文件没有下载”“文件格式不兼容”“规则没有排到前面”和“规则命中了但策略组选择错误”等不同问题。
- 出现 404:核对分支名、路径大小写、目录层级和 Raw 链接,确认文件确实存在于该分支。
- 下载结果像网页:链接可能指向 GitHub 文件展示页、仓库主页或错误页面,重新复制原始文件地址,并在浏览器中检查响应内容。
- YAML 解析失败:检查缩进、冒号、引号、列表格式和文件编码;也要确认
behavior与内容结构相符。 - 提供器已更新但未命中:确认
rules使用的名称与提供器键一致,规则集在兜底规则之前,并且测试域名确实属于集合中的匹配范围。 - 更新后连接突然走错策略:检查 GitHub 最近提交的差异、域名规则是否写得过宽,以及更早的规则是否优先命中;必要时回滚到上一份有效版本。
维护时建议把“规则文件的内容变更”和“主配置的提供器参数变更”分开提交。每次提交说明调整目的,例如新增了哪类域名、删除了哪些过时条目,以及预期策略是什么。发布前用一两个实际域名验证规则,再观察连接日志确认策略命中。若多个设备共用同一规则集,先在一台测试设备上更新并确认结果,再让其他设备刷新;这样即使文件语法或匹配范围有问题,影响面也较小。
与把零散规则不断粘贴进订阅覆写相比,规则提供器更适合需要审查历史、跨设备复用和按主题拆分规则的场景;而一些只提供固定分流模板的工具,未必能让你清楚追踪每次规则变更。Clash 配合规则集与 GitHub 的优势,是把“规则内容、更新来源、策略选择”分成可检查的环节:可以通过提交记录回看改动,也能在连接面板里核对实际命中。若你希望在图形界面中管理配置并验证规则效果,可根据自己的系统选择合适的 Clash 客户端,再从一份小型规则集开始逐步扩展。