NGINX.COM
Web Server Load Balancing with NGINX Plus

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

NGINX Plus R28 的新增特性包括:

  • 额外的 TLS 指标 — NGINX Plus R28 在系统范围、客户端和服务器端收集额外的 TLS 统计信息,可在对代理配置中的 SSL/TLS 相关错误以及与客户端和上游服务器的连接进行故障排除时提供关键洞察。

    NGINX Plus 实时活动监控仪表盘已更新,以显示新的 SSL 会话数据。

  • 在云私有服务中支持 PROXY 协议 v2 TLV — 当您通过 AWS、Google Cloud Platform 和 Microsoft Azure 中的“私有服务”向外部客户端提供资源时,默认情况下,用 PROXY 协议 v2 请求头中的类型长度值 (TLV) 向量表示的服务特定客户端标识符不会传递给后端服务。NGINX Plus R28 引入了用于 httpstream 上下文的模块,这些模块解码 TLV 并定义了一个用于将客户端标识符转发到后端服务的变量。
  • 对粘性 cookie samesite 参数的变量支持 — 在 NGINX Plus R28 中,粘性 cookie 指令的 samesite 参数值可以是一个变量。这种改进有助于更轻松地管理流量并提高安全性。

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

 

重要行为变更

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

平台支持的变更

支持的新操作系统和架构:

  • 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 日停服

 

新增特性详情

额外的 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 及后续版本中,您可以为单个上游服务器和虚拟服务器配置三个指标的集合。

NGINX Plus R28 扩展了 TLS 指标集,为 HTTP 和 Stream 模块中的握手错误和证书验证失败提供了新的计数器(此处我们只提供了 HTTP 模块的示例,可用的 Stream 指标与之类似)。关于为单个上游服务器和虚拟服务器配置指标集的详细信息,请参见 NGINX Plus R27 公告博客

握手错误

NGINX Plus R28 中新增了以下握手错误的计数器:

  • handshake_timeout — 由于握手超时而导致的握手失败次数
  • no_common_cipher — 由于握手双方之间缺少公共密码而导致的握手失败次数(由于不适用,因此未针对上游服务器连接进行收集)
  • no_common_protocol — 由于双方之间缺乏共同协议而导致的握手失败次数
  • peer_rejected_cert — 由于另一方拒绝 NGINX Plus 提供的证书并提供正确的警报消息而导致的握手失败次数

证书验证失败

当您配置证书验证时,证书验证失败现在会在 API 输出的新 verify_failures 部分报告:

当证书验证失败时,相应原因的指标将递增,连接将断开。但是请注意,基本握手计数器仍然是递增的,因为这些失败发生在握手成功之后。

证书验证失败的指标如下:

  • 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_certno_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 > Handshakes failed 列的值上,如图所示。

云私有服务中的 PROXY 协议 v2 TLV 支持

三大领先的云服务提供商 — Amazon Web Services (AWS)、Google Cloud Platform (GCP) 和 Microsoft Azure — 都提供了一种“私有服务”,您可以让外部客户端访问您的服务,而无需在公共互联网上公开这些服务。每个服务都使用一个客户端标识符,该标识符用 PROXY 协议 v2 请求头中的类型长度值 (TLV) 向量表示。服务特定标识符包括:

默认情况下,这些客户端标识符不会传递给后端服务。NGINX Plus R28 引入了用于 httpstream 上下文的模块 — ngx_http_proxy_protocol_vendor_modulengx_stream_proxy_protocol_vendor_module — 这些模块解码 TLV 并定义了一个用于将标识符转发到后端服务的变量。

有关 NGINX Plus 如何使用 PROXY 协议获取 IP 地址和其他客户端信息的一般信息,请参阅《NGINX Plus 管理指南》中的“接受 PROXY 协议”。

AWS 的 PROXY 协议 v2 支持

在 AWS 中,通过虚拟私有云 (VPC) 端点服务来自客户端的流量的源 IP 地址是网络负载均衡器节点的专用 IP 地址。如果后端应用需要客户端的真实 IP 地址和其他标识符,则可以从 PROXY 协议 v2 请求头中获取这些标识符。

在 AWS 中,自定义 TLV 向量在 PROXY 协议 v2 请求头 PP2_SUBTYPE_AWS_VPCE_ID 中解码端点的 VPC ID。(更多信息请参见 AWS 文档。)

字段 长度(八位字节) 描述
类型 1 PP2_TYPE_AWS (0xEA)
长度 2 值的长度
1 PP2_SUBTYPE_AWS_VPCE_ID (0x01)
不等(值长度减 1) 端点的 ID

NGINX Plus R28 解码 TLV,并将端点 ID 传递给 $proxy_protocol_tlv_aws_vpce_id 变量中的后端应用。

注意: 在引用 $proxy_protocol_tlv_aws_vpce_id 变量的 server 块中,还必须在 listen[HTTP][Stream] 指令中包含 proxy_protocol 参数。例如,请参见下面 proxy_protocol_v2.conf 的第 8 行。

这个 AWS 配置示例检查 VPC ID 是否可以接受,如果可以,则将其作为 add_header 指令的第二个参数传递给后端应用:

GCP 的 PROXY 协议 v2 支持

在 GCP Private Service Connect 中,来自客户端的流量的源 IP 地址是“服务提供商的 VPC 网络中某个 Private Service Connect 子网中的地址”。如果后端应用需要客户端的真实 IP 地址和其他标识符,则可以从 PROXY 协议 v2 请求头中获取这些标识符。

在 GCP 中,自定义 TLV 矢量对 PROXY 协议 v2 请求头 pscConnectionId 中的唯一(当时)连接 ID 进行编码。(更多信息请参见 GCP 文档。)

字段 长度(字节) 描述
类型 1 0xE0 (PP2_TYPE_GCP)
长度 2 0x8(8 字节)
8 按网络顺序排列的 8 字节 pscConnectionId

NGINX Plus R28 解码 TLV,并将 pscConnectionId 的值传递给 $proxy_protocol_tlv_gcp_conn_id 变量中的后端应用。

注意:在引用 $proxy_protocol_tlv_gcp_conn_id 变量的 server 块中,还必须在 listen[HTTP][Stream] 指令中包含 proxy_protocol 参数。例如,请参见上面 proxy_protocol_v2.conf 的第 8 行。

Microsoft Azure 的 PROXY 协议 v2 支持

在 Microsoft Azure Private Link 中,来自客户端的流量的源 IP 地址是“使用从提供商的虚拟网络分配的 NAT IP [地址] 在服务提供商端转换的网络地址 (NAT) ”。如果后端应用需要客户端的真实 IP 地址和其他标识符,则可以从 PROXY 协议 v2 请求头中获取这些标识符。

在 Azure 中,自定义 TLV 矢量在 PROXY 协议 v2 请求头 PP2_SUBTYPE_AZURE_PRIVATEENDPOINT_LINKID 中编码客户端的 LinkID。(更多信息请参见 Azure 文档。)

字段 长度(八位字节) 描述
类型 1 PP2_TYPE_AZURE (0xEE)
长度 2 值的长度
1 PP2_SUBTYPE_AZURE_PRIVATEENDPOINT_LINKID (0x01)
4 (4 字节)表示专用端点的 LINKID。以小端格式-编码。

NGINX Plus R28 解码 TLV 并将 LinkID 传递给 $proxy_protocol_tlv_azure_pel_id 变量中的后端应用。

注意:在引用 $proxy_protocol_tlv_azure_pel_id 变量的 server 块中,还必须在 listen[HTTP][Stream] 指令中包含 proxy_protocol 参数。例如,请参见上面 proxy_protocol_v2.conf 的第 8 行。

粘性 Cookie samesite 参数的变量支持

在以前的 NGINX Plus 版本中,粘性 cookie 指令的 samesite 参数可以接受三个静态值(strictlaxnone)。在 NGINX Plus R28 中,该值也可以是一个变量。

默认情况下(没有 samesite 参数),NGINX 不会将 SameSite 属性注入 cookie。当 samesite 参数为变量时,结果取决于变量在运行时的解析方式:

  • 对于一个标准值(strictlaxnone),NGINX 将 SameSite 属性集注入该值
  • 对于一个空值 (""),NGINX 不注入 SameSite 属性
  • 对于表示配置错误的任何其他值,NGINX 将 SameSite 属性集注入 Strict(最安全的设置)

此示例配置基于 HTTP User-Agent 请求头的值设置 samesite 属性(这对于不支持 SameSite 属性的旧客户机很有用):

 

NGINX Plus R28 的其他增强功能

从 NGINX 开源版继承的变更

NGINX Plus R28 基于 NGINX 开源版 1.23.2,继承了自 NGINX Plus R27 发布以来(NGINX 1.23.0 到 1.23.2)的功能变更和漏洞修复。变更和漏洞修复包括:

  • HTTP resolver 指令的新参数 ipv4=off 禁用 ipv4 地址的查找。
  • 当您使用 ssl_session_cache 指令的 shared 参数为 HTTP 会话信息启用共享缓存时,TLS 会话票据密钥现在会自动轮换。
  • 记录几种 TLS/SSL 错误的严重级别从 crit 降至 info

有关从这些版本继承的新功能、变更和漏洞修复的完整列表,请参见变更文件。

NGINX JavaScript 模块的变更

NGINX Plus R28 包含了 NGINX JavaScript 模块 (njs) 0.7.5 到 0.7.8 版本中的变更和修复。我们在博文《使用 njs 0.7.7 提高 NGINX 配置的模块化水平和可重用性》中重点介绍了一些最重要的变更和修复。完整列表请参见《变更》文件。

 

升级或试用 NGINX Plus

如果您是 NGINX Plus 用户,我们强烈建议您尽快升级到 NGINX Plus R28。除了上面提到的内容,您还将获得更多修复和改进,并且 NGINX 团队将会在您需要帮助时为您及时提供支持。

如果您还不是 NGINX Plus 用户,我们建议您立即申请试用 —它具备强大的安全性,可充当负载均衡器、API 网关或者具备增强的监控和管理 API 的 Web 服务器,并且 NGINX 团队将提供支持服务。请立即下载 30 天免费试用版

Hero image
免费 O'Reilly 电子书:
《NGINX 完全指南》

更新于 2022 年,一本书了解关于 NGINX 的一切

关于作者

Robert Haynes

技术营销经理

关于 F5 NGINX

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