Web 控制台

Chute 在运行中的内核里通过 HTTP 提供一个管理控制台。它是唯一在所有平台上都一致的界面,所以每当有东西需要被看见而不是被配置时——一次请求的选路、一条没生效的改写、一个连接为什么被拒——本手册都会指向这里。

它不是 Chute Dashboard。Dashboard 是一个独立的 macOS 应用,去连接某个 Chute 实例;这里说的控制台由内核自己提供,用浏览器打开。

启用与进入

控制台需要在 [General] 段里配置 external-http-controller,默认关闭:

[General]
external-http-controller = 127.0.0.1:9090
external-http-ui = true

访问需要鉴权。如果你没有设置 external-http-secret,Chute 会生成一个令牌并保存在 control-token 文件里,重启后仍沿用同一个——所以实际的进入方式是让 App 把已经带好令牌的地址交给你。页面加载时会从地址里取走令牌并存进浏览器的 localStorage,一个浏览器只需登录一次。每个平台都有对应入口,见打开 Web 控制台

Overview(总览)

服务是否在运行、已运行多久、内存占用、HTTP 与 SOCKS 监听的地址和端口,以及本次运行使用的文件路径。当你不确定某个浏览器标签页连的是哪一个实例时,这一页能认出它。

Traffic(流量)

整个引擎的累计字节数与当前速度、一张速度历史图,以及按出站适配器的分解。用它回答「到底有没有东西在动」,以及当策略组在几个出口之间选择时,实际是哪一个在扛流量。

Connections(连接)

你花时间最多的一页。两个 Tab:

  • Current(当前) —— 此刻打开着的连接。
  • History(历史) —— 已关闭的连接,最新在前,从本次运行的记录里读回。

每一行带有主机、端口、类型、选中的策略、命中的规则、时长和字节数。时长是从这个浏览器标签页第一次看到该连接起算的,不是连接真正建立的时间,所以只在 Current(当前) Tab 上有意义。Inspect(查看) 会就地展开该行,回答这个请求为什么去了那里

字段 它告诉你什么
命中规则 / 规则来源 决定这条连接的那一行规则,以及它来自哪个段
选中策略 / 出站适配器 规则选中的策略,以及实际承载它的出站
DNS 来源 哪个解析器作答,以及是否命中缓存
命中的改写 改动过这条消息的改写或 Mock 规则,用规则自己的原文——每条连接最多保留 16 条命中,超出时该行会注明「另有 N 条未显示」
关闭原因 / 备注 它为什么结束,以及内核想说的话

表格下方,展开的行会显示捕获到的请求响应——报文头与报文体,就是它们在链路上的样子(对启用了 HTTPS 解密的主机,是解密后的)。

报文体的前提是开启流量记录

只有 Chute 捕获过,报文体才会在那里。请在复现问题之前打开记录:

  • [General] 里写 replica = true,或
  • Chute Mac:菜单栏 → 流量捕获,或
  • 走 API:PUT /api/features/record-traffic,请求体 {"enabled": true}

不开也不影响连接出现,选路归因与时间点都还在——只是没有报文体[Replica] 段会进一步限制捕获范围——那里的每个过滤项(包括 hide-crashlytics-request)都会生效——被它过滤掉的请求同样不会有报文体。

导出 HAR

Connections 页上的 Export HAR(导出 HAR) 会把当前 Tab 下载成一个 HAR 1.2 文件——最多 100 条,这是端点的默认上限(在端点上用 limit 最多可提到 300),而 History Tab 本身最多显示 200 条。HAR 是通用格式:可以用浏览器开发者工具打开(Network 面板 → 导入),也可以用 Charles、Proxyman 这类工具。

导出的内容包含这些工具期待的东西——请求与响应的头、时间线,以及开启记录后的报文体——外加每个条目一个 _kl 对象,装着 HAR 没有字段承载的信息:选中的策略、命中的规则,以及命中的改写。发送与接收的耗时来自捕获自身的时间戳,而不是推算出来的,所以它是有意义的。各端 App 也有自己的出口:Chute iOS 的 Dashboard 提供 导出为 HAR全部导出为 HAR(由内核生成,格式相同);Chute Mac 的连接详情窗口有 请求与历史 按钮,会打开控制台——打开的是控制台首页,而不是那条连接。一个条目对应一条连接:在承载了多个请求的 keep-alive 连接上,导出描述的是第一条消息,并注明后续消息还有多少字节未包含。

DNS

解析器缓存及每条记录由哪个服务器作答、来自 [Host] 的条目,以及系统 hosts 文件。Clear Cache(清除缓存) 清空动态记录;这里没有逐条删除——那只存在于 API 的 DELETE /api/dns/records/:domain

Policies(策略)

出站模式(Rule / Global / Direct,即 规则 / 全局 / 直连)以及每个策略组的当前选择。在这里改选择会立刻作用于运行中的内核——和在 App 里切换策略组是同一个动作。

Rules(规则)

这一页上有两类东西,行为并不相同。

路由规则 —— 即 [Rule] 段,按求值顺序列出。只读:它们来自配置文件。

改写与 Mock 规则 —— URL 改写、Header 改写、Body 改写、Mock,以及 MitM 主机列表。这些可以在这里增删:

  • 把规则按你会写进配置文件的样子原样粘进去,然后按 Add(添加)。解析不了的行会连同解析器的抱怨一起被拒绝,而不会被存下来——一条永远匹配不到的规则没有任何症状,所以当场知道更好。
  • Remove(删除) 删除一条;Clear(清空) 清空一族。
  • 这些改动只存在于运行中的内核。它们不会写回配置文件,重载或重启后回到文件里写的样子。用它来试规则,试通了再把成功的那一行写进文件。

改写与 Mock 命中 —— 本次运行中命中过的每一条改写或 Mock 规则,带次数和最近一次命中的时间;这张表最多跟踪 512 条不同的规则,超出的部分会注明还有多少条命中了但没记上。这张表就是对「我的改写没反应」的回答:没出现在这里的规则从未匹配过,这和「匹配了但没有可见变化」是两个不同的问题。如何区分见我的改写为什么没反应?

Diagnostics(诊断)

引擎正持有什么、上一次运行是怎么结束的,以及一组你可以朝它发起的探测。

  • Footprint / CPU / Uptime / Live flows / Superseded flows / Engine generation(内存占用 / CPU / 运行时长 / 活跃流 / 过期代际流 / 引擎代际) —— 本次运行当前的形态。流数持平而内存占用一路上升是值得查的;在 iOS 与 tvOS 上,这也正是系统在回收扩展前盯着的东西。
  • Previous exit(上次退出) —— Clean(正常退出)、Terminated unexpectedly(异常终止)或 Killed for memory(疑似因内存被终止),附带上一次运行的 id、运行时长与峰值内存。Chute「崩了」时请先读这一行:Killed for memory(疑似因内存被终止)意味着是系统回收了 Chute,而不是 Chute 自己出错,这会改变接下来该查什么。
  • Refusals(拒绝计数) —— 引擎拒绝过什么、因为什么,按资源与原因计数的一张表。当一条连接被丢弃而别处都解释不了时,原因通常就在这里。
  • Run a probe(运行探测) —— 可达性(ICMP,给了端口则用 TCP)、经运行中解析器的 DNS 查询、出口 IP 检测,以及某条策略的延迟测试。每项都有上限且只回答一次。未定义的策略名会被拒绝而不是去测量,所以打错字回来的就是打错字。
  • Events(事件) —— 本次运行的关键时刻:大面积失败、出口变化等。
  • Tailscale —— 配置了 [Tailscale] 段时给出引擎实时状态;没有该段时是 idle,这是正常回答。
  • Download diagnostic bundle(下载诊断包) —— 一个脱敏压缩包,可以直接附在支持邮件里。内容见发送诊断包

Config(配置)

运行中的配置,显示在一个可编辑的框里,Reload(重新加载) 会应用框里的内容。

这里显示的配置已经把机密抹掉了。 密码、控制面 secret、CA 口令、WireGuard 密钥之类都显示为 <redacted>。而 Reload(重新加载)原样应用框里的内容,所以照着显示的文本重载,等于把这些机密替换成字面量 <redacted> 写进运行中的内核——需要它们的策略会开始失败。配置文件不受影响,重新选中该配置即可恢复。

请把这一页用于阅读配置,以及应用你完整键入的改动。要编辑文件本身,请用各端 App 里的编辑器。

Logs(日志)

内核日志的实时跟随,按等级着色,Pause(暂停) 可以在你阅读时暂停。详细程度由 loglevel 决定,而不是这一页——如果你要的行不在这里,请调高它并重现。

控制台能交出什么

请把「能访问控制台」等同于「能访问本次运行见过的一切」。它可以给出带有 URL、请求头和进程名的连接记录、捕获到的请求与响应报文体、配置,以及日志。这正是「不鉴权」不能是默认值的原因,也是把它绑到回环之外必须由你自己设置 secret 的原因——见 external-http-secret

S. Smart Rabbit LLC © All Rights Reserved            updated 2026-09-01 13:16:36

本页为英文版的翻译。如内容有出入,以英文版为准。

results matching ""

    No results matching ""