Shadowrocket rules determine whether a connection uses PROXY, DIRECT, or REJECT. This guide is for users who already have their own service provider and subscription and want to adjust Config. It covers domain and IP matching, first-match behavior, the FINAL fallback, and how to verify changes. Example domains and addresses illustrate syntax only; they are not connection resources. After reading, you’ll be able to tell why a rule matched and where to place exceptions.
1. Separate match conditions from connection actions
A rule typically consists of a type, a match value, and an action, separated by English commas. For example, DOMAIN,example.com,DIRECT means: if the target domain available for matching is exactly example.com, choose DIRECT. Rules do not create a working proxy connection. If you choose PROXY, the address, port, and protocol settings in an existing connection entry must still be correct.
PROXY sends traffic through a proxy, DIRECT connects to the destination directly, and REJECT blocks the connection. These are not protocol names like Shadowsocks, VMess, VLESS, Trojan, Hysteria2, or WireGuard. A protocol defines how a proxy connection is established; rules decide which outbound policy applies to each destination. They operate at different layers.
The instructions below refer to the Home, Config, and Global Routing interface labels on iPhone and iPad. Before testing Config rules, go to Home → Global Routing and select Config. Proxy and Direct are global routing modes; they cannot verify whether individual rules in the same Config work as expected. Scene refers to scene settings and should not be treated as another name for Config.
2. DOMAIN, DOMAIN-SUFFIX, and DOMAIN-KEYWORD
All three match domains, but their coverage differs. DOMAIN matches an exact domain; DOMAIN-SUFFIX matches the specified domain and its subdomains; DOMAIN-KEYWORD checks whether a domain contains a given string. Don’t include https://, paths, query parameters, or ports in a rule’s domain value.
| Syntax | Matches | Does not match |
|---|---|---|
DOMAIN,example.com,DIRECT |
example.com |
api.example.com |
DOMAIN-SUFFIX,example.com,PROXY |
example.com、api.example.com |
notexample.com |
DOMAIN-KEYWORD,example,REJECT |
example.com、myexample.net |
sample.net |
DOMAIN-SUFFIX uses domain boundaries, not an arbitrary matching string at the end. So notexample.com is not a subdomain of example.com. DOMAIN-KEYWORD has no such boundary. Short strings such as ads may match domains you did not intend to include; a word in a domain name does not by itself establish what a connection is used for.
[Rule]
DOMAIN,api.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
DOMAIN-KEYWORD,telemetry,REJECT
FINAL,DIRECT
In the example above, api.example.com matches DOMAIN first and uses DIRECT. www.example.com does not match the first rule, so the second rule selects PROXY. Here, telemetry demonstrates string matching only; it does not establish the content or purpose of an actual connection. To reject a confirmed domain, prefer the more precise DOMAIN or DOMAIN-SUFFIX match.
3. GEOIP and IP-CIDR: Match by destination IP
GEOIP matches a destination address using location data in an IP database. A common example is GEOIP,CN,DIRECT. CN is a region code used by the database, not a website language or domain suffix. A Chinese-language page does not necessarily match CN, and the same domain may produce different IP matches if DNS returns different addresses.
IP-CIDR describes an address range using a network prefix. /24 fixes the first 24 bits; /32 specifies a single IPv4 address. The network ranges below are documentation examples to explain the syntax. They are not accessible servers, and you do not need to add them to your everyday configuration.
[Rule]
IP-CIDR,192.0.2.8/32,DIRECT,no-resolve
IP-CIDR,198.51.100.0/24,PROXY,no-resolve
GEOIP,CN,DIRECT
FINAL,PROXY
192.0.2.8/32matches only this IPv4 address, not192.0.2.9.198.51.100.0/24describes the range from198.51.100.0to198.51.100.255. This does not mean every address in the range can be used as a host.no-resolvemeans not to trigger domain resolution solely to match this IP rule. It does not disable DNS for the entire app.- If only a domain is available and no destination IP is known yet, an IP rule with
no-resolvemay not match. When troubleshooting, check what information was actually available for the connection at the time.
IP-CIDR does not check ports. TCP 443 and TCP 8443 on the same destination IP may both match the same network rule. If 443 works but 8443 fails, changing the network mask alone will not solve the problem. For IPv6 addresses, use the corresponding IPv6 rule type; don’t apply the IPv4 examples in this guide to IPv6 addresses.
4. Evaluate rules from top to bottom; put FINAL last
Rules are not automatically sorted by how “precise” their keywords are. DOMAIN does not inherently take priority over DOMAIN-SUFFIX: if a broader suffix rule matches first, a later exact-domain rule never runs. Put exceptions that need priority first, then broader matches later.
[Rule]
DOMAIN,download.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
GEOIP,CN,DIRECT
FINAL,PROXY
- Target:
download.example.com. The first rule matches and selects DIRECT; the second rule is not checked. - Target:
docs.example.com. The first rule does not match, so the second one selects PROXY. GEOIP is not checked afterward. - The target is not one of the domains above, but the database classifies its IP as CN: GEOIP selects DIRECT.
- None of the earlier rules matched:
FINAL,PROXYsends the remaining connection through the proxy.
FINAL has no domain or network field. Its syntax is FINAL,action, not FINAL,example.com,PROXY. It matches connections not handled by earlier rules and usually belongs at the end. Putting FINAL first prevents later ordinary rules from matching.
5. Edit and verify a rule in Config
Testing rules assumes you already have your own service provider and subscription. A connection subscription in Home under Subscribe and the routing configuration in Config are separate. Refreshing a connection subscription does not confirm that a new rule has loaded, and editing Config cannot fix an incorrect protocol password or server port. Back up the original configuration before making changes, and avoid changing connection settings and routing rules at the same time.
-
Back up the configuration
Open Config and locate the configuration currently in use. Use the item’s action menu to export a backup. Note which configuration was selected; test with a copy and keep the original available for recovery.
-
Edit the rules
In Config, open the editor for your test configuration and find
[Rule]. If the section already exists, don’t add its header again. Insert a specific DOMAIN rule before FINAL, then save. -
Select the configuration
Return to Config and confirm that the configuration you just edited is selected. Then go to Home → Global Routing and select Config, and check which connection entry is currently in use in Home.
-
Start a new connection
Close the destination page and visit it again; disconnect and reconnect if needed. Existing long-lived connections may retain their previous state, so don’t use an old session after saving rules to verify the new rules.
-
Check the logs
Check the connection records or logs for the destination domain, destination IP, and actual policy. Change one thing at a time. If the result is unexpected, restore the backup and compare the rule order before and after the change.
For testing, start with a controllable full domain and a DOMAIN rule, then expand to DOMAIN-SUFFIX. Don’t begin with a short DOMAIN-KEYWORD, or it may be difficult to tell which destinations were affected. If an app’s request appears only as an IP address, don’t assume domain rules have enough information to match it.
6. Troubleshoot connection errors separately from rule errors
“The webpage won’t load” does not, by itself, prove that the rule syntax is wrong. First check whether the actual outbound route matches what you expect, then troubleshoot the connection layer. The following error text may appear in connection diagnostics or low-level logs. Full messages vary by platform and system; these are not fixed rule-parsing errors.
Error: Connection refused
Cause and fix: The destination port is not accepting connections or has actively refused them. Check the logs to see whether the proxy server or destination website failed, then ask your own service provider to confirm the address and port for your existing connection. Matching PROXY does not mean the proxy port is reachable.
Error: Operation timed out
Cause and fix: The connection did not complete in time. The network path, server, or firewall may be involved. First compare the actual outbound route for the destination under the current rules with the expected route, then check the network and existing connection settings. A timeout alone does not point to a specific rule keyword.
- Rule not matching: Confirm Global Routing is set to Config, the correct configuration is selected, and no earlier rule takes precedence. Then check whether the target is a domain or an IP address.
- Connection fails after a match: Keep the correct rule and check the protocol, port, and authentication settings for the current connection. For TLS connections, also check the system time and server name settings.
- Unexpected behavior after saving: Check the English commas, number of fields, location of the
[Rule]section, and action names. Restore a known-good rule first, then add new entries one at a time. - Results vary: Record the addresses returned by DNS. GEOIP and IP-CIDR depend on the actual destination IP. If a CDN returns different addresses, you can’t determine the result just by looking at the browser’s address bar.
7. Common questions about rule syntax
I added DOMAIN. Why are subdomains still using the proxy?
DOMAIN matches only the exact domain. To send both example.com and its subdomains through DIRECT, use DOMAIN-SUFFIX,example.com,DIRECT and place it before any broader rule that would take precedence. After editing, go to Home → Global Routing, confirm Config is selected, and start a new connection.
Shouldn’t an exact-match rule take priority if it comes later?
No. Rules don’t get priority automatically. Move DOMAIN,api.example.com,DIRECT before DOMAIN-SUFFIX,example.com,PROXY so the exception matches this subdomain first. After saving, check which configuration is selected to avoid editing a copy while the original remains in use.
Will my manually added rules disappear when I update a subscription?
First, distinguish what is being updated: a connection subscription in Home and a remote configuration in Config are different. Updating a remote configuration may overwrite local changes in that configuration. Back up your test rules and save them in a separate copy. After an update, check the contents of [Rule] again rather than assuming every manually added entry will be preserved.
Should FINAL use DIRECT or PROXY?
Choose based on how you want to handle connections not matched by earlier rules. FINAL,DIRECT sends the rest directly; FINAL,PROXY sends the rest through the proxy. Decide what the fallback should do, then make sure any necessary exceptions appear before FINAL. Neither option replaces a working network connection and correct connection settings.