Rule Types
By writing rules, you can specify different outbound methods for different connections, such as forwarding through a proxy or intercepting. You can match based on the IP, domain name, process name, or a combination of multiple conditions.
For each connection, rules are always matched from top to bottom.
Rules can be classified into two types, where the IP type may trigger DNS resolution:
- Domain-based
- IP-based
- Other composite types
Want to write rules for URLs? Please read the HTTP Rewrite section.
You can add the no-track
parameter at the end of a rule to hide the connections that match this rule, for example SCRIPT,quic,REJECT,no-track
. This is very effective in avoiding a large number of REJECT records cluttering the page.
DOMAIN
Exact match of a domain name, for example DOMAIN,google.com
matches google.com
but not www.google.com
.
DOMAIN-SUFFIX
Match the domain name suffix, for example DOMAIN-SUFFIX,google.com
matches google.com
and www.google.com
.
DOMAIN-KEYWORD
Match the domain name with a keyword, for example DOMAIN-KEYWORD,google
matches google.com
and google.jp
.
GEOIP
Match the country code using MaxMind GeoIP, for example GEOIP,CN
, and you can add no-resolve
to avoid triggering DNS resolution.
Stash allows users to replace the MaxMind GeoIP database that conforms to the MaxMind GeoIP format. Users can choose a MaxMind GeoIP database that is more suitable for their own scenarios according to their needs.
IP-ASN
Match the IP Autonomous System Number (ASN), for example IP-ASN,714
, and you can add no-resolve
to avoid triggering DNS resolution.
IP-CIDR / IP-CIDR6
IP CIDR range, you can add no-resolve
to avoid triggering DNS resolution.
DST-PORT
Destination port.
RULE-SET
Use rule sets when referencing a large number of rules.
GEOSITE
domain-list-community (opens in a new tab) is a domain name list maintained by the v2fly community.
For example, GEOSITE,twitter
matches domain names related to the Twitter (opens in a new tab) company:
ads-twitter.com cms-twdigitalassets.com periscope.tv pscp.tv t.co tellapart.com tweetdeck.com twimg.com twitpic.com twitter.biz twitter.com twitter.jp twittercommunity.com twitterflightschool.com twitterinc.com twitteroauth.com twitterstat.us twtrdns.net twttr.com twttr.net twvid.com vine.co x.com
The domain-list-community data is not distributed with Stash. Stash will load domain name data from github.com on demand when first used. Please ensure the current configuration has connectivity to github.com when first used.
PROCESS-NAME
Process name, for example PROCESS-NAME,Telegram
, only valid for local processes.
Due to limitations of Network Extension, PROCESS-NAME rules are not supported in Stash iOS/tvOS (including the iOS version running on Apple silicon devices). Process-related rules in the configuration will be ignored.
PROCESS-PATH
Process path, for example PROCESS-PATH,/Applications/Telegram.app/Contents/MacOS/Telegram
, only valid for local processes.
Due to limitations of Network Extension, PROCESS-PATH rules are not supported in Stash iOS/tvOS (including the iOS version running on Apple silicon devices). Process-related rules in the configuration will be ignored.
SCRIPT
Match requests using a Python expression. The expression must return a Boolean value, and an error in the execution of the expression will be skipped.
The expression can read the following variables:
{
"network": "string", // one of tcp / udp
"host": "string", // may be empty
"dst_ip": "string", // may be empty
"dst_port": "number",
"src_ip": "string", // only works with gateway mode
"src_port": "number" // only works with gateway mode
}
The expression can call the following functions:
def resolve_ip(host: str) -> str:
pass
def in_cidr(ip: str, cidr: str) -> bool:
pass
def geoip(ip: str) -> str:
pass
def ipasn(ip: str) -> int:
pass
def match_provider(name: str) -> bool:
pass
For example, to intercept requests using the QUIC protocol, you can write:
rules:
- SCRIPT,quic,REJECT
- SCRIPT,udp-cn,ProxyToCN
script:
shortcuts: # can be referenced in rules
quic: network == 'udp' and dst_port == 443 # match QUIC protocol
udp-cn: network == 'udp' and geoip(dst_ip if dst_ip != '' else resolve_ip(host)) == 'CN' # match UDP to CN