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:
MATCHcatches 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/
- Mainland China domains: Check whether
GEOSITEor a customRULE-SETmatched, and whether the outbound isDIRECT. - Overseas domains not listed for direct access: Check whether they fall through to
MATCH, and confirm thatPROXYcurrently selects a proxy node rather thanDIRECT. - 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.