Advanced 12-minute read

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.

  1. Export your current configuration from the Configuration or Subscription page and keep a copy you can import again.
  2. Make sure the configuration includes a policy group named Proxy Selection. If the actual name differs, update every reference in the examples to match.
  3. Find the client's Override, Extended Configuration, or Configuration Editor option, and check whether it merges or replaces rules.
  4. 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 syntaxWhat it matchesWhen to use it
DOMAIN,github.com,Proxy Selectiongithub.com onlyTarget a single hostname exactly
DOMAIN-SUFFIX,github.com,Proxy Selectiongithub.com and subdomains such as api.github.comCover services under the same domain
DOMAIN-SUFFIX,home.arpa,DIRECThome.arpa and its subdomainsLocal 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,CN check the region of domains that have not yet been resolved, omit no-resolve, as in the example.
  • If you add no-resolve to 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

behaviorExample contentsNotes
domainFor '+ .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
ipcidr192.168.0.0/16A list of IP address ranges
classicalDOMAIN-SUFFIX,home.arpaIncludes 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.

  1. 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.
  2. Scheduled updates: interval: 86400 is measured in seconds, or 24 hours. There's no need to request an ordinary domain list every 10 seconds.
  3. 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.
  4. Local files: type: file does 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 is DIRECT.
  • 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-SET or 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

SymptomCheck firstWhat to do
All connections use the proxyGlobal mode or MATCH placed too earlySwitch to Rule mode and move MATCH to the end of the list
Domain rule does not matchActual request hostname; whether the connection shows only an IPCheck the connection details, then investigate DNS and domain recovery
Configuration fails to loadPolicy group name, duplicate keys, indentationFix the field named in the log, then reload
Rule set is present but has no effectRULE-SET name and position in the listCheck the provider name and whether an earlier rule already matched
Rules disappear after a subscription updateWhether you edited the generated configuration or a persistent overrideMove 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.

Download Clash