杂项选项
[General]
ipv6 = true
loglevel = notify
skip-proxy = 127.0.0.1, 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12, 100.64.0.0/10, localhost, *.local
tun-excluded-routes = 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12
tun-included-routes = 192.168.1.12/32
通用选项
启用完整 IPv6 支持(默认:true)
ipv6 = true
loglevel(默认:warning)
loglevel = notify
可选值:none、fatal、warning、notify、info 或 verbose。不建议在日常使用中启用 verbose,因为这会显著降低性能。
skip-proxy
skip-proxy = 127.0.0.1, 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12, 100.64.0.0/10, localhost, *.local
在 iOS 与 tvOS 版本中,主机名条目会被加进隧道的代理例外列表,因此到它的连接由 Chute TUN 处理,而非 Chute 代理;IP 地址或 CIDR 条目还会额外成为隧道的排除路由,因此到该范围的流量会完全离开隧道,而不是交给 Chute TUN 处理。Chute Android 在 VPN 模式下也是这样:系统 HTTP 代理打开时,主机名、* 通配符和 IPv4 地址会加入 VPN 交给应用的那个代理的例外列表;在 Android 13 及更新版本上,每个 IP 地址或 CIDR 条目都会成为 VPN 的排除路由——单个地址按 /32 或 /128 处理;回环条目会被略过,因为回环流量从不进入隧道。在 macOS 版本中,当启用「设为系统代理」时,这些设置将应用于系统。此选项用于解决某些应用程序的兼容性问题。
- 要指定单个域名,输入域名,例如 apple.com。
- 要指定域名下的所有网站,在域名前使用星号,例如 *apple.com。
- 要指定域名的特定部分,指定每个部分,例如 store.apple.com。
- 要通过 IP 地址指定主机或网络,输入特定 IP 地址(如 192.168.2.11)或地址范围(如 192.168.2.* 或 192.168.2.0/24)。
注意:如果你输入 IP 地址或地址范围,仅当你使用该地址连接到该主机时才能绕过代理,而通过解析到该地址的域名连接时不会绕过代理。
代理服务器监听
interface = 127.0.0.1
port = 8118
socks-interface = 127.0.0.1
socks-port = 8119
interface / port 控制 HTTP 代理服务器的监听地址和端口(默认 127.0.0.1:8118)。socks-interface / socks-port 控制 SOCKS5 代理服务器(默认 127.0.0.1:8119)。
对于明文 http:// 请求,HTTP 代理服务器的每条连接只承载一次交换:每个响应都带 Connection: close 发出,发完后关闭连接,客户端会在新连接上发出下一个请求。跟在首个请求后面的流水线请求会被丢弃,客户端会在新连接上重发。需要在同一条连接上往返多次的认证方式(如 NTLM 或 Negotiate)无法经它完成。不解密的 CONNECT 隧道不受影响。WebSocket 升级会保留连接:收到 101 响应之后,数据在两个方向上原样通过。
兼容性别名:
doh-server与doh-service都可作为doh的别名;http-listen/socks5-listen(例如0.0.0.0:6152、[::]:6153或单独的端口号)会被映射到上述 interface/port 设置。使用通配监听地址(0.0.0.0、::或*)还会同时设置allow-wifi-access = true。
入站代理鉴权
http-auth = username:password
要求客户端在使用 Chute 的 HTTP 和 SOCKS5 代理服务器之前进行身份验证。该行可以重复出现以允许多组凭据。
HTTP 代理对没有带有效凭据的请求——无论是普通请求还是 CONNECT——回复 407 Proxy Authentication Required,附带 Proxy-Authenticate: Basic realm="KLNEKit",然后关闭连接。SOCKS5 服务器通过 SOCKS5 的用户名/密码认证接收同一组凭据,客户端不提供这种认证或认证失败时,关闭连接。
绕过系统请求
bypass-system = true
启用后,Chute 会把一份固定的 18 个 Apple 主机名——推送、iCloud 网关、强制门户检测、OCSP 之类——追加到 skip-proxy,并把 IP-CIDR,17.0.0.0/8,DIRECT,no-resolve 追加到你的规则之后、FINAL 之前——所以你自己先命中 17.0.0.0/8 的规则仍然优先。这里没有任何按进程的匹配:这个选项就是那份固定的主机与地址清单,而不是对「请求由哪个进程发出」的过滤。
默认:
true。
始终使用真实 IP
always-real-ip = *.example.com, tracker.example.org
当 Chute 为被劫持的 DNS 查询提供虚拟 IP 地址时(见 hijack-dns),匹配此逗号分隔列表的主机名将始终以其真实解析出的 IP 地址应答。支持通配符。always-ip-address(Shadowrocket 的写法)会被读作这个键:布尔值(true、yes、on、1)表示所有主机,会被改写成 always-real-ip = *;false 直接丢弃;其他取值按主机列表读取。保存配置时统一写作 always-real-ip。
读取系统 hosts 文件
read-etc-hosts = false
是否把系统的 hosts 文件读进 [Host] 表。设为 false 即不读这个文件;修改在重载时生效。见本地 DNS 映射。
默认:
true。
中断现有连接
interrupt-exist-connections = true
启用后,在任何策略组中更改所选策略(通过 URL 测试、回退、负载均衡、SSID 或手动选择)将优雅地断开使用旧策略的现有连接。这确保连接立即使用新选择的代理,而不是继续使用旧代理。
这适用于连接经过的每一个策略组:规则直接指定的组、嵌套在其中的组、串联策略(underlying-proxy)的上游组,以及中继组成员中的组。
每个受影响的连接会以 3 秒超时优雅关闭,之后强制关闭。
默认:
false。这是一个全局设置——影响所有策略组。
Network Framework(macOS / iOS / tvOS)
network-framework = true
为出站连接启用 Apple Network.framework。使用 Network.framework 可以在支持的平台上提供更好的性能和现代化的 TLS 栈集成。
默认:macOS 上为
true,iOS 和 tvOS 上为false。
排除简单主机名
exclude-simple-hostnames = true
启用后,对简单主机名(不含点的单标签名称,例如 localhost)的请求将绕过代理规则并在本地解析。这有助于避免对本地网络名称进行不必要的 DNS 查询。这是 macOS 系统代理自带的「排除简单主机名」设置:Chute Mac 会把它写入系统代理配置,因此只对遵循系统代理的应用生效——增强模式与 TUN 流量不受影响。在 iOS 与 tvOS 上,它同样会写进隧道的代理设置,于是简单主机名由 Chute TUN 处理,而非 Chute 代理,和 skip-proxy 里的主机名一样。Chute Android 不使用这个选项。
在 Chute Mac 上,首次运行时会通过一次性迁移默认启用此选项;用户显式关闭的设置会被尊重。
默认:
false。
禁用数据库记录
disable-db-record = true
启用后,Chute 停止将流量记录写入本地数据库。这可以提高性能并减少存储使用,但流量历史将无法在 Chute Dashboard 中使用。
默认:
false。
菜单栏速度显示(仅 Mac)
menu-bar-show-speed = true
启用后,Chute Mac 在菜单栏中显示当前的上下行速度。
当前引擎会解析但不生效——Chute Mac 里没有任何地方读这个键。菜单栏速度由菜单项显示连接速度控制,该状态保存在应用自己的设置里。保存配置时这个键仍会被写回。
劫持其他 DNS 服务器
hijack-dns = 8.8.8.8:53
默认情况下,Chute 仅为发送到 Chute DNS 地址(198.18.0.2)的 DNS 查询返回虚拟 IP 地址。发送到标准 DNS 的查询将被直接转发。
某些设备或软件始终使用硬编码的 DNS 服务器(例如,Google 音箱始终使用 8.8.8.8)。你可以使用此选项劫持查询以获取虚拟地址。
你可以使用 hijack-dns = *:53 来劫持所有 DNS 查询。
不带端口的条目表示 53 端口,所以 hijack-dns = 8.8.8.8 就是 8.8.8.8:53。无法读取的条目会被跳过并记录提示,该行其余条目照常生效。
虚拟 IP 在 Apple TV 上也可用(tvOS 17 及以上)。此前它在该平台一直被禁用,真机验证仍在进行中。
排除路由
tun-excluded-routes = 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12
Chute VIF 只能处理 TCP 和 UDP 协议。使用此选项绕过特定 IP 范围,允许所有流量直接通过。
注意:此选项适用于 iOS 与 tvOS 的包隧道,这些范围会成为隧道 IP 设置中的排除路由;也适用于 Android 13 及以上的 Chute Android,这些范围会成为 VPN 的排除路由——Android 11 与 12 没有排除路由的接口,因此在那里会被忽略。在 macOS 上它无效,两种增强模式类型都一样——Helper 的 utun 和 Mac 网络扩展都不排除任何路由。由 Chute 代理服务器处理的请求不受影响。结合使用「skip-proxy」和「tun-excluded-routes」以确保某些 HTTP 流量完全绕过 Chute。
此选项可能导致系统错误 ENOMEM(无法分配内存)。这似乎是 iOS 系统中的一个错误。如有可能,请勿使用此选项。
包含路由
tun-included-routes = 192.168.1.12/32
默认情况下,Chute VIF 接口将声明自身为默认路由。但由于 Wi-Fi 接口具有更小的路由,某些流量可能不会通过 Chute VIF 接口。使用此选项添加更小的路由。
默认路由为什么不够:系统是按前缀长度挑路由的,而不是按先后顺序。物理接口自带的直连子网——比如 192.168.1.0/24——比隧道的 0.0.0.0/0 更具体,于是那部分流量永远到不了 Chute。在这里写一条,就会装上一条更具体的路由,从而胜出。这些路由是叠加在默认路由之上的,不会收窄隧道捕获的范围。
注意:不要把私有地址段(
10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)整段列进来。这通常没有必要,还可能扰乱系统自己的路由;Chute 会照办,但会记一条警告——macOS 上增强模式的网络扩展变体除外,它照办但不记警告。用这个选项的常见理由,是要访问另一个 VPN 应用的隧道所占据的地址段。注意:凡是会把 Chute 自己赖以运行的那条通路切断的条目,都会被拒绝,并把原因写进日志:回环地址、VIF 自己的子网(
198.18.0.0/15和fd12:1:1:1::/64)、链路本地地址、组播、广播,以及前缀长度为0。macOS 上增强模式的 Helper utun 变体还会拒绝覆盖当前默认网关的条目。在网络扩展变体下,原因写进系统日志,而不是 Chute 的日志。注意:在 iPhone 上,本地网络要不要捕获由系统单独决定。这里列出的本地子网,只有在应用设置里同时打开包含本地网络才生效——这个开关只有在包含所有网络打开时才能打开;属于另一个应用隧道的地址段则不需要这个开关。Chute tvOS 也显示这些开关,但不会把它们应用到隧道上。在 macOS 上路由是直接安装的,没有这道关卡。
注意:在 macOS 上,增强模式的 Helper utun 变体是在接口挂载时安装这些路由的,所以列表一改,重载时接口就会重新挂载。此选项需要 Helper 0.8.6 或更高版本——更新 Chute 后,请在提示出现时批准一次 Helper 重装,否则 Helper utun 变体会报告 Helper 未在运行。
协议嗅探
sniffing-enabled = true
sniffing-timeout = 100
Chute 可以通过检查连接的初始字节来检测实际协议。这使得像 PROTOCOL,TLS,Proxy 这样的规则即使对非 HTTP 入站连接也能正常工作。
sniffing-enabled(默认:false)
sniffing-enabled = true
启用 TCP 连接的协议检测。在增强模式下,同一个开关还让发往裸 IP 地址的 HTTP/3(QUIC)流按名字匹配:Chute 从 QUIC ClientHello 中读出服务器名,DOMAIN 类规则看到的是这个名字而不是地址,同一流之后的每个报文都沿用首包的裁决。一个报文装不下的超长 ClientHello(后量子密钥交换下很常见)会按流从承载它的各个 Initial 报文中重组,重组后的 hello 上限 16 KiB,名字同样能读到。在 hello 的其余部分还没到齐之前,该流的报文会被扣住而不是按裸地址发出,等名字读出来后再一起沿着这个名字的策略发出——所以被切开的 hello,第一个分片不会再和其余部分走上不同的路。兜底阈值是:等待 1 秒、每条流最多扣 8 个报文或 16 KiB、同时最多 64 条流在重组;越过其中任一项的流,以及 Initial 报文始终凑不齐 ClientHello 的流,仍按地址匹配。
sniffing-timeout(默认:100ms)
sniffing-timeout = 200
等待初始数据以确定协议的最大时间(毫秒)。如果协议检测在慢速连接上失败,请增大此值。
阻断 QUIC
block-quic = auto
控制 Chute 是否拒绝检测到的 QUIC(包括 HTTP/3)流量。QUIC 基于 UDP,无法由 Chute 的 HTTP MitM 解密。拒绝 QUIC 可促使兼容的客户端改用 TCP,从而应用基于 TCP 的代理处理,并在已配置时进行 HTTPS 解密。
| 值 | 行为 |
|---|---|
off |
不进行全局 QUIC 阻断(默认)。检测到的 QUIC 流量继续按普通路由规则处理。 |
on |
拒绝所有检测到的 QUIC 流量,包括路由到 DIRECT 的流量。 |
auto |
仅当最终选定的出站策略为代理时拒绝检测到的 QUIC。路由到 DIRECT 的流量会被放行;路由到 REJECT 的流量仍由对应规则拒绝。 |
all |
Surge 对 on 的写法。 |
all-proxy、per-policy |
Surge 的写法,都按 auto 读取——Chute 没有按策略的 QUIC 阻断,所以 per-policy 会阻断所有经代理的 QUIC 流。保存配置时保留你写的原词。 |
对经 TUN 进入的流量,Chute 会向被拒绝的 QUIC 流返回 ICMP/ICMPv6 Port Unreachable 消息,使兼容的客户端无需等待 QUIC 超时即可回退到 TCP。
被拒绝的 QUIC 流在记录中的策略一律是
REJECT,不论规则选中的是哪个策略。
block-quic使用自动 QUIC 检测,不需要sniffing-enabled;sniffing-enabled控制协议嗅探——TCP 上的 TLS,以及 QUIC 流的服务器名。如需按规则处理单个 QUIC 流,请使用PROTOCOL,QUIC,...规则。
在隧道内应答 ICMP
icmp-auto-reply = false
进入隧道的 ICMP echo 请求——IPv4 或 IPv6——由 Chute 自己应答:应答在本地合成,不会向目标发送任何东西。因此任何目的地址都会得到回应,包括规则会 REJECT 的地址和已宕机的主机,所以在隧道内 ping 通并不说明目标可达。设为 false 可停止应答:此时请求会被中继出本机,但它的回包永远不会经由隧道返回,因此 ping 永远得不到应答。
默认:
true。作用于经 TUN 进入的流量;ICMP 从不经过代理。
绕过 TUN
bypass-tun = 192.168.0.0/16, 10.0.0.0/8
类似于 skip-proxy,但在 TUN/VIF 路由层面工作。到这些 IP 范围的连接将完全绕过 TUN 接口,直接通过系统网络栈传输。
注意:此选项适用于 iOS 与 tvOS 的包隧道,其中的范围会与
tun-excluded-routes一同成为隧道的排除路由;在 Android 13 及以上的 Chute Android 上同样如此(Android 11 与 12 会忽略它)。在 macOS 上它无效,两种增强模式类型都一样。
拒绝时显示错误页面
show-error-page-for-reject = true
启用后,Chute 对被拒绝的请求返回用户友好的错误页面。这只适用于经由 HTTP 代理入站到达的请求;关闭此选项时,这类请求会收到 HTTP/1.1 503 Service Unavailable。来自其他入站的被拒请求,无论开关如何都是直接丢弃。
默认:
false。
乐观 DNS
optimistic-dns = false
启用后,Chute 立即返回缓存的 DNS 结果,同时在后台刷新记录。这减少了连接延迟,但可能返回过时的 DNS 记录。关闭后,TTL 已过期的记录会被丢弃而不是继续返回,查询转而走上游;后台刷新照常进行,因此下一次查询仍可命中缓存。它还在所有平台上决定隧道是否同时向一个域名的多个地址发起连接。
默认:
true。设置optimistic-dns = false可禁用。
允许 Wi-Fi 访问
allow-wifi-access = true
让同一网络中的其他设备可以访问 Chute 的 HTTP 与 SOCKS5 代理端口——把两个监听器的绑定地址放宽到 0.0.0.0。Surge 风格的配置(以及 sing-box 导入时映射的 allow-lan)只带这个标志,interface 仍停在默认的 127.0.0.1,所以必须由标志本身去放宽绑定地址。
这个标志与显式写通配
interface是同一意图的两种写法,Chute 取并集:已经写了0.0.0.0的配置行为完全不变。改动该标志会重新绑定两个监听器,因此收回访问在重载时即刻生效,不必等到下次启动。这些是代理端口,除非设置了
http-auth,否则没有任何鉴权。在你不掌控的网络上,请同时设置凭据。
托管配置
#!MANAGED-CONFIG https://example.com/config.conf interval=86400 strict=false
首行带有 #!MANAGED-CONFIG 头的配置会自动从该 URL 重新获取。头部参数与更新行为详见托管配置。
副本 / 流量录制
replica = true
[General] 中的 replica 键(replica = true)启用流量录制;[Replica] 段负责过滤 Chute Dashboard 显示的内容,其键详见 Replica。
在 iOS、tvOS 和 Android 上还需要有效的许可证:没有许可证时,
replica = true什么也捕获不到。
外部控制器访问(Chute Dashboard)
external-controller-access = password@0.0.0.0:6155
启动供 Chute Dashboard 使用的远程控制服务器。值的格式为 password@host:port;密码前可以选择性地加上用户名(user:password@host:port)。在 iOS 和 tvOS 上,还会在 port + 1 上开启一个配套的 USB 通道(macOS 上没有)。连接方法见 Chute Dashboard 页。
HTTP 控制 API 和 Web 控制台
[General]
external-http-controller = 127.0.0.1:9090
external-http-secret = your-secret-token
external-http-ui = true
external-http-cors = false
Chute 提供内嵌的 HTTP 控制 API 和 Web 控制台,类似于 Clash 和 Surge 面板。API 通过 REST 端点暴露引擎状态、流量、连接、DNS、策略控制和配置管理。
Surge 的 http-api = <密钥>@<主机>:<端口> 会被读作 external-http-controller 加 external-http-secret。各部分也可以分开写:http-api-secret、http-api-ui、http-api-cors 分别读作 external-http-secret、external-http-ui、external-http-cors,http-api-web-dashboard 同样读作 external-http-ui;配置保存时使用 external-http-* 键。http-api-tls 不受支持(控制器只使用明文 HTTP),只会给出提示。
external-http-controller(默认:禁用)
external-http-controller = 127.0.0.1:9090
控制台服务期间常驻的请求上限为 macOS 4 MB,iOS、tvOS 与 Android 1 MB。
HTTP 控制服务器的地址和端口。使用 127.0.0.1 表示仅本地访问。绑定到任何非回环地址(例如 192.168.1.5:9090)都必须显式设置 external-http-secret——否则服务器会拒绝启动,并在日志里说明缺什么。
通配地址(0.0.0.0、::、*)在这项检查里算作非回环:它监听所有网卡,与「仅本地」正好相反。可接受的写法有 0.0.0.0:9090、*:9090(两者等价),IPv6 则写 [::]:9090——裸写 :::9090 会自动补上方括号;解析不了的地址会被报告为配置错误,而不是悄悄让控制器不启动。整个 127.0.0.0/8 都算回环,而不只是 127.0.0.1。
external-http-secret(默认:自动生成的令牌)
external-http-secret = your-secret-token
用于 API 鉴权的 Bearer 令牌。请求必须包含请求头 Authorization: Bearer <secret>——令牌只接受这个请求头,不支持通过查询参数携带,比较采用常量时间算法。鉴权失败返回 401,响应体为 {"ok": false, "error": {"code": "unauthorized", "message": "missing or invalid token"}}。所有数据路由都受鉴权保护:/api/* 路径、Clash 兼容别名,以及只有 Chute Android 还提供的旧式路由(/status、/policies、/dns、/records 等)——这些旧式路由同样只接受这个请求头里的令牌。Chute Android 自己的远程面板现在只用 /api/* 路径。Web 控制台的页面和静态资源(/、/assets/…,Chute Android 上还有 /ui)不需要令牌(external-http-ui = false 时它们根本不存在——页面返回 404)。
未写这一项时,Chute 会生成一个令牌,而不是不加鉴权地提供服务。生成的令牌以仅属主可读的权限写入 Chute 共享目录下的 control-token 文件——不在配置旁边:iOS 与 tvOS 上是 App Group 容器,Android 上是应用的私有数据目录——重启后继续沿用,各端应用会展示给你——见打开 Web 控制台。控制 API 可以交出连接数据库,而其中的记录带有本次运行见过的每一条 URL、请求头和进程名,所以「默认开放」不是一个合理的默认值。
如果确实要不加鉴权地提供服务,请在配置里明说:
external-http-secret = none
该写法仅在回环绑定时被接受。在非回环地址上,none 和「不写」都不够:控制服务器会拒绝启动,并说明它需要什么。
升级提示:如果你此前依赖「不写
external-http-secret即不鉴权」,本机脚本会开始收到401。要么从应用里读出生成的令牌,要么写上external-http-secret = none,明确保留旧行为。
external-http-ui(默认:true)
external-http-ui = true
启用后,Chute 在控制器地址提供内嵌的 Web 控制台。Web 控制台提供概览、连接管理、DNS 检查、流量监控、策略控制和配置编辑。设置为 false 则仅启用 API 而禁用 UI。
打开 Web 控制台
控制台就在控制服务器的地址上,各端应用都能把地址和令牌交给你——包括自动生成的那一个,否则你没有别的办法读到它:
- Chute Mac:菜单栏 → 打开 Web 控制台,以及复制 Web 控制台令牌。连接详情窗口里还有请求与历史,同样会打开控制台——打开的是首页,不是那条连接。
- Chute iOS:控制面板 → Web 控制台那一行 → 打开、复制地址或复制访问令牌。
- Chute tvOS:控制面板另有一行Web 控制台地址,显示主机与端口。选中它时,若监听器能被其他设备访问,就显示二维码——登录令牌只藏在二维码里,不显示在屏幕上;若控制器绑定在回环地址,则显示一段说明,因为回环上的控制台没法从手机打开。
- Chute Android:控制面板 → Web 控制台地址 → 打开或复制地址,另有一行生成的访问令牌,点按即复制。令牌是你自己配置的 secret 时,这两行都不会出现——这种 secret 永远不会被显示。
这些入口给出的地址把令牌带在查询参数里。页面加载时会消费掉它并从地址栏移除,所以打开链接就是一次完整登录,没人需要手抄 32 个十六进制字符。
external-http-cors(默认:false)
external-http-cors = true
在 API 响应中启用 CORS(跨域资源共享)头。当 Web 控制台或第三方工具需要从不同源访问 API 时非常有用。
API 端点:
| 方法 | 端点 | 描述 |
|---|---|---|
GET |
/api/status |
运行时状态、端口、运行时长 |
GET |
/api/traffic |
全局和按策略的流量计数器 |
GET |
/api/connections |
当前活跃连接 |
DELETE |
/api/connections/:id |
关闭一个连接 |
GET |
/api/connections/history |
历史连接记录 |
GET |
/api/connections/processes |
按进程统计的连接信息 |
GET |
/api/connections/:id/request |
某个连接捕获的请求数据 |
GET |
/api/connections/:id/response |
某个连接捕获的响应数据 |
GET |
/api/dns |
DNS 缓存记录 |
DELETE |
/api/dns/cache |
清空 DNS 缓存 |
DELETE |
/api/dns/records/:domain |
删除单条 DNS 记录 |
GET |
/api/config |
当前配置 |
PUT |
/api/config |
重新加载配置 |
POST |
/api/config/validate |
解析一份配置并报告其错误,但不加载它 |
GET |
/api/policies |
策略组及当前选择;每一项都带 hidden,标了 hidden=true 的组为 true |
PUT |
/api/policies/:group |
更改策略组选择 |
PUT |
/api/mode |
设置出站模式 |
GET |
/api/features |
功能开关状态 |
PUT |
/api/features/mitm |
切换 MitM |
PUT |
/api/features/record-traffic |
切换流量录制 |
GET |
/api/rules |
匹配器实际遍历的规则表、每条规则的来源,以及哪些改写规则命中过 |
POST |
/api/rules/match |
一个请求将会被选到哪里,不用真的发出去 |
GET |
/api/logs |
最近的日志条目 |
GET |
/api/loglevel |
当前日志级别,以及正在写入的分区 |
PUT |
/api/loglevel |
不重启就改日志级别或分区 |
GET |
/api/health |
引擎健康:拒绝计数、代际、内存占用、上次退出 |
GET |
/api/events |
本次运行的关键事件 |
GET |
/api/tailscale |
Tailscale 引擎实时状态 |
GET |
/api/scripts |
可按需运行的 generic 脚本 |
POST |
/api/scripts/run |
按名称运行一个 generic 脚本 |
POST |
/api/diagnostics/ping |
ICMP 或 TCP 可达性探测 |
POST |
/api/diagnostics/dns-query |
用运行中的解析器解析域名 |
POST |
/api/diagnostics/egress-probe |
检测地址:Apple 引擎上是本机地址,Android 引擎上是公网出口地址 |
POST |
/api/diagnostics/internet-test |
直连互联网测试:不经代理请求 internet-test-url |
POST |
/api/diagnostics/url-test/:policy |
运行某条策略的延迟测试 |
POST |
/api/diagnostics/bundle |
生成脱敏的诊断包 |
GET |
/api/connections/export |
以 HAR 1.2 导出连接 |
GET |
/api/rewrites |
所有改写/模拟响应族,以及 MitM 主机列表 |
GET |
/api/rewrites/:family |
某一族的规则 |
POST |
/api/rewrites/:family |
新增一条规则 |
DELETE |
/api/rewrites/:family/:id |
删除一条规则 |
DELETE |
/api/rewrites/:family |
清空某一族 |
GET |
/api/mitm/hosts |
当前被解密的主机 |
POST |
/api/mitm/hosts |
新增一个主机 |
DELETE |
/api/mitm/hosts/:host |
删除一个主机 |
DELETE |
/api/mitm/hosts |
清空列表 |
GET |
/api/rules/providers |
规则提供者与规则集,含每一个的状态——包括某个为何没能加载 |
端点说明:
GET /api/connections接受limit(正整数,默认与上限均为 1000)和cursor(只返回id大于游标的连接)。响应data包含connections、total、page_size、has_more,还有更多分页时附带next_cursor。GET /api/connections/history接受limit(默认 100,上限 1000)和cursor/before(同义参数;同时传两个会被拒绝)。GET /api/connections/:id/request与.../response返回{"connection_id": <id>, "data": "<base64>"}。捕获内容超过 2 MiB 时返回413。GET与PUT /api/config也可以通过/api/configs访问,以及 Clash 的别名/configs。GET /api/config返回的配置中,敏感值(http-auth、external-http-secret、ca-p12、ca-passphrase、WireGuard 密钥等)会被替换为<redacted>——不要把结果原样回传给PUT /api/config,否则这些占位符会被逐字写进配置。PUT /api/config接受 JSON{"configuration": "<full text>"}或直接以请求体承载裸配置文本(上限 1 MB)。成功后引擎会重新加载——若尚未运行则直接启动。PUT /api/policies/:group按policy、name、selected、select的顺序取请求体中第一个存在的键作为选择值;取值可以是策略名,也可以是数字下标的字符串。特殊组名GLOBAL用于设置全局选中策略。PUT /api/mode要求 JSON 数字:{"mode": 0}——0规则、1直连、2代理。PUT /api/features/mitm与PUT /api/features/record-traffic接受{"enabled": true}。GET /api/logs接受since(Unix 秒);内存缓冲区保留最近 1000 条,每条为{timestamp, wall_time, level, section, message}——timestamp与wall_time是同一个 Unix 秒数,时钟没有前进时会被往前拨一点,好让各条目严格有序。GET /api/health报告引擎当前持有什么、上一次因何拒绝了请求,以及上次运行是怎么结束的(clean、unclean或suspected_memory——见疑难解答)。GET /api/events返回内存中的事件环;?persisted=1改读本次运行已落盘的历史,关闭记录时返回available: false。- 未配置
[Tailscale]段时,GET /api/tailscale返回state: "idle"——这是正常回答,不是错误。 POST /api/diagnostics/*的各项探测既接受查询参数也接受 JSON 请求体,有 10 秒上限,且只回答一次。url-test/:policy对未定义的策略名直接报错,而不是去测REJECT。GET /api/scripts以{name, type}列出已启用的 generic 脚本;POST /api/scripts/run从请求体或查询字符串取name,上限与各项诊断探测相同,应答为{name, timedOut, result}——timedOut用来区分从未调用$done的脚本和跑完了的脚本。名称不是已启用的 generic 脚本时返回404。POST /api/rules/match回答一个请求会走到哪里,不用建立连接。它接受host(或者一个url,从中取主机和端口;URL-REGEX规则拿这个url原样来匹配,尽管在真实流量里它只会见到纯http://请求)、port(默认 443),以及可选的ip、protocol、process、process_path、src_ip、src_port、in_port、in_type、in_user、in_name、network、ssid、bssid、from_tun、user_agent——不认识的字段会连同可接受列表一起被拒绝,而不是被忽略。应答里有命中的规则matched(规则原文、类型、它指名的策略,以及策略组当前实际指向的resolved_policy)、policy、need_resolve,还有这次计算所依据的rule_count与match_generation。因为域名会被匹配两次——一次按名字,地址已知后再一次——所以passes每一轮一项;不传ip时只有解析前那一轮,应答会在note里说明。加explain=true可以拿到同样可能命中的候选规则,最多 50 条,外加没有展开的规则集数量。POST /api/config/validate解析一份配置然后扔掉:运行中的引擎什么都不会采纳。以{"configuration": "<full text>"}或直接裸文本发送。应答是valid、error_count、advisory_count、rule_count、policy_count,以及一个errors列表,每项为{line, severity, content, error}——severity区分被拒绝的行和被接受但有保留的行,content是出问题的那一行(已脱敏,因为一条坏掉的[Proxy]行往往正带着让它变坏的那个密码)。在PUT /api/config之前用它,因为后者会重启你正在调试的这次运行。GET /api/loglevel报告当前的level、nslog_level、正在写入文件的sections,以及你可以设置的available_levels/available_sections。PUT(或PATCH)接受level、sections或两者:sections是分区名数组或字符串"all",空数组会被拒绝——要停止记录请用level为none。这样改级别不会重启本次运行,这正是它的意义:写在文件里的loglevel = verbose需要重载,而重载会把你正想看的东西弄丢。GET /api/rules还会返回rewrite_hits——本次运行命中过的每条改写或模拟响应规则及其次数。没出现在那里的规则从未命中过,这正是「改写看起来没生效」最常见的原因。这张表最多跟踪 512 条不同的规则,超出的部分以rewrite_hit_dropped_rules报告。rules按顺序列出匹配器实际遍历的全部规则:先是 Tailscale 自动规则,然后是模块规则,再是配置中的[Rule]段,最后是FINAL;rule_regions按下标一一对应地标出每一行的来源(front、module、configuration)。POST /api/rewrites/:family接受{"rule": "<configuration line>"}——就是你会写进配置文件的那一行。解析不了的行会以400拒绝,而不会被存成一条永远匹配不到的规则。:family取值为url-rewrite、header-rewrite、body-rewrite、mock。这样添加的规则只存在于运行中的引擎,不会写回配置文件。GET /api/connections/export?format=har返回的是一份HAR 1.2 文档,POST /api/diagnostics/bundle返回的是一个zip——两者都是文件,因此与其他端点不同,不套{"ok": ..., "data": ...}信封。export接受source(current,默认;或history)、limit(默认 100,最大 300)、ids,以及bodies=1以包含已捕获的正文。每个条目都带一个_kl对象,装着 HAR 没有字段承载的东西:选中的策略、命中的规则,以及命中的改写。- 串联连接在
GET /api/connections和GET /api/connections/history中的记录带有chainPath,即从本设备到出口的路径,例如Airport/HK-01 → Landing;只用了一个策略的连接为空,HAR 导出中则是_kl.chain。在GET /api/traffic的按策略计数中,上游也会计入它为串联连接承载的字节;全局总量只计一次。
示例——读取状态,然后切换策略组:
curl -H "Authorization: Bearer your-secret-token" http://127.0.0.1:9090/api/status
{"ok":true,"data":{"running":true,"outbound_mode":0,"mitm":false, ...}}
curl -X PUT -H "Authorization: Bearer your-secret-token" \
-d '{"policy": "ProxyB"}' http://127.0.0.1:9090/api/policies/MainGroup
{"ok":true,"data":{"outbound_mode":0,"selectable_groups":[...], ...}}
示例 —— 在发出请求之前先问它会走到哪里:
curl -X POST -H "Authorization: Bearer your-secret-token" \
-d '{"url": "https://api.example.com/v1/orders", "explain": true}' \
http://127.0.0.1:9090/api/rules/match
{"ok":true,"data":{"policy":"MainGroup","matched":{"rule":"DOMAIN-SUFFIX,example.com,MainGroup", ...}, ...}}
复现问题时把日志收窄到某一个子系统,不用重启本次运行:
curl -X PUT -H "Authorization: Bearer your-secret-token" \
-d '{"level": "verbose", "sections": ["MitM", "DNS"]}' \
http://127.0.0.1:9090/api/loglevel
注意:此功能默认禁用。所有响应都使用统一信封:成功为
{"ok": true, "data": {...}},错误为{"ok": false, "error": {"code": "...", "message": "..."}};请求体上限为 1 MB。
PUT端点也接受PATCH。为第三方面板提供了 Clash 兼容的别名路径:/version、/traffic、/connections、/configs、/proxies、/rules——路径可达,但响应使用 Chute 自己的信封和字段名而非 Clash 的 schema(/version返回{"name", "run_id", "egress_probe"},其中egress_probe在 Apple 引擎上是network_address,在 Android 引擎上是egress_ip),因此 Clash 面板无法开箱即用。
代理测试 URL
[General]
proxy-test-url = http://cp.cloudflare.com/generate_204
test-timeout = 3
proxy-test-url 是所有未设置自己的 url 的 url-test、fallback 和 load-balance 组所用的测试 URL,test-timeout(秒)是所有未设置 timeout 的此类组的超时时间。配置保存后,这些组仍会继续跟随这两个键;只有写在组行上的 url 或 timeout 才会覆盖它们。无效的 proxy-test-url 属于配置错误。internet-test-url 由 Web 控制台的直连互联网测试使用,并且不经过代理;未配置时,引擎使用内置的成功检测 URL。
策略不支持 UDP 时的处理
udp-policy-not-supported-behaviour = DIRECT
当数据报所属策略无法中继 UDP(例如普通的 HTTP 代理)时如何处理:REJECT(默认)将其丢弃;DIRECT 则改为直接发送。block-quic 会先于此判定,依据的是规则选中的策略:block-quic = auto 时,发往无法中继 UDP 的代理的 QUIC 会被拒绝,而不是改为直连。其他 UDP 仍会回退到 DIRECT。无法经由上游发出 UDP 的串联策略,其 UDP 也按此处理;遵循出站模式而落到不承载 UDP 的策略上的 DoQ 或 DoH3 上游同样如此:REJECT 跳过该上游,DIRECT 直接向它查询。
前置代理
[General]
global-underlying-proxy = Airport
让每个没有自己 underlying-proxy 的代理策略都经由指定的策略或策略组连接——即 Shadowrocket 的「前置代理」,它只能在应用里设置。代理提供者提供的策略也包括在内。以下保持不变:经过前置策略本身的连接可能经过的每个策略——它的成员、成员的上游,以及其中中继组的各跳——这样前置策略永远不会经由自己;写了 underlying-proxy=DIRECT 的策略,表示不使用前置代理;策略组,由它的成员决定;以及 DIRECT、REJECT 和 TAILSCALE。不写这个键或写 DIRECT 即关闭。名称未定义时,它本应覆盖的每个策略都会被拒绝,而不是直接连接。
close-if-proxy-chain-missing(Shadowrocket)会被读取,并在保存配置时写回。Chute 总是按它取 true 时的行为处理:上游缺失的串联策略会被拒绝。false——Shadowrocket 的默认值,会跳过缺失的一跳直接连接节点——不会被遵循,并会给出一次提示。
客户端指纹
global-client-fingerprint = chrome
为所有未自行指定 fingerprint 的策略设置 TLS 客户端指纹, 代理提供者提供的策略也包括在内。 策略自身的取值始终优先,所以这是默认值而不是强制覆盖。
可用取值为 chrome、firefox、safari、ios,以及 edge、360、
qq、android、random——后面这几个都按 Chrome 处理——以及
fingerprint 一节列出的其他名字。无法识别的取值会被忽略,
并记录警告 Ignoring unsupported global-client-fingerprint '<value>',此时使用系统 TLS 栈。
默认:留空,即使用系统 TLS 栈。 ShadowTLS 策略总是读取它;设置了
tls=true或reality=true的 VLESS 策略、设置了tls=true的 Trojan 和 VMess 策略,以及同时设置了ws=true和tls=true的 Shadowsocks 策略也会读取它;走 gRPC 传输的策略同样要写上tls=true。ShadowsocksR 策略不读取它。
本页为英文版的翻译。如内容有出入,以英文版为准。