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」。外部資料網址只保留於內部營運紀錄。

只能在明確授權下使用代理基礎設施與企業憑證。遵守身分、存取控制、隱私與紀錄政策,不得為了讓測試通過而削弱驗證或啟用舊式機制。