如果你打开过机场订阅生成的配置文件,大概见过动辄几百行的 rules 列表。这些规则大多不是机场自己写的,而是引用了社区维护的公共规则集(比较知名的有 ACL4SSR、blackmatrix7 系列),规则集本身托管在远程,配置文件里只是"声明引用了哪些规则集"。
规则集解决了什么问题
没有规则集之前,想精细控制某个 App 或网站的分流,只能一条条手写 DOMAIN-SUFFIX / DOMAIN-KEYWORD,而且规则库需要持续维护(域名会变化、新增服务需要跟进)。规则集把这部分工作转移给了维护规则库的社区,你只需要引用,规则内容由远程文件自动更新。
三个关键字段
| 字段 | 作用 | 常见取值 |
|---|---|---|
| type | 规则集的来源方式 | http(远程订阅,自动更新)、file(本地文件) |
| behavior | 规则集里存放的数据类型,决定了解析方式 | domain(纯域名列表)、ipcidr(IP 段列表)、classical(完整规则语法行) |
| interval | type 为 http 时,自动检查更新的周期(秒) | 常见取值 43200(12 小时)~ 86400(24 小时) |
一个完整的例子
rule-providers: reject: type: http behavior: domain url: https://example.com/reject.txt path: ./ruleset/reject.yaml interval: 86400 direct: type: http behavior: classical url: https://example.com/direct.txt path: ./ruleset/direct.yaml interval: 86400 rules: # 引用规则集,写法固定是 RULE-SET,规则集名称,策略 - RULE-SET,reject,REJECT - RULE-SET,direct,DIRECT - GEOIP,CN,DIRECT - MATCH,PROXY
path 指定本地缓存路径,内核首次拉取规则集后会存一份在本地,之后按 interval 周期性检查更新,即使暂时断网也能用本地缓存正常工作,不会因为拉取失败导致规则整体失效。
常见的坑
- behavior 和实际内容不匹配:如果规则集内容其实是完整语法行(如 DOMAIN-SUFFIX,example.com),但 behavior 填成了 domain(只期望纯域名),会导致解析失败或规则不生效。引用规则集之前最好先看一眼源文件的实际格式。
- 规则顺序放错位置:规则是按从上到下顺序匹配的,如果把范围很宽的规则集(比如一个几乎匹配所有网站的大列表)放在最前面,后面更精细的规则可能永远不会被匹配到。一般建议:拦截规则最先、精细的例外规则次之、宽泛的兜底规则放最后。
- interval 设置得太短:规则集一般不会频繁变化,没必要设置成几分钟更新一次,那样只会增加不必要的网络请求,12~24 小时是比较合理的区间。
- 本地文件路径冲突:多个规则集如果 path 指向了同一个文件,会互相覆盖,建议养成命名规范,比如用规则集名称本身作为文件名。
要不要自己维护规则集
对绝大多数用户来说,直接引用社区维护的公共规则集就足够了,没有必要重新造轮子。只有当你有非常具体的个性化需求——比如公司内部系统的域名列表、只有自己在用的一批特殊网站——才值得用 type: file 建一份本地规则集,和公共规则集搭配使用,各自负责不同的部分。
规则集要解决的是"维护成本"问题,不是"功能"问题——普通规则写法能做的事情,规则集全都能做,只是把维护工作外包了出去。
规则集之间怎么排列组合
实际使用中,一份配置里往往会同时引用好几个规则集,各自负责不同的分类。比较常见的分层方式是:先放拦截类(广告、追踪),再放需要走代理的应用分类(比如常见的海外流媒体、社交软件),然后是国内直连的大列表,最后用 MATCH 兜底。每一层职责单一,出问题时也更容易定位是哪一层规则集导致的。
如果引用的规则集之间出现规则重叠(比如两个规则集都包含同一个域名,但指向了不同策略),实际生效的永远是排在前面、先被匹配到的那一条。所以规则集的引用顺序本身也是一种优先级声明,调整顺序有时候比修改规则集内容更快能解决问题。
怎么验证规则集是否生效
配置好规则集后,不需要靠猜测判断有没有生效。前面文章提到的控制面板里,"连接"视图会显示每条连接实际命中的规则名称——如果显示的是某个规则集的名字而不是"未匹配",就说明规则集已经正常工作。这是排查规则问题时最直接、最省时间的方法,比反复修改配置再测试要高效得多。