How the Rule Engine Works
Clash's rule engine matches rules top to bottom. The first matching rule takes effect and no further rules are checked. Each rule consists of three parts:
# Format: rule-type,match-value,target-policy
- DOMAIN-SUFFIX,google.com,Proxy
- GEOIP,CN,DIRECT
- MATCH,DIRECT # catch-all rule, must be placed last
Understanding this top-down matching mechanism is crucial: put precise rules first, broad rules later, and MATCH last as the catch-all.
Rule Types Explained
Domain Rules
| Rule Type | Match Method | Example |
|---|---|---|
DOMAIN | Exact domain match | DOMAIN,www.google.com,Proxy |
DOMAIN-SUFFIX | Matches domain and all subdomains | DOMAIN-SUFFIX,google.com,Proxy |
DOMAIN-KEYWORD | Domain contains keyword | DOMAIN-KEYWORD,googleapis,Proxy |
DOMAIN-REGEX | Regex match on domain | DOMAIN-REGEX,^api\..+\.com$,Proxy |
DOMAIN-SUFFIX,google.com,Proxy matches google.com, www.google.com, mail.google.com, and all other subdomains simultaneously. It is the most commonly used domain rule.
IP Address Rules
| Rule Type | Match Method | Example |
|---|---|---|
IP-CIDR | Matches IPv4 CIDR range | IP-CIDR,192.168.0.0/16,DIRECT |
IP-CIDR6 | Matches IPv6 CIDR range | IP-CIDR6,::1/128,DIRECT |
GEOIP | Matches by IP country/region | GEOIP,CN,DIRECT |
IP-CIDR rules trigger DNS resolution by default (resolving the domain to an IP before matching). In fake-ip mode, IP-CIDR rules do not work for domains â use domain rules first. To skip DNS resolution for IP-CIDR, append no-resolve: IP-CIDR,10.0.0.0/8,DIRECT,no-resolveOther Rule Types
| Rule Type | Description | Example |
|---|---|---|
PROCESS-NAME | Match by process name (desktop) | PROCESS-NAME,git.exe,Proxy |
PROCESS-PATH | Match by full process path | PROCESS-PATH,/usr/bin/curl,Proxy |
NETWORK | Match by protocol type | NETWORK,udp,Proxy |
PORT | Match by destination port | DST-PORT,22,DIRECT |
RULE-SET | Reference external ruleset | RULE-SET,gfw,Proxy |
MATCH | Catch-all, unconditional match | MATCH,DIRECT |
proxy-groups Policy Group Configuration
Policy groups define where traffic is forwarded after a rule match. Clash supports the following policy group types:
Manual Selection (select)
proxy-groups:
- name: "Proxy"
type: select
proxies:
- "Auto Select"
- "Hong Kong 01"
- "Singapore 01"
- "Japan 01"
- DIRECT
The user manually selects which node or sub-policy group to use in the client interface. The outermost default policy group typically uses the select type.
Automatic Latency Selection (url-test)
- name: "Auto Select"
type: url-test
url: "https://www.gstatic.com/generate_204"
interval: 300 # test interval in seconds, recommended 180-300
tolerance: 50 # don't switch nodes if latency difference is within 50ms
proxies:
- "Hong Kong 01"
- "Hong Kong 02"
- "Singapore 01"
Automatically tests latency for all nodes and always selects the lowest-latency node. Ideal for latency-sensitive use cases (gaming, video conferencing).
Failover (fallback)
- name: "Failover"
type: fallback
url: "https://www.gstatic.com/generate_204"
interval: 300
proxies:
- "Primary Node"
- "Backup Node 01"
- "Backup Node 02"
Prefers the first node in the list and only switches to the next when that node is unavailable. Best for stability-first scenarios.
Load Balancing (load-balance)
- name: "Load Balance"
type: load-balance
strategy: round-robin # round-robin / consistent-hashing
url: "https://www.gstatic.com/generate_204"
interval: 300
proxies:
- "Node A"
- "Node B"
- "Node C"
Distributes traffic across multiple nodes to increase overall throughput. round-robin cycles through nodes evenly; consistent-hashing always uses the same node for the same destination, suitable for session-persistent scenarios.
rule-providers External Rulesets
Manually maintaining hundreds of rules is tedious and error-prone. rule-providers lets you subscribe to large, community-maintained rulesets from an external URL or local file, with automatic updates.
rule-providers:
gfw:
type: http
behavior: domain # domain / ipcidr / classical
url: "https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/gfw.txt"
path: ./ruleset/gfw.yaml
interval: 86400 # auto-update every 24 hours
cn-cidr:
type: http
behavior: ipcidr
url: "https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/cncidr.txt"
path: ./ruleset/cncidr.yaml
interval: 86400
direct:
type: http
behavior: domain
url: "https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/direct.txt"
path: ./ruleset/direct.yaml
interval: 86400
rules:
- RULE-SET,direct,DIRECT
- RULE-SET,gfw,Proxy
- RULE-SET,cn-cidr,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,Proxy
Complete Configuration Template
Below is a minimal working configuration template that includes rule-based routing, policy groups, and external rulesets:
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
dns:
enable: true
enhanced-mode: fake-ip
nameserver:
- 223.5.5.5
- 119.29.29.29
fallback:
- tls://8.8.8.8:853
proxies:
- name: "Hong Kong 01"
type: vmess
server: hk01.example.com
port: 443
uuid: "your-uuid-here"
alterId: 0
cipher: auto
tls: true
proxy-groups:
- name: "Proxy"
type: select
proxies: ["Auto Select", "Hong Kong 01", DIRECT]
- name: "Auto Select"
type: url-test
url: "https://www.gstatic.com/generate_204"
interval: 300
proxies: ["Hong Kong 01"]
rule-providers:
gfw:
type: http
behavior: domain
url: "https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/gfw.txt"
path: ./ruleset/gfw.yaml
interval: 86400
rules:
# Custom high-priority rules (place first)
- DOMAIN-SUFFIX,openai.com,Proxy
- DOMAIN-KEYWORD,notion,Proxy
# External rulesets
- RULE-SET,gfw,Proxy
# Domestic IP direct connect
- GEOIP,CN,DIRECT
# LAN direct connect
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
# Catch-all
- MATCH,DIRECT
Common Split-Tunneling Scenarios
Streaming Unlock
Netflix, Disney+, YouTube Premium, and other streaming services have regional restrictions and require unlock nodes in specific regions:
proxy-groups:
- name: "Netflix"
type: select
proxies: ["US Node", "Singapore Node", "Japan Node"]
rules:
- DOMAIN-SUFFIX,netflix.com,Netflix
- DOMAIN-SUFFIX,nflxvideo.net,Netflix
- DOMAIN-KEYWORD,netflix,Netflix
Developer Tools Optimization
npm, pip, Docker Hub, and similar services need a proxy, while intranet services and local dev servers need direct connections:
rules:
# Dev tools go through proxy
- DOMAIN-SUFFIX,npmjs.org,Proxy
- DOMAIN-SUFFIX,pypi.org,Proxy
- DOMAIN-SUFFIX,docker.io,Proxy
- PROCESS-NAME,git.exe,Proxy # Windows
- PROCESS-NAME,git,Proxy # macOS/Linux
# Local dev direct connect
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
- DOMAIN-SUFFIX,local,DIRECT
Rule Configuration Best Practices
- Precision first: Place
DOMAINbeforeDOMAIN-SUFFIX, andDOMAIN-SUFFIXbeforeDOMAIN-KEYWORD, to reduce false matches - GEOIP goes later: GEOIP requires DNS resolution to work, which takes time â place it after domain rules
- MATCH must be last: As the catch-all rule, MATCH handles all traffic that didn't match any prior rule
- Use logs for debugging: Check the "Logs" page in the Clash client to see which rule each connection matched in real time, making it easy to troubleshoot routing issues
- no-resolve reduces latency: For IP-CIDR rules that target known internal IPs, add
no-resolveto skip the DNS resolution step
Summary
- Rules are matched top to bottom: precise rules first, broad rules later, MATCH as catch-all
- Common rule types:
DOMAIN-SUFFIX(domain & subdomains),GEOIP(IP geolocation),IP-CIDR(IP range),PROCESS-NAME(process name) proxy-groupsdefines node selection strategies: select (manual) / url-test (auto latency) / fallback (failover) / load-balance (load balancing)rule-providerssubscribes to large external rulesets with automatic updates, no manual maintenance required
Further Reading
- TUN Mode Guide: Route all traffic through Clash rules
- DNS Anti-Pollution Setup: Solve DNS pollution issues alongside rule-based routing
- Subscription Auto-Update Setup: Automatically keep nodes and rulesets up to date