BLOG | NGINX

隆重推出 NGINX Plus R25

NGINX-Part-of-F5-horiz-black-type-RGB
Zach Westall 缩略图
Zach Westall
Published September 28, 2021

我们很高兴宣布推出 NGINX Plus R25。NGINX Plus 基于 NGINX 开源软件构建而成,是唯一一款集软件 Web 服务器、负载均衡器、反向代理、内容缓存和 API 网关于一身的一体化产品。

NGINX Plus R25 的新增特性包括:

重要变更

上游区域的内存需求增加

下文 “更细粒度的 HTTP 响应代码报告” 这一部分详细指出,NGINX Plus R25 支持对响应代码单独计数以及按类别汇总。当 NGINX Plus 被配置为反向代理或负载均衡器时,如果上游的 “节点”(后端服务器)超过 20 个,那么可能需要增加用于监控这些节点的共享内存区域的大小。

如果共享内存分配不足,NGINX Plus R25 将无法启动,而这会导致升级失败。在升级之前,我们必须要检查每个上游区域的内存使用情况。有关检查和调整内存分配的说明,请参阅下文 “分配足够内存,以防启动失败” 部分。

NGINX Plus 代码库组织方式和安装程序的更改

NGINX Plus R24 发布时, 所有 NGINX 软件的软件包代码库都进行了重组,这导致 NGINX Plus 安装程序发生了改变。

安装或升级 NGINX Plus 时,操作系统的软件包管理器(apt, yum 或类似管理器)配置了 NGINX Plus 的软件代码库。在那些使用旧代码库的现有系统(那些运行 NGINX Plus R23 或更早版本的系统)上,您需要更新软件包管理器以引用新代码库。请参阅 F5 知识库 中的说明。

对于 NGINX Plus R25 的初始安装,请参阅《NGINX Plus 管理员指南》中的 “安装 NGINX Plus” 部分。

注: 必须使用新的软件代码库。旧代码库将不再更新,因此未来使用旧代码库安装和升级可能会出错。

停用 Cookie-Flag 模块

NGINX Plus R23 发布时宣布弃用第三方 CookieFlag 模块,并将从 NGINX Plus R26 的动态模块代码库中删除该模块。模块中定义的 set_cookie_flag 指令被内置的 proxy_cookie_flags 指令替换。我们建议您尽快使用 proxy_cookie_flag 指令替换配置中的所有 set_cookie_flags 指令。

平台支持的变更

  • 全新操作系统支持:
    • Debian 11 (x86_64, aarch64)
    • AAlpine Linux 3.14 (x86_64, aarch64)
  • 不再支持旧版操作系统:
    • Alpine Linux 3.10;支持的最早版本是 3.11
    • Amazon Linux 1 (2018.03+);切换至 Amazon Linux 2 LTS
    • FreeBSD 11.4+;支持的最早版本是 12.1+
    • Ubuntu 16.04 LTS;支持的最早版本是 18.04 LTS
  • 旧版操作系统已弃用并计划在 NGINX Plus R26 中移除:
    • Alpine Linux 3.11

新增特性详情

更多 JSON Web Token 用例和功能

NGINX Plus R24 引入了对 加密 JSON Web Token (JWE) 的初始支持,提升了这种最流行的客户端验证方法的数据保密性。NGINX Plus R25 在此基础之上引入了对其他更多更高级的身份验证用例的支持,可在签名(JWS)和加密(JWE)用例中提高基于 JWT 的身份验证的安全性。这些改进既降低了个人身份信息(PII)的泄露风险,又提供了更高的灵活性。NGINX Plus 的全新 JWT 功能和改进包括:

解密 JWE 密文的变量

JWT 用于 HTTP 请求,是一种使用广泛且值得信赖的无状态身份验证方法(即基于令牌的身份验证)。通过在令牌载荷中传输终端用户属性,JWT 可帮助提高请求的安全性。然而,安全研究人员和 DevSecOps 从业人员一致认为,在 Web 客户端存储未加密的 PII 所带来的风险需要亟待处理。因此,他们制定了 JSON Web 加密标准(RFC 7516),从而为加密令牌的实现提供了指导方针。

NGINX Plus R24 新增了对 JWE 的支持,为整个声明集提供了数据的完整性和机密性。在加密令牌中对 PII 进行编码极大地降低了使用 JWT 时的数据泄露风险。

NGINX Plus R25 在初始的 JWE 支持之上增加了一个新变量 $jwt_payload,该变量可支持 NGINX Plus 解密 JWE 和密文,然后在处理 HTTP 请求时访问明文。这一新功能可用于实施高级访问控制策略和请求路由决策,并支持用户将 NGINX Plus 部署为后端应用的 JWE 解密层。

嵌套 JWT 支持

JWE 令牌可有效保护 PII,密文则负责保障 PII 的保密性,即使在 CDN 和其他 TLS 终止代理之间也是如此。但是加密是一把双刃剑,因为 JWE 可能会增加应用环境的复杂性。解决此问题的一种方法是使用嵌套 JWT。

嵌套 JWT 的结构剖析

嵌套 JWT 以 JWE 密文的形式嵌入 JWS。NGINX Plus R25 既支持 JWS 又支持 JWE,因此允许使用嵌套 JWT 对 HTTP 请求进行身份验证。在一个操作中,NGINX Plus 现在可解密 JWE 中的密文,以 JWS 的形式验证得到的明文,并使用所附令牌中的 exp(失效时间)和 nbf(在此之前无效)声明来验证其有效性。这使得现有的 JWS 环境能够通过将有效载荷加密包装在 JWE 中进行升级。

以下配置代码段说明了该过程。auth_jwt_type 指令的新嵌套参数要求 NGINX Plus 执行 JWE 解密和 JWS 验证。它还影响 JWT 标头和 JWT 声明变量的评估方式:

通过以下配置,NGINX Plus 可以向后端应用构建并发送额外的 HTTP 请求标头。来自 JWE 标头($jwt_header_enc 变量)的加密算法和来自 JWS 有效载荷($jwt_claim_sub 变量)的主题声明由原始请求代理。这意味着应用可以使用 HTTP 标头来实施基于 JWE 的身份验证,而无需加密代码或库的支持。

对于在零信任架构中操作的用户,以下配置支持后端应用验在 $jwt_payload 变量中捕获的 JWS 令牌。该变量包含了 JWE 密文的解密明文版本。如果存在嵌套 JWT,则 JWS 可作为 Bearer 令牌传递给后端应用。

嵌套 JWT 支持 NGINX Plus 解密和验证安全令牌,同时为后端应用解析或代理 “常规 JWT” 签名令牌,从而在本质上简化操作并提高应用安全性。

JWE 非对称加密

NGINX Plus R24 新增了对 AES 标准令牌的对称加密支持。NGINX Plus R25 增强了对使用 RSA 密钥对的非对称加密的支持。非对称加密技术使用不同的密钥(公共和私有)进行加密和解密,这些密钥在数学上通过 RSA (Rivest–Shamir–Adleman) 算法 相互关联,这与客户端和服务器之间使用 SSL/TLS 加密 HTTPS 流量所采用的机制相同。

NGINX Plus R25 支持将基于最优非对称加密填充(OEAP)的 RSA 作为密钥管理算法,且无需在 NGINX Plus 侧进行显式配置。JWS alg(算法)标头支持的值为 RSA-OAEPRSA-OAEP-256RSA-OAEP-384RSA-OAEP-512

以下配置说明了为 JWE 实施非对称加密所需的全部操作即是将包含 RSA 私有(解密)密钥的 JSON Web Key(JWK)文件指定为 auth_jwt_key_file 指令(或也可使用 auth_jwt_key_request 指令)的参数。

多源 JWK 支持

使用嵌套 JWT 意味着关联的 JWK 可能来自多个来源。NGINX Plus R25 支持同一个上下文中的多个 auth_jwt_key_fileauth_jwt_key_request 指令。NGINX Plus 从所有指定来源加载密钥,并在这些密钥组合而成的密钥集中查找匹配的验证密钥。由外部身份提供者发布并嵌套在 JWE 中的 JWS加密通常由单独的进程完成,对于多源 JWK 的支持在这种场景下非常有用。

此功能进一步提高了 NGINX Plus 部署为 API 网关时的灵活性、安全性和性能。

自定义的 JWT 验证规则

当 NGINX Plus 部署为 API 网关时,通常会检查 JWT 声明,以实现细粒度的访问控制,但这同时也会导致配置变得复杂。在之前的 NGINX Plus 版本中,您可以使用 if 配置块来评估 JWT 声明,但这种方法具有一定的局限性,并且不适用于加密令牌。

NGINX Plus R25 提供了一种在 JWT 验证过程中对令牌执行额外检查的本地方法,从而解决了此限制。auth_jwt_require 指令为 JWT 验证过程添加了一个可选且可定制的步骤。它接受一个用空格分隔的字符串列表,当所有字符串都必须不为空且不等于 0(零),才能成功完成 JWT 验证。这大大提高了 JWT 验证过程的灵活性。

JWT 标准未规定哪些是强制性声明,因此您可以使用 auth_jwt_require 列出适用于每个环境的声明。

以下配置可确保 expsub 声明都显示在每个令牌中。

您可以使用 map 块 或 NGINX Plus 键值存储将布尔值传递给 auth_jwt_require 指令,从而配置更复杂的用例。您还可以使用 NGINX JavaScript 模块实施丰富的身份验证解决方案,例如双向 TLS (mTLS) 客户端证书绑定访问令牌(定义见 RFC 8705)。

以下配置可同时执行客户端证书身份验证 (mTLS) 和 JWT 验证。第 14 行的 auth_jwt_require 指令可调用待评估的 $thumbprint_match 指令,只有该指令包含一个非零值,才会成功完成 JWT 验证。该变量通过执行第 2 行调用的 JavaScript 函数来进行评估。

以下是前面片段第 2 行中调用的验证函数的代码:

更细粒度的 HTTP 响应代码报告

监控和可视化是应用实现出色性能、可用性和安全性的基石。HTTP 响应代码是洞察应用运行状态的最重要来源之一。NGINX Plus API 可跟踪支持 NGINX 和客户端交互以及 NGINX 和上游服务器交互的 HTTP 响应代码;响应代码的数量显示在 NGINX Plus 实时活动监控仪表盘 的相关选项卡上。

之前的 NGINX Plus API 版本按类别汇总 HTTP 响应代码(2xx4xx 等)的数量。当前的版本还支持对代码单独计数(200404503 等)。这可以帮助您更深入地了解应用的运行状态,区分不同原因引发的错误,例如身份验证失败的激增(403)和内容丢失(404)引起的错误。 有关收集配置指标的信息,请参阅 《NGINX Plus 管理员指南》

NGINX Plus API 最新版本(7)与 NGINX Plus R25一起发布,在响应对象中添加了一个代码对象,支持对各个 HTTP 响应代码单独计数。

新版本仍然提供汇总响应功能,之前的 NGINX Plus API 版本(不包含代码对象)仍然可以和 NGINX Plus R25 搭配使用。以下是一组新指标的示例:

$ curl -s http://localhost:8080/api/7/http/server_zones/www.example.com | jq{
  "processing": 31,
  "requests": 63192,
  "responses": {
    "1xx": 0,
    "2xx": 54368,
    "3xx": 8454,
    "4xx": 330,
    "5xx": 9,
    "codes": {
      "200": 54368,
      "302": 8454,
      "401": 30,
      "404": 200,
      "429": 100,
      "503": 9
    },
    "total": 63161
  },
  "discarded": 0,
  "received": 693436,
  "sent": 13843478
}

分配足够内存,以防启动失败

重要说明: 当NGINX Plus 配置为反向代理或负载均衡器时,对各个代码单独计数会增加每个上游组共享内存区的内存占用率。如果上游组中的节点超过 20 个,您可能需要利用 zone 指令进行配置以增加内存大小。

如果上游区域配置不足,则 NGINX Plus R25 无法启动,这将会导致升级失败。

以下是上游组共享内存区的典型配置:

B在升级到 NGINX Plus R25之前,检查现有上游区域的内存使用情况非常重要。为此,在使用下列任意方法之前,请确保已启用 NGINX Plus API

  • 查看实时活动监控仪表盘的 HTTP Upstreams 选项卡,在该示例(来自 demo.nginx.com)中,内存使用率为 54%:

  • 通过运行以下命令,直接从主机使用 NGINX Plus API。首先:

    • 安装 jq utility(如果需要)
    • api 指令启用的地址赋值给变量 API
    $ API=http://localhost:8080/api; for i in `curl -s $API/1/http/upstreams | jq -r '.[].zone | @uri'`; do echo -n $i; curl -s $API/1/slabs/$i | jq -r '.pages | 100*(.used / (.used + .free)) | " \(round)% used"'; done

如果当前的内存使用率超过 40%(如上方截图所示),则至少将 zone 指令的第二个(size)参数上调 2.5 倍。例如,我们建议在上面的配置片段中将 64k 增加到 160k

为代理连接动态加载 SSL/TLS 客户端证书

双向 TLS (mTLS) 是一种常见的身份验证方法,包含客户端和服务器身份验证。借助 NGINX Plus,您可以使用变量动态定义上游组中的服务器。这意味着您可能还需要能够动态选择 NGINX Plus 所使用的 TLS 证书,从而向上游服务器验证自己。

NGINX Plus R25 将用于 mTLS 的配置指令扩展到后端服务器,以接受代表证书的变量。变量可以指向以下任意一项:

  • 磁盘上的文件
  • 前缀为 data:的 PEM 格式的原始数据

NGINX Plus 将能够动态选择证书和私钥,这对于经常变化的现代应用环境而言非常有用。您可以将证书和私钥存储在 NGINX Plus 键值存储 中——由于私钥是存储在内存中而不是磁盘上,这样做可以增强安全性。另一个用例是自动证书轮换,您可以使用 API 调用来更新键值存储中的证书。

在以下配置中,NGINX Plus 根据主机名将请求路由到不同的上游组。系统使用 mTLS 建立代理连接,并为每个上游动态选择合适的客户端证书。

以下指令支持使用上游服务器为 mTLS 动态加载证书:

HTTP 请求处理安全性的强化

NGINX 理念的一大核心就是持续改进,尤其是在安全性方面。我们充分利用所有可用资源,包括与安全研究人员的合作,将 F5 行业领先的安全技术集成到我们的产品以及内部开发工作中。

作为这种改进的例子之一,NGINX Plus R25 对 HTTP 请求执行多项额外检查,以保护应用免受潜在攻击,例如请求夹带攻击。它将在以下情况下返回错误:

  • HTTP/1.0 请求中包含 Transfer-Encoding 标头
  • Transfer-EncodingContent-Length 标头同时出现
  • 请求行或任何标头名称中包含空格或控制字符
  • Host 标头中包含空格或控制字符
  • 使用了 CONNECT 方法

此外,在代理 URI 中,以下字符将一律转义:"<>\^`{|}

请注意,这些更改是主动实施的安全增强特性,并不是为了应对任何已知的漏洞。

在整个 TCP/UDP 应用重加载前后,保持健康检查的状态持久化

NGINX Plus 使用强制性健康检查来确保添加到上游组的新服务器经过测试并且运行良好,然后再将客户端请求代理到它们。在 NGINX Plus R23 及更早版本中,系统会认为重加载配置后的上游服务器是不健康的——无论它在重加载配置之前的状态如何。因此,在上游服务器通过重加载后的第一次强制性检查之前,NGINX Plus 不会向其发送请求。

NGINX Plus R24 允许您选择在重加载前后,将 HTTP 应用的强制性健康检查结果持久化。如果重加载前的最后一次强制性健康检查成功,重加载后 NGINX Plus 可立即向服务器发送请求,而不必等待新一轮强制性健康检查。

NGINX Plus R25 e该功能扩展到了 TCP/UDP 应用(在 stream 上下文中)。对于 HTTP,将 persistent 参数以及 mandatory 参数添加到 health_check 指令。

NGINX JavaScript 模块的增强

TNGINX JavaScript 模块 (njs) 已更新到版本 0.6.2,其中修复了几个漏洞,添加了一些增强功能,增强了与 JavaScript ES6 的兼容性。

包含 letconst 关键字的变量声明

之前的 NGINX Plus 版本和 njs 只支持使用 var 关键字来声明变量及为其赋值的,而 NGINX JavaScript 现在支持使用 let 和 const 关键字来声明范围变量。对于被限制在特定的 block 所声明的范围内的变量,这种声明的方式在以前是不适用的。但是不同的项目、编程语言和工程团队在共享代码库或库上开展协作所带来的复杂性,恰恰需要这样的功能。

JavaScript ES6 提供了 letconst 关键字来定义作用域变量:

  • let 变量被限制在使用它的 block 声明或表达式范围内。相反,var 关键字将全局或局部变量声明到整个函数,而不考虑块的作用域。
  • const 变量是块作用域,与使用 let 关键字声明的变量十分相似。常量的值不能通过重新赋值来改变,也不能重新声明。

支持所有 Promise 构造器方法

加上 Promise.all()Promise.allSettled()Promise.any()Promise.race() 构造器方法,njs 现在可支持 JavaScript ES6 标准中定义的全部构造函数方法。

升级或试用 NGINX Plus

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

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


"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."