Subscription rules handle the common cases; the gaps are yours to fill: an intranet domain being wrongly proxied, a niche site missing from the lists, per-app routing. Writing rules takes five minutes to learn. They belong in a Merge config (here is why and how); this page is about the syntax.
The general shape
TYPE,value,exit[,option]
The exit is a group name (like PROXY), DIRECT or REJECT. Rules match top to bottom and stop at the first hit — internalize that and priority questions answer themselves.
The types you will actually use
| Type | Example | Notes |
|---|---|---|
DOMAIN | DOMAIN,ads.example.com,REJECT | Exact hostname match |
DOMAIN-SUFFIX | DOMAIN-SUFFIX,netflix.com,PROXY | Domain plus all subdomains — the workhorse |
DOMAIN-KEYWORD | DOMAIN-KEYWORD,google,PROXY | Substring match; broad, use sparingly |
IP-CIDR | IP-CIDR,10.0.0.0/8,DIRECT,no-resolve | Destination IP range |
GEOIP | GEOIP,CN,DIRECT | Country by IP; needs the Geo database |
PROCESS-NAME | PROCESS-NAME,steam.exe,DIRECT | Route by originating process |
MATCH | MATCH,PROXY | The catch-all; always the last line |
Add no-resolve to IP rules. Without it, domain-based requests trigger a DNS lookup just to evaluate the IP rule — slower, and a potential leak vector.
Three ready-to-paste examples
Force the company intranet direct
prepend-rules:
- DOMAIN-SUFFIX,corp.example.com,DIRECT
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
Lightweight ad blocking
prepend-rules:
- GEOSITE,category-ads-all,REJECT
Catches in-app ads that browser extensions never see. If something legitimate breaks, whitelist its domain with a DOMAIN rule placed above this line.
Keep torrent traffic off the proxy
prepend-rules:
- PROCESS-NAME,qbittorrent.exe,DIRECT
- PROCESS-NAME,transmission.exe,DIRECT
RULE-SET: when the list grows
Past a hundred rules, a flat Merge file becomes unmanageable. Mihomo can pull rule lists from external files:
rule-providers:
my-direct:
type: http
behavior: domain
url: "https://example.com/my-direct.yaml"
interval: 86400
prepend-rules:
- RULE-SET,my-direct,DIRECT
Host the list in a GitHub repo and every device shares one maintained source.
Verifying a rule fires
The Connections page is the ground truth: each connection shows the rule it matched and the exit it took. The loop is fast — edit rule, reactivate profile, visit the site, check the page. When a rule seems dead, the usual cause is an earlier rule capturing the traffic first.