curl 8.22 阻止 SPNEGO 内部回退到 NTLM:企业代理升级前应测试认证链路

curl 8.22.0 于 2026 年 9 月 2 日发布,其中一项认证变更被 curl 项目描述为“spnego:阻止 SPNEGO 协商回退到 NTLM”。使用 Negotiate 连接企业 HTTP 代理的团队,应把它视为兼容性与安全边界变化,而不是普通传输补丁。

全球互联网认证网关允许已验证令牌路径通过,并在入口前终止旧式回退路径

这并不代表 curl 删除了所有 NTLM 支持。在构建和配置允许时,显式 NTLM 仍是独立机制。关键区别是:配置为 Negotiate 的请求,不应再在 SPNEGO 交换内部静默选择 NTLM 完成认证。它可能揭示一些被称为“Kerberos”的环境,实际成功却依赖回退。

为什么代理团队需要关注

企业正向代理通常返回 HTTP 407,并提供一个或多个 Proxy-Authenticate 挑战。客户端可以启用 Negotiate,并通过 Windows SSPI 或其他系统的 GSSAPI 获取凭据。如果 Kerberos 前置条件不完整,旧客户端路径可能仍通过 SPNEGO 内的 NTLM 回退成功。

升级后,同一请求可能失败而不是降级。这可能正是预期安全结果,但仍需运营方案。否则调度器会轮换网关、用同一错误身份反复重试、消耗工作线程,并把事件误判为代理池不稳定。

分开四个认证决定

不要把问题简化成“启用或关闭 NTLM”。分别记录:

  1. 代理在 407 中公布哪些认证方案;
  2. 应用允许哪些代理认证方案;
  3. 使用 Negotiate 时,SPNEGO 选择哪个机制;
  4. 客户端为代理网关提交哪个身份与服务主体。

目标站认证和代理认证也不同。目标可以返回 401,代理则返回 407。两者必须分别测试,避免目标挑战掩盖代理回归。

升级前盘点

对每个应用记录运行时 curl/libcurl 版本、认证选项、操作系统提供方、代理服务名称、网关主机名、连接池模型和凭据来源。命令行、嵌入式库、SDK 与容器镜像都要覆盖;主机上的 curl 命令版本可能不同于应用实际加载的 libcurl。

搜索 Negotiate、any-auth 与显式 NTLM 配置。确认组织要求 Kerberos-only、允许有文档的旧系统 NTLM 例外,还是完全禁止 NTLM。

盘点中不得复制密码、票据、keytab、Cookie 或认证头。只保存秘密引用、凭据类型、负责人和轮换策略。

建立受控认证矩阵

只使用组织控制的测试代理与身份,不要在无关企业网关或外部系统上实验。准备:

  • 有效 Kerberos 票据与正确代理服务主体;
  • 无票据或过期票据;
  • 服务主体不匹配;
  • 只公布 Negotiate 的代理;
  • 分别公布 Negotiate 与 NTLM 的代理;
  • 策略允许时的显式代理 NTLM 对照;
  • 错误凭据与被拒绝账号;
  • 代理 407 成功后,目标端再返回 401。

在当前批准版本与 curl 8.22.0 上执行同一矩阵,保持网关、身份、DNS、请求、超时和代理策略不变。

验证完整 407 交换

记录状态码和认证轮次,但不保存令牌内容。有效跟踪应说明第一次请求是否未认证、代理公布哪些方案、第二次请求是否携带代理认证,以及最终是 200、再次 407 还是有界客户端错误。

如果客户端能报告最终认证方案,也要保存方案名称。另行记录连接 ID、网关、认证耗时、curl 错误码以及是否发送了应用数据。

对严格 Negotiate 策略,8.22 的期望结果应是 Kerberos 成功,或清晰且有界的失败;不应把 SPNEGO 内通过 NTLM 获得的模糊成功当作验收标准。

覆盖连接复用与并发

实际部署中 Negotiate 与 NTLM 可能与连接状态关联。单请求无法发现身份复用、连接池污染和重连问题。至少测试:

  • 新代理连接上的首次请求;
  • 同一身份的重复请求;
  • 使用隔离连接池的两个身份;
  • 认证后被代理关闭的连接;
  • 接近空闲过期的复用连接;
  • 同时收到 407 的并发请求;
  • 认证期间代理网关切换。

确保一个身份认证过的连接不会被另一身份复用。失败后,排队任务应停止或在严格预算内重试,而不是形成认证风暴。

可结合代理凭据轮换指南检查秘密生命周期,并通过代理重试放大控制指南限制重复 407。

诊断常见失败

如果 curl 8.22 返回 407,而旧版本成功,不要立即开启显式 NTLM。先检查票据可用性、时间同步、DNS 规范化、服务主体名称、域配置、凭据委派与代理端 Kerberos 支持。

如果代理同时公布 Negotiate 与 NTLM,确认应用策略显式选择预期方案。“任意认证”设置可能不同于严格 Negotiate。

如果只在复用连接失败,检查连接池归属与网关粘性;如果只在网关轮换后失败,确认所有端点都有正确服务主体与密钥材料。

定义安全上线门槛

上线门槛可要求:

  • 计划使用 Negotiate 的身份和网关全部通过 Kerberos;
  • 未批准 NTLM 使用为零;
  • 连接池没有身份交叉;
  • 407 轮次与重试有界;
  • p95 认证延迟稳定;
  • 强制代理时不允许直连回退;
  • 审计证据完整且不含秘密;
  • 关键客户端已有验证过的回滚方案。

先发布到少量工作节点,监控 407 比例、实际认证方案、票据错误、连接抖动、重试放大、有效请求率与单个有效业务动作成本。

升级检查清单

  • [ ] 已记录运行时 curl 与 libcurl 版本。
  • [ ] 已盘点代理 Negotiate 与显式 NTLM 配置。
  • [ ] 已写明 Kerberos-only 或旧系统例外策略。
  • [ ] 已验证网关服务主体与 DNS 名称。
  • [ ] 已测试有效、过期与缺失票据。
  • [ ] 代理 407 与目标 401 分开报告。
  • [ ] 已覆盖首次使用、复用、并发与故障转移。
  • [ ] 日志不包含凭据、令牌或票据内容。
  • [ ] 重试限制可防止认证风暴。
  • [ ] 强制代理流程不会静默直连。
  • [ ] 灰度阈值与回滚条件已批准。

常见问题

curl 8.22 删除 NTLM 了吗?

没有。发布说明只表示阻止 SPNEGO 协商内部回退到 NTLM。显式 NTLM 是独立配置,应遵守组织策略。

所有使用 --proxy-negotiate 的代理都会失败吗?

不会。正确的 Kerberos/SPNEGO 部署仍应成功。依赖回退或 Kerberos 前置条件不完整的环境更可能暴露问题。

新出现的 407 能证明代理服务商故障吗?

不能。它可能来自客户端策略变化、票据缺失、主体不匹配、DNS 或网关差异。应比较受控的升级前后跟踪再归因。

重试是否应该更换代理出口?

不要自动更换。认证策略错误通常跟随身份或配置,轮换出口只会放大问题。仅对已知瞬时条件按严格预算重试。

内部来源说明:curl 项目《Changes in 8.22.0》,2026 年 9 月 2 日发布;条目“spnego: block NTLM fallback in SPNEGO negotiation”。外部资料地址只保留在内部运营记录中。

只能在明确授权下使用代理基础设施与企业凭据。遵守身份、访问控制、隐私和日志策略,不得为了让测试通过而削弱认证或启用旧式机制。