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”。分别记录:
- 代理在 407 中公布哪些认证方案;
- 应用允许哪些代理认证方案;
- 使用 Negotiate 时,SPNEGO 选择哪个机制;
- 客户端为代理网关提交哪个身份与服务主体。
目标站认证和代理认证也不同。目标可以返回 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”。外部资料地址只保留在内部运营记录中。
只能在明确授权下使用代理基础设施与企业凭据。遵守身份、访问控制、隐私和日志策略,不得为了让测试通过而削弱认证或启用旧式机制。