网络代//理//的分流规则、代//理//协议、HTTP引擎、自建DNS、配置举例、定时任务、性能增强、HTTP重写、远程代//理//。
规则类型
通过编写规则可以指定不同连接的出站方式,例如通过某个代//理//转发,或者拦截。可以依据连接的 IP、域名、进程名或者组合多个条件去匹配。
对于每一条连接,总是从上到下匹配规则。
规则可以分类为两种类型,其中 IP 类型可能会触发 DNS 解析:
基于域名
基于 IP
其他复合类型
💡
希望针对 URL 编写规则?请阅读后面的 HTTP 重写章节。
💡
在规则的末尾可以添加 no-track 参数,可以隐藏匹配到此规则的连接,例如 SCRIPT,quic,REJECT,no-track。这对于避免大量 REJECT 记录充斥页面十分有效。
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 范围,可以添加 no-resolve 避免触发 DNS 解析。
DST-PORT
目标端口。
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", // 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
}
表达式可以调用下面的函数:
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
例如,需要拦截 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
规则集合
利用规则集合,可以在较低资源占用情况下引用大量规则,并且可以在后台静默更新而无需重新加载 Stash。要使用规则集合,必须在 rule-provide 下完成声明,此后便可以在 rules 下引用集合。
rule-providers:
proxy-domain:
behavior: domain # 使用 domain 类规则集,可以使匹配更高效
format: yaml # 使用 yaml 格式的规则集
url: https://cdn.jsdelivr.net/gh/Loyalsoldier/c-l-a-s-h-rules@release/proxy.txt
interval: 86400
cn-cidr:
behavior: ipcidr # 使用 ipcidr 类规则集,可以使匹配更高效
format: text # 使用 text 格式的规则集
url: https://cdn.jsdelivr.net/gh/Loyalsoldier/c-l-a-s-h-rules@release/cncidr.txt
interval: 86400
rules:
- RULE-SET,proxy-domain,Proxy
- RULE-SET,cn-cidr,DIRECT,no-resolve # ipcidr 类规则集支持 no-resolve 参数
Stash 支持多种规则集合格式,不同的格式支持不同的内容,并且有不同的资源占用:
行为(behavior) | 格式 | 支持内容 | 例子 | 匹配性能 |
---|---|---|---|---|
domain | yaml | 域名 / 域名通配符 | link (opens in a new tab) | 优秀 |
domain | text | 域名 / 域名通配符 | link (opens in a new tab) | 优秀 |
ipcidr | yaml | IPv4 / IPv6 集合,CIDR 格式 | link (opens in a new tab) | 优秀 |
ipcidr | text | IPv4 / IPv6 集合,CIDR 格式 | link (opens in a new tab) | 优秀 |
classical | yaml | 任意 | link (opens in a new tab) | 很差 |
classical | text | 任意 | link (opens in a new tab) | 很差 |
💡
domain(-text) 和 ipcidr(-text) 两种类型的规则集合专门针对大量数据进行了优化,在规则条目较多时建议优先选择。
不建议使用内含大量规则的 classical 规则集合,会显著提高 Stash 内存占用,降低规则匹配速度。
协议类型
Stash 支持多种类型的代//理//协议,可以代//理// TCP / UDP 协议。
每个代//理//必须含有以下参数:
name:代//理//名称,每个代//理//的名称是唯一的。
type:代//理//类型。
server:服务器地址,可以是域名或者 IP 地址。
port:端口。
代//理//可能支持以下参数:
tls:布尔值,是否基于 TLS 转发。
skip-cert-verify:布尔值,TLS 握手时是否忽略证书验证。
server-cert-fingerprint:字符串,TLS 握手时验证服务器证书 SHA256 指纹,以 Hex 编码。
sni:字符串,TLS 握手时候发送的 Server Name Indication(opens in a new tab)。若 sni 为空,默认为 server 字段。
alpn:字符串数组,TLS 握手时候发送的 Application-Layer Protocol Negotiation (ALPN)(opens in a new tab)。
interface-name:绑定网卡出口,仅在 macOS 支持。
此外,对于单个代//理//的延迟测试,支持修改以下参数:
benchmark-url:延迟测试使用的 URL,默认为 http://www.apple.com/。
benchmark-timeout:延迟测试超时,单位秒,默认为 5 秒。
你可以访问后面的关于测试代//理//延迟的信息。
不同类型的代//理//还需要指定一些参数,可以参考下文。
Sh/ad/ow/so/cks
name: ss1
type: ss
server: server
port: 443
cipher: chacha20-ietf-poly1305
password: 'password'
udp: true
plugin: null
plugin-opts:
mode:
host:
支持以下的加密方式(cipher):
aes-128-gcm
aes-192-gcm
aes-256-gcm
aes-128-cfb
aes-192-cfb
aes-256-cfb
aes-128-ctr
aes-192-ctr
aes-256-ctr
rc4-md5
chacha20
chacha20-ietf
xchacha20
chacha20-ietf-poly1305
xchacha20-ietf-poly1305
支持以下的插件(plugin):
plugin: obfs
plugin-opts:
mode: tls # 混淆模式,可以选择 http 或 tls
host: bing.com # 混淆域名,需要和服务器配置保持一致
plugin: v-2-r-a-y-plugin
plugin-opts:
mode: websocket # 暂时不支持 QUIC 协议
tls: true # wss
skip-cert-verify: true # 不验证证书
host: bing.com
path: '/'
headers: # 自定义请求头
key: value
Sh/ad/ow/so/cksR
name: ssr
type: ssr
server: server
port: 443
cipher: chacha20-ietf
password: 'password'
obfs: ''
protocol: ''
obfs-param: ''
protocol-param: ''
支持的加密方式(cipher)与 Sh/ad/ow/so/cks 相同。
支持的混淆方式(obfs):
plain
http_simple
http_post
random_head
tls1.2_ticket_auth
tls1.2_ticket_fastauth
支持的协议(protocol):
origin
auth_sha1_v4
auth_aes128_md5
auth_aes128_sha1
auth_chain_a auth_chain_b
SOCKS5
name: socks
type: socks5
server: server
port: 443
# username: username
# password: password
# tls: true
# skip-cert-verify: true
# udp: true
HTTP
name: http
type: http
server: server
port: 443
headers:
key: value
tls: true # https
skip-cert-verify: true
# username: username
# password: password
VMess
name: vmess
type: vmess
server: server
port: 443
uuid: d0529668-8835-11ec-a8a3-0242ac120002
cipher: auto
network:
支持加密方式(cipher):
auto
aes-128-gcm
chacha20-poly1305
none
支持的承载网络(network):
ws
h2
http
grpc
network: ws
ws-opts:
path: /path
headers:
Host: v-2-r-a-y.com
max-early-data: 2048
early-data-header-name: Sec-WebSocket-Protocol
network: h2
tls: true
h2-opts:
host:
- http.example.com
- http-alt.example.com
path: /
Snell
name: snell
type: snell
server: server
port: 443
psk: yourpsk
udp: true # 需要 v3 以上服务端
version: 3
# obfs-opts:
# mode: http # 或 tls
# host: bing.com
Snell UDP 需要 v3 版本以上的服务端支持。
支持的混淆模式(obfs-opts.mode)支持:
http
tls
Trojan
name: trojan
type: trojan
server: server
port: 443
password: yourpassword
# udp: true
# sni: example.com # Server Name Indication,如果空会使用 server 中的值
# alpn:
# - h2
# - http/1.1
# skip-cert-verify: true
支持的承载网络(network):
ws
grpc
Hysteria
Hysteria 是一个功能丰富的,专为恶劣网络环境进行优化的网络工具(双边加速),比如卫星网络、拥挤的公共 Wi-Fi、在中国连接国外服务器等。 基于修改版的 QUIC 协议。
Hysteria 服务端部署请参考这里(opens in a new tab)。
name: 'hysteria'
type: hysteria
server: server
port: 443
up-speed: 100 # 上传带宽(单位:Mbps)
down-speed: 100 # 下载带宽(单位:Mbps)
auth-str: your-password
# auth: aHR0cHM6Ly9oeXN0ZXJpYS5uZXR3b3JrL2RvY3MvYWR2YW5jZWQtdXNhZ2Uv # bytes encoded in base64
protocol: '' # udp / wechat-video
obfs: '' # obfs password
sni: example.com # Server Name Indication,如果空会使用 server 中的值
alpn:
- hysteria
skip-cert-verify: true
上传、下行带宽单位为 Mbps,请尽量正确填写,超出实际带宽会有反效果。
外部链接:base64 在线编码工具(opens in a new tab)。
Hysteria2
⚠️
请注意,Hysteria 2 与 Hysteria 1.x 完全不兼容,两者差异请参考官方说明(opens in a new tab)。
Hysteria2 服务端部署请参考这里(opens in a new tab)。
name: 'hysteria2'
type: hysteria2
server: server
port: 443
auth: your-password
fast-open: true
sni: example.com # Server Name Indication,如果空会使用 server 中的值
skip-cert-verify: true
up-speed: 100 # 上传带宽(可选的,单位:Mbps)
down-speed: 100 # 下载带宽(可选的,单位:Mbps)
VLESS
XTLS 协议在 TLS 环境下摆脱冗余加密,提供更优秀的转发性能。
name: vless
type: vless
server: server
port: 443
uuid: d0529668-8835-11ec-a8a3-0242ac120002
# flow: xtls-rprx-direct
# skip-cert-verify: true
# network: h2
# tls: true
# ws-opts:
# path: /path
# headers:
# Host: v-2-r-a-y.com
# grpc-opts:
# grpc-service-name: "example"
# h2-opts:
# host:
# - http.example.com
# - http-alt.example.com
# path: /
支持的 XTLS 模式(flow):
xtls-rprx-origin
xtls-rprx-direct
xtls-rprx-splice
TUIC
TUIC 是一个轻量的基于 QUIC 的代//理//协议,由 rust 语言编写,目前支持 v4 和 v5 版本。你可以在这里(opens in a new tab)找个更多信息。
name: tuic-v5
type: tuic
server: server
port: 443
version: 5
uuid: d0529668-8835-11ec-a8a3-0242ac120002 # for v5
password: your_password # for v5
skip-cert-verify: true
sni: ''
alpn:
- h3
name: tuic-v4
type: tuic
server: server
port: 443
version: 4
token: 'your_token' # for v4
skip-cert-verify: true
sni: ''
alpn:
- h3
💡
需要注意的是,Stash 客户端不支持 ALPN 为空,默认的 ALPN 为 h3。请在 TUIC 服务端加上 --alpn h3 参数。
请在服务端选择适合的拥塞控制算法 --congestion-controller 参数以充分利用带宽。
WireGuard
WireGuard(opens in a new tab) 是一个高效的 Layer 3 的 VPN,Stash 支持将其作为 Layer 4 的代//理//使用,并支持通过其他协议转发 WireGuard 数据包。
name: wireguard
type: wireguard
server: server # domain is supported
port: 51820
ip: 10.8.4.8
# ipv6: fe80::e6bf:faff:fea0:9fae # optional
private-key: 0G6TTWwvgv8Gy5013/jv2GttkCLYYaNTArHV0NdNkGI= # client private key
public-key: 0ag+C+rINHBnvLJLUyJeYkMWvIAkBjQPPObicuBUn1U= # peer public key
# preshared-key: # optional
dns: [1.0.0.1, 223.6.6.6] # optional
# mtu: 1420 # optional
# reserved: [0, 0, 0] # optional
# keepalive: 45 # optional
# underlying-proxy: # optional
# type: trojan
# server: your-underlying-proxy
# port: 443
# password: your-password
💡
WireGuard 并非以高吞吐为设计目标的代//理//协议,Stash 需要在用户空间完成 Layer 3 与 Layer 4 的转换,其性能损耗会比常见代//理//协议大。在移动设备上,WireGuard 吞吐量一般会比 Layer4 代//理//协议低。
⚠️
若使用 underlying-proxy,其必须支持 UDP 中继,建议使用 UDP over TCP 的协议(如 Trojan、VLESS、VMess、Snell)。
DIRECT with Specified Interface
通过新建类型为 direct 的代//理//,并指定 interface-name 可以强制某些流量通过指定网卡,常用于解决 VPN 与 Stash 无法同时使用的情况。
例如,本机上的 OpenVPN 使用了 utun3,并且希望 10.4.8.0/24 都进入 utun3 而不是 macOS 的默认网卡。
name: my-corp-vpn
type: direct
interface-name: utun3
rules:
- IP-CIDR,10.4.8.0/24,my-corp-vpn
💡
上述 utun3 请根据实际情况更改。
你可以使用 netstat -rn | grep utun3 查询 utun3 的静态路由表。
策略组
策略组(proxy-groups)是一系列代//理//(或策略组)的组合。策略组可以像单个代//理//一样被分流规则引用,并可以指定特殊的策略提高可用性。
分流规则可以直接引用代//理//或策略组,但不能引用远程代//理//集
策略组可以包含多个代//理//,或者多个远程代//理//集
策略组可以包含另一个策略组
不包含任何代//理//的策略组,会被当作为 DIRECT 策略处理
支持 filter 字段,通过正则表达式过滤节点
可以通过 include-all: true 引用所有的代//理//和远程代//理//集
策略组
💡
策略组内代//理//的排序方式默认为配置文件顺序,可以在「网络设置」页面改为按延迟测试结果排序。
url-test
url-test 可以定时对包含的代//理//执行连通性检查,自动选择延迟最短的服务器,不健康的代//理//会被跳过。
- name: auto
type: url-test
proxies:
- ss1
- ss2
- vmess
interval: 300
fallback
fallback 可以尽量按照用户书写的服务器顺序,在确保服务器可用的情况下,由上至下自动选择服务器,不健康的代//理//会被跳过。
- name: fallback-auto
type: fallback
proxies:
- ss1
- ss2
- vmess
load-balance
load-balance 能充分利用多个代//理//的带宽,不健康的代//理//会被跳过。
- name: load-balance
type: load-balance
strategy: # consistent-hashing / round-robin
proxies:
- ss1
- ss2
- vmess
一般建议将 strategy 设置为 consistent-hashing,避免频繁改变 IP 触发服务端的安全策略。
select
select 用来允许用户手动选择。
- name: select
type: select
proxies:
- ss1
- ss2
- vmess
- auto
relay
代//理//的转发链,流量将通过一系列的代//理//转发到达目的地,仅支持转发 TCP。relay 策略组并不受到内部代//理//延迟测试的结果影响,需要单独指定测试 URL。
- name: relay
type: relay
benchmark-url: http://www.apple.com # 建议只使用HTTP协议
benchmark-timeout: 5 # 延迟测试超时,单位:秒
# 流量: stash <-> http <-> vmess <-> ss1 <-> ss2 <-> 互联网
proxies:
- http
- vmess
- ss1
- ss2
额外功能
定时执行延迟测试
Stash 默认会每 600 秒为策略组内包含的代//理//进行延迟测试,如果策略组包含另外一个策略组,则会递归进行测试。
定时执行延迟测试支持修改下述配置:
interval:单位秒,按一定间隔执行延迟测试,默认为 600 秒,设置为负数则不进行延迟测试。
lazy:懒惰模式,如果设置为 true,且策略组在过去一段时间没有被使用,Stash 会跳过自动延迟测试以节省资源。
proxy-groups:
- name: my-proxy-group
type: select
# ...
interval: 300 # 每 300s 检查一次
lazy: true # 在策略组没有被使用时候,不进行延迟测试
基于网络状态自动切换策略
select 类型的策略组可以根据设备的 SSID / 蜂窝数据自动切换策略。
default 和 cellular 是两个可选的保留策略:
当在 Wi-Fi 环境下,没有匹配到任何 SSID 时,会自动切换到 default 对应的代//理//;
在蜂窝数据下,会自动切换到 cellular 对应的代//理//;
当没有 default 或 cellular 时候,不会触发任何操作。
- name: ssid-group
type: select # 类型必须为 select,兼容原版 c-l-a-s-h 配置
proxies:
- ss1
- ss2
- ss3
- DIRECT
ssid-policy:
# 在 SSID 为 office 的 Wi-Fi 中自动切换为 ss1 策略
# 在 SSID 为 home 的 Wi-Fi 中自动切换为 ss2 策略
# 在蜂窝数据中自动切换为 ss3 策略
# 其他的 SSID 默认为 DIRECT
office: ss1
home: ss2
cellular: ss3
default: DIRECT
灵活地组合代//理//
Stash 支持各种方式将多个代//理//组合成一个策略组。
可以通过 include-all: true 引用所有的代//理//和远程代//理//集
不包含任何代//理//的策略组,会被当作为 DIRECT 策略处理。
支持 filter 字段,通过正则表达式过滤节点
proxy-groups:
- name: my-hongkong-group
type: select
include-all: true # 引用所有 proxies & proxy-providers
filter: 'HK|香港' # 筛选含有 HK 或香港关键字的代//理//
远程代//理//集
在配置文件直接声明的代//理//,无法在后台自动更新。我们更推荐使用远程代//理//集(proxy-provider),能在后台自动从 URL 更新策略组。
要使用远程代//理//集,需要在 proxy-providers 下定义,并在 proxy-groups 中引用。
proxy-providers:
provider-a:
url: https://raw.githubusercontent.com/STASH-NETWORKS-LIMITED/stash-example/main/config.yaml
interval: 3600
filter: 'example'
provider-b:
url: https://raw.githubusercontent.com/STASH-NETWORKS-LIMITED/stash-example/main/config.yaml
interval: 3600
proxy-groups:
- name: auto
type: url-test
interval: 300
use:
- provider-a # reference to provider-a
- provider-b # reference to provider-b
一个合法的远程代//理//集必须包含 proxies 字段:
proxies:
- name: 'ss1'
type: ss
server: server
port: 443
cipher: AEAD_CHACHA20_POLY1305
password: 'password'
- name: 'ss2'
type: ss
server: server
port: 443
cipher: AEAD_CHACHA20_POLY1305
password: 'password'
远程代//理//集支持通过 filter 字段,使用正则表达式过滤代//理//名。远程代//理//集为空时候,会以 DIRECT 替代。
快捷引用远程代//理//集
Stash 也支持通过 use-url 在策略组中快捷引用远程代//理//集,此时不可指定更新时间和名称。
proxy-groups:
- name: auto
type: url-test
interval: 300
use-url:
- https://raw.githubusercontent.com/STASH-NETWORKS-LIMITED/stash-example/main/config.yaml
延迟测试
在 Stash 中,你可以为每个代//理//指定单独的延迟测试参数,包括:延迟测试目标 URL,测试的超时时间。
延迟测试超时的代//理//,会被标记为不健康。
proxies:
- name: your-proxy
type: ss
server: server
port: 443
benchmark-url: http://www.apple.com # 建议只使用HTTP协议
benchmark-timeout: 5 # 延迟测试超时,单位:秒
💡
如果一个代//理//被多个策略组引用,多个策略组会共享这个代//理//的延迟测试结果。
若希望一个代//理//在不同的策略组使用不同的延迟测试参数,请手动创建多个代//理//。
延迟测试方式
Stash 支持多种方式对代//理//进行延迟测试,包括:
ICMP:使用 ICMP 报文进行延迟测试
TCP:使用 TCP 握手进行延迟测试
HTTP HEAD:默认方式,通过代//理//发送 HTTP HEAD 进行延迟测试
配置样例
Stash 所有的配置文件均使用 YAML(opens in a new tab) 格式。在 YAML 格式中,缩进影响了整个配置的结构,用户可以在 www.yamllint.com(opens in a new tab) 检查配置是否符合 YAML 格式。
Stash 配置由单个配置文件和若干个覆写文件组成,配置文件是必须的,覆写文件是可选的,具体看后面章节介绍。覆写的优先级比配置文件高,覆写文件中的字段会覆盖配置文件中的字段。用户可以通过配置和覆写的组合,打造符合自己需求的配置。
虽然配置文件的必须的,但其中每一个字段都有默认值,用户仅需要填写希望更改的字段即可。
# 配置基于 https://github.com/Hackl0us/SS-Rule-Snippet 修改
# 规则模式:rule(规则) / global(全局代//理//)/ direct(全局直连)
mode: rule
# 设置日志输出级别 (默认级别:silent,即不输出任何内容,以避免因日志内容过大而导致程序内存溢出)。
# 5 个级别:silent / info / warning / error / debug。级别越高日志输出量越大,越倾向于调试,若需要请自行开启。
log-level: info
# HTTP 引擎相关
http:
# 强制使用 HTTP 引擎处理 TCP 连接
# 捕获后的连接可以使用高级功能,例如重写和脚本
force-http-engine:
- '*:80'
- '*:4480' # BiliBili CDN
- '*:9102' # BiliBili CDN
# 以 PKCS #12 编码的 CA 证书
ca: ''
# 证书密码
ca-passphrase: ''
# 开启 MitM 功能的域名列表,需要确保上述 CA 证书已受系统信任
mitm:
- g.cn
- '*.google.cn'
- weather-data.apple.com # 默认只对 443 端口开启
- weather-data.apple.com:* # 使用通配符对所有端口开启
- '*.weather-data.apple.com' # 域名中也可以使用通配符
- '-exclude.weather-data.apple.com' # 用-前缀排除域名
# HTTP(S) 重写,支持 header、302、307、reject 多种策略
url-rewrite:
- ^http://g\.cn http://www.google.com header # 重写请求头的域名
- ^https?://www\.google\.cn https://www.google.com 302 # 直接返回一个 302 重定向的响应
- ^https?://ad\.example - reject # 拒绝请求
# 使用 JavaScript 脚本改写 HTTP(S) 请求
script:
- match: https://weather-data.apple.com/v2/weather/[\w-]+/-?[0-9]+\.[0-9]+/-?[0-9]+\.[0-9]+\?
name: weather-us-aqi # 引用 script-providers 中的脚本
type: response # 脚本类型:request / response
require-body: true # 如果需要 request / response body,请设置为 true
timeout: 10 # script timeout in second (optional)
argument: '' # script argument (optional)
debug: false # 开发模式,每次执行前会从 provider 加载最新脚本
binary-mode: false # 以二进制模式获取 body
max-size: 1048576 # 1MB
# 定时任务
cron:
# 定时执行 JavaScript 脚本
script:
- name: weather-us-aqi # 引用 script-providers 中的脚本
cron: '* * * * *' # cron 表达式,可以在 https://crontab.guru/ 获取更多介绍
timeout: 10 # script timeout in second (optional)
argument: '' # script argument (optional)
debug: false # 开发模式,每次执行前会从 provider 加载最新脚本
script-providers:
weather-us-aqi:
url: https://raw.githubusercontent.com/STASH-NETWORKS-LIMITED/stash-example/main/script/iOS15_Weather_AQI_Standard.js
interval: 86400
script:
shortcuts: # 使用 Python 表达式编写自定义规则
# 4483 与 9305 为 BiliBili 的 QUIC CDN
quic: network == 'udp' and (dst_port == 443 or dst_port == 4483 or dst_port == 9305) # 可以在 rule 中引用
# 支持通配符域名 (例如: *.c-l-a-s-h.dev, *.foo.*.example.com )
# 不使用通配符的域名优先级高于使用通配符的域名 (例如: foo.example.com > *.example.com > .example.com )
# 注意: +.foo.com 的效果等同于 .foo.com 和 foo.com
hosts:
'*.c-l-a-s-h.dev': 127.0.0.1
'.dev': 127.0.0.1
'alpha.c-l-a-s-h.dev': '::1'
# DNS 服务器配置
dns:
# 以下填写的 DNS 服务器将会被用来解析 DNS 服务的域名
# 仅填写 DNS 服务器的 IP 地址
default-nameserver:
- 223.5.5.5
- 114.114.114.114
- system # 使用 iOS 系统 DNS
# 支持 UDP / TCP / DoT / DoH 协议的 DNS 服务,可以指明具体的连接端口号。
# 所有 DNS 请求将会直接发送到服务器,不经过任何代//理//。
# Stash 会使用最先获得的解析记录回复 DNS 请求
nameserver:
# 不建议配置超过 2 个 DNS 服务器,会增加系统功耗
- https://doh.pub/dns-query
- https://dns.alidns.com/dns-query
- quic://dns.adguard.com:853
- doq://test.dns.nextdns.io:853
- system # 使用 iOS 系统 DNS
# 跳过证书验证,解决部分兼容性问题 https://help.nextdns.io/t/g9hdkjz
skip-cert-verify: true
# 对部分域名使用单独的 DNS 服务器
nameserver-policy:
'www.baidu.com': 114.114.114.114
'+.internal.crop.com': system
# 在以下列表的域名将不会被解析为 fake ip,这些域名相关的解析请求将会返回它们真实的 IP 地址
fake-ip-filter:
# from: https://github.com/Kr328/c-l-a-s-hForAndroid/blob/ffa559a57102ed8bc20eba41aa236a7764741bf9/core/src/main/golang/native/config/defaults.go#L10
# Stun Services
- '+.stun.*.*'
- '+.stun.*.*.*'
- '+.stun.*.*.*.*'
- '+.stun.*.*.*.*.*'
# Google Voices
- 'lens.l.google.com'
# Nintendo Switch
- '*.n.n.srv.nintendo.net'
# PlayStation
- '+.stun.playstation.net'
# XBox
- 'xbox.*.*.microsoft.com'
- '*.*.xboxlive.com'
# Microsoft
- '*.msftncsi.com'
- '*.msftconnecttest.com'
# Bilibili CDN
- '*.mcdn.bilivideo.cn'
proxies:
# Sh/ad/ow/so/cks
# 支持加密方式:
# aes-128-gcm aes-192-gcm aes-256-gcm
# aes-128-cfb aes-192-cfb aes-256-cfb
# aes-128-ctr aes-192-ctr aes-256-ctr
# rc4-md5 chacha20 chacha20-ietf xchacha20
# chacha20-ietf-poly1305 xchacha20-ietf-poly1305
- name: 'ss1'
type: ss
server: server
port: 443
benchmark-url: http://www.apple.com
benchmark-timeout: 5
cipher: chacha20-ietf-poly1305
password: 'password'
- name: 'ss2'
type: ss
server: server
port: 443
benchmark-url: http://www.apple.com
benchmark-timeout: 5
cipher: AEAD_CHACHA20_POLY1305
password: 'password'
plugin: obfs
plugin-opts:
mode: tls # 混淆模式,可以选择 http 或 tls
host: bing.com # 混淆域名,需要和服务器配置保持一致
- name: 'ss3'
type: ss
server: server
port: 443
benchmark-url: http://www.apple.com
benchmark-timeout: 5
cipher: AEAD_CHACHA20_POLY1305
password: 'password'
plugin: v-2-r-a-y-plugin
plugin-opts:
mode: websocket # 暂时不支持 QUIC 协议
tls: true # wss
skip-cert-verify: true
host: bing.com
path: '/'
headers:
custom: value
# vmess
# 支持加密方式:auto / aes-128-gcm / chacha20-poly1305 / none
- name: 'vmess'
type: vmess
server: server
port: 443
benchmark-url: http://www.apple.com
benchmark-timeout: 5
uuid: d0529668-8835-11ec-a8a3-0242ac120002
alterId: 32
cipher: auto
tls: true
skip-cert-verify: true
servername: example.com # 优先级高于 wss host
network: ws
ws-opts:
path: /path
headers:
Host: v-2-r-a-y.com
max-early-data: 2048
early-data-header-name: Sec-WebSocket-Protocol
- name: 'vmess-h2'
type: vmess
server: server
port: 443
benchmark-url: http://www.apple.com
benchmark-timeout: 5
uuid: d0529668-8835-11ec-a8a3-0242ac120002
alterId: 32
cipher: auto
network: h2
tls: true
h2-opts:
host:
- http.example.com
- http-alt.example.com
path: /
- name: 'vmess-http'
type: vmess
server: server
port: 443
benchmark-url: http://www.apple.com
benchmark-timeout: 5
uuid: d0529668-8835-11ec-a8a3-0242ac120002
alterId: 32
cipher: auto
network: http
http-opts:
method: 'GET'
path:
- '/'
- '/video'
headers:
Connection:
- keep-alive
- name: 'vmess-grpc'
server: server
port: 443
benchmark-url: http://www.apple.com
benchmark-timeout: 5
type: vmess
uuid: d0529668-8835-11ec-a8a3-0242ac120002
alterId: 32
cipher: auto
network: grpc
tls: true
servername: example.com
skip-cert-verify: true
grpc-opts:
grpc-service-name: 'example'
# socks5
- name: 'socks'
type: socks5
server: server
port: 443
benchmark-url: http://www.apple.com
benchmark-timeout: 5
username: username
password: password
tls: true
skip-cert-verify: true
# http
- name: 'http'
type: http
server: server
port: 443
benchmark-url: http://www.apple.com
benchmark-timeout: 5
username: username
password: password
tls: true # https
skip-cert-verify: true
# snell
- name: 'snell'
type: snell
server: server
port: 44046
benchmark-url: http://www.apple.com
benchmark-timeout: 5
psk: yourpsk
version: 3
obfs-opts:
mode: http # 或 tls
host: bing.com
# Trojan
- name: 'trojan'
type: trojan
server: server
port: 443
benchmark-url: http://www.apple.com
benchmark-timeout: 5
password: yourpsk
sni: example.com # Server Name Indication,如果空会使用 server 中的值
alpn:
- h2
- http/1.1
skip-cert-verify: true
# hysteria https://github.com/HyNetwork/hysteria/wiki/%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95
- name: 'hysteria'
type: hysteria
server: server
port: 443
benchmark-url: http://www.apple.com
benchmark-timeout: 5
up-speed: 100 # 上传带宽(单位:Mbps)
down-speed: 100 # 下载带宽(单位:Mbps)
auth-str: your-password
# auth: aHR0cHM6Ly9oeXN0ZXJpYS5uZXR3b3JrL2RvY3MvYWR2YW5jZWQtdXNhZ2Uv # bytes encoded in base64
protocol: '' # udp / wechat-video
obfs: '' # obfs password
sni: example.com # Server Name Indication,如果空会使用 server 中的值
alpn:
- hysteria
skip-cert-verify: true
# Sh/ad/ow/so/cksR
# 支持的加密方式: SS 中支持的所有流加密方式
# 支持的混淆方式:
# plain http_simple http_post
# random_head tls1.2_ticket_auth tls1.2_ticket_fastauth
# 支持的协议:
# origin auth_sha1_v4 auth_aes128_md5
# auth_aes128_sha1 auth_chain_a auth_chain_b
- name: 'ssr'
type: ssr
server: server
port: 443
benchmark-url: http://www.apple.com
benchmark-timeout: 5
cipher: chacha20-ietf
password: 'password'
obfs: tls1.2_ticket_auth
protocol: auth_sha1_v4
obfs-param: domain.tld
protocol-param: '#'
- name: 'vless'
type: vless
server: server
port: 443
benchmark-url: http://www.apple.com
benchmark-timeout: 5
uuid: d0529668-8835-11ec-a8a3-0242ac120002
flow: xtls-rprx-direct
skip-cert-verify: true
network: h2
tls: true
ws-opts:
path: /path
headers:
Host: v-2-r-a-y.com
grpc-opts:
grpc-service-name: 'example'
h2-opts:
host:
- http.example.com
- http-alt.example.com
path: /
proxy-groups:
# 代//理//的转发链, 在 proxies 中不应该包含 relay. 不支持 UDP.
# 流量: c-l-a-s-h <-> http <-> vmess <-> ss1 <-> ss2 <-> 互联网
- name: 'relay'
type: relay
icon: https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/Color/Direct.png
proxies:
- http
- vmess
- ss1
- ss2
# url-test 可以自动选择延迟最短的服务器
- name: 'auto'
type: url-test
proxies:
- ss1
- ss2
- vmess
interval: 300
# fallback 可以尽量按照用户书写的服务器顺序,在确保服务器可用的情况下,自动选择服务器
- name: 'fallback-auto'
type: fallback
proxies:
- ss1
- ss2
- vmess
interval: 300
# load-balance 可以使相同 eTLD 请求在同一条代//理//线路上
- name: 'load-balance'
type: load-balance
proxies:
- ss1
- ss2
- vmess
interval: 300
# select 用来允许用户手动选择 代//理//服务器 或 服务器组
# 您也可以使用 RESTful API 去切换服务器,这种方式推荐在 GUI 中使用
- name: Proxy
type: select
proxies:
- ss1
- ss2
- vmess
- auto
# 基于 SSID 的策略,方便在特殊网络环境下使用特定的代//理//
- name: ssid-group
type: select # 类型必须为 select,兼容原版 c-l-a-s-h 配置
proxies:
- ss1
- ss2
- DIRECT
ssid-policy:
# 在 SSID 为 office 的 Wi-Fi 中自动切换为 ss1 策略
# 在 SSID 为 home 的 Wi-Fi 中自动切换为 ss2 策略
# 在蜂窝数据中自动切换为 ss3 策略
# 其他的 SSID 默认为 DIRECT
office: ss1
home: ss2
cellular: ss3
default: DIRECT
- name: UseProvider
type: select
use:
- provider1
proxies:
- Proxy
- DIRECT
proxy-providers:
provider1:
url: https://raw.githubusercontent.com/STASH-NETWORKS-LIMITED/stash-example/main/config.yaml
interval: 3600
rule-providers:
proxy-domain:
behavior: domain # 使用 domain 类规则集,可以使匹配更高效
url: https://cdn.jsdelivr.net/gh/Loyalsoldier/c-l-a-s-h-rules@release/proxy.txt
interval: 86400
proxy-domain-text:
behavior: domain-text # 推荐使用 text 格式
url: https://cdn.jsdelivr.net/gh/Loyalsoldier/surge-rules@release/proxy.txt
interval: 86400
lan-cidr:
behavior: ipcidr
url: https://cdn.jsdelivr.net/gh/Loyalsoldier/c-l-a-s-h-rules@release/lancidr.txt
interval: 86400
ip-cidr-text:
behavior: ipcidr-text
url: https://cdn.jsdelivr.net/gh/17mon/china_ip_list@master/china_ip_list.txt
interval: 86400
apple-direct:
behavior: classical # 不推荐使用 classical 类规则集
url: 'https://cdn.jsdelivr.net/gh/Hackl0us/SS-Rule-Snippet@master/Rulesets/c-l-a-s-h/Basic/Apple-direct.yaml'
interval: 3600
rules:
- SCRIPT,quic,REJECT,no-track
- RULE-SET,proxy-domain,Proxy
- RULE-SET,apple-direct,DIRECT
- RULE-SET,lan-cidr,DIRECT
- RULE-SET,ip-cidr-text,DIRECT
- GEOIP,CN,DIRECT
- MATCH,Proxy
覆写文件(Override)
覆写文件(Override)允许用户修改配置文件的部分字段,常用于修改托管、订阅的配置的内容。Stash 允许同时启用多个覆写文件,会从上到下覆盖了原来配置中。
一个最佳实践是,为了便于单独控制开关和分享,通常以单个功能点划分覆写文件。
语法参考
覆写文件使用 YAML 格式,后缀名为 stoverride;
通常地,使用 name 与 desc 字段作为覆写文件的名称和描述,这两个字段仅用于展示;
覆写文件对配置文件的修改,采用如下规则:
对于简单类型的同名 key,例如 string、number、boolean,会直接覆盖;
对于字典类型的同名 key,采用递归按 key 合并;
对于数组类型的同名 key,采用覆写文件的数组会插入在配置文件数组的前面。
对于字典类型和数组类型的 key 后面新增注释(line comment)#!replace,则会采用覆盖方式合并
⚠️
暂时不支持修改数组中的元素,后续会提供其他语法进行修改。
常见的覆写样例:
name: BiliBili 重定向 MCDN / PCDN 到正规 CDN
desc: 加载更流畅的 BiliBili 更值得干杯🍻!
http:
force-http-engine:
- 'upos-*.bilivideo.com:80'
- '*:4480'
- '*:9102'
url-rewrite:
- https?:\/\/(.*):4480\/upgcxcode http://upos-sz-mirrorcos.bilivideo.com/upgcxcode 302
- https?:\/\/(.*):9102\/upgcxcode http://upos-sz-mirrorcos.bilivideo.com/upgcxcode 302
- https?:\/\/upos-.*-.*oss\d*\.bilivideo\.com\/upgcxcode http://upos-sz-mirrorcos.bilivideo.com/upgcxcode 302
- https?:\/\/upos-sz-mirror(?!cos\.).*bilivideo\.com\/upgcxcode http://upos-sz-mirrorcos.bilivideo.com/upgcxcode 302
# alternative:
# upos-sz-mirrorhw.bilivideo.com
# upos-sz-mirrorcos.bilivideo.com
# upos-sz-mirrorcoso1.bilivideo.com
# upos-sz-mirrorcoso2.bilivideo.com
# upos-sz-mirrorbs.bilivideo.com
# upos-sz-mirrorali.bilivideo.com
script:
shortcuts:
bilibili-quic: network == 'udp' and geoip(dst_ip) == 'CN' and dst_port == 3478
rules:
- SCRIPT,bilibili-quic,REJECT
采用了 #!replace 语法的覆写样例:
name: 仅使用 CloudFlare DNS
dns:
# 将会完整覆盖原有 default-nameserver
default-nameserver: #!replace
- system
- 223.5.5.5
- 1.0.0.1
# 将会完整覆盖原有 nameserver
nameserver: #!replace
- https://1.0.0.1/dns-query # CF IPv4
- https://[2606:4700:4700::1111]/dns-query # CF IPv6
下面为一个简单的合并实例:
# config.yaml
dict:
k1: true
k2: 1
k3:
- 1
- 2
- 3
k4:
- 1
- 2
- 3
# override file
key: value
dict:
k3:
- 0
k4: #!replace
- 1
k5: null
# after override
key: value
dict:
k1: true
k2: 1
k3:
- 0
- 1
- 2
- 3
k4:
- 1
k5: null
策略组图标
为了区分不同的策略组,你可以为不同的策略组指定一个图标。在配置文件的 proxy-groups 章节的策略组里添加 icon 字段,并输入图片的 URL 即可,支持 JPG、PNG 格式的图片。
- name: 'auto'
type: url-test
icon: https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/Color/Direct.png
proxies:
- ss1
- ss2
- vmess
interval: 300
HTTP 引擎
Stash HTTP Engine
Stash 内置高效的 HTTP 引擎,允许用户对系统中的 HTTP 请求进行改写、拦截、抓取、重放,以及对 HTTPS 请求通过 MitM 方式进行解密。
入站逻辑
系统中并非所有连接都是 HTTP 请求,Stash 会按照以下策略控制连接是否进入 HTTP 引擎。
在「仅使用 Tunnel 代//理//」关闭的情况下,Stash 会向系统声明 HTTP Proxy。进入 HTTP Proxy 的 HTTP 请求会流入 HTTP 引擎处理。
对于从 Tunnel 进入,且命中 force-http-engine 列表的 TCP 连接,也会流入 HTTP 引擎处理。
对于命中 MitM 列表的 HTTPS 请求,也会流入 HTTP 引擎处理,并且 Stash 会根据 SNI 使用配置的根证书生成临时证书,完成 TLS 握手。
其他未命中请求会以 TCP 流转发,不进入 HTTP 引擎。
暂时不支持处理 HTTP/3 的请求,Stash 会当作普通 UDP 包转发,此时整体吞吐量一般不如基于 TCP 的 HTTP/1 与 HTTP/2 协议。
在遇到 HTTP 改写、脚本不生效时,可以核对上述规则排查。
协商与连接管理
Stash HTTP Engine 完整支持解析 HTTP/1.x 与 HTTP/2 协议。
对于 HTTP 请求,Stash HTTP Engine 仅支持 HTTP/1.x 协议,不支持 HTTP/2 Cleartext。
对于 HTTPS 请求且开启了 MitM,Stash 会尝试与 App 协商升级到 HTTP/2,也会与 Web Server 协商升级到 HTTP/2,L、R 两侧连接是各自独立无影响的。
Stash HTTP Engine 对于 L、R 两侧连接实行分别管理,对于 R 侧连接,Stash 会最大限度地复用 TCP 连接,以减少 TCP / TLS 握手的消耗。
实践与表现
在实践中,存在:
部分 App 不进行 HTTP/2 协商,但 Web Server 支持 HTTP/2 的情况。在 Stash HTTP Engine 通过 MitM 接管后, L 侧会使用 HTTP/1.1 协议,但 R 侧会协商至 HTTP/2。
部分 App 即使在 Web Server 支持 HTTP/2 的情况下,仍为每个 HTTPS 请求创建一个 TLS 连接的情况。在 Stash HTTP Engine 通过 MitM 接管后,实际只会创建单条 TCP 连接到 Web Server。
MitM
如果想对 HTTPS 请求进行查看、改写、执行脚本,必须启用 MitM 功能。在启用 MitM 功能前,你的设备需要信任自行签发的 CA 证书,该 CA 证书可以由用户导入 Stash,或由 Stash 生成。
⚠️
基于数据安全以及私隐的考虑,任何时候你不应该与他人共享证书,或使用互联网上提供的 CA 证书。
使用配置文件配置 MitM
配置 CA 证书
http:
# 以 PKCS #12 编码的 CA 证书
ca: ''
# 证书密码
ca-passphrase: ''
# 开启 MitM 功能的域名列表,需要确保上述 CA 证书已受系统信任
配置 MitM 列表
http:
# 开启 MitM 功能的域名列表,需要确保上述 CA 证书已受系统信任
mitm:
- g.cn
- '*.google.cn'
- weather-data.apple.com # 默认只对 443 端口开启
- weather-data.apple.com:* # 使用通配符对所有端口开启
- '*.weather-data.apple.com' # 域名中也可以使用通配符
至此,MitM 配置完毕。
使用图形界面配置 MitM
如果无法在配置文件中添加 CA 证书,可以使用 Stash 的图形界面生成 CA 证书。
配置 CA 证书
1、在 Stash 首页,找到 MitM ,选择 [CA 证书];
2、点击 [Stash Generated CA] 生成新的证书;
3、点击 [安装 证书] 安装新证书;
4、 Stash 会自动跳转到 Safari 进行证书安装,点击 [允许] 安装新的证书;
5、出现 [已下载描述文件] ,则代表证书已成功安装;
配置 MitM 列表
1、在 Stash 首页,找到 MitM ,选择 [主机名];
2、输入您想添加的域名,如 *.google.cn ,域名中可以使用通配符,点击旁边的 [+ 号],添加到 MitM 列表里;
系统信任证书
强制 HTTP 引擎
Force HTTP Engine
默认地,所有经由 HTTP Proxy 的请求会由 HTTP 引擎处理,以使用改写、脚本等功能。若希望来自 Tunnel 的 TCP 连接经由 HTTP 引擎处理,需要配置 force-http-engine。
http:
# 强制使用 Stash 引擎以 HTTP 协议处理 TCP 连接
# 捕获后的连接可以使用高级功能,例如重写和脚本
force-http-engine:
- '*:80'
- '*:4480' # BiliBili CDN
- '*:9102' # BiliBili CDN
⚠️
无法解析的请求会被 HTTP 引擎以 Bad Request 响应拒绝。
HTTP 重写
HTTP 重写允许用户通过正则表达式匹配 URL,拒绝或者重定向 HTTP(S) 请求,常用于去广告,避免隐私跟踪等目的。
配置格式:
http:
# HTTP(S) 重写,支持header、302、307、reject多种策略
url-rewrite:
- ^http://g\.cn https://www.google.com transparent
- ^https?://www\.google\.cn https://www.google.com 302 # 直接返回一个 302 重定向的响应
- ^https?://ad\.example - reject # 拒绝请求
header-rewrite:
- ^http://g\.cn request-add DNT 1
- ^http://g\.cn request-del DNT
- ^http://g\.cn request-replace DNT 1
- ^http://g\.cn request-replace-regex User-Agent Go-http-client curl
- ^http://g\.cn response-add DNT 1
- ^http://g\.cn response-del DNT
- ^http://g\.cn response-replace DNT 1
- ^http://g\.cn response-replace-regex User-Agent Go-http-client curl
URL 重写
transparent
拦截并修改请求的 URL,效果类似透明代//理//,应用对此无感知,支持重定向 HTTP / HTTPS。
302 / 307
HTTP 引擎会返回一个 3xx 状态码,并且会自动设置 Location 字段,以达到重定向的目的。
reject
返回 404 响应,和空的响应 body。
reject-200
返回 200 响应,和空的响应 body。
reject-img
返回 200 响应,和 1px gif 的响应 body。
reject-dict
返回 200 响应,和内容为 {} 的响应 body。
reject-array
返回 200 响应,和内容为 [] 的响应 body。
HTTP header 重写
header 重写允许用户增加、删除、替换 HTTP 请求 / 响应的任意 header。
request-add / response-add
对 HTTP 请求 / 响应新增 header。
request-del / response-del
对 HTTP 请求 / 响应删除 header。
request-replace / response-replace
对 HTTP 请求 / 响应替换 header 的值。
request-replace-regex / response-replace-regex
对 HTTP 请求 / 响应通过正则表达式替换 header 的值。
使用 JavaScript 引擎重写
如果上述功能无法满足需求,请参考后面介绍的使用 JavaScript 引擎"重写 HTTP"。
语法与接口
基础方法
$script.name:脚本名称
$script.type:脚本类型,如 request, response 和 tile
$script.startTime:脚本开始运行的时间
$environment[“stash-build”]:Stash Build 编号
$environment[“stash-version”]:Stash 版本号
$environment.language:Stash 运行语言
$environment.system:Stash 运行系统 (iOS / macOS)
$argument:运行参数
$done(value):结束脚本运行,释放资源
$notification.post(title, subtitle, body):发送 iOS 通知
console.log(value):输出日志,脚本日志会输出到单独的文件
setTimeout(callback, delay):延迟执行回调函数
$done(value)
⚠️
对于所有脚本,在结束时候必须调用 $done(value) 方法释放资源。
持久化存储
$persistentStore.write(value, key):写入持久化存储
$persistentStore.read(key):读取持久化存储
HTTP Client
$httpClient.get(url, callback)
$httpClient.get(request, callback)
同样地,还有:
$httpClient.post()
$httpClient.put()
$httpClient.delete()
$httpClient.head()
$httpClient.options()
$httpClient.patch()
请求的超时为 5 秒,可以通过设置 X-Stash-Selected-Proxy 指定请求的使用的代//理//,或设置 binary-mode 开启二进制模式,例如:
$httpClient.get('http://httpbin.org/get', (error, response, data) => {
if (error) {
console.log(error)
} else {
console.log(data)
}
})
const yourProxyName = 'a fancy name with 😄'
$httpClient.post(
{
url: 'http://httpbin.org/post',
headers: {
'X-Header-Key': 'headerValue',
'X-Stash-Selected-Proxy': encodeURIComponent(yourProxyName),
},
body: '{}', // can be object or string
'binary-mode': true,
},
(error, response, data) => {
if (error) {
console.log(error)
} else {
console.log(data)
}
}
)
改写 HTTP
用户可以通过 JavaScript 脚本修改流经 Stash 的 HTTP 请求、响应。
配置格式
http:
script:
- match: url-you-want-to-match
name: your-fancy-script
type: response # request / response
require-body: true
timeout: 20
argument: ''
binary-mode: false
max-size: 1048576 # 1MB
script-providers:
your-fancy-script:
url: https://your-fancy-script.com/your-fancy-script.js
interval: 86400
参数:
match: 脚本匹配的 URL 正则表达式。
type: 脚本类型,可选值为 request 或 response。
require-body: 是否需要请求体 / 响应体,在脚本中处理 body 需要消耗更多的内存空间,仅在必要时启用。
timeout: 脚本执行超时时间,单位为秒。
argument: 脚本执行时的参数,类型为 string。
binary-mode:二进制模式,body 会以 Uint8Array 而不是 string 传递给脚本。
max-size:单位为字节,body 超过这个大小的请求不会触发脚本。
Request Object
$request.url:请求 URL
$request.method:请求方法
$request.headers:请求头
$request.body:请求体,仅在 require-body: true 时有,根据是否开启二进制模式,可以为 string 或者 Uint8Array
Response Object
$request.url:请求 URL
$request.method:请求方法
$request.headers:请求头
$response.status:响应状态码
$response.headers:响应头
$response.body:响应体,仅在 require-body: true 时有,根据是否开启二进制模式,可以为 string 或者 Uint8Array
$done(value)
⚠️
对于所有脚本,在结束时候必须调用 $done(value) 方法释放资源。
对于 request 类型的脚本,调用 $done(object) 可以改写 HTTP 请求,object 可以包含下述字段:
url:修改请求的 URL
headers:修改请求的 headers
body:修改请求的 body
response:替换 HTTP 响应,不再实际发出 HTTP 请求
你可以调用 $done() 来打断请求,或者 $done({}) 不修改请求的任何内容。
对于 response 类型的脚本,调用 $done(object) 可以改写 HTTP 响应,object 可以包含下述字段:
status:修改响应的状态码
headers:修改响应的 headers
body:修改响应的 body
你可以调用 $done() 来打断请求,或者 $done({}) 不修改响应的任何内容。
面板 (Tile)
用户可以通过 JavaScript 脚本控制 Stash 首页的 Tile 面板。
配置格式
tiles:
- name: your-fancy-script
interval: 600
title: 'Awesome Tile'
content: 'This is Super Cool'
icon: 'theatermasks.circle.fill' # 或 https://stash.ws/amazing.png
backgroundColor: '#663399'
script-providers:
your-fancy-script:
url: https://your-fancy-script.com/your-fancy-script.js
interval: 86400
参数:
argument: 可选,脚本执行时的参数,类型为 string。
title: 可选,脚本第一次运行前的标题默认值。
content: 可选,脚本第一次运行前的内容默认值。
icon: 可选,脚本第一次运行前的图标默认值。图标支持 SF Symbols 或以 http 开头的远程图片。
backgroundColor: 可选,脚本第一次运行前的背景颜色默认值。
url: 可选,脚本第一次运行前的跳转 URL 。
以上部分字段可被 $done(object) 覆盖更新。
语法与接口
请参考 JavaScript 脚本语法与接口 。
例子
$httpClient.get('https://api.my-ip.io/ip', function (error, response, data) {
$done({
title: '当前 IP 地址',
content: data,
backgroundColor: '#663399',
icon: 'network',
})
})
$done(value)
⚠️
对于所有脚本,在结束时候必须调用 $done(value) 方法释放资源。
对于 Tile 类型的脚本,调用 $done(object) 可以更新 Tile 面板内容,object 可以包含下述字段:
title: 可选,新的 Tile 标题。
content: 可选,新的 Tile 内容。
icon: 可选,新的 Tile 图标。
backgroundColor: 可选,新的 Tile 背景颜色。
url: 可选,新的跳转 URL 。
以上字段如为空则不更新。你可以直接调用 $done({}) 不修改任何内容。
定时任务
Stash 可以在后台执行定时任务,目前仅支持执行 JavaScript 脚本,定时任务需要依赖 Network Extension(VPN) 在已连接状态。
Script / 定时脚本
Stash 可以在后台定时执行 JavaScript 脚本,以实现自动化的任务,执行的结果可通过系统通知或记录到持久化存储。
JavaScript 脚本的语法和接口请参考 JavaScript 脚本。
定时脚本通过 cron 表达式指定执行时间、间隔,cron 表达式的语法请参考这里(opens in a new tab)。
cron:
script:
- name: your-script-name
cron: '*/5 * * * *' # at every 5th minute
argument: '{ "key": true }' # optional
timeout: 10 # optional
- name: your-script-name
cron: '0 20 * * *' # at 20:00
argument: '{ "key": false }' # optional
timeout: 15 # optional
script-providers:
your-script-name:
url: https://example.com/your-script.js
interval: 86400
💡
你可以在多个场景引用同一个脚本,并通过环境变量判断事件来源(如 HTTP 改写、定时任务)。
内置 DNS 服务
自定义上游 DNS 服务器
Stash 支持同时配置多个 DNS 服务器,在进行查询时,Stash 会并发请求所有服务器,并采用最快响应的结果。Stash 支持下述 DNS 协议:
使用系统提供的 DNS:system
DNS over UDP:8.8.8.8 or udp://8.8.8.8
DNS over TCP:tcp://8.8.8.8
DNS over TLS(opens in a new tab):tls://8.8.8.8:853 or dot://8.8.8.8:853
DNS over HTTPS(opens in a new tab):https://1.1.1.1/dns-query or doh://1.1.1.1/dns-query
DNS over HTTP/3: http3://1.1.1.1/dns-query or doh3://1.1.1.1/dns-query
DNS over QUIC(opens in a new tab):quic://dns.adguard.com:853 or doq://dns.adguard.com:853
default-nameserver 将会被用来解析 DNS 服务的域名,仅支持填写 DNS 服务器的 IP 地址。
dns:
# 以下填写的 DNS 服务器将会被用来解析 DNS 服务的域名
# 仅填写 DNS 服务器的 IP 地址
default-nameserver:
- 223.5.5.5
- 114.114.114.114
# 支持 UDP / TCP / DoT / DoH / DoQ 协议的 DNS 服务,可以指明具体的连接端口号。
# 所有 DNS 请求将会直接发送到服务器,不经过任何代//理//。
# Stash 会使用最先获得的解析记录回复 DNS 请求
nameserver:
# 不建议配置超过 2 个 DNS 服务器,会增加系统功耗
- https://doh.pub/dns-query
- https://dns.alidns.com/dns-query
- quic://dns.adguard.com:853
- doq://test.dns.nextdns.io:853
- system # 使用 iOS 系统 DNS
# 跳过证书验证,解决部分兼容性问题 https://help.nextdns.io/t/g9hdkjz
skip-cert-verify: true
# DNS 查询跟随代//理//规则
follow-rule: false
Stash 会对 DNS 查询使用 LRU 算法进行本地缓存。当本地缓存过期时,Stash 会继续沿用缓存结果,并在后台静默更新记录,这会有效降低 DNS 缓存过期引发的请求延迟。
基于域名的自定义 DNS 服务
nameserver-policy 可以对指定域名使用特定的 DNS 服务器。
dns:
# 对部分域名使用单独的 DNS 服务器
nameserver-policy:
'www.baidu.com': 114.114.114.114
'+.internal.crop.com': system
自定义 Hosts
# 支持通配符域名 (例如: *.c-l-a-s-h.dev, *.foo.*.example.com )
# 不使用通配符的域名优先级高于使用通配符的域名 (例如: foo.example.com > *.example.com > .example.com )
# 注意: +.foo.com 的效果等同于 .foo.com 和 foo.com
hosts:
'*.c-l-a-s-h.dev': 127.0.0.1
'.dev': 127.0.0.1
'alpha.c-l-a-s-h.dev': '::1'
DNS 查询跟随规则
默认情况下,Stash 发出的 DNS 查询均会直接出站,而不经由任何代//理//规则转发。开启 follow-rule 选项后,Stash 会根据代//理//规则进行 DNS 查询的转发。
⚠️
绝大部分场景下,不需要开启此配置。DNS 查询由代//理//转发后,可能会破坏云服务商的 CDN 全球优化策略,导致静态资源加载缓慢。DNS 查询请求进入 Stash 网络引擎,也会导致轻微的延迟上升。
请仅在必要时开启此配置。
⚠️
由于连接代//理//服务器可能需要进行 DNS 解析,DNS 查询由代//理//转发后,会存在递归查询的问题。开启此配置前请确保满足以下其中一项条件:
转发 DNS 请求的代//理//地址为 IP 地址,而不是域名
DNS 服务器地址为 IP 地址,而不是域名
为局域网设备提供代//理//
Stash iOS,Stash tvOS 与 Stash Mac 均支持为局域网设备提供代//理//。
Stash iOS 支持提供 HTTP 代//理//和 SOCKS 代//理//
Stash tvOS 和 Stash Mac 支持提供 HTTP 代//理//,SOCKS 代//理//和透明代//理//(网关模式)
💡
网关模式可以为局域网内设备提供透明代//理//,也常称为旁路由或增强模式。
HTTP 代//理//或 SOCKS 代//理//
Stash iOS 与 Stash Mac 均支持在 7890 端口提供 HTTP 代//理//与 SOCKS 代//理//,在开启「允许局域网连接」之后,局域网设备可以通过 7890 端口访问 Stash 提供的代//理//服务。
例如局域网内 192.168.1.10 的设备运行着 Stash,可以通过下述命令为 shell 配置代//理//。
export https_proxy=http://192.168.1.10:7890
export http_proxy=http://192.168.1.10:7890
export all_proxy=socks5h://192.168.1.10:7890
通过个人热点提供代//理//
在 iPhone / iPad 等设备开启个人热点后,通过运行 Stash 可以为连上个人热点的设备提供 HTTP 代//理//或 SOCKS 代//理//,此功能同样需要开启「允许局域网连接」。
Stash tvOS & Stash Mac 网关模式
Stash tvOS 仅支持在 Thread-enabled Apple TV(opens in a new tab) 上启用透明代//理//
Stash Mac 启用透明代//理//需要开启「增强模式」
假设局域网内 192.168.1.10 的设备运行着 Stash,为局域网设备提供代//理//需要如下设置:
将局域网内设备的网关配置为 192.168.1.10
DNS 设置为 198.18.0.2
保持 IP 地址和子网掩码不变
网关模式可以代//理// TCP、UDP、ICMP 流量。
💡
如果 Apple TV 休眠一段时间后,Apple TV 旁路由无响应。可以根据 Apple 的指引排查 Apple TV 是否已经设置为家居中枢。
服务提供商订阅
Stash 支持由服务提供商管理的配置,可以定时更新配置文件,并显示服务剩余流量、过期信息。
定时更新配置
在配置文件的首行加入如下注释,Stash 会将配置认定为服务提供商管理的配置,该配置会定时从指定的 URL 获取新版本。目前检查更新的间隔为 12 小时,用户可以在设置页面更改这个配置。
#SUBSCRIBED https://proxy.service/stash/config
展示服务信息
服务提供商可以通过 HTTP Response Header 提供服务信息,包括:上行流量、下行流量、流量总量、过期时间。格式为:
Subscription-Userinfo: upload=%f; download=%f; total=%f; expire=%f
服务信息会被 Stash 解析,并在 App 首页显示。
Stash 会首先采用定时更新配置 URL 中的服务信息,如果没有定时更新 URL,则会使用配置文件中的 proxy-providers 中的 url,该字段可以在可视化编辑页面设置。
💡
Stash 会优先使用 HEAD 方法获取服务信息以降低流量消耗。
网络性能增强
Stash 在网络连接的每一层面进行了性能优化,尽力提供低延迟、高吞吐的访问体验。
💡
部分功能需要手动在「网络设置」中启用。
并发 DNS 查询
Stash 允许用户配置多个 DNS 服务器。在进行查询时,Stash 会并发请求所有服务器,并采用最快响应的结果。
乐观 DNS 缓存(Optimistic DNS)
Stash 会对 DNS 查询使用 LRU 算法进行本地缓存。当本地缓存过期时,Stash 会继续沿用缓存结果,并在后台静默更新记录,这会有效降低 DNS 缓存过期引发的请求延迟。
并发连接
当域名拥有多个 A / AAAA 记录的场景下,Stash 会并发向所有 IP 发起 TCP 连接,并选择最快握手成功的结果,这在访问 CDN 场景下避免单节点失效有较好表现。
混合使用多个网络
当 Wi-Fi / 蜂窝网络(Cellular)/ 有线网络同时可用的场景下,Stash 会尝试同时使用多个网络建立连接,并选择最快握手成功的结果,此功能可以与「并发连接」同时使用。混合使用多个网络能在弱网与网络切换的场景下降低连接超时的概率。
按需启动
保持 Stash 开启
启用该选项后,Stash 会保持一直开启,您仅能通过 Stash App 内的停止按钮来关闭 Stash 。
✅
即使在系统重新启动后也能自动开启 Stash 。
按需连接
如果您希望在特定的网络环境下停用 Stash,可以通过配置按需连接,使 Stash 在不同的情况下自动启动或禁用。
如启用按需连接后,关闭蜂窝数据按钮,则 Stash 不会在蜂窝数据下启用。
您还可以在部分 Wi-Fi 网络停用 Stash ,如路由器包含透明代//理//的网络里,防止流量被重复代//理//。
您只需要填入 Wi-Fi 的 SSID 到排除 SSIDs 里,则 Stash 不会在该 SSID 下启用。
编写高效的配置文件
由于 iOS Network Extension 在 iOS 14 限制使用 15 MB 内存,在 iOS 15+ 限制使用 50 MB 内存,不合理的配置文件可能会导致 Stash 被 iOS 关闭。下面是一些编写高效的配置文件的建议。
配置合理的 DNS 服务器
Stash 会同时向所有的 DNS 服务器发起查询,后续会通过 LRU 算法缓存 DNS 查询。在移动设备上,配置 1 ~ 2 个 DNS 服务器已满足使用场景。
DoH、DoT、DoQ 会比传统基于 UDP 的查询更消耗资源,延迟一般也更高
Stash 会使用 Fake IP 来避免需要代//理//的请求进行本地 DNS 查询。对于中国用户建议使用国内 DNS,配置 8.8.8.8 / 1.1.1.1 等国外 DNS 服务没任何意义。
使用规则集合
对于去广告,按 IP 地理信息分流等用到大量规则的场景,使用 domain / ipcidr 规则集合会降低内存占用,也会提高匹配速度。
⚠️
不建议使用大量地 classical 规则集合,会显著提高 Stash 内存占用。
禁用 QUIC 协议
HTTP3 / QUIC 协议基于 UDP,在目前的网络环境下较为低效,建议通过 Script Shortcuts 禁用。
script:
shortcuts:
# 4483 与 9305 为 BiliBili 的 QUIC CDN
quic: network == 'udp' and (dst_port == 443 or dst_port == 4483 or dst_port == 9305)
rules:
- SCRIPT,quic,REJECT
防止代//理//被检测
部分应用程序可能会检测系统是否使用代//理//软件,从而禁止用户在代//理//环境下使用。Stash 提供了「仅使用 Tunnel 代//理//」模式来防止应用程序检测代//理//程序,该选项将禁用 Stash Proxy,使得所有 HTTP(S) 请求亦会交由 Stash Tunnel 进行处理,以改善和某些应用的兼容性问题。
在 Stash 的设置页面,选择「网络设置」
打开「仅使用 Tunnel 代//理//」
💡
开启这个选项会使得 Stash HTTP Engine 失效 ,导致 HTTP 改写功能失效。避免该问题,请参考 Force HTTP Engine。
IPv6 兼容性
在绝大多数场景下,你不需要手动启用 IPv6,Stash 会根据 iOS / macOS 系统回报 IPv4 / IPv6 的状态,自动选择最优的连接策略。在 IPv4 / IPv6 均可用的情况下,Stash 会同时向 IPv4 / IPv6 发起 TCP 握手,并选择首个握手成功的连接进行后续的数据传输。
在代//理//服务器支持 IPv6 的情况下,由于 Stash 使用 Fake IP 机制,总是尽可能地向代//理//服务器转发域名而不是 IP 的请求,此时 IPv4 / IPv6 的选择取决于代//理//服务器。
由于 Fake IP 机制的存在,Stash Tunnel 的大部分场景为接受 Fake IP 的路由并由 Stash 将 Fake IP 反查域名,Stash Tunnel 默认只启用 IPv4。对于大部分 HTTP(S) 请求,即使直接输入 IPv6 地址,由于 HTTP 代//理//的存在,请求并不经过 Stash Tunnel。在上述的两种机制下,Stash 默认支持:
通过域名访问仅支持 IPv6 的服务器
直接通过 IP 访问仅支持 IPv6 的网站
对于直接通过 IPv6 访问且经由 Stash Tunnel 的情况(如 SSH、FTP 等),需要开启「网络设置 - 启用 Tunnel IPv6 路由」。请注意,若在网络环境不支持 IPv6 的情况下开启该功能,可能会遇到兼容性问题。
URL Schema
Stash 支持使用 URL Schema stash:// 和 c-l-a-s-h:// 来控制 Stash, 包含的 URL 需要 Encode 。
link.stash.ws
除了上述的 URL Schema 之外,Stash 还支持使用 https://link.stash.ws 标准 URL 来控制,格式为 https://link.stash.ws/command/url,包含的 URL 不含 Schema 且无需 Encode 。
以一键安装 BoxJS 为例,
原 URL:https://raw.githubusercontent.com/chavyleung/scripts/master/box/rewrite/boxjs.rewrite.stash.stoverride
一键安装 URL:https://link.stash.ws/install-override/raw.githubusercontent.com/chavyleung/scripts/master/box/rewrite/boxjs.rewrite.stash.stoverride
💡
默认的远程 URL Schema 为 HTTPS ,如需使用 HTTP ,请加上参数 ?scheme=http。
💡
如远程 URL 无法访问,链接将返回 404。
导入配置文件
stash://install-config?url=
u
r
l
−
e
n
c
o
d
e
d
c
−
l
−
a
−
s
−
h
:
/
/
i
n
s
t
a
l
l
−
c
o
n
f
i
g
?
u
r
l
=
{url-encoded} c-l-a-s-h://install-config?url=
url−encodedc−l−a−s−h://install−config?url={url-encoded}
https://link.stash.ws/install-config/example.com/stash.yaml
导入远程覆写
stash://install-override?url=
u
r
l
−
e
n
c
o
d
e
d
c
−
l
−
a
−
s
−
h
:
/
/
i
n
s
t
a
l
l
−
o
v
e
r
r
i
d
e
?
u
r
l
=
{url-encoded} c-l-a-s-h://install-override?url=
url−encodedc−l−a−s−h://install−override?url={url-encoded}
https://link.stash.ws/install-override/example.com/stash.stoverride
导入图标集
stash://install-icon-set?url=
u
r
l
−
e
n
c
o
d
e
d
c
−
l
−
a
−
s
−
h
:
/
/
i
n
s
t
a
l
l
−
i
c
o
n
−
s
e
t
?
u
r
l
=
{url-encoded} c-l-a-s-h://install-icon-set?url=
url−encodedc−l−a−s−h://install−icon−set?url={url-encoded}
https://link.stash.ws/install-icon-set/example.com/stash.json
开关 Stash
开启 Stash
stash://start
c-l-a-s-h://start
https://link.stash.ws/start
关闭 Stash
stash://stop
c-l-a-s-h://stop
https://link.stash.ws/stop
切换开关
stash://toggle
c-l-a-s-h://toggle
https://link.stash.ws/toggle