我们很高兴地宣布,NGINX Plus Release 28 (R28)现已发布。NGINX Plus基于NGINX Open Source,是一款集软件Web服务器、负载均衡器、反向代理、内容缓存和API网关于一体的解决方案。
NGINX Plus R28的新增和增强功能包括:
- 更多TLS指标:NGINX Plus R28可在整个系统、客户端和服务器端层面收集更多TLS统计信息,为排查代理配置以及客户端和上游服务器连接中的SSL/TLS相关错误提供关键洞察。NGINX Plus实时活动监控仪表板也已更新,可显示新的SSL会话数据。
- 云私有服务支持PROXY protocol v2 TLV:通过AWS、Google Cloud Platform和Microsoft Azure中的“私有服务”向外部客户端提供资源时,默认情况下,PROXY protocol v2标头中以类型-长度-值(TLV)向量表示的服务专用客户端标识符不会传递给后端服务。NGINX Plus R28为
http和stream上下文引入了相应模块,用于解码TLV并定义变量,以便将客户端标识符转发到后端服务。 - 粘性 Cookie 的
samesite参数支持变量:在 NGINX Plus R28 中,samesite参数的值可在stickycookie指令中设置为变量。这项改进有助于更轻松地管理流量并增强安全性。
本次版本还包括继承自NGINX Open Source的新功能和错误修复,以及对NGINX JavaScript模块的更新。
重要行为变更
注意:如果从NGINX Plus R27以外的版本升级,请务必查看当前版本与此版本之间所有版本的发布公告博客中的“重要行为变更”部分。
平台支持变更
新增支持的操作系统和架构:
- AlmaLinux 8 和 9(x86_64、aarch64)
- Alpine 3.17(x86_64,arm64)
- Oracle Linux 9(x86_64)
- Rocky Linux 8 和 9(x86_64、aarch64)
已移除的旧版操作系统:
- Debian 10,已于2022年8月终止支持(EOL)
已弃用并计划在NGINX Plus R29中移除的旧版操作系统和架构:
- Alpine 3.13,已于2022年11月1日终止支持
多个同名标头的处理方式变更
- 现在会忽略大多数已知的重复上游响应标头,并发出警告
- 现在会拒绝重复的“
Content-Length”和“Transfer-Encoding”标头;如果响应中的“Content-Length”或“Transfer-Encoding”标头无效,或者同时存在“Content-Length”和“Transfer-Encoding”标头,也会拒绝该响应
新功能详解
其他TLS指标
在排查代理配置、上游服务器和客户端的TLS相关问题时,SSL/TLS事件和错误的可观测性非常重要。自NGINX Plus R13引入NGINX Plus API以来,NGINX Plus已在系统级别收集三项TLS指标:
handshakes:成功完成的SSL握手次数handshakes_failed,SSL握手失败次数(不包括SSL握手后发生的证书验证失败)session_reuses,SSL会话复用次数
在NGINX Plus R27<.htmla>及更高版本中,可以配置为各个上游服务器和虚拟服务器收集这三项指标。
NGINX Plus R28扩展了TLS指标集,在HTTP和Stream模块中新增了握手错误和证书验证失败计数器(此处仅提供HTTP模块的示例,但可用的Stream指标与之类似)。有关如何为各个上游服务器和虚拟服务器配置指标收集的详细信息,请参阅NGINX Plus R27<.htmlspan>发布公告博客。
握手错误
NGINX Plus R28新增了以下握手错误的计数器:
handshake_timeout:因握手超时导致的握手失败次数no_common_cipher:因握手双方没有共同的密码套件而导致的握手失败次数(不适用于与上游服务器的连接,因此不收集此项数据)no_common_protocol:因双方缺少共同协议而导致的握手失败次数peer_rejected_cert:因对方拒绝NGINX Plus提供的证书并返回相应警报消息而导致的握手失败次数
证书验证失败
配置证书验证后,证书验证失败信息现在会在API输出新增的“verify_failures”部分中报告:
- 对于使用
ssl_verify_client[HTTP][Stream]指令的客户端连接 - 对于使用以下协议特定指令的服务器连接:
grpc_ssl_verifyproxy_ssl_verify[HTTP][Stream]uwsgi_ssl_verify
证书验证失败时,与相应原因对应的指标会递增,并且连接会断开。但请注意,基本的handshakes计数器仍会递增,因为这些失败发生在握手成功之后。
证书验证失败的指标如下:
expired_cert:对等方提供的证书已过期hostname_mismatch:服务器证书与主机名不匹配(不针对与客户端的连接收集此信息)no_cert,客户端未按要求提供证书(不针对与上游服务器的连接收集此信息)revoked_cert,对等方提供了已吊销的证书other:用于明确统计其他证书验证失败次数的计数器
指标输出示例
以下是一组系统级HTTP连接TLS指标示例:
$ curl 127.0.0.1:8080/api/8/ssl{ "handshakes": 32, "session_reuses": 0, "handshakes_failed": 8, "no_common_protocol": 4, "no_common_cipher": 2, "handshake_timeout": 0, "peer_rejected_cert": 0, "verify_failures": { "no_cert": 0, "expired_cert": 2, "revoked_cert": 1, "hostname_mismatch": 2, "other": 1 }}以下是客户端与HTTP虚拟服务器之间连接的一组示例指标:s9(如前所述,此类连接不收集hostname_mismatch计数器):
$ curl 127.0.0.1:8080/api/8/http/server_zones/s9{ ... "ssl": { "handshakes": 0, "session_reuses": 0, "handshakes_failed": 1, "no_common_protocol": 0, "no_common_cipher": 1, "handshake_timeout": 0, "peer_rejected_cert": 0, "verify_failures": { "no_cert": 0, "expired_cert": 0, "revoked_cert": 0, "other": 0 } } ...}以下是与上游组u2中的服务器建立HTTP连接时的一组指标示例(如前所述,此类连接不收集no_cert和no_common_cipher计数器数据):
$ curl 127.0.0.1:8080/api/8/http/upstreams/u2{ "peers": [ { "id": 0, "server": "127.0.0.1:8082", "name": "127.0.0.1:8082", ... "ssl": { "handshakes": 1, "session_reuses": 0, "handshakes_failed": 0, "no_common_protocol": 0, "handshake_timeout": 0, "peer_rejected_cert": 0, "verify_failures": { "expired_cert": 1, "revoked_cert": 0, "hostname_mismatch": 0, "other": 0 } }, ... } ],}NGINX Plus仪表板显示扩展的TLS指标
对于NGINX Plus R28及更高版本,实时活动监控仪表板会显示上述新的TLS指标。此屏幕截图显示了客户端连接的指标。要查看新指标,请按图所示将鼠标悬停在“SSL > 握手失败”列中的值上。

Cloud Private Services 支持 PROXY Protocol v2 TLV
三家主要的云提供商(Amazon Web Services (AWS)、Google Cloud Platform (GCP)和Microsoft Azure)均提供“私有服务”,可让外部客户端访问您的服务,而无需将其暴露在公共互联网上。每项服务都使用一个客户端标识符,该标识符以PROXY protocol v2标头中的类型-长度-值(TLV)向量表示。各项服务的专用标识符如下:
- AWS PrivateLink:
PP2_SUBTYPE_AWS_VPCE_ID - GCP Private Service Connect:
pscConnectionId - Microsoft Azure Private Link:
PP2_SUBTYPE_AZURE_PRIVATEENDPOINT_LINKID
默认情况下,这些客户端标识符不会传递给后端服务。NGINX Plus R28为http和stream上下文引入了ngx_http_proxy_protocol_vendor_module和ngx_stream_proxy_protocol_vendor_module模块。这些模块可解码TLV,并定义一个变量,用于将标识符转发给后端服务。
有关NGINX Plus如何使用PROXY协议获取客户端IP地址及其他信息的一般说明,请参阅NGINX Plus管理指南中的《接受PROXY协议》。
对AWS的PROXY Protocol v2支持
在AWS中,客户端通过虚拟私有云(VPC)端点服务传入的流量,其源IP地址是网络负载均衡器节点的私有IP地址。如果后端应用需要客户端的真实IP地址及其他标识符,可以从PROXY protocol v2标头中获取。
在AWS中,自定义TLV向量会将端点的VPC ID编码到PROXY protocol v2标头PP2_SUBTYPE_AWS_VPCE_ID中。(有关详细信息,请参阅AWS文档。)
| 字段 | 长度(八位字节) | 说明 |
|---|---|---|
| 类型 | 1 | PP2_TYPE_AWS(0xEA) |
| 长度 | 2 | 值的长度 |
| 值 | 1 | PP2_SUBTYPE_AWS_VPCE_ID(0x01) |
| 可变(值长度减去 1) | 端点ID |
NGINX Plus R28 对TLV进行解码,并通过变量$proxy_protocol_tlv_aws_vpce_id将端点ID传递给后端应用程序。
注意:在引用server块中的$proxy_protocol_tlv_aws_vpce_id变量时,还必须在proxy_protocol参数中包含listen[HTTP][Stream]指令。有关示例,请参阅下方proxy_protocol_v2.conf的第8行。
此AWS示例配置会检查VPC ID是否可接受;如果可接受,则将其作为add_header指令的第二个参数传递给后端应用:
正在加载代码示例…
GCP对PROXY Protocol v2的支持
在GCP Private Service Connect中,来自客户端的流量所使用的源IP地址是“服务提供方VPC网络中某个Private Service Connect子网内的地址”。如果后端应用需要客户端的真实IP地址及其他标识符,可以从PROXY protocol v2标头中获取。
在GCP中,自定义TLV向量会将当时唯一的连接ID编码到PROXY protocol v2标头pscConnectionId中。(有关详细信息,请参阅GCP文档。)
| 字段 | 长度(字节) | 说明 |
|---|---|---|
| 类型 | 1 | 0xE0(PP2_TYPE_GCP) |
| 长度 | 2 | 0x8(8 字节) |
| 值 | 8 | 按网络字节序排列的8字节pscConnectionId |
NGINX Plus R28 对TLV进行解码,并将pscConnectionId的值通过变量$proxy_protocol_tlv_gcp_conn_id传递给后端应用程序。
注意:在引用server块中的$proxy_protocol_tlv_gcp_conn_id变量时,还必须在proxy_protocol参数中包含listen[HTTP][Stream]指令。有关示例,请参阅上方proxy_protocol_v2.conf的第 8 行。
对Microsoft Azure的PROXY Protocol v2支持
在Microsoft Azure Private Link中,来自客户端的流量所使用的源IP地址,是“服务提供商端使用从提供商虚拟网络分配的NAT IP[地址]进行网络地址转换(NAT)后得到的地址”。如果后端应用需要客户端的真实IP地址及其他标识符,可以从PROXY protocol v2标头中获取。
在Azure中,自定义TLV向量会将客户端的LinkID编码到PROXY protocol v2标头PP2_SUBTYPE_AZURE_PRIVATEENDPOINT_LINKID中。(有关详细信息,请参阅Azure文档。)
| 字段 | 长度(八位字节) | 说明 |
|---|---|---|
| 类型 | 1 | PP2_TYPE_AZURE(0xEE) |
| 长度 | 2 | 值的长度 |
| 值 | 1 | PP2_SUBTYPE_AZURE_PRIVATEENDPOINT_LINKID(0x01) |
| 4 | UINT32(4 字节),表示专用终结点的LINKID。采用小端格式编码。 |
NGINX Plus R28 对TLV进行解码,并通过变量“$proxy_protocol_tlv_azure_pel_id”将LinkID传递给后端应用程序。
注意:在引用server块中的$proxy_protocol_tlv_azure_pel_id变量时,还必须在proxy_protocol参数中添加到listen[HTTP][Stream]指令。有关示例,请参阅上文proxy_protocol_v2.conf的第 8 行。
粘性 Cookie samesite 参数的变量支持
在之前的NGINX Plus版本中,strict、lax和none这3个静态值可用于samesite参数,该参数属于sticky cookie指令。在NGINX Plus R28中,该参数值也可以是变量。
默认情况下(未设置samesite参数),NGINX不会在Cookie中注入SameSite属性。当samesite参数为变量时,结果取决于该变量在运行时解析为何值:
- 解析为标准值之一(
strict、lax或none)时,NGINX会注入SameSite属性,并将其设置为该值 - 设置为空值(
"")时,NGINX不会注入SameSite属性 - 设置为任何其他值均表示配置错误,此时NGINX会注入
SameSite属性,并将其设置为Strict(安全性较高的设置)
此示例配置根据HTTP samesite 标头的值设置User-Agent属性(适用于不支持SameSite属性的旧版客户端):
正在加载代码示例…
NGINX Plus R28 的其他增强功能
继承自NGINX Open Source的更改
NGINX Plus R28基于NGINX Open Source 1.23.2,并继承了NGINX Plus R27发布后(NGINX 1.23.0至1.23.2)所做的功能变更和错误修复,包括:
- HTTP
ipv4=off指令的新参数可禁止resolver查找 IPv4 地址。 - 使用
shared参数为HTTP会话信息启用共享缓存后,ssl_session_cache指令现在会自动轮换TLS会话票证密钥。 - 多种TLS/SSL错误的日志记录严重性级别从
crit降低为info。
有关从这些版本继承的新增功能、变更和错误修复的完整列表,请参阅CHANGES文件。
NGINX JavaScript模块的变更
NGINX Plus R28整合了NGINX JavaScript模块(njs)0.7.5至0.7.8版本中的变更和修复。我们在博客文章《使用njs 0.7.7进一步提升NGINX配置的模块化程度和可复用性》中重点介绍了其中一些重要内容。有关完整列表,请参阅“Changes”文件。
升级或试用 NGINX Plus
如果您正在运行NGINX Plus,强烈建议尽快升级到NGINX Plus R28。升级后还可获得多项其他修复和改进,并有助于NGINX在您需要提交支持工单时提供帮助。
如果您尚未体验过NGINX Plus,不妨试用一下。它可用于安全防护、负载均衡和API网关,也可作为获得全面支持的Web服务器,并提供增强的监控和管理API。立即开始30天免费试用。
关于作者
相关博客文章
NGINX Plus R26 正式发布
NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。
使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。
Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。
NGINX Plus R19 正式发布
NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。
NGINX现已正式加入F5
NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。

