Clash Custom Rules

Learn Clash rule types, matching order, no-resolve, and how to use rule-providers.

Three prerequisites for rules to take effect

Clash rules choose an outbound policy for connections; they do not create proxy nodes. Nodes, proxy groups, and rules serve different purposes: nodes provide an exit, proxy groups organize available exits, and rules decide which exit handles each connection. When troubleshooting, check these layers separately so an unavailable node is not mistaken for a rule that failed to match.

  1. The connection has reached the core. The system proxy usually affects only applications that honor proxy settings. Games, some command-line tools, and UDP traffic may bypass it. TUN can capture more traffic, but routing, exclusions, and permissions still need to be checked.
  2. Rule mode is enabled. The configuration should contain mode: rule. Global and direct modes do not apply the rules in this list for normal traffic routing.
  3. You are editing the configuration that is actually running. The original subscription, override configuration, and final configuration loaded by the core may differ. After saving, check the configuration validation result, then reload it.

Rule Syntax and Common Types

Most rules use the format type,match,policy. Use standard ASCII commas. Add each rule as a YAML list item under rules:, preceded by a hyphen. The built-in policies DIRECT and REJECT mean direct connection and reject, respectively. Other policy names must exactly match a defined node or proxy group.

Rule typeExampleWhat it matches
DOMAINDOMAIN,api.example.com,DIRECTMatches this exact domain, but not its subdomains.
DOMAIN-SUFFIXDOMAIN-SUFFIX,example.com,DIRECTMatches the root domain and its subdomains, but not otherexample.com.
DOMAIN-KEYWORDDOMAIN-KEYWORD,example,DIRECTMatches a string anywhere in the domain name; broader than a suffix rule.
IP-CIDRIP-CIDR,192.168.0.0/16,DIRECT,no-resolveMatches IPv4 destinations in the specified range; this example covers 192.168.0.0 through 192.168.255.255.
IP-CIDR6IP-CIDR6,fc00::/7,DIRECT,no-resolveMatches an IPv6 range; this example uses the unique local address range.
GEOIPGEOIP,CN,DIRECT,no-resolveMatches IP addresses using the local IP geolocation database. Accuracy depends on the database.
PROCESS-NAMEPROCESS-NAME,curl.exe,DIRECTMatches the process name detected by the core; results depend on the operating system and permissions.
MATCHMATCH,egressCatches connections that did not match any preceding rule. No match value is required.

Domain rules do not include a scheme, port, or path

To route https://api.example.com:443/v1/status, put only api.example.com in the domain rule. Adding the full URL to DOMAIN will not match it as a web address. To match by destination port, use DST-PORT if your core supports it. Keep in mind that DST-PORT,443,egress matches every connection on port 443 that reaches that point in the list, not just one website.

The example.com domains in this article are reserved for documentation and demonstrate syntax only. Replace them with the domains you actually want to route; the example rules will not change the route used by popular websites.

Matching Order and Exceptions

Regular rules are checked from top to bottom. The first matching rule determines the policy, and no later rules are considered. The core does not automatically choose the “most specific” rule or reconsider a match because a later rule rejects the connection. Put exceptions before general rules, and place MATCH last.

rules:
  - DOMAIN,api.example.com,DIRECT
  - DOMAIN,ads.example.com,REJECT
  - DOMAIN-SUFFIX,example.com,egress
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - MATCH,egress
  • api.example.com matches the first rule and connects directly.
  • ads.example.com matches the second rule, so the connection is rejected.
  • www.example.com matches the third rule and is handled by the “egress” proxy group.
  • A connection with the known destination address 192.168.1.20 that did not match any preceding domain rule matches the LAN entry.
  • All other connections go to the final MATCH rule.

If you move the third suffix rule to the top, both api.example.com and ads.example.com will match it first. The later direct and reject rules will never run, even if their syntax is correct.

Process Rules Follow the Same Order

Putting PROCESS-NAME,curl.exe,DIRECT at the top means connections from that process may go direct before website rules are checked. For an exception to a specific domain, use a domain rule where possible. Use a process rule only when the entire application should always use a particular route. Process names commonly include .exe on Windows, but not on Linux or macOS. Use the process name shown in the connection details.

What no-resolve Actually Means

no-resolve means that when checking this IP-based rule, the core will not initiate a DNS lookup just for a connection that has only a domain name. It does not disable DNS or guarantee that the connection will never resolve the domain. DNS resolution may still be triggered by client DNS settings, other rules, or the process of establishing the outbound connection.

rules:
  - DOMAIN-SUFFIX,example.com,egress
  - IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
  - GEOIP,CN,DIRECT,no-resolve
  - MATCH,egress

Suppose a connection has only domain information and did not match the first rule. When the core checks later IP rules, no-resolve prevents it from performing an extra lookup for those rules. If the connection already has a usable destination IP, IP-based rules can still match it. Whether an actual destination IP is available depends on the DNS mode, connection entry point, and metadata; the domain’s eventual DNS result alone does not guarantee a match.

Two Common Trade-offs

  • Prioritize domain-based routing: Put your main domain rules first and add no-resolve to IP rules to avoid lookups during rule evaluation. The trade-off is that some connections with only domain information may fall through to the default rule.
  • Route by resolved IP: Omit no-resolve from specific IP rules to allow DNS lookups during evaluation. This makes matching dependent on DNS responses and lookup time, so check your DNS configuration as well.

GEOIP,CN checks an IP’s location in the database. It does not identify who operates a website and is not equivalent to “all websites in mainland China.” A website using a CDN may produce different results depending on the resolved IP. For consistent routing, use explicit domain rules for the services you need to control.

Reuse Rules with rule-providers

If multiple configurations need the same domains and IP ranges, move the match conditions into a rule provider and reference it with RULE-SET. The provider loads the rules; their priority is determined by where RULE-SET appears in the main rules list, not by where the provider is declared.

Main Configuration: Local classical Rule Set

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

rules:
  - DOMAIN,api.example.com,egress
  - RULE-SET,local-direct,DIRECT
  - MATCH,egress

Rule set file: rules/local-direct.yaml

payload:
  - DOMAIN-SUFFIX,example.com
  - IP-CIDR,192.168.0.0/16,no-resolve
  - IP-CIDR6,fc00::/7,no-resolve

Entries in a rule set do not include DIRECT or a proxy group name; the main configuration assigns the target policy with RULE-SET,local-direct,DIRECT. In this example, api.example.com still matches the first rule in the main list. Other subdomains under the same root domain fall through to the rule set and connect directly.

path is usually resolved relative to the core’s working directory, which may not be the directory containing the downloaded subscription file. Check which rule file locations the client allows and create the file first. A missing file, inaccessible directory, or invalid content format can prevent the provider from loading.

behaviorContent formatUse case
classicalTyped rules, such as DOMAIN-SUFFIX,example.comOne set needs to include multiple types of conditions, such as domains and IP addresses.
domainEnter domain entries using the core’s domain rule-set syntaxFor maintaining domain-only sets without classical type prefixes.
ipcidrEnter address ranges such as 192.168.0.0/16For maintaining sets of IPv4 and IPv6 ranges.

You cannot mix these three formats by changing only behavior. For an HTTP provider, you also need a trusted, valid rule URL and an update interval. Remote rules can change routing behavior, so check their source and contents. Do not put an unknown set ahead of all your custom exceptions.

A Minimal Configuration You Can Test

The configuration below verifies mihomo syntax and matching order. It contains no proxy nodes, and the “egress” group contains only DIRECT, so all outbound traffic is direct except for connections matched by a reject rule. Once you have confirmed the rule behavior, add your existing nodes or proxy providers to the group.

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info

proxy-groups:
  - name: egress
    type: select
    proxies:
      - DIRECT

rules:
  - DOMAIN,api.example.com,DIRECT
  - DOMAIN,ads.example.com,REJECT
  - DOMAIN-SUFFIX,example.com,egress
  - 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
  - MATCH,egress

This configuration explicitly uses port 7890 for command-line testing. If another process is using it, choose an available port and update the test command too. allow-lan: false keeps the proxy listener closed to your local network. A client may override the listening port; check the running configuration and listener status.

Validate the Configuration, Then Test a Request

mihomo -t -f ./config.yaml
curl -I --proxy http://127.0.0.1:7890 https://example.com

The first command assumes the local executable is named mihomo and config.yaml is in the current directory. In a graphical client, use its configuration validation feature instead. The second command sends the request explicitly through the HTTP proxy, avoiding uncertainty about whether the command line inherits system proxy settings. In Windows PowerShell, use curl.exe to call the corresponding program.

The example request should match DOMAIN-SUFFIX,example.com,egress. Verify the rule type, match value, and policy chain in the connection details or logs—not by page load speed or the exit IP alone. Different rules can point to the same policy, so seeing the same exit does not prove that the same rule matched.

Troubleshooting Rules That Do Not Take Effect

  1. Check whether the connection appears. If the target request is missing from the client’s connection list, check the proxy entry point, TUN routing, and application settings first. If the request never reaches the core, changing rule order will not help.
  2. Check the active mode. Make sure the client is not in global or direct mode, and confirm which configuration is active—not just the file name shown in the editor.
  3. Check the first matching rule. If a broad suffix, keyword, or process rule catches the connection, move any necessary exception above it. Do not add rules after MATCH and expect them to take effect.
  4. Check policy names. “egress” and “proxy-egress” are different names. Referencing an undefined policy usually causes configuration validation to fail; fix the loading error first.
  5. Check domain and process metadata. If a connection has only an IP address, a domain rule may have nothing to match. If the process name is missing, a process rule cannot work as expected. TUN does not automatically supply domain and process information for every connection.
  6. Check provider status. Make sure the file exists, its format matches behavior, and the client has loaded the rule set successfully. After editing a local file, update the provider or reload the configuration as required by the client.
  7. Start a fresh test connection. Existing long-lived connections may continue using their original outbound route after a configuration update. Stop the request and start a new connection; if necessary, close the existing connection before testing again.

A consistent order makes rules easier to manage: put explicit reject and direct exceptions first, followed by service-specific domain sets; arrange process and IP rules according to their intended priority; and keep a clear MATCH rule last. Change one type of condition at a time and check the result with a new connection. This makes issues easier to isolate than changing DNS, TUN, and the entire rule set at once.

Download Clash Clients