连接到独立代理线路的两个互联网信任保险库

高吞吐代理应用会复用连接,以减少 TCP 与 TLS 握手开销。但当不同请求采用不同 CA 设置、证书固定规则、代理线路或租户策略时,进入同一连接池可能造成信任边界混淆。

安全设计并不是完全禁用复用,而是把信任配置纳入连接身份,用负向测试证明隔离,并在边界变化时关闭不再适用的连接。

先定义完整的信任配置

信任配置是判断 TLS 对端是否可接受的全部规则。为每套配置分配不可变的内部 ID,至少包含:

  • 是否启用操作系统原生 CA 存储;
  • 自定义 CA 包或信任库版本;
  • 证书或公钥固定集合;
  • 主机名验证策略;
  • TLS 最低与最高版本;
  • 双向 TLS 使用的客户端证书身份;
  • 代理协议、主机、端口及代理 TLS 设置;
  • 会改变以上任一项目的租户、地区或工作负载策略。

不要用易变的展示名称作为身份。应先规范化配置,再计算不含秘密的 trust_profile_id

代理场景要分别识别两段链路

经代理发送 HTTPS 请求时,可能存在两个受保护链路。TLS 代理有自己的证书和信任判断,目标站点还有另一套。CONNECT 隧道也可能在代理连接内部保留独立的端到端 TLS 会话。

因此要分别记录:

  1. 代理链路:代理协议、主机、端口、代理 CA 策略和代理客户端证书。
  2. 目标链路:目标主机、目标 CA 策略、固定集合和目标客户端证书。

即使代理线路不变,目标信任配置变化后也不能默认复用原连接。同样,代理信任变化不能继承已有的代理 TLS 会话。

构造完整的连接池键

连接池键必须区分会改变路由、对端身份或信任判断的所有设置。可以采用以下概念模型:

传输协议 + 代理端点 + 代理信任配置 + 目标端点 + 目标信任配置 + 客户端身份 + 隐私分区

不同库的字段会不同,但不变量相同:有效信任判断不同的两个请求,绝不能竞争同一个活动连接。

如果连接池由客户端库内部管理,应查看其复用规则并测试真实行为。复用 handle 上的配置 setter 不一定会使所有相关连接失效。

用双配置负向测试证明隔离

正向测试只能说明获批证书可用;负向测试才能证明信任不会串用。

准备两个受控 TLS 目标或代理监听器:

  • 配置 A 信任测试 CA A,并拒绝 CA B;
  • 配置 B 信任测试 CA B,并拒绝 CA A;
  • 每个监听器使用独立的服务端线路标记。

按生产客户端生命周期执行:

  1. 使用配置 A 请求目标 A,应成功。
  2. 使用配置 B 请求目标 B,应成功。
  3. 使用配置 A 请求目标 B,应发生证书失败。
  4. 使用配置 B 请求目标 A,应发生证书失败。
  5. 在允许连接复用时执行 A → B → A。
  6. 禁用复用后重复,作为控制组。
  7. 在生产 multi handle、工作进程或共享缓存拓扑中重复。

如果故意错误的配置只在之前成功请求之后被接受,应立即阻止发布。

测试长生命周期客户端的配置变化

很多问题只会在客户端已连接后修改配置时出现。每次只改变一个维度:

  • 原生 CA 存储开 → 关 → 开;
  • CA 包版本 A → B → A;
  • 固定集合 A → B → A;
  • 代理端口 A → B → A;
  • 同一工作进程中的租户 A → 租户 B;
  • 若策略允许,直连 → 代理 → 直连。

期望结果只能是正确隔离的复用连接,或一次新握手。旧策略验证过的连接不能作为新策略的信任证据。

记录证据但不泄露秘密

每次传输建议记录:

  • 请求 ID 与追踪 ID;
  • 客户端及 TLS 库版本;
  • 规范化代理端点标签;
  • 目标端点标签;
  • proxy_trust_profile_idorigin_trust_profile_id
  • 连接 ID 及新建或复用状态;
  • 协商的 TLS 版本和策略允许的证书指纹;
  • 成功、证书拒绝、代理认证、超时或策略拦截等结果分类;
  • 重试次数及最终线路。

禁止记录私钥、代理密码、令牌、原始 Cookie、完整代理 URL 或完整客户端证书。配置 ID 应由配置标签计算,不能由秘密计算。

回退与重试必须故障关闭

信任失败不是普通的瞬时网络错误。自动改用更宽松的信任配置,可能把一次安全拒绝变成非预期访问。

  • 证书错误后不得关闭验证;
  • 不得从固定证书配置自动退到未固定配置;
  • 除非策略明确允许,否则不能绕过代理;
  • 重试必须有上限,并保留原信任配置;
  • 策略失败应与容量失败分开告警。

可使用代理绕过审计检查意外直连,并通过代理故障转移恢复演练验证获批备用线路。

安全发布步骤

  1. 盘点信任配置及其负责人。
  2. 在配置和日志中加入不可变配置 ID。
  3. 扩展连接池键,或按配置隔离连接池。
  4. 在 CI 中部署负向测试矩阵。
  5. 只用少量获授权流量进行金丝雀发布。
  6. 观察证书失败、复用率、握手率、延迟和直连尝试。
  7. 信任配置变化时排空旧连接池。
  8. 回滚代码时不得恢复过期信任库。

同时结合代理凭据轮换,确保凭据和信任材料可以独立变更。

验收清单

  • 每个请求都能解析出明确的代理与目标信任配置 ID。
  • 不同信任配置无法共享活动连接。
  • 错误 CA 与错误固定集合测试稳定失败。
  • 长生命周期 handle 的配置变化会隔离连接或重新握手。
  • 未明确批准时不存在直连回退。
  • 重试保留原信任策略且有上限。
  • 日志不含秘密或完整代理 URL。
  • 信任库变化后旧连接池已排空。
  • 监控能区分证书、认证、路由和容量错误。

常见问题

一个进程可以安全服务多套信任配置吗?

可以,前提是连接池、缓存、客户端身份和日志都按完整配置分区。高敏感边界使用独立进程通常更简单。

代理 CA 存储等于目标 CA 存储吗?

不一定。TLS 代理和目标站点是两个独立对端,应分别建模和测试信任规则。

证书错误应该重试吗?

通常不应按普通瞬时错误重试。只有在保持相同信任要求、目的明确且次数受限的策略下才可重试。

CA 包更新后应做什么?

增加信任配置版本,禁止复用旧配置建立的连接,排空旧连接池,并重新执行正向与负向测试。

来源背景与合规

本文参考了 curl 项目于 2026 年 9 月 2 日发布的“native CA store conn reuse”安全公告。该公告说明了 Windows 与 macOS 上受影响的连接复用行为,并建议升级至 curl 8.22.0。外部来源地址仅保存在内部运营记录中。

代理和数据采集系统只能用于获授权的范围。请遵守隐私义务、合同、速率限制、访问控制和地区法律。信任隔离是安全控制,不是绕过平台保护的方法。