1. Start with a Minimal Split-Routing Setup

If you already have a working subscription, keep your proxies and policy groups and replace only the rules. This configuration sends private addresses, mainland China domains, and mainland China IPs direct; all other requests go through PROXY. This is a snippet to merge, not a complete, ready-to-connect configuration.

mode: rule
geodata-mode: true

rules:
  - 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
  - GEOIP,CN,DIRECT
  - MATCH,PROXY

“Direct access for mainland China” here means routing based on database classifications. It is not a definitive judgment about a website’s operator, language, or server location. Databases can have gaps, and CDN addresses can change. For important services, add explicit domain rules and verify the results in the connection log.

If you use a subscription-based client, make sure you’re editing the right place: save changes in a supported override, merge configuration, or persistent extension. Direct edits to a file generated from a downloaded subscription may be overwritten at the next update. The settings location varies by client; check its current documentation.

2. Rule Order: Top to Bottom, First Match Wins

mihomo checks connections in the order listed under rules. Once a usable rule matches, mihomo applies its specified outbound and stops; it won’t continue looking for a “more specific” rule later in the list. Rules aren’t automatically sorted by domain length.

Put Explicit Exceptions Before Broad Categories

rules:
  - DOMAIN-SUFFIX,example.com,PROXY
  - DOMAIN,downloads.example.org,DIRECT
  - GEOSITE,cn,DIRECT
  - GEOIP,CN,DIRECT
  - MATCH,PROXY

These example domains are for syntax illustration only and don’t represent real services. DOMAIN-SUFFIX,example.com matches the root domain and its subdomains, such as api.example.com; DOMAIN matches only the specified hostname. If an earlier rule routes a domain through a proxy, a later mainland China IP rule won’t switch it to direct.

  • Layer 1: Exact exceptions that must be proxied, sent direct, or rejected.
  • Layer 2: LAN addresses and rule sets grouped by use case.
  • Layer 3: Broader categories such as GEOSITE and GEOIP.
  • Final layer: MATCH catches connections that haven’t matched any earlier rule.

MATCH doesn’t mean “successfully identified as an overseas address”; it’s an unconditional fallback. This example sends unmatched traffic through a proxy, so mainland China domains missing from the database may also be proxied. If you put it on the first line, the rules that follow won’t take effect.

3. What GEOSITE and GEOIP Do

Rule type What it matches Where to use it
GEOSITE,cn The cn category in the domain database After domain exceptions, before IP-based categories
GEOIP,CN The database category for the destination IP For connections not covered by domain rules
MATCH No additional match conditions As the final fallback in the rules list

GEOSITE doesn’t need to determine where a server is located

When a connection includes a usable domain name, GEOSITE,cn,DIRECT can match its domain category directly. A mainland China website using an overseas CDN doesn’t automatically change its classification in the domain database. Conversely, an overseas service hosted on a mainland China IP isn’t necessarily classified as cn by GEOSITE.

GEOIP May Trigger DNS Resolution

If a connection has only a domain name and no destination IP yet, an IP-based rule may need to resolve the domain. GEOIP,CN,DIRECT can therefore provide an additional check for connections that didn’t match a domain category, but the result and DNS path can affect the decision.

# Resolve the domain when needed to check the destination IP
- GEOIP,CN,DIRECT

# Do not actively resolve the domain for this rule
- GEOIP,CN,DIRECT,no-resolve

no-resolve doesn’t “disable all DNS” or make all traffic faster. It prevents that IP rule from actively triggering a DNS lookup; connections that already have a destination IP can still match it. If you expect GEOIP to provide an additional check for domain-based connections but add no-resolve, some requests may fall through to the final MATCH.

4. Move Rule Lists into Separate rule-providers

As your rules grow, you can move domain lists out of the main configuration. rule-providers defines the source and format of a rule set; RULE-SET determines where it matches in the main rules and which outbound to use. Defining a provider without referencing it won’t affect routing.

Start with an Inspectable Local Domain List

The following defines a file-based rule set named local-direct. The path is relative to mihomo’s working directory. Put the file in a configuration directory the client can access, and confirm the actual working directory instead of guessing based on your terminal’s current directory.

rule-providers:
  local-direct:
    type: file
    behavior: domain
    format: yaml
    path: ./rules/local-direct.yaml

rules:
  - RULE-SET,local-direct,DIRECT
  - GEOSITE,cn,DIRECT
  - GEOIP,CN,DIRECT
  - MATCH,PROXY

Create rules/local-direct.yaml with the following complete contents. It contains two explicit choices to route direct; it is not a complete domain database for mainland China.

payload:
  - '+.baidu.com'
  - '+.qq.com'

behavior: domain means the file contains only domain match entries; don’t put the entire line DOMAIN-SUFFIX,baidu.com,DIRECT in it. The outbound is set by RULE-SET,local-direct,DIRECT in the main configuration. The +. syntax covers the domain itself and its subdomains.

Use classical for Mixed Rules

If the same file needs both domain and IP conditions, use behavior: classical and the corresponding rule syntax. The following is the contents of the rule-set file; don’t add an outbound name to each entry:

payload:
  - DOMAIN-SUFFIX,baidu.com
  - IP-CIDR,192.168.0.0/16,no-resolve

Don’t change the file contents without also updating the provider’s behavior. For remote rule sets, check the declared format too: YAML, plain text, and binary rule sets aren’t interchangeable. For HTTP providers, interval: 86400 checks for updates every 86,400 seconds. This setting doesn’t sync local files.

5. The Limits of DNS, fake-ip, and TUN

Routing rules apply only to connections that reach mihomo. The system proxy covers only apps that follow the proxy settings; command-line tools, games, and other apps that connect directly may bypass it. TUN mode uses a virtual network interface to capture more IP traffic, but capture still depends on routing, permissions, and exclusions.

  • Traffic capture: First check whether the app’s requests appear in the client’s connection list. If there’s no connection record, check the system proxy, the app’s proxy settings, or TUN routing.
  • Identification: Check whether the connection record shows a domain or only an IP. Without a domain, GEOSITE usually has no domain information to match directly.
  • Rules: Check which rule matched, which policy group is selected, and which proxy node is active. Distinguish the rule’s decision from the node selection.

In fake-ip mode, DNS can return synthetic addresses, such as addresses from the 198.18.0.1/16 range used by common configurations. The core maps these addresses to the original domains; don’t treat a synthetic address as the real server IP for geolocation. Don’t add the entire fake-ip range to the direct list to “fix GEOIP.”

When using encrypted DNS in a browser, a separate DNS client, and TUN together, check whether domain information still reaches the core. Sniffing can recover domains for some protocols, but it can’t restore them for every connection and isn’t a substitute for checking how DNS traffic is captured.

6. Check the Configuration and Test Three Types of Connections

Validate the Syntax Before Loading It in the Client

You can run mihomo’s configuration check directly. The command below assumes the configuration file is in the current directory. If the client uses a separate working directory, specify the correct directory and make sure the database and local rule sets are available there.

mihomo -t -f ./config.yaml

A successful check means the configuration can be loaded; it doesn’t prove that a proxy node is reachable or that every domain will route as expected. After loading, make sure the client is in rule mode so global or direct mode doesn’t affect your test results.

Use Consistent Test Endpoints and Check the Matching Rules

If the client’s actual HTTP or mixed port is 7890, you can specify the proxy explicitly for testing. This is an example port; use the one in your current configuration. There’s no need to enable TUN just to test an HTTP proxy.

curl -I --proxy http://127.0.0.1:7890 https://www.baidu.com/
curl -I --proxy http://127.0.0.1:7890 https://www.wikipedia.org/
  1. Mainland China domains: Check whether GEOSITE or a custom RULE-SET matched, and whether the outbound is DIRECT.
  2. Overseas domains not listed for direct access: Check whether they fall through to MATCH, and confirm that PROXY currently selects a proxy node rather than DIRECT.
  3. LAN services: Test with an existing router or NAS address and confirm that the private network rules are working. Whether LAN access goes through a proxy also depends on the app’s bypass list and TUN exclusion routes.

These domains illustrate how to check routing; they don’t guarantee a match in any particular database version. An HTTP status code of 200, 301, or 403 alone doesn’t prove that routing is correct. Check the rule type, outbound chain, and logs in the connection details.

7. Troubleshoot Common Problems by Layer

A Mainland China Website Still Goes Through the Proxy

  • First check for an earlier matching proxy rule, especially a service-specific rule set included with your subscription.
  • Check whether the domain is in the current GEOSITE data. If the connection shows only an IP, investigate GEOIP and the DNS resolution path.
  • Make sure you edited the active configuration, not an unselected subscription copy. Reload it, then test with a new connection.

All Requests Use the Same Outbound

Check mode: rule, the position of MATCH, and the actual selection in the PROXY group, in that order. A policy group named “Proxy” doesn’t guarantee that it has a proxy node selected. Existing long-lived connections may keep their original outbound after you change the rules; close the affected connections or restart the test app.

Custom Rules Disappear After a Subscription Update

Move the rules into a persistent override or merge configuration supported by the client, and check the merge order. Appending custom rules after the existing MATCH won’t make them work, even if the changes are saved successfully. After each subscription update, recheck at least one direct domain and one proxied domain.

Web Pages Load, but Games or UDP Traffic Still Fail

First confirm that the app’s traffic is being captured. Then check whether the proxy protocol, server, and policy group selection support the required UDP forwarding. TUN solves only part of the traffic capture problem; it won’t make an outbound that doesn’t support UDP capable of forwarding it. Check IPv6 separately too—a successful IPv4 request doesn’t verify dual-stack connectivity.

Keep the final rule order easy to understand: explicit exceptions first, domain categories next, IP categories as a fallback, and MATCH last. After adding each rule, check the connection log to see what it matched before expanding the list further.