背景
最近在做一个涉及多环境路由的联调需求,需要用 Whistle 把特定域名的请求代理到测试环境,同时往请求头里注入环境标识,让下游网关按 Header 路由到对应的测试实例。
规则写起来很简单:
api.example.com proxy://127.0.0.1:8899?host=10.25.13.175 reqHeaders://X-Env-Id=test-001
配完之后发现一个诡异的现象——Network 面板里请求状态是 captureError,Host 列显示 Tunnel to,下游网关死活收不到 X-Env-Id 这个头。接口能通,但环境路由完全不生效。
排查了一圈证书、代理配置、规则语法,最后发现根因只有一行:
* disable://capture
就是这行全局规则,让所有 HTTPS 请求跳过了报文解析,自定义 Header 在隧道里"隐身"了。
这篇文章记录一下这个问题的完整因果链,避免后来者踩同样的坑。
问题现象
Rules 里配置了全局禁用捕获:
* disable://capture
然后你会发现三件事同时发生:
| 表现 | 现象 |
|---|---|
| Network 面板 | 请求状态显示 captureError,点开看不到请求体/响应体 |
| Host 列 | 显示 Tunnel to,而不是实际业务域名 |
| 业务影响 | 所有通过 reqHeaders:// 注入的自定义请求头全部丢失,下游服务收不到任何环境标识 |
最迷惑的地方在于——请求本身是通的(返回 200),但 Header 就是传不过去。这很容易让人往证书、规则语法、下游服务配置上排查,方向完全跑偏。
根因解析
disable://capture 到底做了什么?
Whistle 处理 HTTPS 请求有两种模式:
| 默认模式(enable) | disable://capture | |
|---|---|---|
| HTTPS 处理 | MITM 中间人解密,完整解析应用层报文 | 仅建立 TCP 隧道,加密流量原样透传 |
| 请求头 | 可读、可修改、可追加 | 代理层不可见 |
| 规则执行 | proxy / reqHeaders / values 等全部生效 | 建立 CONNECT 隧道后规则链终止 |
| Network 展示 | 正常 Method + 域名 + 明文内容 | CONNECT + Tunnel to + captureError |
disable://capture 的本质是告诉 Whistle:“别解密这个域名的 HTTPS 流量,直接帮客户端和服务器牵根网线就行。”
问题就出在这里——自定义请求头(reqHeaders://)是应用层数据,必须在解密解析之后才能被 Whistle 读取并注入。隧道模式下 Whistle 看不到应用层内容,注入规则自然不会执行,下游收到的就是没有额外 Header 的原始请求。
为什么请求还能通?
因为 TCP 隧道本身就是个"透明管道",客户端和服务端自己完成了 TLS 握手和通信。Whistle 在其中只扮演了"接线员"的角色,不介入内容。所以请求能正常到达后端、正常返回响应——只是中间没有人动过报文。
快速识别
以后在 Whistle Network 面板看到以下组合,第一反应应该是查 Rules 里有没有 disable://capture:
- Method 列显示
CONNECT - Host 列显示
Tunnel to - 状态列显示
captureError - 配了
reqHeaders:///proxy://等规则但下游没生效
这几乎不可能是证书问题,也不是网络问题,就是规则配置导致的。
解决方案
✅ 方案一:直接删掉全局禁用(首选)
如果你不是在处理特殊的证书校验冲突,最简单粗暴:
- * disable://capture
删完保存,刷新请求,一切恢复正常。
✅ 方案二:精准限定范围(推荐用于生产调试)
如果确实有部分第三方域名因为证书问题需要跳过解密,不要全局禁用,精确匹配:
# 仅第三方域名跳过捕获
*.third-party.com disable://capture
# 自己的业务域名强制开启
api.example.com enable://capture
✅ 方案三:全局开启 + 信任根证书(最规范)
- Whistle 控制台 → HTTPS 标签页 → Download RootCA
- 系统安装并信任该根证书
- 勾选
Capture TUNNEL CONNECTs - Rules 里不写任何
disable://capture
证书报错通过信任根证书解决,而不是牺牲调试能力。
避坑总结
- 不要随手加
* disable://capture——这等于关闭了 Whistle 最核心的报文处理能力,所有依赖请求头透传的场景(环境路由、灰度、鉴权注入、Mock)全部失效 - 规则遵循最小权限原则——禁用捕获只针对确实需要跳过的个别域名
- 串联代理场景注意层级——如果流量经过多层代理(比如 Whistle → 本地 tunnel 代理 → 测试机),确保最终做 TLS 终止的那一层开启了捕获,否则中间层看到的全是隧道
Tunnel to+captureError= 排查入口——看到这两个词,先Ctrl+F搜 Rules 里的disable,比查证书快十倍
写在最后
这个坑之所以隐蔽,是因为它不会让请求"失败"——接口照常返回 200,只有当你依赖请求头做路由/鉴权/环境隔离时才会暴露。而且 disable://capture 这个规则名本身就容易让人误以为只是"不抓包显示而已",实际上它影响的是整个代理的报文处理能力。

374

被折叠的 条评论
为什么被折叠?



