NGINX.COM
Web Server Load Balancing with NGINX Plus

很高兴宣布推出 NGINX Plus Release 32 (R32)。NGINX Plus 基于 NGINX 开源版构建而成,是唯一一款将软件 Web 服务器、负载均衡器、反向代理、内容缓存和 API 网关集于一身的多合一产品。

NGINX Plus R32 的新增和增强特性包括:

  • SSL 证书缓存 —— 对于具有大量 location 代码块和重复 SSL 证书/密钥对的配置,NGINX Plus R32 对 NGINX 启动时间和内存使用率进行了重大改进。
  • Stream_pass 模块 —— NGINX Plus R32 现在支持 stream 模块充当路由器,允许有条件地将连接从 stream 模块转发到 http、mail 等其他模块,或者转回 stream 模块本身。
  • NGINX Plus 官方容器镜像 —— 随 NGINX Plus R32 发布了适用于特权和非特权容器运行时的 NGINX Plus 官方容器镜像。上述两种部署方法都随附了可选的容器镜像,其中包括 NGINX Agent —— 这是一个配套守护进程,支持无缝集成 NGINX 管理平面解决方案。

此外,该版本还包括从 NGINX 开源版继承的新功能和漏洞修复,以及对 NGINX JavaScript 模块的更新。

 

重要行为变更

注:如果您不是从 NGINX Plus R31 升级至 NGINX Plus R32,请务必查看之前公告博客中的“重要行为变更”部分,了解当前版本和最新版本之间所有版本的演变过程。

弃用 OpenTracing 模块

NGINX Plus R18 中引入的 OpenTracing 模块即将被弃用,并计划在 NGINX Plus R34 中移除。但在此之前,相关模块包将包含在所有 NGINX Plus 版本中。我们强烈建议,将所用的 OpenTracing 模块替换为 NGINX Plus R29 中引入的 OpenTelemetry 模块

移除 ModSecurity 模块

鉴于 ModSecurity 模块已于 2024 年 3 月 31 日停服,NGINX Plus 仓库现已删除 modsec 模块包,并且今后将不再提供。

PGP 密钥更新

NGINX 开源版和 NGINX Plus 软件包使用 PGP 密钥进行签名。此密钥将于 2024 年 6 月 16 日到期。我们更新了密钥的有效期,以便在 2024 年 6 月 16 日之后继续验证现有软件包。对于即将发布的版本,我们将生成新的密钥对,用于对软件包进行签名。

所有 NGINX 用户都应按照以下步骤下载并安装更新的 PGP 密钥:

Ubuntu/Debian:

wget -qO - https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

RHEL/CentOS:

sudo rpm -e gpg-pubkey-7bd9bf62-5762b5f8
sudo rpm --import https://nginx.org/keys/nginx_signing.key

2024 年 6 月 16 日之后,若不更新密钥,您将无法验证软件签名。

未来打包和发布政策

在未来的 NGINX Plus 版本中,我们将简化打包和发布政策。NGINX Plus 将仅在支持的操作系统发行版的最新版本上进行构建和测试。当在旧版发行版上安装 NGINX Plus 时,软件包管理器可能会建议您更新依赖库和软件包。

平台支持的变更

此版本对支持的平台做了以下更改。

全新操作系统支持:

  • Ubuntu 24.04

不再支持的旧版操作系统:

  • FreeBSD 12,已于 2023 年 12 月 31 日停服

以下旧版操作系统已弃用并计划在 NGINX Plus R33 中移除:

  • CentOS7/RHEL7/Oracle Linux 7
  • Alpine Linux 3.16

 

新增特性详情

通过 SSL 证书缓存改善 NGINX 加载行为

以前,每次在 NGINX 配置中引用证书、密钥或证书吊销列表时,NGINX 都会加载该列表。这意味着对同一对象的多次引用会导致该对象被重新加载多次。在继承受信任证书列表等指令时,这种延迟会变得更加严重。在某些情况下,该行为会严重影响 NGINX 的启动时间,并可能需要大量内存来存储配置。

在新行为模式下,SSL 指令现在会引用缓存的证书文件和相关对象。这样一来,重复引用同一证书对象的配置所需的内存空间和加载时间将大大减少。在涉及大型 NGINX 配置的情况下,这种优势最为明显,因为在大量 location 代码块中只需引用一小部分受信任证书。

下图显示了配置约 5400 个 location 代码块(顶层和嵌套)和 878 个证书的 NGINX 的加载时间改善情况。

请注意,在图表右侧,加载时间明显减少。在新行为模式下,平均加载时间从更改前的约 40 秒减少到约 6 秒。

将连接从 Stream 模块转发到其他模块

NGINX Plus R32 继承了 NGINX 开源版 1.25.5 的一项特性,进一步提升了 NGINX 的可配置性。具体来说,NGINX stream 模块现在可以发挥路由器的作用,作为代理将连接从 stream 上下文转发到其他上下文(例如 http、mail)或 stream 上下文本身中的单独虚拟服务器。

这一功能作为此版本中引入的 ngx_stream_pass_module 模块的一部分提供。 该模块执行一个指令“pass”,可用于指定客户端连接转发的目标地址 ——既可通过 IP 地址和端口组合、套接字路径指定,也可由 NGINX 变量引用。

有了这项功能,希望通过单个四层端点运行所有流量的客户现在能够终止四层 stream 上下文中的 SSL 连接,并将其转发给其他模块(http、mail)或 stream 上下文中的其他虚拟服务器。此外,您还可根据服务器名称或协议有条件地终止 SSL 连接,同时将其余流量代理到其他位置。这为管理来自单个端点的流量解锁了新的配置可能性。

下面的配置代码段会终止 stream 模块中的 SSL 连接,并根据请求的服务器名称,有条件地将这些连接转发给 http 上下文或 stream 上下文中的另一台虚拟服务器。

http {
    server {
        listen 8000;

        location / {
            return 200 foo;
        }
    }
}

stream {
	 map $ssl_server_name $pass_port {
		foo.example.com 8000;
		default 9001;
	
	}

    server {
        listen 9000 ssl;

        ssl_certificate     domain.crt;
        ssl_certificate_key domain.key;

        pass 127.0.0.1:$pass_port;
    }
	server{
		listen 9001;
		return bar\n;
	}

}

在本例中,所有 SSL 连接均在 stream server 代码块中终止。根据传入请求中的服务器名称,连接要么被转发到监听 8000 端口的 http 服务器,要么被转发到监听 9001 端口的 stream 虚拟服务器。

该模块的另一个应用解决了第三方模块不支持 SSL 卸载的用例。在这些用例中,stream_pass 模块会先终止 TLS 加密连接,然后再将其转发给第三方模块。

本示例演示了 RTMP 模块(原生不支持 SSL)如何使用 stream_pass 模块接受 TLS 加密流量。

rtmp {
    server {
        listen 1935;#rtmp
	
	application foo{
		
		live on;
        }
    }
}

stream {
    server {
        listen 1936 ssl; #rtmps

        ssl_certificate     domain.crt;
        ssl_certificate_key domain.key;

        pass 127.0.0.1:1935;
    }
}

在此配置代码段中,SSL 连接在 stream server 代码块中终止,并转发到 rtmp。对于 RTMP 模块来说,连接是未加密的,因此无需额外定制或处理开销来支持 SSL 连接。

NGINX Plus 容器镜像

随 NGINX Plus R32 发布了适用于特权和非特权容器运行时的 NGINX Plus 官方容器镜像。这两种容器类型还可选择安装 NGINX Agent,以便轻松连接到 NGINX 支持的管理平面。镜像可以从 NGINX 仓库下载,网址为:privateregistry.nginx.com。请按照这些说明使用 NGINX Plus 证书和密钥或 JSON Web Token (JWT) 访问镜像。

 

NGINX Plus R32 中的其他增强功能和漏洞修复

MQTT 模块中的漏洞修复

  • 使用默认属性时出现格式错误的数据包:此版本修复了 NGINX Plus R2 中引入消息队列遥测传输 (MQTT) 模块中导致数据包格式错误的问题。以前,如有属性字段且其中包含 MQTT Connect 消息中所有属性的默认值,则传出数据包的长度不计入属性长度字段(1 个字节)。这导致数据包长度比预期少 1 个字节,造成数据包格式错误。R32 中的这一漏洞修复解决了该问题。

zone_sync 模块中的漏洞修复

  • 重新加载配置时内存泄漏:以前,待处理队列同步操作使用的链节都分配自一个从不释放的内存池,导致主进程和所有 worker 进程中的内存泄漏。此版本中恢复为早期的区域同步实现,使用循环池来支持待处理队列。

安全修复

在 HTTP3/QUIC 实验性实现中发现并修复了以下潜在安全问题。

  • 写入时堆溢出 (CVE-2024-32760):未公开的 HTTP/3 编码器指令可能导致 NGINX worker 进程终止或造成其他潜在影响。
  • 栈溢出/释放后重用 (CVE-2024-31079):未公开的 HTTP/3 请求可能导致 NGINX worker 进程终止或造成其他潜在影响。这种攻击需要在连接耗尽过程中专门对请求进行定时,但攻击者对此缺乏可视性,所能施加的影响有限。
  • 请求头为空的空指针解引用(CVE-2024-35200):未公开的 HTTP/3 请求可能导致 NGINX worker 进程终止或造成其他潜在影响。
  • QUIC 握手期间内存泄露 (CVE-2024-34161):如果网络基础设施支持最大传输单元 (MTU) 为 4096 或更高且没有分段,则未公开的 QUIC 消息可能导致 NGINX worker 进程终止或先前释放的内存泄露。

从 NGINX 开源版继承的变更

NGINX Plus R32 基于 NGINX 开源版 1.25.5,继承了自 NGINX Plus R31 发布以来(NGINX 1.25.4 和 1.25.5)的功能变更、特性及漏洞修复。

特性:

  • tream 模块中的虚拟服务器。
  • ngx_stream_pass_module。
  • stream 模块中“listen”指令的 “deferred”、“accept_filter”及“setfib”参数。
  • 检测某些架构的缓存行大小。
  • 支持 Apple Silicon 上的 Homebrew。

漏洞修复:

  • Windows 交叉编译漏洞修复和改进。
  • 在 QUIC 中使用 0-RTT 时意外关闭连接。
  • 在正常关闭旧的 worker 进程时,可能会过早关闭与待执行 AIO 操作的连接。
  • 在正常关闭旧的 worker 进程后请求快速关闭时,不再记录套接字泄露警报。
  • 如果在子请求中使用了 AIO,则 worker 进程(用于处理 SSL 代理)中可能会发生套接字描述符错误、套接字泄露或分段错误。
  • 如果结合使用 SSL 代理和“image_filter”指令,并使用“error_page”指令重定向代码为 415 的错误,则 worker 进程中可能会发生分段错误。
  • HTTP/3 的漏洞修复和改进。

安全性:

有关从最新版本继承的新变更、特性、漏洞修复及变通方案的完整列表,请参见 NGINX 变更文件。

NGINX JavaScript 模块的变更

NGINX Plus R32 包含 NGINX JavaScript (njs) 模块版本 0.8.4 的变更。以下是 njs 自 0.8.2(NGINX Plus R31 随附的版本)以来的重大变更列表。

特性

  • 特性:可设置传出请求头的 Server 请求头。
  • 特性:CLI 中的 QuickJS 引擎支持。

变更

  • 改进:验证 r.subrequest() 中的 URI 和 args 参数。
  • 改进:检查重复的 js_set 变量。

漏洞修复

  • 漏洞修复:修复了 Headers.set()。
  • 漏洞修复:修复了 js_set 的 Buffer 值。
  • 漏洞修复:修复了在未指定超时的情况下共享字典的 clear() 方法。
  • 漏洞修复:修复了启用 js_periodic 时的 stub_status 统计数据问题。
  • 漏洞修复:修复了使用 libxml2 2.12 及更高版本进行构建的问题。
  • 漏洞修复:修复了 Date 构造函数溢出和 NaN 值的问题。
  • 漏洞修复:修复了 querystring.parse() 中的下溢问题。
  • 漏洞修复:修复了 String.prototype.match() 中可能存在的缓冲区过度读取问题。
  • 漏洞修复:修复了 for-in 循环的解析问题。
  • 漏洞修复:修复了十六进制、八进制和二进制字面量不含数字的解析问题。
  • 漏洞修复:修复了 0.8.3 中引入的共享字典的 clear() 方法(没有超时)。
  • 漏洞修复:修复了共享字典的 r.send() 方法(Buffer 参数没有超时)。
  • 漏洞修复:修复了处理非填充 base64 字符串的 atob() 的问题。

有关所有特性、变更及漏洞修复的完整列表,请参阅 njs 变更日志

 

升级或试用 NGINX Plus

如果您是 NGINX Plus 用户,我们强烈建议您尽快升级到 NGINX Plus R32。除了上述所有新特性以外,您还将获得更多修复和改进,这便于 NGINX 团队在您需要时为您提供支持。

如果您还不是 NGINX Plus 用户,我们建议您立即申请试用。您可将其用于安全防护、负载均衡及 API 网关用例,或者用作 Web 服务器 —— 采用增强型监控和管理 API 并拥有全面的售后技术支持。请立即下载 30 天免费试用版

Hero image
免费白皮书:
NGINX 企阅版全解析

助力企业用户规避开源治理风险,应对开源使用挑战

关于作者

Prabhat Dixit

首席产品经理

关于 F5 NGINX

F5, Inc. 是备受欢迎的开源软件 NGINX 背后的商业公司。我们为现代应用的开发和交付提供一整套技术。我们的联合解决方案弥合了 NetOps 和 DevOps 之间的横沟,提供从代码到用户的多云应用服务。访问 nginx-cn.net 了解更多相关信息。