Clash Rule-Based Routing in Practice: Fine-Grained Traffic Control with Domains and GeoIP

Clash rules for direct China sites and proxy for the rest: DOMAIN-SUFFIX, GEOIP, RULE-SET syntax, match order, priority, plus a ready snippet.

Rule-based routing is the core capability that sets Clash apart from ordinary proxy tools. The rules section of a configuration file determines which proxy group each network request ultimately goes through, based on domain, IP location, process name, or port. A well-written rule set lets local sites connect directly, sites outside mainland China route through the proxy, and specific services use dedicated lines — all without manual switching. This article breaks down rule types, syntax, and priority mechanics in a practical order, and provides a ready-to-use rule snippet.

DOC-01

Basic Structure of Rule Matching

Every rule in a Clash configuration file follows a unified format:

rule type,match value,target policy

For example:

rules:
  - DOMAIN-SUFFIX,google.com,Proxy
  - DOMAIN-SUFFIX,baidu.com,DIRECT
  - GEOIP,CN,DIRECT
  - MATCH,Proxy

The three fields each have a clear role: the first segment is the rule type, determining what dimension is used for matching; the second is the specific match value, which varies by type (domain, IP range, process name, and so on); the third is the policy group or action to hand off to once matched — this can be a custom proxy group name, or a built-in action such as DIRECT (direct connection) or REJECT (block).

Rules are compared one by one from top to bottom, and matching stops at the first hit — subsequent rules are never checked. This means order itself is priority; reversing the order can render a carefully designed rule set useless.

DOC-02

The DOMAIN Family: Routing by Domain

Domain-based rules are the most commonly used category, split into several variants with progressively broader matching scope:

In terms of granularity, DOMAIN is the most precise, DOMAIN-SUFFIX covers subdomains, and DOMAIN-KEYWORD is the broadest. In practice, DOMAIN-SUFFIX covers the vast majority of needs, while DOMAIN-KEYWORD is generally reserved for services with irregular domain structures.

Note

Domain rules only recognize domain names — they cannot detect connections made directly via IP. If a target site bypasses DNS resolution (for example, a client with a hardcoded IP), you'll need an IP-CIDR or GEOIP rule instead to catch it.

DOC-03

GEOIP: Matching by IP Location

GEOIP rules match based on the country or region code associated with a target IP, and are the key tool for implementing an overall "local traffic direct, everything else via proxy" strategy. Example syntax:

rules:
  - GEOIP,CN,DIRECT

This rule means: any connection whose resolved IP falls within a mainland China IP range goes direct, bypassing the proxy entirely. GEOIP rules are typically placed near the end of the full rule list, acting as a fallback for anything domain rules didn't cover — use DOMAIN-SUFFIX to handle known sites precisely first, then let GEOIP catch the remaining traffic that can be correctly classified purely by IP location.

GEOIP rules rely on a built-in or externally loaded IP geolocation database. The mihomo core has optimized both the update mechanism and matching performance for this database, making lookups faster than in earlier versions. Keep the IP database up to date, or location detection may lag behind — especially for newly allocated IP ranges.

DOC-04

IP-CIDR and RULE-SET: Finer-Grained or Bulk Matching

IP-CIDR matches a specific IP range, written in CIDR notation:

rules:
  - IP-CIDR,192.168.0.0/16,DIRECT
  - IP-CIDR,10.0.0.0/8,DIRECT

This is commonly used to keep internal network ranges on a direct connection, preventing LAN traffic from being mistakenly routed through the proxy tunnel. For IPv6, the equivalent is IP-CIDR6.

RULE-SET references an external rule set file, bundling large numbers of domain or IP rules into a single file that's referenced with just one line in the config:

rule-providers:
  reject:
    type: http
    behavior: domain
    url: "https://example.com/reject-list.yaml"
    path: ./rules/reject.yaml
    interval: 86400

rules:
  - RULE-SET,reject,REJECT
  - RULE-SET,direct,DIRECT
  - RULE-SET,proxy,Proxy

The value of RULE-SET is that it saves you from manually maintaining hundreds or thousands of domain rules — once the rule set author updates the upstream list, the client automatically re-fetches the latest content on the interval defined by interval. The behavior field describes the content type of the rule set: domain means a domain list, ipcidr means an IP range list, and classical means a mixed list using full rule syntax. Each behavior corresponds to a different internal file format, and the referenced behavior must match the actual file type or parsing will fail.

DOC-05

Complete Rule Snippet: Local Direct + Overseas Proxy

Below is a rule snippet tailored to the classic "mainland China sites direct, everything else via proxy" scenario. The order is already arranged by match priority, and it can be used as-is or adjusted as needed:

rules:
  # LAN and internal addresses — always direct
  - IP-CIDR,192.168.0.0/16,DIRECT
  - IP-CIDR,10.0.0.0/8,DIRECT
  - IP-CIDR,172.16.0.0/12,DIRECT
  - IP-CIDR,127.0.0.0/8,DIRECT

  # Ad and tracking domains — blocked outright
  - RULE-SET,reject,REJECT

  # Commonly used local sites — precise direct match
  - DOMAIN-SUFFIX,baidu.com,DIRECT
  - DOMAIN-SUFFIX,qq.com,DIRECT
  - DOMAIN-SUFFIX,taobao.com,DIRECT
  - DOMAIN-SUFFIX,jd.com,DIRECT
  - DOMAIN-SUFFIX,bilibili.com,DIRECT

  # Common overseas sites — routed through the proxy group
  - DOMAIN-SUFFIX,google.com,Proxy
  - DOMAIN-SUFFIX,youtube.com,Proxy
  - DOMAIN-SUFFIX,github.com,Proxy
  - DOMAIN-SUFFIX,twitter.com,Proxy

  # Externally maintained local domain rule set — bulk direct
  - RULE-SET,direct,DIRECT

  # Externally maintained proxy domain rule set
  - RULE-SET,proxy,Proxy

  # Fallback by IP location: mainland China direct
  - GEOIP,CN,DIRECT

  # Anything not yet matched — hand off to the proxy group
  - MATCH,Proxy

This snippet reflects a general design approach to rule writing: handle special cases first (LAN, ad blocking), then handle known high-frequency domains, let rule sets cover the long tail in bulk, and finally use GEOIP and MATCH as a catch-all, ensuring any traffic not matched by earlier rules still has a clear destination instead of failing to connect due to an incomplete rule list.

DOC-06

Priority Mechanics and Common Pitfalls

Two things to keep in mind about priority:

  1. Rules are compared one by one from top to bottom in the order written; the first match takes effect, and no subsequent rules are checked.
  2. The broader a rule type's matching scope, the more likely placing it too early will "jump the queue" and catch traffic that should have been handled by a more precise rule further down, producing routing results that don't match expectations.

Common ordering mistakes include: placing DOMAIN-KEYWORD at the very top of the rule list, causing many unintended domains to get caught by mistake; placing GEOIP,CN,DIRECT before overseas domain rules, causing some CDN-distributed domains whose IP happens to fall in a mainland China range — but which actually need the proxy — to be incorrectly routed direct; or forgetting to add a MATCH catch-all rule at the end, leaving the behavior of unmatched connections undefined.

When debugging rules, it's more efficient to use the client's built-in connection log or rule-hit viewer to check exactly which rule a specific domain actually matched, and adjust the order from there, rather than repeatedly guessing based on intuition.

Reminder

A rule set's declared behavior type (domain/ipcidr/classical) must match the actual content format of the rule set file. A mismatch causes the entire rule set to fail parsing, which in turn invalidates every domain judgment that depends on it — when switching to a different rule set source, check its documented behavior type first.

DOC-07

Working Alongside Proxy Groups

A rule's final target can be a proxy group name rather than a single node. Paired with proxy group types like select (manual selection), url-test (automatic latency-based switching), and fallback (failover), rule-based routing and node-selection strategy can be fully decoupled: rules only decide "should this kind of traffic go through the proxy or direct," while the specific node choice is left entirely to the proxy group. This layered design is key to why Clash configurations can be both flexible and maintainable at the same time.

proxy-groups:
  - name: Proxy
    type: url-test
    proxies:
      - Node A
      - Node B
    url: "http://www.gstatic.com/generate_204"
    interval: 300

As in the example above, the Proxy referenced in a rule corresponds to the proxy group defined here, whose member nodes are automatically speed-tested by the url-test type to select the one with the lowest latency. The rule file itself doesn't need to know anything about specific nodes, so switching subscriptions or adding/removing nodes later doesn't require touching the rules section at all.

Get the Clash Client

Rule-based routing requires a client that supports full rule syntax and RULE-SET to work properly — get the latest version from the download page and follow the setup guide to complete the basic configuration.

Download Clash