规则类型
通过编写规则,您可以指定不同连接的出站方式,例如通过某个代理转发或拦截。规则可以根据连接的 IP、域名、进程名或组合多个条件进行匹配。
对于每一条连接,系统总是从上到下匹配规则。
规则可以分为以下几种类型,其中 IP 类型可能会触发 DNS 解析:
- 基于域名
- 基于 IP
- 其他复合类型
希望针对 URL 编写规则?请阅读 HTTP 重写 章节。
在规则的末尾可以添加 no-track
参数,以隐藏匹配到此规则的连接,例如
SCRIPT,quic,REJECT,no-track
。这对于避免大量 REJECT 记录充斥页面十分有效。
可以使用 REJECT
和 REJECT-DROP
这两个内置代理来拦截连接。REJECT
会立即返回错误,而 REJECT-DROP
会静默丢弃连接,以避免产生连接风暴。
DOMAIN
完全匹配域名,例如 DOMAIN,google.com
匹配 google.com
,但不匹配 www.google.com
。
DOMAIN-SUFFIX
匹配域名后缀,例如 DOMAIN-SUFFIX,google.com
匹配 google.com
和 www.google.com
。
DOMAIN-KEYWORD
关键词匹配域名,例如 DOMAIN-KEYWORD,google
匹配 google.com
和 google.jp
。
GEOIP
通过 MaxMind GeoIP 匹配国家代码,例如 GEOIP,CN
。可以添加 no-resolve
以避免触发 DNS 解析。
Stash 允许用户替换符合 MaxMind GeoIP 格式的数据库。用户可以根据自身需求选择更适合自己场景的 MaxMind GeoIP 数据库。
IP-ASN
通过 IP 自治系统编号匹配,例如 IP-ASN,714
。可以添加 no-resolve
以避免触发 DNS 解析。
IP-CIDR / IP-CIDR6
IP CIDR 范围匹配,例如 IP-CIDR,192.168.1.0/24
。可以添加 no-resolve
以避免触发 DNS 解析。
DST-PORT
目标端口匹配,例如 DST-PORT,80
。
RULE-SET
在引用大量规则时,请使用 规则集合。
GEOSITE
domain-list-community (opens in a new tab) 是由 v2fly 社区维护的域名列表。
例如 GEOSITE,twitter
匹配 Twitter (opens in a new tab) 公司相关域名:
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
domain-list-community 数据并不随 Stash 分发,Stash 会在首次使用时从 github.com 按需加载域名数据。首次使用请确保当前配置对 github.com 的连通性。
PROCESS-NAME
进程名称匹配,例如 PROCESS-NAME,Telegram
。仅对本机进程有效。
由于 Network Extension 的限制,Stash iOS/tvOS(包括运行于 Apple silicon 设备上的 iOS 版)不支持 PROCESS-NAME 规则,配置中进程相关规则会被忽略。
PROCESS-PATH
进程路径匹配,例如 PROCESS-PATH,/Applications/Telegram.app/Contents/MacOS/Telegram
。仅对本机进程有效。
由于 Network Extension 的限制,Stash iOS/tvOS(包括运行于 Apple silicon 设备上的 iOS 版)不支持 PROCESS-PATH 规则,配置中进程相关规则会被忽略。
SCRIPT
通过 Python 表达式匹配请求。表达式必须返回 Boolean 值,执行错误的表达式会被忽略。
表达式可以读取以下变量:
{
"network": "string", // 可以是 tcp 或 udp
"host": "string", // 可能为空
"dst_ip": "string", // 可能为空
"dst_port": "number",
"src_ip": "string", // 仅在网关模式下有效
"src_port": "number" // 仅在网关模式下有效
}
表达式可以调用以下函数:
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
def match_geosite(name: str) -> bool:
pass
例如,需要拦截 QUIC 协议的请求,可以这样写:
rules:
- SCRIPT,quic,REJECT
- SCRIPT,udp-cn,ProxyToCN
script:
shortcuts: # 可以在 rule 中引用
quic: network == 'udp' and dst_port == 443 # 匹配 QUIC 协议
udp-cn: network == 'udp' and geoip(dst_ip if dst_ip != '' else resolve_ip(host)) == 'CN' # 匹配发往 CN 的 UDP
instagram-quic: network == 'udp' and dst_port == 443 and match_geosite('instagram') # 匹配 Instagram 的 QUIC