我们很高兴地宣布NGINX Plus Release 25 (R25)已经推出。 NGINX Plus 基于 NGINX 开源,是唯一集Web 服务器、负载均衡器、反向代理、内容缓存和 API 网关于一体的软件。
NGINX Plus R25的新功能包括:
如在更细粒度的 HTTP 响应代码报告中详细描述的那样, NGINX Plus R25提供了单个状态代码的计数以及每个类的聚合计数。 当 NGINX Plus 配置为反向代理或负载均衡器时,如果有超过 20 个对等点,则可能需要增加用于监控上游“对等点”(后端服务器)的共享内存区域的大小。
如果共享内存区域配置不足, NGINX Plus R25将无法启动,从而导致升级失败。 升级之前,检查每个上游区域的内存利用率非常重要。 有关检查和调整内存分配的说明,请参阅分配足够的内存以防止启动失败。
在NGINX Plus R24发布时,所有 NGINX 软件的软件包存储库都进行了重新组织,从而改变了 NGINX Plus 的安装过程。
当您安装或升级 NGINX Plus 时,操作系统的包管理器( apt
、 yum
或同等软件)会配置 NGINX Plus 的软件存储库。 在配置为使用旧 repo 的现有系统(运行NGINX Plus R23或更早版本的系统)上,您需要更新包管理器以引用新的 repo。 请参阅F5 知识库中的说明。
如果要执行NGINX Plus R25的初始安装,请参阅NGINX Plus 管理指南中的安装 NGINX Plus 。
笔记: 您必须使用新的软件存储库。 旧的 repo 将不再更新,并且可能会导致未来的安装和升级出现错误。
正如NGINX Plus R23发布时宣布的那样,第三方 Cookie‑Flag 模块已被弃用,并将从NGINX Plus R26中的动态模块库中删除。 该模块中定义的set_cookie_flag
指令被内置的proxy_cookie_flags
指令取代。 我们建议您尽快用proxy_cookie_flags
指令替换配置中的所有set_cookie_flag
指令。
NGINX Plus R24引入了对加密 JSON Web Tokens (JWE) 的初始支持,通过数据保密性扩展了最流行的客户端身份验证方法之一。 NGINX Plus R25在该功能的基础上,引入了对更多更高级的身份验证用例的支持,有助于提高基于 JWT 的身份验证在签名(JWS)和加密(JWE)用例中的安全性。 这些增强功能既降低了泄露个人身份信息(PII)的风险,又提供了更大的灵活性。 NGINX Plus 的新 JWT 功能和增强功能包括:
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 解密层。
JWE 令牌可以有效保护 PII,其密文甚至可以跨 CDN 和其他 TLS 终止代理来保护机密性。 但加密是一把双刃剑,因为 JWE 会给应用环境带来复杂性。 解决此问题的一种方法是使用嵌套 JWT。
嵌套的 JWT 将 JWS 嵌入为 JWE 的密文。 NGINX Plus R25通过同时支持 JWS 和 JWE,使嵌套 JWT 成为验证 HTTP 请求的一种方法。 在一次操作中,NGINX Plus 现在可以解密 JWE 中的密文,将生成的纯文本验证为 JWS,并使用所附令牌中的exp
(到期时间)和nbf
(不早于)声明来验证它是否有效。 这使得现有的 JWS 环境能够通过将它包装在 JWE 中来升级为使用有效负载加密。
以下配置片段说明了该过程。 auth_jwt_type
指令的新嵌套
参数告诉 NGINX Plus 执行 JWE 解密和 JWS 验证。 它还会影响 JWT 标头和 JWT 声明的变量的评估方式:
auth_jwt_header_set
指令对外部 JWE 标头进行操作。auth_jwt_claim_set
指令对嵌套的 JWS 声明进行操作。$jwt_header_ name
变量包含外部 JWE 标头属性。$jwt_claim_ name
变量包含嵌套的 JWS 声明。
通过以下配置,NGINX Plus 构建并发送额外的 HTTP 请求标头到后端应用。 JWE 标头中的加密算法( $jwt_header_enc
变量)和 JWS 有效负载中的 JWT 主题声明( $jwt_claim_sub
变量)与原始请求一起代理。 这意味着应用只需使用 HTTP 标头即可利用基于 JWE 的身份验证,而无需实现加密代码或库。
对于在零信任架构中操作的用户,以下配置允许后端应用验证$jwt_payload
变量中捕获的 JWS 令牌。 该变量包含 JWE 密文的解密明文版本。 如果有嵌套的 JWT,则可以将 JWS 作为承载令牌传递给后端应用。
本质上,嵌套的 JWT 通过使 NGINX Plus 能够同时解密和验证安全令牌来简化操作并提高应用的安全性,同时为后端应用解析或代理“常规 JWT”签名的令牌。
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
指令)。
利用嵌套的 JWT 意味着相关的 JWK 可能来自多个来源。 NGINX Plus R25在同一上下文中支持多个auth_jwt_key_file
和auth_jwt_key_request
指令。 NGINX Plus 从所有指定的来源加载密钥,并在组合密钥集中查找匹配的验证密钥 - 在使用由外部身份提供者颁发并嵌套在 JWE 中的 JWS 时非常有用,其中加密由单独的过程完成。
此功能为作为 API 网关部署的 NGINX Plus 增加了进一步的灵活性、安全性和功能。
当 NGINX Plus 部署为 API 网关时,通常会检查 JWT 声明以实现细粒度的访问控制。 这可能会导致复杂的配置。 在以前的 NGINX Plus 版本中,您可以使用if
配置块来评估 JWT 声明,但这种方法有些有限,并且不适用于加密令牌。
NGINX Plus R25通过提供在 JWT 验证过程中对令牌执行额外检查的本机方法解决了这一限制。 auth_jwt_require
指令在 JWT 验证过程中添加了一个可选的、可定制的步骤。 它接受一个空格分隔的字符串列表,所有字符串必须非空且不等于0
(零)表示 JWT 验证成功。 这为 JWT 验证过程增加了巨大的灵活性。
JWT 标准没有规定哪些声明是强制性的,因此您可以使用auth_jwt_require
列出每个环境的适当声明。
以下配置确保每个令牌中都存在exp
和sub
声明。
您可以使用映射
块或 NGINX Plus 键值存储将布尔值传递给auth_jwt_require
指令来配置更复杂的用例。 您还可以使用 NGINX JavaScript 模块来实现丰富的身份验证解决方案,例如相互 TLS (mTLS) 客户端证书绑定访问令牌(在RFC 8705中定义)。
以下配置执行客户端证书认证(mTLS)和 JWT 验证。 第 14 行的auth_jwt_require
指令要求评估$thumbprint_match
变量,只有当其具有非零值时,JWT 验证才会成功。 通过执行第 2 行调用的 JavaScript 函数来评估此变量。
以下是上一个代码片段第 2 行调用的验证
函数的代码:
监控和可见性是应用性能、可用性和安全性的基石。 HTTP 响应代码是了解应用健康状况的最重要来源之一。 NGINX Plus API跟踪 NGINX 与客户端之间以及 NGINX 与上游服务器之间的交互的 HTTP 响应代码;计数报告在 NGINX Plus实时活动监控仪表板的相关选项卡上。
以前版本的NGINX Plus API按类别 ( 2xx
、 4xx
等等 ) 聚合 HTTP 响应代码计数。 现在代码也单独计算( 200
,404
,503
, ETC。)。 这可让您更深入地了解应用到底发生了什么,区分不同原因导致的错误,例如身份验证失败次数激增(403
)和缺失内容(404
)。 有关配置指标收集的信息,请参阅NGINX Plus 管理指南。
随NGINX Plus R25发布的最新版本的 NGINX Plus API (版本 7 )在responses
对象中包含一个codes
对象,以便对单个 HTTP 响应代码进行计数。 聚合响应仍然可用,并且NGINX Plus API的早期版本(不包含代码
对象)仍然可以与NGINX Plus R25一起使用。 以下是一组新指标的示例:
$ curl -s http://localhost:8080/api/7/http/server_zones/www.example.com | jq { “处理”: 31、“请求”: 63192,"响应":{"1xx": 0,“2xx”: 54368, "3xx": 8454, "4xx": 330, "5xx": 9,“代码”:{“200”: 54368, "302": 8454, "401": 30,“404”: 200, "429": 100,“503”: 9 }, “总计”: 63161 }, “丢弃”: 0,“已收到”: 693436,“已发送”: 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; 对于 i 在 `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"'; 完成
如果当前利用率高于 40%(如屏幕截图所示),则将区域
指令的第二个(大小)参数至少增加 2.5 倍。 例如,我们建议在上面的配置片段中将64k
增加到160k
。
相互 TLS (mTLS) 是一种常见的身份验证实践,涉及验证客户端和服务器的身份。 使用 NGINX Plus,您可以动态地并使用变量定义上游组中的服务器。 这意味着您可能还需要能够动态选择 NGINX Plus 使用的 TLS 证书来向那些上游服务器验证自己。
NGINX Plus R25将用于 mTLS 的配置指令扩展至后端服务器,以接受代表证书的变量。 该变量可以引用以下任一项:
数据为前缀:
这使得 NGINX Plus 能够动态选择证书和私钥——这对于不断变化的现代应用环境很有用。 您可以将证书和私钥存储在NGINX Plus 键值存储中,这样可以增强安全性,因为私钥存储在内存中而不是磁盘上。 另一个用例是自动证书轮换,您可以使用 API 调用来更新键值存储中的证书。
在以下配置中,NGINX Plus 根据主机名将请求路由到不同的上游组。 代理连接使用 mTLS 建立,并动态选择每个上游的适当客户端证书。
以下指令支持使用上游服务器的 mTLS 动态证书加载:
grpc_ssl_证书
grpc_ssl_certificate_key
proxy_ssl_certificate
代理服务器证书密钥
uwsgi_ssl_certificate
uwsgi_ssl_certificate_key
NGINX 哲学的核心原则之一是持续改进,尤其是在安全性方面。 我们利用所有可用资源,包括与安全研究人员的合作、将 F5 业界领先的安全技术集成到我们的产品中以及内部开发努力。
作为最后一个例子, NGINX Plus R25对 HTTP 请求执行了几项额外检查,以保护您的应用免受潜在攻击,例如请求走私。 对于以下情况,它会返回错误:
Transfer-Encoding
标头Transfer-Encoding
和Content-Length
标头均存在Host
标头中有空格或控制字符CONNECT
方法此外,以下字符现在在代理 URI 中始终会被转义: “
、 <
、 >
、 \
、 ^
、 `
、 {
、 |
、 }
。
请注意,这些更改是主动的安全增强措施,并不是为了应对任何已知漏洞而做出的。
NGINX Plus 使用强制健康检查来确保在客户端请求代理到上游组之前,对新服务器进行测试并保证其健康。 在NGINX Plus R23及更早版本中,无论上游服务器在重新加载配置之前的状态如何,它们都会被视为不健康。 因此,NGINX Plus 直到第一次强制检查通过后才向服务器发送请求。
NGINX Plus R24为 HTTP应用引入了在重新加载时可选的强制健康检查状态持久性。 如果重新加载之前的最后一次强制健康检查成功,NGINX Plus 可以立即向服务器发送请求,而不必等待重新加载后的强制健康检查成功。
NGINX Plus R25将此功能扩展到 TCP/UDP应用(在流
上下文内)。 对于 HTTP,将持久
参数与强制
参数一起添加到health_check
指令中。
NGINX JavaScript 模块(njs)已更新至 0.6.2 版本,修复了几个错误并增强了一些功能,增强了与JavaScript ES6 的兼容性。
let
和const
关键字声明变量NGINX JavaScript 现在支持使用let
和const
关键字声明范围变量。 NGINX Plus 和 njs 的早期版本仅支持使用var
关键字来声明和分配变量。 这并没有提供仅限于特定块
语句范围的变量,这些变量是处理不同项目、编程语言和工程团队在共享代码库或库上进行协作时经常出现的复杂性所必需的。
JavaScript ES6 提供了let
和const
关键字来定义作用域变量:
let
变量仅限于使用它的块
语句或表达式的范围。 相比之下, var
关键字声明一个全局变量,或者声明一个整个函数的本地变量,而不管块范围如何。const
变量具有块作用域,与使用let
关键字声明的变量非常相似。 常量的值不能通过重新赋值来改变,也不能重新声明。Promise
构造函数方法随着Promise.all()
、 Promise.allSettled()
、 Promise.any()
和Promise.race()
构造函数方法的添加,njs 现在支持 JavaScript ES6 标准中定义的完整构造函数方法集。
如果您正在运行 NGINX Plus,我们强烈建议您尽快升级到NGINX Plus R25 。 您还将获得一些额外的修复和改进,当您需要提出支持单时,它将帮助 NGINX 为您提供帮助。
如果您还没有尝试过 NGINX Plus,我们鼓励您尝试一下 – 为了安全、负载均衡和 API 网关,或者作为具有增强监控和管理 API 的完全支持的 Web 服务器。 您今天就可以开始享受30 天免费试用。
“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”