If you've ever opened a config file generated by a provider's subscription, you've probably seen a rules list that runs hundreds of lines long. Most of those rules weren't written by the provider itself — they're references to publicly maintained community rule sets (well-known ones include ACL4SSR and the blackmatrix7 series). The rule set itself is hosted remotely, and the config file simply "declares which rule sets it references."
What problem do Rule Providers solve?
Without Rule Providers, fine-grained control over routing for a specific app or site meant writing DOMAIN-SUFFIX / DOMAIN-KEYWORD entries one by one, and the rule list needed constant upkeep as domains changed and new services appeared. Rule Providers shift that maintenance burden onto the community that maintains the rule set — you just reference it, and the content updates automatically from the remote file.
Three key fields
| Field | What it does | Common values |
|---|---|---|
| type | Where the rule set comes from | http (remote subscription, auto-updating), file (local file) |
| behavior | The kind of data the rule set contains, which determines how it's parsed | domain (plain domain list), ipcidr (IP range list), classical (full rule syntax lines) |
| interval | When type is http, how often (in seconds) it checks for updates | Commonly 43200 (12 hours) to 86400 (24 hours) |
A complete example
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: # Reference a rule set with RULE-SET,rule-set-name,policy - RULE-SET,reject,REJECT - RULE-SET,direct,DIRECT - GEOIP,CN,DIRECT - MATCH,PROXY
path specifies the local cache location. Once the core fetches a rule set for the first time, it saves a copy locally and then checks for updates periodically according to interval. Even if you're briefly offline, it keeps working from the local cache instead of breaking every rule that depends on it.
Common pitfalls
- behavior doesn't match the actual content: if a rule set's content is actually full syntax lines (like DOMAIN-SUFFIX,example.com) but behavior is set to domain (which expects plain domains only), parsing fails or the rules simply won't take effect. Check the source file's actual format before referencing a rule set.
- Rules in the wrong order: rules are matched top to bottom. If a very broad rule set (say, a large list that matches almost every site) is placed near the top, more specific rules further down may never get a chance to match. As a rule of thumb: put blocking rules first, specific exceptions next, and broad catch-all rules last.
- interval set too short: rule sets don't usually change that often, so there's no need to check every few minutes — that just adds unnecessary network requests. 12–24 hours is a reasonable range.
- Local file path conflicts: if multiple rule sets have path pointing to the same file, they'll overwrite each other. Get in the habit of using a clear naming convention, such as naming the file after the rule set itself.
Should you maintain your own rule set?
For most users, referencing publicly maintained community rule sets is more than enough — there's no need to reinvent the wheel. It's only worth creating a local rule set with type: file when you have a very specific, personal need — say, a list of internal company domains, or a handful of niche sites only you use — and pairing it alongside the public rule sets, each handling its own slice of the traffic.
What Rule Providers solve is a "maintenance cost" problem, not a "capability" problem — anything a regular rule can do, a rule set can also do. It just outsources the upkeep.
How rule sets combine and layer together
In practice, a single config often references several rule sets at once, each covering a different category. A common layering approach: blocking rules first (ads, tracking), then app categories that need to go through the proxy (for example, region-restricted streaming and social apps), then large local/direct-routing lists, and finally a MATCH catch-all at the end. Each layer has a single responsibility, which also makes it much easier to pinpoint which rule set is causing an issue.
If referenced rule sets overlap (say, two rule sets both include the same domain but point to different policies), whichever one is matched first — i.e., listed earlier — always wins. So the order in which you reference rule sets is itself a kind of priority declaration; sometimes reordering solves a problem faster than editing the rule set's contents.
How to verify a rule set is working
Once a rule set is configured, you don't have to guess whether it's active. In the dashboard covered in an earlier article, the "Connections" view shows exactly which rule each connection actually matched — if it shows the name of a rule set instead of "no match," the rule set is working correctly. This is the fastest, most direct way to troubleshoot rule issues, far more efficient than repeatedly tweaking the config and testing again.