This document covers all traffic routing rules available in ClashRS, including rule types, syntax, and practical examples.
ClashRS uses a rule-based system to determine how traffic should be routed. Rules are processed in order from top to bottom, and the first matching rule determines the routing decision.
Each rule follows this basic format:
rules:
- RULE-TYPE,RULE-VALUE,PROXY-NAMEWhere:
RULE-TYPE: The type of rule (DOMAIN, IP-CIDR, etc.)RULE-VALUE: The value to match againstPROXY-NAME: The proxy or proxy group to use
Exact domain matching:
rules:
- DOMAIN,google.com,proxy-us
- DOMAIN,github.com,proxy-us
- DOMAIN,example.com,DIRECTDomain suffix matching (matches domain and all subdomains):
rules:
- DOMAIN-SUFFIX,google.com,proxy-us
- DOMAIN-SUFFIX,github.com,proxy-us
- DOMAIN-SUFFIX,apple.com,DIRECTDomain keyword matching (matches any domain containing the keyword):
rules:
- DOMAIN-KEYWORD,google,proxy-us
- DOMAIN-KEYWORD,youtube,proxy-us
- DOMAIN-KEYWORD,facebook,proxy-usDomain regex matching:
rules:
- DOMAIN-REGEX,^.*\.google\.com$,proxy-us
- DOMAIN-REGEX,.*\.github\.io$,proxy-us
- DOMAIN-REGEX,^[a-z0-9]+\.example\.com$,DIRECTIPv4 CIDR matching:
rules:
- IP-CIDR,192.168.0.0/16,DIRECT
- IP-CIDR,10.0.0.0/8,DIRECT
- IP-CIDR,172.16.0.0/12,DIRECT
- IP-CIDR,127.0.0.0/8,DIRECT
# With no-resolve: skip DNS resolution, only match on already-known IPs
- IP-CIDR,8.8.8.8/32,DIRECT,no-resolveIPv6 CIDR matching:
rules:
- IP-CIDR6,::1/128,DIRECT
- IP-CIDR6,fc00::/7,DIRECT
- IP-CIDR6,fe80::/10,DIRECT
# With no-resolve: skip DNS resolution
- IP-CIDR6,2001:db8::/32,DIRECT,no-resolveThe optional no-resolve parameter prevents ClashRS from resolving domain names to IPs when evaluating IP-CIDR rules. Add no-resolve to avoid unnecessary DNS lookups for rules that only need to match on already-resolved IPs.
Source IP CIDR matching:
rules:
- SRC-IP-CIDR,192.168.1.0/24,proxy-home
- SRC-IP-CIDR,10.0.0.0/8,DIRECT
- SRC-IP-CIDR,172.16.0.0/12,DIRECT
# With no-resolve: skip DNS resolution
- SRC-IP-CIDR,192.168.1.0/24,proxy-home,no-resolveGeographic IP matching:
rules:
- GEOIP,CN,DIRECT
- GEOIP,US,proxy-us
- GEOIP,JP,proxy-jp
- GEOIP,KR,proxy-kr
# With no-resolve: skip DNS resolution, match on original IP only
- GEOIP,CN,DIRECT,no-resolveThe optional no-resolve parameter prevents ClashRS from resolving domain names to IPs when evaluating this rule. Without it, domains are resolved to check their IP against the GeoIP database.
Domain category matching using the geosite database (requires geosite database configured):
rules:
- GEOSITE,cn,DIRECT
- GEOSITE,google,proxy-us
- GEOSITE,category-ads-all,REJECT{% hint style="info" %}
GEOSITE categories are defined in the geosite database file. Common categories include cn, google, youtube, netflix, category-ads-all. See v2ray-rules-dat for the full list.
{% endhint %}
Destination port matching:
rules:
- DST-PORT,80,DIRECT
- DST-PORT,443,DIRECT
- DST-PORT,22,proxy-ssh
- DST-PORT,21,proxy-ftpSource port matching:
rules:
- SRC-PORT,8080,DIRECT
- SRC-PORT,1080,proxy-socks
- SRC-PORT,7890,DIRECTMatch traffic by the originating process name:
rules:
- PROCESS-NAME,curl,DIRECT
- PROCESS-NAME,wget,DIRECT
- PROCESS-NAME,ssh,proxy-ssh{% hint style="warning" %} PROCESS-NAME is not supported on all platforms. It works on macOS, Linux, and Windows but may be unavailable in some environments. {% endhint %}
Match traffic by the full path of the originating process:
rules:
- PROCESS-PATH,/usr/bin/curl,DIRECT
- PROCESS-PATH,/usr/local/bin/node,proxy-devExternal rule set matching:
rules:
- RULE-SET,ads-block,REJECT
- RULE-SET,cn-domains,DIRECT
- RULE-SET,us-domains,proxy-us
- RULE-SET,streaming,proxy-mediaNetwork type matching:
rules:
- NETWORK,tcp,auto
- NETWORK,udp,proxy-udpComposite rules let you combine multiple conditions using boolean logic. The syntax wraps sub-rules in parentheses.
All conditions must match:
rules:
# Route UDP traffic to google.com through a specific proxy
- AND,((DOMAIN,google.com),(NETWORK,udp)),proxy-udp
# Block TCP traffic to a specific IP on port 80
- AND,((IP-CIDR,1.2.3.4/32),(DST-PORT,80)),REJECTAny condition must match:
rules:
# Match either domain
- OR,((DOMAIN,google.com),(DOMAIN,youtube.com)),proxy-us
# Match TCP or UDP on port 53
- OR,((NETWORK,tcp),(NETWORK,udp)),DIRECTInvert the condition:
rules:
# Match everything except CN traffic
- NOT,((GEOIP,CN)),proxy-us
# Match everything except direct domains
- NOT,((DOMAIN-SUFFIX,local)),autoComposite rules can be nested arbitrarily:
rules:
# (domain=google.com AND network=UDP) OR (domain=youtube.com AND network=TCP)
- OR,((AND,((DOMAIN,google.com),(NETWORK,udp))),(AND,((DOMAIN,youtube.com),(NETWORK,tcp)))),proxy-usCatch-all rule (must be last):
rules:
- MATCH,autoRule sets allow you to organize rules into external files for better management.
rule-providers:
ads-block:
type: http
url: "https://example.com/ads-block.yaml"
interval: 86400
path: ./rules/ads-block.yaml
behavior: domain
cn-domains:
type: file
path: ./rules/cn-domains.yaml
behavior: domain
us-ip:
type: http
url: "https://example.com/us-ip.yaml"
interval: 86400
path: ./rules/us-ip.yaml
behavior: ipcidr
classical-rules:
type: file
path: ./rules/classical.yaml
behavior: classical# rules/domain-set.yaml
payload:
- google.com
- github.com
- stackoverflow.com# rules/ipcidr-set.yaml
payload:
- 192.168.0.0/16
- 10.0.0.0/8
- 172.16.0.0/12# rules/classical-set.yaml
payload:
- DOMAIN-SUFFIX,google.com
- DOMAIN-KEYWORD,youtube
- IP-CIDR,192.168.0.0/16rules:
- RULE-SET,ads-block,REJECT
- RULE-SET,cn-domains,DIRECT
- RULE-SET,us-ip,proxy-us
- RULE-SET,classical-rules,autorules:
# Local network
- DOMAIN,localhost,DIRECT
- IP-CIDR,127.0.0.0/8,DIRECT
- IP-CIDR,192.168.0.0/16,DIRECT
- IP-CIDR,10.0.0.0/8,DIRECT
- IP-CIDR,172.16.0.0/12,DIRECT
- IP-CIDR,169.254.0.0/16,DIRECT
- IP-CIDR,224.0.0.0/4,DIRECT
# IPv6 local
- IP-CIDR6,::1/128,DIRECT
- IP-CIDR6,fc00::/7,DIRECT
- IP-CIDR6,fe80::/10,DIRECT
# Block ads
- RULE-SET,ads-block,REJECT
# Streaming services
- DOMAIN-SUFFIX,netflix.com,proxy-streaming
- DOMAIN-SUFFIX,hulu.com,proxy-streaming
- DOMAIN-SUFFIX,disney.com,proxy-streaming
- DOMAIN-KEYWORD,youtube,proxy-streaming
# Social media
- DOMAIN-SUFFIX,facebook.com,proxy-social
- DOMAIN-SUFFIX,twitter.com,proxy-social
- DOMAIN-SUFFIX,instagram.com,proxy-social
# Development tools
- DOMAIN-SUFFIX,github.com,proxy-dev
- DOMAIN-SUFFIX,stackoverflow.com,proxy-dev
- DOMAIN-SUFFIX,npmjs.com,proxy-dev
# Process-specific rules
- PROCESS-NAME,curl,DIRECT
- PROCESS-NAME,wget,DIRECT
- PROCESS-NAME,ssh,proxy-ssh
# Port-specific rules
- DST-PORT,53,DIRECT
- DST-PORT,80,auto
- DST-PORT,443,auto
- DST-PORT,22,proxy-ssh
# Geographic rules
- GEOIP,CN,DIRECT
- GEOIP,US,proxy-us
- GEOIP,JP,proxy-jp
# Source-based rules
- SRC-IP-CIDR,192.168.1.0/24,proxy-home
- SRC-IP-CIDR,192.168.2.0/24,proxy-work
# Final rule
- MATCH,autorules:
# Gaming platforms
- DOMAIN-SUFFIX,steam.com,proxy-gaming
- DOMAIN-SUFFIX,epicgames.com,proxy-gaming
- DOMAIN-SUFFIX,battle.net,proxy-gaming
- DOMAIN-SUFFIX,riotgames.com,proxy-gaming
# Gaming ports
- DST-PORT,25565,proxy-gaming # Minecraft
- DST-PORT,7777,proxy-gaming # Common game port
- DST-PORT,27015,proxy-gaming # Source engine gamesrules:
# Corporate domains
- DOMAIN-SUFFIX,company.com,DIRECT
- DOMAIN-SUFFIX,corp.local,DIRECT
- DOMAIN-KEYWORD,intranet,DIRECT
# VPN detection bypass
- DOMAIN-SUFFIX,whatismyipaddress.com,DIRECT
- DOMAIN-SUFFIX,ipinfo.io,DIRECT
# Work applications
- DOMAIN-SUFFIX,slack.com,proxy-work
- DOMAIN-SUFFIX,zoom.us,proxy-work
- DOMAIN-SUFFIX,teams.microsoft.com,proxy-work
# Source IP based on office networks
- SRC-IP-CIDR,10.0.0.0/8,proxy-work
- SRC-IP-CIDR,172.16.0.0/12,proxy-workrules:
# 1. Most specific rules first
- DOMAIN,specific.example.com,proxy-special
- DOMAIN-SUFFIX,example.com,proxy-general
# 2. Frequently matched rules early
- GEOIP,CN,DIRECT # Common in China
- DOMAIN-KEYWORD,google,proxy-us
# 3. Expensive rules last
- DOMAIN-REGEX,.*\.complex\.pattern\.com$,proxy-complex
# 4. Catch-all rule must be last
- MATCH,auto{% hint style="info" %} Rule Performance:
- Use DOMAIN-SUFFIX instead of DOMAIN-KEYWORD when possible
- Place frequently matched rules at the top
- Use GEOIP rules for geographic routing
- Avoid complex regex patterns in high-traffic scenarios {% endhint %}
Enable rule logging to debug routing decisions:
log-level: debugLook for logs like:
[Router] match rule: DOMAIN-SUFFIX,google.com -> proxy-us
rules:
# Bypass local traffic
- DOMAIN,localhost,DIRECT
- IP-CIDR,127.0.0.0/8,DIRECT
- IP-CIDR,192.168.0.0/16,DIRECT
- IP-CIDR,10.0.0.0/8,DIRECT
- IP-CIDR,172.16.0.0/12,DIRECT
# Bypass Chinese websites
- GEOIP,CN,DIRECT
- DOMAIN-SUFFIX,baidu.com,DIRECT
- DOMAIN-SUFFIX,qq.com,DIRECT
- DOMAIN-SUFFIX,taobao.com,DIRECTrules:
# Block ads
- DOMAIN-SUFFIX,doubleclick.net,REJECT
- DOMAIN-SUFFIX,googleadservices.com,REJECT
- DOMAIN-KEYWORD,analytics,REJECT
- DOMAIN-KEYWORD,tracker,REJECT
# Block malware
- DOMAIN-SUFFIX,malware.com,REJECT
- DOMAIN-SUFFIX,phishing.com,REJECTrules:
# Netflix
- DOMAIN-SUFFIX,netflix.com,proxy-streaming
- DOMAIN-SUFFIX,nflximg.net,proxy-streaming
- DOMAIN-SUFFIX,nflxext.com,proxy-streaming
- DOMAIN-SUFFIX,nflxso.net,proxy-streaming
# YouTube
- DOMAIN-SUFFIX,youtube.com,proxy-streaming
- DOMAIN-SUFFIX,googlevideo.com,proxy-streaming
- DOMAIN-SUFFIX,ytimg.com,proxy-streaming
# Disney+
- DOMAIN-SUFFIX,disneyplus.com,proxy-streaming
- DOMAIN-SUFFIX,disney-plus.net,proxy-streaming
- DOMAIN-SUFFIX,disneystreaming.com,proxy-streaming{% hint style="success" %} Rule Best Practices:
- Keep rules organized and commented
- Use rule sets for better management
- Test rules with different traffic types
- Monitor rule performance and adjust order
- Use specific rules before general ones
- Always include a MATCH rule at the end {% endhint %}
{% hint style="warning" %} Common Pitfalls:
- Forgetting the final MATCH rule
- Using overly broad DOMAIN-KEYWORD rules
- Not considering rule order for performance
- Complex regex patterns affecting performance
- Not testing rules with real traffic {% endhint %}
{% hint style="info" %} Rule Maintenance:
- Regularly update rule sets
- Remove unused rules
- Monitor rule hit rates
- Update geographic rules as needed
- Keep rule documentation current {% endhint %}