Hotdry.
security

LLM 工具流量透明代理:Sherlock MITM 架构与协议解析实践

深入解析基于透明代理的 LLM 工具流量拦截方案,涵盖 mitmproxy 集成、OpenAI/Anthropic 协议字段提取与实时监控面板配置。

当我们将 Claude Code、Cursor 或 ChatGPT 接入生产代码库时,一个核心问题随之浮现:这些 AI 工具与后端 LLM API 之间的通信完全被 TLS 加密,传统的网络抓包工具无法获取请求与响应的明文内容。开发者往往只能依赖 API 提供商的控制台或账单面板,间接推测 token 消耗模式与上下文窗口使用情况。Sherlock 项目提供了一种透明 MITM 代理方案,能够在不改写任何业务代码的前提下,实时拦截并解析 LLM 工具的 HTTPS 流量,将原本黑盒的 API 交互转化为可观测、可回溯的调试数据平面。

透明代理的核心工作原理

Sherlock 基于 mitmproxy 构建透明代理层,其工作模式与传统 HTTP 代理有本质区别。传统代理需要客户端显式配置代理地址,而透明代理通过操作系统级别的流量转发(IPTables 或路由表),将原本发往目标服务器的数据包拦截并导向本地代理进程。这意味着只要 LLM 工具遵循操作系统网络配置,代理即可自动生效,无需在每个工具内部单独设置。

代理启动后,mitmproxy 会动态生成 CA 证书用于中间人解密。由于 HTTPS 连接要求证书链验证,客户端必须信任 mitmproxy 颁发的根证书才能成功建立加密通道。Sherlock 在首次运行时引导用户完成证书安装流程:Linux 环境下通常将证书写入系统信任存储(/usr/local/share/ca-certificates/),macOS 通过安全命令行工具导入到钥匙串,Windows 则调用 certutil 添加到本地计算机信任根证书存储。完成信任配置后,所有流经代理的 TLS 会话均可在代理层解密,获得完整的明文请求体与响应体。

代理层的核心拦截逻辑位于 mitmproxy 的 addon 脚本中。Sherlock 实现了 http_connecthttp_response 两个钩子函数:前者处理代理隧道建立请求,后者负责在响应返回时提取并处理业务数据。对于流式响应(SSE 协议),mitmproxy 提供了 streaming_messages 回调,允许在数据块传输过程中逐块解析,实现 token 生成的实时可视化。开发者可以在面板上看到每个请求的 prompt tokens、completion tokens、模型名称、temperature 参数,以及响应流中每个 chunk 的到达时间戳。

OpenAI 与 Anthropic 协议字段提取策略

不同 LLM 提供商的 API 响应结构存在差异,Sherlock 通过统一的解析适配层屏蔽了这些差异。OpenAI 的标准响应格式包含 idobjectcreatedmodelchoicesusage 等顶层字段,其中 usage 对象提供了 prompt_tokenscompletion_tokenstotal_tokens 三个核心计量指标。Anthropic 的 Claude API 则采用不同的命名约定:请求体中使用 max_tokens 而非 OpenAI 的 max_completion_tokens,响应体通过 content 数组承载文本块,计量信息位于 usage 字段的 input_tokensoutput_tokens

解析层需要处理两种常见的非标准情况。第一种是流式响应中的片段化 token 计数:OpenAI 在流式模式下不返回完整的 usage 字段,而是依赖客户端自行累加 usage 中缺失的指标。Sherlock 通过监听 data 消息中的 x-blob-usage 扩展头,提取每个 chunk 实际消耗的 token 增量,再在本地维护累加器以计算会话级的准确消耗。第二种是批量请求与批处理响应:部分企业级 API 支持在单次调用中并发多个子请求,响应体以数组形式组织。解析逻辑需要遍历数组中的每个元素,分别计算其计量数据并在面板上以独立卡片形式展示。

除计量数据外,协议解析层还提取了若干对调试与审计有价值的元数据字段。请求体中的 system 字段包含隐式的系统提示词,这部分内容往往决定了模型的行为边界但不会显式出现在聊天界面中。Sherlock 自动将 system 提示词归档至独立的 JSON 文件,便于安全团队审计潜在的 prompt 注入风险或敏感信息泄露。响应体中的 stop_reason 字段记录了生成终止的具体原因,可能是自然语言结束、达到 token 上限、触发安全过滤器或调用方主动取消,这些信息对于诊断模型行为异常至关重要。

实时监控面板与数据持久化

Sherlock 的终端面板采用富文本渲染,能够在同一界面中并行展示多个维度的实时指标。主区域采用卡片式布局,每个活跃请求占用一张卡片,实时更新 token 计数器与流式响应进度条。面板右侧维护了一个全局燃料表,以可视化仪表盘形式展示当日累计 token 消耗与上下文窗口使用率,仪表盘右侧标注了当前会话的预估成本(基于各模型的官方定价)。当累计消耗突破预设阈值时,面板会以颜色变化与声音提示两种方式发出告警。

数据持久化模块采用双写策略:每完成一次请求响应周期,Sherlock 同时向本地文件系统与可选的远程存储写入完整记录。本地存储格式为 Markdown 与 JSON 双版本:Markdown 版本保留原始请求体与响应体的易读格式,便于直接在编辑器中查阅;JSON 版本则保留完整的协议字段与元数据,适合后续脚本化分析。文件名由时间戳、模型名称与请求 ID 组合生成,确保唯一性的同时支持按时间范围快速检索。远程存储支持对接 Elasticsearch 或 Loki,便于在团队环境中统一管理多台开发机的流量日志。

持久化模块还实现了自动的日志轮转与压缩策略。单个日志目录下的文件数量超过阈值后,最早的 20% 文件会被打包为 gzip 归档并移入子目录,释放主目录空间的同时保留历史可追溯性。归档文件保留最近 30 天的完整记录,超过此范围的归档进一步压缩为.tar.gz 格式以节省存储成本。这一策略在保留足够调试信息的同时,避免了长期运行导致的磁盘耗尽问题。

跨平台部署与代理配置参数

Sherlock 支持 Linux、macOS 与 Windows 三大桌面平台,各平台的流量转发机制存在差异。Linux 系统使用 iptables 将 443 端口的出站 TCP 流量重定向至本地代理端口,命令形式为 iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 代理端口。macOS 从 High Sierra 开始引入了更为严格的系统完整性保护,推荐使用 pfctl 配合锚文件配置流量转发规则。Windows 则依赖 netsh 的 portproxy 功能或第三方驱动级代理工具,由于驱动签名要求较高,官方文档提供了预编译驱动包的下载链接。

代理进程本身的启动参数提供了灵活的配置空间。--listen-host 指定代理监听的网卡地址,默认为 0.0.0.0 即所有网络接口;--listen-port 指定监听端口,默认为 8080。生产环境中建议将监听地址改为 127.0.0.1 或内网网卡,避免暴露至不受信任的网络。--ssl-insecure 参数控制是否跳过证书链验证,开发调试时可开启以避免证书错误,但生产环境应始终保持关闭。--stream-quiet 参数抑制流式响应的逐行日志输出,仅在会话结束时记录完整数据,可显著降低高并发场景下的 IO 开销。

环境变量层面的配置同样重要。HTTPS_PROXYHTTP_PROXY 变量影响所有遵循 Proxy Environment Variables 规范的客户端工具,包括 curl、wget 与部分 Python HTTP 库。对于 Node.js 应用(如 Claude Code),还需额外设置 NO_PROXY 以排除本地代理自身的通信,避免循环引用导致的连接失败。Sherlock 提供了自动配置脚本,能够检测当前 shell 类型并向 .bashrc.zshrc 或 PowerShell 配置文件注入正确的环境变量定义。

错误恢复与安全边界设计

代理层的稳定性直接影响下游 LLM 工具的可用性。Sherlock 实现了多层次的异常处理与恢复机制:单次请求解析失败时,错误信息被捕获并记录至专用日志文件,同时该请求的卡片在面板上显示为红色状态但不影响其他请求的正常处理;代理进程本身被设计为无状态运行,任何未捕获的异常都会触发进程重启并保留已有日志;进程重启后,持久化模块自动恢复会话状态,确保数据不丢失。

安全层面的设计同样需要审慎考量。MITM 代理本质上是中间人攻击的工程化实现,若证书私钥泄露,攻击者可利用该证书解密同一网络内的其他加密流量。Sherlock 将证书与私钥存储于用户目录下的隐藏目录(~/.config/sherlock/ssl/),权限设置为仅当前用户可读写。部分企业环境还要求代理层支持审计日志的只读导出,以便安全团队定期审查敏感数据访问记录,Sherlock 提供了只读模式启动参数,在此模式下代理不修改任何日志文件,仅从共享目录读取已归档的历史数据。

在 AI 安全的语境下,透明代理既是调试工具也是潜在的风险入口。研发团队在部署此类工具时,应在内部 wiki 中明确标注其安全边界:仅限受信任的开发机使用,禁止在共享开发机上保留未加密的日志文件,定期轮换代理证书并在团队成员离职后撤销其本地证书副本。这些措施确保了工具的审计价值不被其自身的攻击向量所抵消。

工程实践中的典型应用场景

实际工程中,Sherlock 的典型价值体现在三个维度。第一维度是成本优化:通过实时监控 token 消耗与成本面板,团队能够快速定位异常的资源使用行为,例如某个 prompt 模板因未限制输出长度导致每次调用消耗数万 token,优化后可将单次成本降低一个数量级。第二维度是行为诊断:当模型输出出现不符合预期的内容时,开发者可以回溯完整的请求响应历史,检查是否存在 system 提示词被意外覆盖、temperature 参数被重置、或上下文窗口达到上限导致内容被截断等问题。第三维度是安全合规:对于处理敏感数据的企业,代理层提供了唯一的流量审计入口,安全团队可在此处部署 DLP 规则,自动检测并告警 prompt 或响应中出现的敏感信息模式。

需要注意的是,代理层无法捕获本地模型推理的场景,例如 Ollama 或 LM Studio 直接在本地 GPU 上运行的模型。这类场景的流量完全不经过网络协议栈,透明代理无能为力。对于混合部署场景(部分请求走本地模型、部分请求走云端 API),Sherlock 仅能审计云端部分的流量,开发者需要在本地模型侧补充其他可观测性手段。


参考资料

查看归档