Nginx 1.26 变更概览
随着 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"} {"标题 3", "值 3"} {"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 中禁止使用的各种标头值。
场景 | 示例 |
---|---|
在 HEADERVALUE 之间允许\r\n 或包含 WS 或 HTAB 的\r\n 组合 |
{"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"} |
\n 或\n 允许 WS 或 HTAB 的组合(介于 HEADERVALUE 之间) |
{"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"}, {"标头\t14", "Value14"}, {"标头\t 32", "Value32"}, {"标头\t33", "Value33"}, {"Header- 36", "Value36"}, {"标头-\t40", "Value40"}, {"Header 4a", "Value4a"}, {"标头\t 59", "Value59"}, {"Header\t 60", "Value60"} |