Enable Rule mode first, then confirm traffic reaches the core
Open the client’s mode selector and choose “Rule.” Then go to “Proxies” and select a reachable node in the proxy group you plan to use. Rules determine the route for split traffic. Global mode bypasses this routing logic, while Direct mode won’t select a proxy based on the rules below.
This guide targets clients running the mihomo core. Clash is a commonly used name for the client and configuration ecosystem, but older Clash cores differ in their support for GEOSITE, data files, and some options. Check the core name in the client’s About or core information page. If the configuration fails, check the actual core and its logs rather than relying on the app’s name.
- Check the active configuration: Find the enabled subscription under “Profiles” and export a backup first. Put custom settings in the client’s override, merge, or extension configuration where possible, so they won’t be lost when the subscription updates.
- Check how traffic is captured: For browser testing, start by enabling the system proxy. To cover apps that ignore system proxy settings, enable TUN. Both capture methods can use the same split-routing rules.
- Check the listening port: The example below uses
mixed-port: 7890. Use the port in the active configuration; don’t assume the client listens on 7890 just because the example does. - Enable connection logging: Find “Connections” and “Logs.” You’ll need to check the destination domain, matched rule, and final policy chain.
What GEOSITE, GEOIP, and RULE-SET are for
Split routing can use either the domain name or destination IP. Services in mainland China often use CDNs distributed across regions, and overseas services may resolve to nearby addresses. An IP’s geographic location doesn’t necessarily determine which route a service should use. In general, apply explicit domain rules first, then use IP geolocation data as a fallback.
| Rule type | Matches against | Best used for |
|---|---|---|
DOMAIN-SUFFIX | A domain and its subdomains | Specific services that need a fixed route |
GEOSITE | A domain classification database | Bulk classification of services in mainland China and overseas |
GEOIP | Destination IP and an address database | Private networks or additional IP-based geolocation checks |
RULE-SET | A rule provider declared in the configuration | Separately maintained direct, proxy, or blocking lists |
MATCH | Connections not matched by earlier rules | The last line in the rules list |
Rule order: first match wins
rules are evaluated from top to bottom. The first matching rule determines the policy. A useful order is: essential exceptions, ad blocking, LAN direct access, service-specific domain rules, domains in mainland China, overseas domains, domestic IPs, and finally a catch-all. If you put MATCH earlier, later rules won’t run.
cn and geolocation-!cn are category names in commonly used GEOSITE datasets, but not every data source includes them. The latter also doesn’t mean “every domain outside mainland China.” Check that your current geosite data includes these categories before using them. Having a GEOIP data file doesn’t mean GEOSITE is available too.
Rule setup: direct routing in China, overseas proxies, and ad blocking
This example uses two local rule sets: one for ad domains and one for business domains that should connect directly. This lets you verify that rules load and match before switching to remotely maintained lists. PROXY is a proxy group name; replace it with a group that exists in your configuration, or make sure a group with that name is already defined. It’s not a keyword that creates proxy nodes automatically.
Step 1: Create local rule-set files
Create a rules folder in a directory the core can access, then save the two files below. Relative paths are usually resolved from the core’s working directory, which may differ from the directory containing downloaded subscription files. Some GUI clients restrict file access, so use a configuration directory the client allows.
rules/local-ads.yaml: Use the classical behavior. Include the full rule types in the file, but don’t specify an outbound policy.
payload:
- DOMAIN-SUFFIX,doubleclick.net
- DOMAIN-SUFFIX,googlesyndication.com
rules/local-direct.yaml: Use the domain behavior and include only domain patterns. In this rule-set syntax, the +. prefix matches both the domain itself and its subdomains.
payload:
- '+.bilibili.com'
- '+.bilibili.cn'
This ad list contains only two domains to demonstrate the blocking flow; it isn’t comprehensive. Ad domains can be tied to login, analytics, or content loading, so test entries individually as you expand the list. The direct-routing list is also just an example: video, image, and account services may use other domains, which you can identify in the connection log.
Step 2: Add the rule providers and routing rules
Merge the following fields into the active configuration. If rule-providers already exists, keep its existing entries. If rules already exists, merge the rules in order rather than adding a second key at the same YAML level. Client-side “append rules” won’t work if they’re placed after the subscription’s MATCH; use prepended rules or an override that lets you control the full order.
mixed-port: 7890
mode: rule
rule-providers:
local-ads:
type: file
behavior: classical
format: yaml
path: ./rules/local-ads.yaml
local-direct:
type: file
behavior: domain
format: yaml
path: ./rules/local-direct.yaml
rules:
- RULE-SET,local-ads,REJECT
- 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
- RULE-SET,local-direct,DIRECT
- GEOSITE,cn,DIRECT
- GEOSITE,geolocation-!cn,PROXY
- GEOIP,CN,DIRECT
- MATCH,PROXY
This is a merge example and depends on existing nodes, proxy-groups, and available geolocation databases; it can’t be used as a subscription on its own. The private address ranges shown are common examples, not a complete list of special-use addresses. If your enterprise network uses other internal ranges, add them according to your network plan.
Step 3: Check the fallback policy and compatibility
- Prioritize direct routing for domains in mainland China: Place
GEOSITE,cn,DIRECTbefore IP-based checks. This prevents services in mainland China from falling through to the proxy just because they resolve to a CDN in another region. - Prioritize proxies for classified overseas services: Put overseas domain rules before domestic IP rules to reduce the chance that a service gets routed directly because of its CDN address.
- Send unmatched connections through the proxy:
MATCH,PROXYfavors access to overseas services. If you change it toMATCH,DIRECT, unlisted overseas domains may fail to connect directly. Choose the fallback that fits your needs. - Remove unsupported categories first: If the core reports that a GEOSITE category doesn’t exist, get the configuration loading again before setting up a data source that includes it. Don’t keep restarting the client to mask a loading error.
DNS and no-resolve: don’t mistake resolution issues for rule issues
After saving and reloading the configuration, check the logs for errors such as missing rule-set files, nonexistent proxy groups, or failed geolocation database reads. Once the configuration loads, check DNS. Unexpected DNS results can cause direct connections to time out or services to fail even when the rules are ordered correctly.
Should you add no-resolve to the domestic IP rule?
The example’s GEOIP,CN,DIRECT rule doesn’t include no-resolve, so the core can trigger a DNS lookup when a rule needs an IP but the connection only has a domain name. This can route domestic IPs directly even when their domains aren’t in the domestic domain category, but it also increases reliance on DNS results.
If you change it to GEOIP,CN,DIRECT,no-resolve, the rule won’t trigger a DNS lookup to match itself. Connections with a known destination IP can still match; those with only a domain and no available IP may fall through to MATCH. Adding this option doesn’t improve domestic classification accuracy.
What to check with Fake-IP and TUN
- Fake-IP: An app may receive a mapped address in the commonly used
198.18.0.0/16range. The actual range depends onfake-ip-range. This isn’t the server’s real geographic location, so don’t use it to assess routing by region. - Domain information: Proper DNS interception and mapping help the core recover domain names and apply GEOSITE rules. Results may vary if an app uses its own encrypted DNS, connects directly to a cached IP, or reuses an existing connection.
- TUN: Confirm that virtual network interface routing and DNS interception are actually working. TUN captures more traffic, but won’t fix proxy group names, rule order, or database categories automatically.
- Resolver selection: Test the resolution results for domains in mainland China and domains routed through a proxy separately. Set
nameserver-policyonly if you need to choose resolvers by domain. Before changing it, check the current mihomo documentation and how your client handles DNS overrides.
Verify split routing by checking matched rules, not just whether a page loads
After reloading, close any existing connections still in use by the test app, or end them on the client’s Connections page before making a new request. Existing TCP connections usually won’t switch routes as soon as rules change, and browser connection reuse can keep old results around for a while.
- Check direct routing in mainland China: Open
www.bilibili.comand filter the connection log by domain. The homepage domain should matchlocal-director another earlier direct-routing rule, withDIRECTas the final policy. Check supporting resources separately. - Check proxy routing overseas: Visit an overseas service that actually requires a proxy. Check whether it matches
geolocation-!cnorMATCH, and confirm that the policy chain routes throughPROXYto the expected node rather than a direct option within the group. - Check ad blocking: Request
https://doubleclick.net/. The connection should matchlocal-adsand useREJECT. A browser error alone isn’t enough; check the connection log to confirm the rule blocked it rather than DNS or network failure. - Check LAN routing: Visit your router or NAS at its actual address and check that the private-network rule matches and the outbound route is direct. If your company network has custom routing, also check the system routing table.
Use an explicit proxy to rule out system proxy settings
Run the command below in macOS Terminal to send the request explicitly to port 7890 on your Mac. --max-time 15 limits the test to 15 seconds; this is a diagnostic setting, not a performance benchmark. Change the command first if your port is different.
curl -I --max-time 15 \
--proxy http://127.0.0.1:7890 \
https://www.bilibili.com/
curl -I --max-time 15 \
--proxy http://127.0.0.1:7890 \
https://www.wikipedia.org/
The destination service determines the HTTP status code. Redirects, access restrictions, or a server that doesn’t accept HEAD requests can all affect the output. The main checks here are whether the request appears in the client’s connection log and which rule and policy chain it matches. A 200, 403, or single timeout alone can’t tell you whether split routing is correct.
Common routing issues: check configuration, matching, and outbound route
| Symptom | Check first | What to do |
|---|---|---|
| A site in mainland China still uses the proxy | Actual domain, direct-routing list, and rule order | Add domains based on the connection log; move explicit direct-routing rules ahead of proxy rules |
| An overseas site is routed directly | Overly broad direct rules and proxy group selection | Narrow the domain match and check whether the proxy group selected DIRECT |
| Changes have no effect after saving | Active configuration, override result, and mode | Confirm the intended configuration is running and switch to Rule mode |
| Ads still appear | Whether ads are served from the same domain and whether the rule matched | Add separate ad domains; content served from the same domain requires browser-based content filtering |
| Proxy requests time out | Matched connection, node connectivity, and DNS | Confirm the route first, then test the node and DNS; don’t add rules blindly |
| Reload reports a file error | Path, YAML indentation, and behavior | Check the working directory and make sure the file format matches the rule provider declaration |
Keep exceptions narrowly scoped
If an ad rule blocks login, put only the necessary, verified domains before the blocking rule. Prefer an exact DOMAIN match instead of allowing an entire provider’s parent domain. Conversely, if an overseas service needs a fixed proxy route, add an exact rule before the domestic categories rather than removing the entire set of direct-routing rules.
When switching a rule set from a local file to a remote subscription, check type, behavior, format, and the update interval together. A domain list can’t be read directly as classical rules, and changing a YAML file’s extension doesn’t turn it into a binary rule set. Keep a rollback copy of the configuration after updating, then repeat the same domain tests.
The final checks come down to three things: the connection reaches the core, the expected rule matches, and the policy group uses the correct outbound route. Track these separately to keep direct routing in mainland China, overseas proxy routing, and ad blocking maintainable instead of relying on trial and error. For client instructions, see the Setup Guide; for configuration options, see Advanced Configuration.