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.
- 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.
- 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. - 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 type | Example | What it matches |
|---|---|---|
DOMAIN | DOMAIN,api.example.com,DIRECT | Matches this exact domain, but not its subdomains. |
DOMAIN-SUFFIX | DOMAIN-SUFFIX,example.com,DIRECT | Matches the root domain and its subdomains, but not otherexample.com. |
DOMAIN-KEYWORD | DOMAIN-KEYWORD,example,DIRECT | Matches a string anywhere in the domain name; broader than a suffix rule. |
IP-CIDR | IP-CIDR,192.168.0.0/16,DIRECT,no-resolve | Matches IPv4 destinations in the specified range; this example covers 192.168.0.0 through 192.168.255.255. |
IP-CIDR6 | IP-CIDR6,fc00::/7,DIRECT,no-resolve | Matches an IPv6 range; this example uses the unique local address range. |
GEOIP | GEOIP,CN,DIRECT,no-resolve | Matches IP addresses using the local IP geolocation database. Accuracy depends on the database. |
PROCESS-NAME | PROCESS-NAME,curl.exe,DIRECT | Matches the process name detected by the core; results depend on the operating system and permissions. |
MATCH | MATCH,egress | Catches 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.commatches the first rule and connects directly.ads.example.commatches the second rule, so the connection is rejected.www.example.commatches the third rule and is handled by the “egress” proxy group.- A connection with the known destination address
192.168.1.20that did not match any preceding domain rule matches the LAN entry. - All other connections go to the final
MATCHrule.
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-resolveto 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-resolvefrom 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.
| behavior | Content format | Use case |
|---|---|---|
classical | Typed rules, such as DOMAIN-SUFFIX,example.com | One set needs to include multiple types of conditions, such as domains and IP addresses. |
domain | Enter domain entries using the core’s domain rule-set syntax | For maintaining domain-only sets without classical type prefixes. |
ipcidr | Enter address ranges such as 192.168.0.0/16 | For 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
- 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.
- 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.
- 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
MATCHand expect them to take effect. - 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.
- 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.
- 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. - 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.