Nginx 變更總覽
Apigee Edge for Private Cloud 4.54.00 包含 Edge 路由器上 Nginx 1.30 版的強制升級。
Nginx 1.26 版推出後,我們進行了幾項重要變更,以強化安全性並確保符合 HTTP 標準。主要更新如下:
標頭名稱和值中的空白字元處理方式
為提升安全性,我們強化了 RFC 7230 的遵循機制,尤其是標頭中空白字元的處理方式。如要進一步瞭解這些異動,請參閱附錄。
處理 Content-Length 和 Transfer-Encoding 標頭
要求走私攻擊常用的技術之一,是傳送同時含有 Content-Length 和 Transfer-Encoding 標頭的 HTTP 要求。雖然 Apigee Edge 已強化防範這類攻擊,但 Nginx 現在會明確封鎖同時包含這兩個標頭的要求。如果傳送這類要求,Nginx 會回應 400 Bad Request 錯誤。
支援的加密方式
本次發布的內容可能會變更北向要求的支援加密清單。你可以在路由器主機上查看 OpenSSL 支援的加密編譯,取得可用的加密編譯最新清單。
支援的金鑰大小
先前系統預設接受小於 2048 位元的 RSA、DSA 和 DH 金鑰,以及小於 224 位元的 ECC 金鑰。不過,這項更新生效後,這類金鑰將無法再用於北向要求的單向和雙向 TLS 連線。
附錄
標頭中的空白字元
主要異動如下:
- Nginx 1.26 現在不允許使用先前允許的某些標頭名稱。如果要求包含這些標頭,會導致「400 Bad Request」錯誤。
- Nginx 1.26 現在不允許使用先前允許的某些標頭值。如果要求包含這些標頭,也會導致 400 Bad Request 錯誤。
- Nginx 過去會接受某些標頭,但這些標頭會導致訊息處理器下游發生故障,現在 Nginx 會直接拒絕這類標頭。雖然這些標頭仍會導致 API 失敗,但 HTTP 失敗訊息會有所變更。
下節提供各種不允許的標題名稱和標題值範例。清單中僅列舉部分檢查事項,僅供參考之用。建議遵守 RFC 7230 的標頭規範。
標頭名稱異動
本節列出 Nginx 1.20.1 允許,但 Nginx 1.26 不允許的各種標頭名稱。
| 情境 | 標頭名稱範例 |
|---|---|
| 標頭名稱開頭、結尾或中間有控制字元 | { '\u0001'Header0, Value0 } { Header6'\u0002', Value6 } { Header'\u0005'4, Value4 } |
| 標頭名稱開頭和結尾有空格 | {"Header2 ", "Value2"} {" Header3", "Value3"} {" Header4 ", "Value4"} |
| 標頭名稱開頭和結尾有 HTAB | {"\tHeader11", "Value11"} {"Header12\t", "Value12"} {"\tHeader13\t", "Value13"} |
| 標頭名稱中開頭和結尾的 HTAB、WS 組合 | {"\t Header24", "Value24"} {" \tHeader25", "Value25"} {"Header26 \t", "Value26"} {"Header27\t ", "Value27"} |
| 標頭名稱之間有換行符號 (\n),後面緊接著 WS 或一連串 WS | {"Header\n 57Mutiline", "Value57"} {"Header\n 58Mutiline", "Value58"} |
| 標頭名稱之間有新行 (\n),後面緊接著 HTAB 或一系列 HTAB | {"Header\n\t73", "Value73"} {"Header\n\t\t74", "Value74"} |
| 標頭名稱後方緊接著回車字元 (\r) 和換行字元 (\n),然後是 HTAB 或一系列 HTAB | {"Header\r\n\t69", "Value69"} {"Header\r\n\t\t70", "Value70"} |
| 標頭名稱之間的回車字元 (\r) 換行字元 (\n),後面緊接著 WS 或一系列 WS | {"Header\r\n 71", "Value71"} {"Header\r\n 72", "Value72"} |
標頭值異動
本節說明 Nginx 1.20.1 允許,但 Nginx 1.26 不允許的各種標頭值。
| 情境 | 範例 |
|---|---|
| \r\n 或 \r\n 與 WS 或 HTAB 的組合,允許在 HEADERVALUE 之間 |
{"Header47", "Value47\r\n MultiLine"}, {"Header48", "Value48\r\n MultiLine"}, {"Header49b", "Value49b\r\n \r\nMultiLine"}, {"Header50", "Value50 \r\n MultiLine"}, {"Header51", "Value51\r\n\tMultiLine"}, {"Header52", "Value52\r\n\t\tMultiLine"}, {"Header53", "Value53\t\r\n\tMultiLine"} |
| HEADERVALUE 之間允許 \n 或 \n 與 WS 或 HTAB 的組合 |
{"Header61", "Value\n 61Multiline"}, {"Header62", "Value\n 63Multiline"}, {"Header65", "Value\n\t65"}, {"Header66", "Value\n\t\t66"}, {"Header67", "Value\n 67"}, {"Header68", "Value\n 68"} |
HTTP 失敗回應異動
本節說明舊版 Nginx 允許但上游訊息處理器拒絕的標頭,這會導致 400 狀態碼。不過,在 Nginx 1.26 中,這類標頭會直接導致 Nginx 發生故障,因此要求無法轉送至訊息處理器。
對於傳送這類標頭的用戶端,HTTP 狀態碼仍為 400。不過,HTTP 回應主體可能會變更,因為失敗現在會由 Nginx 產生,而非訊息處理器。
| 情境 | 範例 |
|---|---|
| HEADERNAME 之間有 HTAB 或 WS
訊息處理器會拒絕這類要求。在 Nginx 1.26 中,這類要求會由 Nginx 本身拒絕。API 使用者會收到 400 錯誤回應,內文包含 Nginx 錯誤訊息。 |
{"Header 5", "Value5"}, {"Header\t14", "Value14"}, {"Header\t 32", "Value32"}, {"Header \t33", "Value33"}, {"Header- 36", "Value36"}, {"Header-\t40", "Value40"}, {"Header 4a", "Value4a"}, {"Header\t 59", "Value59"}, {"Header\t 60", "Value60"} |