Prerequisites: Rule Mode and Proxy Groups

Direct connections in mainland China and proxy routing elsewhere depend on domain lists, destination IP ranges, and rule order. A Chinese-language site may use an overseas API, while an international service may use a mainland China CDN. Aim to send known mainland China domains direct and handle all other traffic with an explicit policy—not to treat domain suffixes as a guide to server location.

This guide applies to clients running the Mihomo core. Before you begin, switch the mode to Rule, make sure you have imported working nodes, and confirm that your config includes a policy group named PROXY. DIRECT is built into the core; you do not need to create it. PROXY is just the group name used in this guide, not a built-in outbound policy.

  • If your group is named “Node Selection”, replace every PROXY used as a rule target in these examples with “Node Selection”. The group name must match exactly.
  • Back up your current config first, then save your local rules using your client's override or merge feature. Direct edits to subscription-generated files may be overwritten the next time the subscription updates.
  • Make sure application traffic actually reaches the core. Enabling the system proxy does not mean every app will use it. TUN can capture more traffic, but it does not change rule matching order.

GEOSITE Setup: Domains First, Then IPs, Then a Fallback

If you already have working GeoSite and GeoIP data, use the rules below as a baseline. Put LAN exceptions first to keep local services off the proxy. Place domain rules before IP-based rules so overseas services are not sent direct just because their resolved IP is in mainland China.

mode: rule

rules:
  - DOMAIN-SUFFIX,localhost,DIRECT
  - DOMAIN-SUFFIX,local,DIRECT
  - IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
  - 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,::1/128,DIRECT,no-resolve
  - IP-CIDR6,fc00::/7,DIRECT,no-resolve
  - IP-CIDR6,fe80::/10,DIRECT,no-resolve
  - GEOSITE,cn,DIRECT
  - GEOSITE,geolocation-!cn,PROXY
  - GEOIP,CN,DIRECT,no-resolve
  - MATCH,PROXY

What Each Layer Does

Rule layerMatch criteriaAction
LAN exceptionsLocal domains, loopback, and private IP rangesDIRECT
GEOSITE,cnThe cn domain list in the data fileDIRECT
GEOSITE,geolocation-!cnThe corresponding domain list in the data filePROXY
GEOIP,CNKnown destination IP locationDIRECT
MATCHConnections not matched by any earlier rulePROXY

GEOSITE matches domain categories; it does not determine a server's physical location. geolocation-!cn is a category name in the dataset, not an expression that dynamically negates the cn result. Coverage varies by data source, and some sources may not include this category. If you get a category-not-found error, first check which GeoSite source your client uses.

In GEOIP,CN,DIRECT,no-resolve, no-resolve means this rule will not trigger a domain lookup just to make a match. If the connection already has a usable destination IP, the rule can use it. If only a domain is available and none of the earlier domain lists match, this rule may be skipped and MATCH will handle the connection. This trades off coverage to reduce extra lookups; it does not guarantee that every mainland China IP goes direct.

Geo Data Update Caveats

GeoSite and GeoIP are local data files. On first load, you need a usable file or an accessible download source. Updating a subscription does not necessarily update these files. Check the client's Geo data settings, core logs, and actual data source separately. If Geo data fails, repeatedly refreshing your node subscription will not fix it.

rule-providers Setup: Update Remote Rule Sets Separately

Use rule-providers when you need to manage rule sources and update schedules independently. A provider downloads and parses a set; RULE-SET references that set at a specific position in the rules list. Declaring a provider alone does not route traffic or automatically place the set at the top of the rules.

The example below uses public release files from Loyalsoldier/clash-rules to demonstrate the syntax. Both files are YAML domain lists, so they use behavior: domain and format: yaml. Before deploying, check the source contents and make sure they are reachable from your network. These are not node subscription URLs.

rule-providers:
  overseas-domains:
    type: http
    behavior: domain
    format: yaml
    url: "https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/proxy.txt"
    path: ./ruleset/overseas-domains.yaml
    interval: 86400

  domestic-domains:
    type: http
    behavior: domain
    format: yaml
    url: "https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/direct.txt"
    path: ./ruleset/domestic-domains.yaml
    interval: 86400

rules:
  - DOMAIN-SUFFIX,localhost,DIRECT
  - DOMAIN-SUFFIX,local,DIRECT
  - IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
  - 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,::1/128,DIRECT,no-resolve
  - IP-CIDR6,fc00::/7,DIRECT,no-resolve
  - IP-CIDR6,fe80::/10,DIRECT,no-resolve
  - RULE-SET,overseas-domains,PROXY
  - RULE-SET,domestic-domains,DIRECT
  - MATCH,PROXY

You can replace the rules list from the previous section with this one; do not concatenate the two complete lists. The earlier MATCH catches every remaining connection, so rules placed after it will never be evaluated. This example deliberately avoids GeoIP: domains missing from the lists and IP connections not matched by LAN rules all fall through to the proxy.

  • interval: 86400 is measured in seconds, so it checks for updates every 24 hours. It does not guarantee how long a cached file remains valid.
  • path is a local file path relative to the core's working directory. Give each provider a different path to prevent them from overwriting each other's files.
  • overseas-domains and domestic-domains are custom names and must exactly match the names used in RULE-SET.
  • This example places the proxy set before the direct set. If the sets overlap, the first matching proxy rule wins. Do not assume lists maintained by different people will never overlap.

Rule Formats: domain, ipcidr, and classical

A URL opening successfully does not mean its contents are in the right format. Node configs returned by a subscription service, HTML login pages, and plain-text domain lists cannot all be parsed the same way. behavior defines what the entries mean; format defines how the file is encoded. Both must match the source.

behaviorExample YAML payload entryUse for
domain'+ .example.com' is invalid. The standard form is +.example.com; neither '+ .' nor a backslash is needed. See the correct entry in the code below.Domain match list
ipcidr'192.168.0.0/16'IP range list
classical'DOMAIN-SUFFIX,example.com'Entries with rule types

A domain list uses this concise syntax. +.example.com matches the root domain and its subdomains, with no spaces or backslashes:

payload:
  - '+.example.com'
  - 'api.example.net'

For classical, write entries of the same kind in this format. Do not specify an outbound policy in the rule set; set it in the outer RULE-SET,set-name,policy rule.

payload:
  - DOMAIN-SUFFIX,example.com
  - DOMAIN,api.example.net

The file extension does not determine how content is parsed. Although direct.txt above ends in .txt, its contents are YAML with a payload key, so the config uses format: yaml. Use format: text only for a plain-text source with one entry per line, as required by that source.

Exceptions and DNS: Keep Mainland China APIs Off the Proxy

Put Specific Exceptions Before the Sets

If a service needs a direct connection for login risk checks, intranet access, or local device discovery, find the actual request domain in the connection log and add a precise rule. Do not switch an entire set of overseas domains to direct because one API is acting up. This is a syntax example: example.com is a reserved example domain, so replace it with the destination shown in your connection log.

rules:
  - DOMAIN,api.example.com,DIRECT
  - DOMAIN-SUFFIX,example.com,PROXY
  - RULE-SET,overseas-domains,PROXY
  - RULE-SET,domestic-domains,DIRECT
  - MATCH,PROXY

With this order, api.example.com matches the direct rule first, while other example.com subdomains go to the proxy. The principle is specific rules before broad ones—not that DOMAIN inherently takes priority over DOMAIN-SUFFIX. Swapping the two rules changes the result.

Routing Rules Are Not DNS Routing

GEOSITE,cn,DIRECT determines the connection's outbound route; it does not specify which DNS server resolves the domain. Check the relevant settings under dns, such as nameserver and nameserver-policy, to control DNS upstreams. If you enable respect-rules so DNS connections follow routing rules, configure proxy-server-nameserver as required by the current core documentation to resolve node hostnames and avoid a resolution dependency loop.

Fake-IP returns synthetic addresses, with the core maintaining the mapping between domains and connections. Do not use a synthetic IP to infer the real location. redir-host relies more heavily on actual DNS results. In either mode, check the domain, matched rule, and final outbound shown in the connection log before deciding whether the issue is with DNS resolution or routing.

Test and Troubleshoot: Check Each Connection Log Entry

After saving the config, confirm that validation and reload both succeed before testing new connections. Existing long-lived connections may continue using their original outbound. After changing rules, closing the relevant connections or restarting the test app gives you more useful results than repeatedly refreshing the same page.

  1. Check the operating mode. Confirm that it is set to Rule. Traffic observed under Global cannot verify whether this rules list is working correctly.
  2. Check the traffic entry point. If your client shows that the local mixed port is 7890, use the command below to test with the proxy explicitly. If the port is different, use the value shown in the client.
  3. Check the match result. In your client's connection list, note the destination domain, rule type, rule payload, policy group, and actual node. A PROXY match does not guarantee that traffic uses a remote node; that group may also be set to DIRECT.
  4. Check provider status. Verify the last update time and entry count. If the logs show a download timeout, check the remote URL and download path first. If parsing fails, check whether the file returned YAML, plain text, or HTML.
  5. Check the merged config. Make sure subscription rules have not overridden your local overrides, custom rules appear before the fallback, and every rule target name exists.
curl --proxy http://127.0.0.1:7890 --head https://www.baidu.com
curl --proxy http://127.0.0.1:7890 --head https://www.wikipedia.org

The commands above create HTTP proxy connections for easier troubleshooting. They do not guarantee that these domains will match a particular set from every source. An HTTP status code alone does not prove routing worked: the server may redirect or deny the request. Check the core's connection log to confirm the outbound.

Common Symptoms and What to Check

  • Mainland China sites use the proxy: First check whether they matched MATCH. If so, see whether their domains are included in the direct list. If not, check earlier proxy rules or overlapping sets.
  • International sites show a direct connection: Check whether an earlier domain exception or GEOIP,CN rule matched, then check whether the proxy group is set to a direct outbound.
  • Browser works, but other apps do not: Check whether the app respects the system proxy and whether it needs TUN capture. Do not assume a missing domain in the rule set is the cause.
  • Rules have no effect after an update: Confirm that you updated the rule provider, not the node subscription. Test with a new connection and check whether the client is still loading a different config.

For easier maintenance, keep a short, explicit list of local exceptions and choose either GeoSite or a remote rule set as your primary source of categories. Change one type of rule at a time and record the match results before and after. This helps distinguish data coverage, rule order, DNS resolution, and traffic capture issues instead of masking the cause by piling on more sets.