NGINX Plus R25 正式发布

NGINX | 2021年9月28日

我们很高兴地宣布,NGINX Plus Release 25 (R25)现已发布。NGINX Plus基于NGINX Open Source构建,将软件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时所宣布的,第三方Cookie-Flag模块已弃用,并将在NGINX Plus R26中从动态模块存储库移除。该模块中定义的set_cookie_flag指令已由内置的proxy_cookie_flags指令取代。建议尽快将配置中的所有set_cookie_flag指令替换为proxy_cookie_flags指令。

平台支持变更

  • 新增支持的操作系统:
    • Debian 11(x86_64,aarch64)
    • Alpine 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在此功能基础上,进一步支持更多高级身份验证用例,有助于提高基于JWT的身份验证在签名(JWS)和加密(JWE)用例中的安全性。这些增强功能既能降低个人身份信息(PII)泄露的风险,又能提供更高的灵活性。NGINX Plus新增的JWT功能和增强功能包括:

解密后的JWE密文变量

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

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

NGINX Plus R25在初始JWE支持的基础上新增了变量$jwt_payload,使NGINX Plus能够解密JWE和密文,并在处理HTTP请求期间访问明文。这项新功能可用于实施高级访问控制策略和请求路由决策,还可将NGINX Plus部署为后端应用的JWE解密层。

支持嵌套JWT

JWE令牌可有效保护个人身份信息(PII)。即使数据经过CDN和其他终止TLS连接的代理,密文也能帮助保持其机密性。但加密是一把双刃剑,因为JWE可能会增加应用环境的复杂性。解决这一问题的一种方法是使用嵌套JWT。

嵌套JWT的结构

嵌套JWT将JWS作为JWE的密文嵌入其中。NGINX Plus R25通过同时支持JWS和JWE,使嵌套JWT可用于验证HTTP请求。NGINX Plus现在可在一次操作中解密JWE中的密文,将解密后的明文作为JWS进行验证,并使用所含令牌中的exp(过期时间)和nbf(生效时间)声明来验证该令牌是否有效。这样,只需将现有JWS环境封装在JWE中,即可通过有效负载加密对其进行升级。

以下配置片段说明了这一过程。nested 指令的新参数 auth_jwt_type 会指示NGINX Plus同时执行JWE解密和JWS验证。该参数还会影响JWT标头和JWT声明变量的求值方式:

正在加载代码示例…

采用以下配置后,NGINX Plus会构造额外的HTTP请求标头,并将其发送到后端应用。来自JWE标头的加密算法($jwt_header_enc变量)和来自JWS有效负载的JWT主题声明($jwt_claim_sub变量)会随原始请求一起转发。这意味着应用只需读取HTTP标头即可使用基于JWE的身份验证,无需实现加密代码或库。

正在加载代码示例…

对于采用零信任架构的用户,以下配置可让后端应用验证由$jwt_payload变量捕获的JWS令牌。该变量包含JWE密文解密后的明文。如果存在嵌套JWT,可将JWS作为不记名令牌传递给后端应用。

正在加载代码示例…

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

JWE 的非对称加密

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

NGINX Plus R25支持将采用最优非对称加密填充(OEAP)的RSA用作密钥管理算法,无需在NGINX Plus端进行显式配置。JWS alg(算法)标头支持的值包括RSA-OAEP、RSA-OAEP-256、RSA-OAEP-384和RSA-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_file和auth_jwt_key_request指令。NGINX Plus会从所有指定来源加载密钥,并在合并后的密钥集中查找匹配的验证密钥。这对于以下场景非常有用:JWS由外部身份提供商签发并嵌套在JWE中,而加密则由另一个进程完成。

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

自定义JWT验证规则

将NGINX Plus部署为API网关时,通常需要检查JWT声明,以实施精细的访问控制。这可能会导致配置复杂。在以前的NGINX Plus版本中,可以使用if配置块评估JWT声明,但这种方法存在一定局限性,并且不适用于加密令牌。

NGINX Plus R25提供了一种原生方式,可在JWT验证过程中对令牌执行额外检查,从而解决这一限制。auth_jwt_require指令在JWT验证过程中增加了一个可选的自定义步骤。该指令接受以空格分隔的字符串列表。要成功完成JWT验证,所有字符串都必须为非空值且不等于0(零)。这大幅提升了JWT验证过程的灵活性。

JWT标准未规定哪些声明为必填项,因此可以使用auth_jwt_require列出适用于各个环境的声明。

以下配置可确保每个令牌中都包含exp和sub声明。

正在加载代码示例…

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

以下配置同时执行客户端证书身份验证(mTLS)和JWT验证。第14行的auth_jwt_require指令要求对$thumbprint_match变量求值,并且仅当该变量的值非零时,JWT验证才会成功。该变量通过执行第2行调用的JavaScript函数进行求值。

正在加载代码示例…

以下是上一个代码片段第 2 行调用的validate函数的代码:

正在加载代码示例…

更精细的HTTP响应代码报告

监控和可观测性是保障应用性能、可用性和安全性的基石。HTTP响应代码是洞察应用运行状况的重要信息来源之一。NGINX Plus API会跟踪NGINX与客户端之间以及NGINX与上游服务器之间交互产生的HTTP响应代码;相关计数会显示在NGINX Plus实时活动监控仪表板的相应选项卡中。

以前版本的NGINX Plus API按类别汇总HTTP响应代码计数(2xx、4xx等)。现在还会分别统计各个代码(200、404、503等)。这样可以更深入地了解应用的具体运行状况,并区分原因截然不同的错误,例如身份验证失败次数激增(403)和内容缺失(404)。有关配置指标收集的信息,请参阅《NGINX Plus管理指南》。

随NGINX Plus R25发布的最新版NGINX Plus API(版本 7)在codes对象中新增了一个responses对象,用于统计各个HTTP响应代码。聚合响应仍然可用,不包含codes对象的旧版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将无法启动,导致升级失败。

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

正在加载代码示例…

升级到NGINX Plus R25之前,请务必检查现有上游区域的内存使用情况。为此,请确保在使用以下任一方法之前,已启用NGINX Plus API:

  • 查看实时活动监控仪表板的“HTTP 上游”选项卡,如以下来自“demo.nginx.com”的示例所示,其中利用率为 54%:
  • 运行以下命令,直接从主机使用NGINX Plus 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
  • 根据需要安装jq实用工具 if necessary
  • 将API变量设置为启用了api指令的位置

如果当前利用率超过40%(如截图所示),请将zone指令的第二个参数(大小)至少提高到原来的2.5倍。例如,建议在上述配置片段中将64k提高到160k。

动态加载用于代理的SSL/TLS客户端证书

双向TLS(mTLS)是一种常见的身份验证方式,用于验证客户端和服务器双方的身份。借助NGINX Plus,可以动态定义上游组中的服务器,也可以使用变量进行定义。这意味着,可能还需要动态选择NGINX Plus向这些上游服务器验证自身身份时使用的TLS证书。

NGINX Plus R25 扩展了用于与后端服务器建立 mTLS 连接的配置指令,使其可接受表示证书的变量。该变量可引用以下任一项:

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

这样,NGINX Plus便可动态选择证书和私钥,适用于不断变化的现代应用环境。您可以将证书和私钥存储在NGINX Plus键值存储中,由于私钥存储在内存而非磁盘中,因此有助于增强安全性。另一种用例是自动轮换证书,即通过API调用更新键值存储中的证书。

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

正在加载代码示例…

以下指令支持为与上游服务器之间的mTLS动态加载证书:

强化HTTP请求处理安全性

持续改进是NGINX理念的核心原则之一,尤其是在安全方面。我们充分利用各种可用资源,包括与安全研究人员合作、将F5先进的安全技术集成到产品中,以及开展内部研发。

以内部开发工作为例,NGINX Plus R25会对HTTP请求执行多项额外检查,帮助保护应用免受潜在攻击,例如请求走私。遇到以下情况时,它会返回错误:

  • HTTP/1.0请求包含Transfer-Encoding标头
  • 同时存在“Transfer-Encoding”和“Content-Length”标头
  • 请求行或任何标头名称中包含空格或控制字符
  • 以下内容中存在空格或控制字符:Host标头
  • 使用了CONNECT方法

此外,代理URI中的以下字符现在始终会被转义:",<,>,\,^,`,{,|,}。

请注意,这些变更属于主动实施的安全增强措施,并非为应对任何已知漏洞。

重新加载TCP/UDP应用时保留强制健康检查状态

NGINX Plus使用强制健康检查,确保新添加到上游组的服务器经过测试且运行状况正常后,再将客户端请求代理到这些服务器。在NGINX Plus R23及更早版本中,无论上游服务器在配置重新加载前的状态如何,重新加载后都会被视为运行状况异常。因此,在首次强制检查通过之前,NGINX Plus不会向服务器发送请求。

对于HTTP应用,NGINX Plus R24引入了可选功能,可在重新加载配置后保留强制健康检查状态。如果重新加载配置前的最后一次强制健康检查成功,NGINX Plus可以立即向服务器发送请求,而无需等待重新加载配置后的强制健康检查成功。

NGINX Plus R25将此功能扩展到TCP/UDP应用(在stream上下文中)。与HTTP应用一样,请在health_check指令中同时添加mandatory参数和persistent参数。

正在加载代码示例…

NGINX JavaScript 模块增强功能

NGINX JavaScript模块(njs)已更新至0.6.2版,其中包含多项错误修复和部分功能增强,进一步提升了与JavaScript ES6的兼容性。

使用let和const关键字声明变量

NGINX JavaScript现在支持使用let和const关键字声明具有作用域的变量。旧版NGINX Plus和njs仅支持使用var关键字声明变量并为其赋值,无法将变量限制在特定block语句的作用域内。当不同项目、编程语言和工程团队协作开发共享代码库或库时,往往会产生复杂问题,而这类变量正是应对这些问题所必需的。

JavaScript ES6提供了let和const关键字,用于定义作用域变量:

  • 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在您需要提交支持工单时提供帮助。

如果您尚未体验过NGINX Plus,建议立即试用。它可用于安全防护、负载均衡和API网关,也可作为提供全面支持的Web服务器,并配备增强的监控和管理API。立即开始30天免费试用。


分享

关于作者

相关博客文章

NGINX Plus R26 正式发布
NGINX | 2022/02/15

NGINX Plus R26 正式发布

NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
NGINX | 2022/02/10

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击

gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
NGINX | 2021/09/13

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划

了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。

NGINX Plus R19 正式发布
NGINX | 2019/09/03

NGINX Plus R19 正式发布

NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。

NGINX现已正式加入F5
NGINX | 2019/05/09

NGINX现已正式加入F5

NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。

使用NGINX和NGINX Plus实现高性能缓存
NGINX | 2016/08/24

使用NGINX和NGINX Plus实现高性能缓存

我将介绍NGINX在内容缓存和性能方面的工作原理,并分享一些控制NGINX内容缓存方式的技巧。