Clash Rule Routing Guide: GEOIP, DOMAIN-SUFFIX, and RULE-SET
Learn how rule order works, route traffic in mainland China directly and overseas traffic through a proxy, and configure and update rule-providers.
Check the routing mode and configuration entry point
Routing rules decide which outbound a connection uses; they do not create proxy nodes. Before you begin, make sure your subscription is imported and your nodes connect, then select Rule in the client's proxy mode. Global mode typically sends traffic through the global policy, while Direct mode does not route traffic according to the rules in this guide.
This guide focuses on YAML configurations for Clash Meta and its successor project, mihomo. Support for rule-set formats and update options varies across classic Clash and different clients. Before editing, check the running core under About or Core Information. The examples use YAML rule sets and do not rely on the MRS binary rule-set format.
- Export your current configuration from the Configuration or Subscription page and keep a copy you can import again.
- Make sure the configuration includes a policy group named
Proxy Selection. If the actual name differs, update every reference in the examples to match. - Find the client's Override, Extended Configuration, or Configuration Editor option, and check whether it merges or replaces rules.
- Save a minimal rule set first. Once it loads successfully, add remote rule sets.
Rule order: the first matching rule determines the outbound
rules is an ordered list. The core checks rules from top to bottom and applies the policy specified by the first match; it does not continue looking for a “more specific” rule. Put personal exceptions first, shared rule sets in the middle, and the fallback MATCH rule last.
mode: rule
rules:
- DOMAIN,github.com,Proxy Selection
- DOMAIN-SUFFIX,home.arpa,DIRECT
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,Proxy Selection
This is a configuration snippet; it does not include node or policy-group definitions. When merging it into an existing configuration, keep a single top-level rules key—do not paste in a second key with the same name. The last line means “use Proxy Selection if none of the preceding rules match.” It does not mean the core has identified the destination as overseas.
Three names that are easy to confuse
DIRECT: The built-in direct outbound, which connects to the destination over your local network.Proxy Selection: The policy group name used in this example. It must be defined, and its current selection must be a working node.MATCH: The fallback rule type, not a policy group. The field after it specifies the outbound target.
If you put MATCH,Proxy Selection on the first line, none of the direct-connection rules below it will get a chance to match. If the policy group currently selects DIRECT, a connection may still go direct even when the log says it matched “Proxy Selection.” When troubleshooting, check both the matched rule and the final outbound chain.
DOMAIN-SUFFIX: Handle known domain patterns first
Domain rules are useful for expressing clear routing intent. DOMAIN matches an exact domain, while DOMAIN-SUFFIX matches that domain and its subdomains. Enter only the domain—no scheme, path, or port.
| Rule syntax | What it matches | When to use it |
|---|---|---|
DOMAIN,github.com,Proxy Selection | github.com only | Target a single hostname exactly |
DOMAIN-SUFFIX,github.com,Proxy Selection | github.com and subdomains such as api.github.com | Cover services under the same domain |
DOMAIN-SUFFIX,home.arpa,DIRECT | home.arpa and its subdomains | Local domain names on a home network |
DOMAIN-SUFFIX,github.com does not match notgithub.com, nor does it automatically cover githubusercontent.com. A site's login, images, and downloads may use different domains, so the browser's address bar alone won't reveal every request. Check the actual destinations in the connection log, then add rules as needed.
Domain rules can match only when the core has the domain name
Domain requests sent through an HTTP proxy usually retain the hostname; direct connections to an IP address are different. In TUN mode, DNS interception, fake-IP mapping, or traffic sniffing may help recover the domain, but none of these mechanisms works for every protocol. If your browser uses its own encrypted DNS, check whether its DNS requests bypass the configuration you expect.
Don't assume that enabling TUN makes every domain rule work automatically. First check the connection details to see whether the destination is a domain or just an IP, then investigate DNS, sniffing, or IP rules as appropriate. See the Glossary for related concepts.
GEOIP: Use the destination IP for regional matching
GEOIP,CN,DIRECT sends a connection direct when its destination IP matches a CN entry in the current geolocation database. It checks the IP—not the domain suffix or operator's location. A Chinese-language site may use an overseas CDN, while an overseas service may use an edge server in mainland China, so the result may not match your expectations.
rules:
- DOMAIN-SUFFIX,github.com,Proxy Selection
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR6,fc00::/7,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,Proxy Selection
These common private address ranges help keep local network devices from falling through to the proxy fallback. They are not a complete list of special-purpose addresses. If your setup uses loopback, link-local, or other reserved addresses, also check the TUN route exclusions supported by your client. Direct-routing rules and route exclusions operate at different layers; a direct rule does not mean the traffic never entered the core.
What no-resolve actually does
IP-based rules may need to resolve a domain before they can check its destination IP. Adding no-resolve tells the rule not to trigger DNS resolution for that check. It does not disable DNS for the connection as a whole, and it does not skip IP matching when the destination IP is already available.
- Rules for local network ranges can usually include
no-resolve, avoiding DNS lookups for every domain near the start of the list. - To let
GEOIP,CNcheck the region of domains that have not yet been resolved, omitno-resolve, as in the example. - If you add
no-resolveto GEOIP, some domain connections may continue down the list and end up at the proxy fallback.
GEOIP results also depend on the database source, its update date, and the addresses returned by DNS. Changing rules does not update the database. If a particular service is misclassified, add a verified domain exception before considering a wholesale reversal of the regional rules.
RULE-SET: Maintain shared lists separately from personal rules
rule-providers defines where a rule set comes from, and RULE-SET references it in the rule list. Declaring a provider alone has no routing effect; you must reference the same name in rules. The snippet below separates shared direct-connection domains from personal local-network rules and sets the remote resource to update once a day.
rule-providers:
direct-domains:
type: http
behavior: domain
format: yaml
url: https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/direct.txt
path: ./rules/direct-domains.yaml
interval: 86400
local-policy:
type: file
behavior: classical
format: yaml
path: ./rules/local-policy.yaml
rules:
- RULE-SET,local-policy,DIRECT
- DOMAIN-SUFFIX,github.com,Proxy Selection
- RULE-SET,direct-domains,DIRECT
- GEOIP,CN,DIRECT
- MATCH,Proxy Selection
The remote URL points to a public third-party rule source that the core downloads at runtime. Availability and updates are controlled by that project. A .txt extension does not guarantee plain-text list contents: this source uses YAML with a payload structure, so the provider is declared as format: yaml.
path is a cache or file path under the core's working directory, not the browser's download folder. A desktop client may place its working directory in the application data folder; don't assume it sits next to the installer. For type: file, create the file before loading the configuration.
Full contents of the personal rule file
Save the following contents as rules/local-policy.yaml in the working directory. A file-based provider supplies the match conditions; the external RULE-SET,local-policy,DIRECT rule specifies the final policy, so don't add DIRECT to the file itself.
payload:
- DOMAIN-SUFFIX,home.arpa
- IP-CIDR,10.0.0.0/8,no-resolve
- IP-CIDR,172.16.0.0/12,no-resolve
- IP-CIDR,192.168.0.0/16,no-resolve
- IP-CIDR6,fc00::/7,no-resolve
The behavior must match the contents
| behavior | Example contents | Notes |
|---|---|---|
domain | For '+ .example.com', remove the space after the plus sign; '+.example.com' must not contain a hidden character. It's best to use the source's original contents directly. | A domain list, not complete rules entries |
ipcidr | 192.168.0.0/16 | A list of IP address ranges |
classical | DOMAIN-SUFFIX,home.arpa | Includes the rule type, but not the final policy |
Do not use ad-blocking syntax, a full Clash configuration, or raw HTML as a rule set. A successful download only means that a response was received; it does not mean the contents can be parsed. If parsing fails, check behavior, format, indentation, and the response body.
Rule updates: subscriptions, rule sets, and geolocation databases
These three data sources follow different update paths. Updating a subscription usually refreshes nodes and the configuration provided with it. HTTP rule sets update according to the provider's interval, while GEOIP databases are managed by the core or the client's database update feature. Clicking Update Subscription once does not mean all three have been updated.
- First load: Check that the rule set downloaded and parsed successfully. If no usable cache exists and the download fails, the configuration may not load as expected; don't assume a complete direct-connection list will be available automatically.
- Scheduled updates:
interval: 86400is measured in seconds, or 24 hours. There's no need to request an ordinary domain list every 10 seconds. - Manual check: Update the rule set from the client's Rule Sets or related management page. If there is no such option, reload the configuration using a method supported by the client and check the logs.
- Local files:
type: filedoes not fetch remote content. After editing the file, use a reload option supported by the client to make the core read the updated contents.
Remote rules are configuration inputs that need review. A bulk direct-connection list may bypass the proxy for some login or download services. For domains that require a specific outbound, put personal rules before shared lists and keep a verified configuration for rollback.
Verification order: check the matched rule, then the final connection
A page loading proves only that one route worked; it doesn't prove the routing matches your design. After editing, close existing connections to the test page and make a new request to avoid reusing a connection established before the change. If needed, close the relevant connection from the client's Connections page, but remember that this will interrupt any active downloads.
Test rules with three types of destinations
- Local network destination: If your router is at
192.168.1.1, open its admin page and check that the local network rule matched and the final outbound isDIRECT. - Domain that should use a proxy: Visit
github.com, check that the domain rule near the top of the list matched, and confirm that “Proxy Selection” resolves to the expected node. - Domain that should connect directly: Choose a domain that is actually included in the shared direct-connection rule set. Check whether
RULE-SETor the subsequent GEOIP rule matched—don't judge by page content alone.
If your current configuration really uses 7890 as its mixed proxy port, you can also run the command below to explicitly use the local HTTP proxy. Use the port shown by your client. This tests the explicit proxy route; it does not replace a test of TUN interception.
curl --proxy http://127.0.0.1:7890 --head --max-time 15 https://github.com
In Windows PowerShell, if curl is mapped to another command, use curl.exe. The HTTP status code is not the only measure; even a redirect can help confirm the request route when checked against the connection log.
Narrow down the problem by symptom
| Symptom | Check first | What to do |
|---|---|---|
| All connections use the proxy | Global mode or MATCH placed too early | Switch to Rule mode and move MATCH to the end of the list |
| Domain rule does not match | Actual request hostname; whether the connection shows only an IP | Check the connection details, then investigate DNS and domain recovery |
| Configuration fails to load | Policy group name, duplicate keys, indentation | Fix the field named in the log, then reload |
| Rule set is present but has no effect | RULE-SET name and position in the list | Check the provider name and whether an earlier rule already matched |
| Rules disappear after a subscription update | Whether you edited the generated configuration or a persistent override | Move personal rules to the client's persistent extension mechanism |
Keep a clear, easy-to-explain order: personal exceptions, local network rules, shared domain lists, GEOIP, then MATCH. For every rule you add, be able to answer: “What does it match, which policy does it use, and why is it here?” For problems with the system proxy or TUN interception, see the Troubleshooting Guide. The rule list itself cannot fix traffic that never reached the core.