Most people install Clash because they need reliable access to services that are distributed around the world. The moment you flip on a naive “everything through the tunnel” profile, you also drag domestic banking portals, campus SSO pages, and latency-sensitive game servers across longer paths than necessary. Rule-based routing exists to break that compromise: each outbound connection is classified, the first matching rule wins, and you can send “stay local” traffic to DIRECT while international destinations follow your proxy chain. This guide explains how that engine thinks, which primitives you will edit in real YAML, and how to debug the mistakes that make split tunneling feel random.

Why split traffic instead of global proxying?

Global modes are easy to reason about—every TCP session shares one policy—but they carry predictable costs. Domestic CDNs may answer from the wrong continent, voice calls pick up extra milliseconds, and compliance-sensitive sessions might touch foreign ASNs you never intended to use. Conversely, keeping everything direct means you manually toggle clients whenever a site needs an exit abroad. RULE mode is the middle path Clash popularized: declarative lists declare intent once, and the runtime enforces them consistently across browsers, IDEs, and—when you enable TUN—applications that ignore system proxy settings.

The mental model is not “AI decides for you.” It is closer to a firewall ACL: ordered lines, deterministic matching, explicit fallbacks. Respect that model and your profile stays auditable; fight it and you will chase ghosts in DNS.

MODE, policy targets, and proxy groups

Before rules execute, the active profile must declare mode: Rule (spelling may vary between cores, but the semantics hold). In Rule mode every flow asks the engine for a policy, which can be DIRECT, REJECT, a load-balancing construct, or a named proxy group such as 🔰 Manual. Those names are not magical strings—they must exactly match definitions under proxy-groups in the same YAML document.

Typical subscription bundles ship three families of groups: a manual selector for hand-picked nodes, an auto URL-test group for resilience, and sometimes specialty buckets for streaming or torrenting. When you write MATCH,🔰 Manual you are really saying “anything that survived earlier filters inherits whatever node I picked in that selector.” Rename the group in one place and every rule that references the old label will refuse to load, so copy pasta carefully.

Rule order is the entire game

Clash walks your rules: array from top to bottom. The instant a line matches, evaluation stops. That single property explains ninety percent of “why did my domestic site detour through Singapore?” incidents. Broad matchers belong after precise ones; catastrophic catch-alls like MATCH belong at the bottom.

When you inherit a provider profile containing thousands of lines, resist the urge to shuffle them unless you understand the sections. Instead, append a compact personal block at the end (before MATCH if the file is yours) with workplace VPN domains, home NAS names, or government portals that deserve deterministic DIRECT treatment.

Tip: Think of the rule list as a triage queue. Authentication portals, LAN RFC1918 ranges, and regulatory sites that break when geo hops should jump to the front of the line; generic GEOIP buckets and provider-maintained censorship lists sit in the middle; your final MATCH inherits the selector you trust for “everything else.”

DOMAIN, DOMAIN-SUFFIX, and DOMAIN-KEYWORD

Hostname rules are the scalpel of split tunneling. DOMAIN pins a single host label exactly—useful for an API endpoint that must never be wildcarded. DOMAIN-SUFFIX matches the suffix and every deeper subdomain, which is how templates capture entire SaaS estates with one line. DOMAIN-KEYWORD performs substring matching; powerful but prone to false positives, so keep those lines rare and well tested.

Providers often distribute remote rule fragments via rule-providers in Mihomo-class cores. Whether rules are inline or fetched from GitHub, ordering still applies: inline customs should slot ahead of bulky downloaded lists only when you need to override their mistakes; otherwise merge them at the end per upstream documentation.

GEOIP and country-level splitting

GEOIP consults an MMDB database to map an IP address to a country or region. The pattern GEOIP,CN,DIRECT is folklore for readers who want mainland destinations to stay off the foreign tunnel, but remember GEOIP classifies resolved destination IPs, not political intent. Multinational CDNs may announce Chinese prefixes for caches while still serving global content, and anycast can confuse expectations during football-night traffic spikes.

Keep the database fresh: stale MMDB files mis-tag entire AS blocks. Many clients bundle automatic updates; if yours allows manual replacement, schedule it alongside subscription refreshes.

IP-CIDR and PRIVATE semantics

Use IP-CIDR (and IPv6 counterparts where supported) for static ranges your resolver will never express as a friendly hostname—think office VPN concentrators, printer subnets, or IoT VLANs. Pair RFC1918 ranges with DIRECT so local discovery protocols stop erroring when a SOCKS hop strips broadcast traffic.

Some templates expose GEOIP,private,DIRECT as shorthand; if your fork lacks it, explicit IP-CIDR,192.168.0.0/16,DIRECT lines cover the same ground with boring clarity.

Process and metadata matchers (where available)

Modern Mihomo derivatives can match on process names, IPCIDR sets bundled with rule providers, logical ports, and more. These features help when a single binary (say a proprietary chat client) must always take PROXY regardless of IP geography. Availability depends on OS hooks and build flags, so treat advanced matchers as accelerants, not replacements for solid DOMAIN coverage.

DNS, fake-ip, and why misconfiguration looks like “broken rules”

Routing rules observe connections after DNS in many traditional setups. If the operating system resolver returns a globally anycasted address before Clash sees the hostname, your careful DOMAIN lines never get a chance to fire. Fake-ip addresses that gap by handing clients synthetic LAN-range responses, preserving the original name inside Clash so DOMAIN rules stay authoritative.

Watch for double resolves: browser “secure DNS” features, hard-coded DoH inside mobile SDKs, or systemd-resolved shortcuts can bypass the profile you labored over. When weirdness appears, capture a log line showing which rule hit and whether the connection was IP-first. Toggling TUN after fake-ip is configured often settles stubborn Electron apps that secretly ignored PAC files.

Warning: Do not stack contradictory DNS policies. Pointing nameserver at a filtered resolver while expecting accurate GEOIP lookups for rare ccTLDs is a recipe for divergence between browsers on the same laptop.

Worked example: domestic direct with an international fallback

The following skeleton is educational; swap policy labels for whatever your subscription defines.

mode: Rule

rules:
  - DOMAIN-SUFFIX,cn,DIRECT
  - DOMAIN-KEYWORD,baidu,DIRECT
  - GEOIP,CN,DIRECT
  - GEOIP,private,DIRECT
  - MATCH,Proxy

In production YAML you would interleave provider-managed blocks, streaming exceptions, ad filtering (REJECT), and per-app overrides. Notice how MATCH inherits a group named Proxy rather than a bare node—selectors let you change servers without editing rule text again.

Provider lists versus handcrafted YAML

Commercial subscriptions compete on list quality: anti-ad rules, streaming unlock sections, malware sinkholes, and meticulously maintained China / foreign splits. That does not absolve you from reading the MATCH destination. If MATCH points to DIRECT accidentally, you will wonder why nothing routes through your tunnel; if every line ends in PROXY, you are back to global mode with extra steps.

When you patch upstream lists, document the reason in a comment (ASCII only to avoid parser quirks) so future you remembers why a DOMAIN-SUFFIX crept above the GEOIP section.

Testing and observability habits

Reliable operators keep a three-step ritual:

  1. Reload YAML deliberately after each edit; stale runtimes mask typos.
  2. Open the live log and trigger a test browsing session—logs show the exact rule hit and latency to selector.
  3. Cross-check with external IP tools only after confirming logs; public IP sites tell you the exit country but not whether LAN traffic leaked.

Add automated benchmarks if you run homelab CI: a script can curl domestic APIs through Clash and alert when response times jump, hinting that a provider update shuffled rule order.

Performance, QUIC, and the long tail

UDP-heavy protocols and QUIC can sneak around naive HTTP proxies. If your split policy must govern video conferencing or HTTP/3-heavy sites, verify whether your build supports the relevant outbound transports and whether TUN is required to capture the traffic class. LATENCY matters too: chaining multiple policy groups (fallback of fallback) adds CPU overhead on low-power routers—flatten structures on embedded devices.

Security and compliance considerations

Split tunneling reduces exposure but does not replace endpoint hygiene. Logging sensitive domains in DEBUG level traces may violate corporate policy; scrub logs before sharing them in support tickets. Likewise, GEOIP mistakes that send regulated traffic through offshore exits can alarm compliance officers—test banking sessions explicitly.

Where Mihomo extends the story

Forks based on Clash Meta (often packaged as Mihomo) add richer rule providers, inline script hooks, and tighter integration with emerging transports. The routing philosophy remains: ordered rules, deterministic policies, DNS awareness. If you migrate, budget time to convert legacy Classical rule files into provider references and to revalidate fake-ip sections; converters help but rarely preserve comments.

Troubleshooting cheatsheet

  • Symptom: domestic media buffers – Inspect whether traffic exited overseas due to CDN address families; add DOMAIN-SUFFIX for the vendor’s mainland hostnames.
  • Symptom: international sites flip-flop – Check if two rules share overlapping keywords or if URL-test groups thrash between nodes.
  • Symptom: local NAS unreachable – Confirm RFC1918 IP-CIDR directives precede any broad MATCH that might capture RFC1918 space accidentally.
  • Symptom: DNS leak tests fail – Align secure DNS inside browsers with your resolver strategy or enable TUN-wide capture.

Why the client still matters for rule fidelity

Even perfect YAML fails when the GUI around it hides errors or ships a core too old to parse your provider’s newest dialect. Some abandoned forks stopped receiving GEOIP updates years ago, which quietly rots split accuracy until entire countries drift into the wrong bucket. Others present a “smart mode” toggle that sets global routing behind your back, making hours of YAML tuning feel pointless.

Maintained Clash distributions pair fresh rule engines with transparent logging so you can see whether GEOIP,CN,DIRECT fired or a DOMAIN exception saved the day. If your current build has not tracked upstream in multiple release cycles, you are troubleshooting phantom bugs that newer cores already fixed. When you want RULE mode to stay predictable as providers rotate endpoints, switching to an actively supported client is often faster than hand-editing workarounds.

If you prefer the same open YAML workflow described here—with modern protocol coverage and clearer diagnostics—install the latest Clash release from the official download hub so your domestic and international paths truly stay on their own lanes.

Download Clash for your platform →