NGINXPlus基于NGINXOpenSource,是唯一一款集软件Web服务器、负载均衡器、反向代理、内容缓存和API网关为一体的软件。
NGINXPlusR25的新特性包括:
- 另外,更先进的JSON网络令牌使用情况 -NGINX加上R25基础上在推出加密JSON网络令牌(JWE)的支持NGINX加R24。
- 的HTTP响应代码更详细的报告 -该NGINX加上API现在共有HTTP响应代码单独以及通过类合计。您可能需要增加内存分配;请参阅分配足够的内存以防止启动失败。
- 代理连接的动态SSL/TLS客户端证书加载 -您可以使用变量为NGINXPlus和后端服务器之间的mTLS连接动态选择证书。
- HTTP请求处理的强化安全性 ——NGINXPlus对HTTP请求执行多项额外检查,以保护您的应用程序免受潜在攻击。
- 跨TCP/UDP应用程序重新加载的健康检查状态持久性 –针对TCP/UDP服务器的强制性健康检查的结果现在可以跨配置重新加载持久化。
- 对NGINXJavaScript模块的增强 -增强了与JavaScriptES6的兼容性。
行为的重要变化
上游区域的内存需求增加
如HTTP响应代码的更多粒度报告中详细描述的,NGINXPlusR25提供单个状态代码的计数以及每个类的聚合计数。当NGINXPlus配置为反向代理或负载均衡器时,如果有超过20个对等点,您可能需要增加用于监控上游“对等点”(后端服务器)的共享内存区域的大小。
如果共享内存区域配置不足,NGINXPlusR25不会启动,从而导致升级失败。在升级之前,检查每个上游区域的内存使用情况很重要。有关检查和调整内存分配的说明,请参阅分配足够的内存以防止启动失败。
对NGINXPlus存储库组织和安装程序的更改
在NGINXPlusR24发布时,所有NGINX软件的软件包存储库都进行了重组,导致NGINXPlus安装过程发生了变化。
当您安装或升级NGINX另外,操作系统的包管理器(apt,yum或等同)配置与软件存储库NGINX加。在配置为使用旧存储库(运行NGINXPlusR23或更早版本的系统)的现有系统上,您需要更新包管理器以引用新存储库。请参阅F5知识库中的说明。
如果执行NGINXPlusR25的初始安装,请参阅NGINXPlus管理指南中的安装NGINXPlus。
注意:您必须使用新的软件存储库。旧的repo将不再更新,并且可能会导致未来安装和升级的错误。
弃用的Cookie标志模块
正如NGINXPlusR23发布时所宣布的,第三方Cookie‑Flag模块已被弃用,并将从NGINXPlusR26中的动态模块存储库中删除。该set_cookie_flag模块中定义的指令被内置proxy_cookie_flags指令替换。建议您尽快set_cookie_flag用proxy_cookie_flags指令替换配置中的任何指令。
平台支持的变化
- 支持的新操作系统:
- Debian11(x86_64,aarch64)
- AlpineLinux3.14(x86_64,aarch64)
- 删除了旧操作系统:
- 阿尔卑斯Linux3.10;最早支持的版本是3.11
- 亚马逊Linux1(2018.03+);切换到AmazonLinux2LTS
- FreeBSD11.4+;支持的最早版本是12.1+
- Ubuntu16.04LTS;最早支持的版本是18.04LTS
- 较旧的操作系统已弃用并计划在NGINXPlusR26中删除:
- 高山Linux3.11
详细的新功能
其他JSONWeb令牌用例和功能
NGINXPlusR24引入了对加密JSONWeb令牌(JWE)的初始支持,扩展了最流行的客户端身份验证方法之一,具有数据机密性。NGINXPlusR25建立在该功能的基础上,并引入了对其他和更高级的身份验证用例的支持,这些用例有助于提高签名(JWS)和加密(JWE)用例的基于JWT的身份验证的安全性。这些增强功能既降低了泄露个人身份信息(PII)的风险,又提供了更大的灵活性。NGINXPlus的新JWT功能和增强功能包括:
- 解密JWE密文的新变量
- 支持嵌套的JWT
- JWE的非对称加密
- 多源JSONWebKey支持
- 其他自定义JWT验证规则
解密JWE密文的变量
JWT是一种广泛使用且值得信赖的HTTP请求无状态身份验证方法(即基于令牌的身份验证)。通过在令牌负载中传输最终用户属性,JWT有助于使请求更加安全。然而,安全研究人员和DevSecOps从业者一致认为,在Web客户端上存储未加密的PII带来的风险是一个紧迫的问题——因此开发了JSONWeb加密标准(RFC7516),该标准为实施加密令牌提供了指导方针。
NGINXPlusR24引入了对JWE的支持,为整个声明集提供数据完整性和机密性。在加密令牌中编码PII可以大大降低使用JWT时数据泄露的风险。
NGINXPlusR25在最初的JWE支持基础上增加了一个新变量,$jwt_payload使NGINXPlus能够解密JWE和密文,然后在处理HTTP请求期间访问明文。这一新功能可用于实施高级访问控制策略和请求路由决策,以及使用户能够将NGINXPlus部署为后端应用程序的JWE解密层。
支持嵌套JWT
JWE令牌可有效保护PII,即使在CDN和其他TLS终止代理之间,密文也可用于保护机密性。但加密是一把双刃剑,因为JWE可能会给应用程序环境带来复杂性。解决此问题的一种方法是使用嵌套的JWT。
嵌套JWT将JWS嵌入为JWE的密文。NGINXPlusR25通过同时支持JWS和JWE来启用嵌套JWT作为验证HTTP请求的方法。在一次操作中,NGINXPlus现在可以解密JWE中的密文,将生成的明文验证为JWS,并使用封闭令牌中的exp(到期时间)和nbf(不是之前)声明来验证它是否有效。这使得现有的JWS环境能够通过将其包装在JWE中来使用有效载荷加密进行升级。
以下配置片段说明了该过程。该指令的新nested参数auth_jwt_type告诉NGINXPlus执行JWE解密和JWS验证。它还影响JWT标头和JWT声明变量的评估方式:
- 该auth_jwt_header_set指令对外部JWE标头进行操作。
- 该auth_jwt_claim_set指令对嵌套的JWS声明进行操作。
- $jwt_header_name变量包含外部JWE标头属性。
- $jwt_claim_name变量包含嵌套的JWS声明。
Failedloadinggisthttps://gist.github.com/9d8b15a48a382b77a44f2c35bc583ce6.json:timeout
通过以下配置,NGINXPlus构造并向后端应用程序发送额外的HTTP请求标头。来自JWE标头($jwt_header_enc变量)的加密算法和来自JWS有效负载($jwt_claim_sub变量)的JWT主题声明与原始请求一起代理。这意味着应用程序可以通过使用HTTP标头来利用基于JWE的身份验证,而无需实现加密代码或库。
Failedloadinggisthttps://gist.github.com/9d8b15a48a382b77a44f2c35bc583ce6.json:timeout
对于在零信任架构中操作的用户,以下配置使后端应用程序能够验证$jwt_payload变量中捕获的JWS令牌。该变量包含JWE密文的解密明文版本。如果存在嵌套的JWT,则JWS可以作为不记名令牌传递给后端应用程序。
Failedloadinggisthttps://gist.github.com/9d8b15a48a382b77a44f2c35bc583ce6.json:timeout
从本质上讲,嵌套JWT通过使NGINXPlus能够同时解密和验证安全令牌来简化操作并提高应用程序安全性,同时为后端应用程序解析或代理“常规JWT”签名令牌。
JWE的非对称加密NGINXPlusR24引入了对使用AES标准的令牌对称加密的支持。NGINXPlusR25在使用RSA密钥对时增加了对非对称加密的支持。非对称加密使用不同的密钥(公共和私有)进行加密和解密,这些密钥通过RSA(Rivest–Shamir–Adleman)算法在数学上相互关联,与客户端和服务器之间的HTTPS流量的SSL/TLS加密所使用的机制相同。
NGINXPlusR25支持带有最佳非对称加密填充(OEAP)的RSA作为密钥管理算法,无需在NGINXPlus端进行显式配置。对于JWS支持的值alg(算法)头是RSA-OAEP,RSA-OAEP-256,RSA-OAEP-384,和RSA-OAEP-512。
以下配置显示了为JWE实现非对称加密所需的全部内容是指定包含RSA私有(解包)密钥的JSONWeb密钥(JWK)文件作为auth_jwt_key_file指令的参数(auth_jwt_key_request也可以使用该指令)。
Failedloadinggisthttps://gist.github.com/9d8b15a48a382b77a44f2c35bc583ce6.json:timeout
多源JWK支持利用嵌套的JWT意味着关联的JWK可能来自多个来源。NGINX加上R25支持多重auth_jwt_key_file和auth_jwt_key_request指令在同一语境。NGINXPlus从所有指定来源加载密钥,并在组合的密钥集中查找匹配的验证密钥——在使用由外部身份提供者发布并嵌套在JWE中的JWS时非常有用,其中加密由一个单独的过程。
此功能为部署为API网关的NGINXPlus增加了进一步的灵活性、安全性和功能。
自定义JWT验证规则当NGINXPlus部署为API网关时,通常会检查JWT声明以实现细粒度的访问控制。这会导致复杂的配置。在以前的NGINXPlus版本中,您可以使用if配置块来评估JWT声明,但这种方法有些限制,并且不适用于加密令牌。
NGINXPlusR25通过提供一种在JWT验证过程中对令牌执行额外检查的本机方式来解决此限制。该auth_jwt_require指令在JWT验证过程中添加了一个可选的、可定制的步骤。它接受一个以空格分隔的字符串列表,所有字符串都必须非空且不等于0(零)才能使JWT验证成功。这为JWT验证过程增加了巨大的灵活性。
JWT标准没有规定哪些声明是强制性的,因此您可以使用auth_jwt_require列出每个环境的适当声明。
以下配置确保每个令牌中都存在exp和sub声明。
Failedloadinggisthttps://gist.github.com/9d8b15a48a382b77a44f2c35bc583ce6.json:timeout
您可以通过使用map块或NGINXPlus键值存储将布尔值传递给auth_jwt_require指令来配置更复杂的用例。您还可以使用NGINXJavaScript模块来实现丰富的身份验证解决方案,例如双向TLS(mTLS)客户端证书绑定访问令牌(在RFC8705中定义)。
以下配置执行客户端证书身份验证(mTLS)和JWT验证。第auth_jwt_require14行的指令要求对$thumbprint_match变量求值,并且JWT验证只有在它具有非零值时才能成功。这个变量是通过执行第2行调用的JavaScript函数来计算的。
Failedloadinggisthttps://gist.github.com/9d8b15a48a382b77a44f2c35bc583ce6.json:timeout
下面是在validate上一个片段的第2行调用的函数的代码:
Failedloadinggisthttps://gist.github.com/9d8b15a48a382b77a44f2c35bc583ce6.json:timeout
更精细的HTTP响应代码报告监控和可见性是应用程序性能、可用性和安全性的基石。HTTP响应代码是洞察应用程序健康状况的最重要来源之一。所述NGINX加API轨道HTTP响应代码既为NGINX和客户端之间,和NGINX和上游服务器之间的相互作用;计数报告在NGINXPlus实时活动监控仪表板的相关选项卡上。
先前版本的NGINX加API的类合计HTTP响应代码计数(2xx,4xx,等)。现在码也单独地计数(200,404,503,等等)。这让您可以更深入地了解应用程序究竟发生了什么——区分原因非常不同的错误,例如身份验证失败的峰值(403)和丢失的内容(404)。有关配置指标收集的信息,请参阅NGINXPlus管理指南。
与NGINXPlusR25一起发布的最新版NGINXPlusAPI(第7版)在对象中包含一个对象,以启用对单个HTTP响应代码的计数。聚合响应仍然可用,并且NGINXPlusAPI的早期版本( 不包括对象)仍然可以与NGINXPlusR25一起使用。以下是一组新指标的示例:codesresponsescodes
$curl-shttp://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 }分配足够的内存以防止启动失败
重要提示:当NGINXPlus被配置为反向代理或负载均衡器时,单个代码的计数会增加每个上游组共享内存区域的内存利用率。如果上游组中有20个以上的对等点,您可能需要增加内存大小,如使用zone指令配置。
如果上游区域配置不足,NGINXPlusR25不会启动,从而导致升级失败。
这是上游组的共享内存区域的典型配置:
Failedloadinggisthttps://gist.github.com/9d8b15a48a382b77a44f2c35bc583ce6.json:timeout
在升级到NGINXPlusR25之前,检查现有上游区域的内存利用率非常重要。为此,请确保在使用以下方法之一之前启用NGINXPlusAPI:
-
检查实时活动监控仪表板的HTTPUpstreams选项卡,如demo.nginx.com中的示例,其中利用率为54%:
-
通过运行以下命令,直接从主机使用NGINXPlusAPI。第一的:
- 必要时安装该jq实用程序
- 将API变量设置api为启用指令的位置
$API=http://localhost:8080/api;foriin`curl-s$API/1/http/upstreams|jq-r'.[].zone|@uri'`;doecho-n$i;curl-s$API/1/slabs/$i|jq-r'.pages|100*(.used/(.used+.free))|"(round)%used"';done
如果当前利用率高于40%(如屏幕截图所示),则将zone指令的第二个(大小)参数至少增加2.5倍。例如,建议增加 64k以 160k在配置片段以上。
用于代理的动态SSL/TLS客户端证书加载
相互TLS(mTLS)是一种常见的身份验证实践,涉及验证客户端和服务器的身份。使用NGINXPlus,您可以使用变量动态定义上游组中的服务器。这意味着您可能还需要能够动态选择NGINXPlus使用的TLS证书来向这些上游服务器验证自身。
NGINXPlusR25将用于mTLS的配置指令扩展到后端服务器,以接受代表证书的变量。变量可以指以下任何一个:
- 磁盘上的文件
- PEM格式的原始数据,前缀为data:
这使NGINXPlus能够动态选择证书和私钥——这对于经常变化的现代应用程序环境非常有用。您可以将证书和私钥存储在NGINXPlus键值存储中,这增强了安全性,因为私钥存储在内存中而不是磁盘上。另一个用例是自动证书轮换,您可以使用API调用来更新键值存储中的证书。
在以下配置中,NGINXPlus根据主机名将请求路由到不同的上游组。代理连接是使用mTLS建立的,并为每个上游动态选择适当的客户端证书。
Failedloadinggisthttps://gist.github.com/9d8b15a48a382b77a44f2c35bc583ce6.json:timeout
以下指令支持使用上游服务器为mTLS动态加载证书:
- grpc_ssl_certificate
- grpc_ssl_certificate_key
- proxy_ssl_certificate
- proxy_ssl_certificate_key
- uwsgi_ssl_certificate
- uwsgi_ssl_certificate_key
HTTP请求处理的强化安全性
NGINX哲学的核心原则之一是持续改进,尤其是在安全方面。使用所有可用资源,包括与安全研究人员的合作、将F5行业领先的安全技术集成到的产品中以及内部开发工作。
作为最后一个示例,NGINXPlusR25对HTTP请求执行多项额外检查,以保护您的应用程序免受潜在攻击,例如请求走私。它在以下情况下返回错误:
- HTTP/1.0请求包含Transfer-Encoding标头
- 的Transfer-Encoding和Content-Length标头两者都存在
- 请求行或任何头名称中有空格或控制字符
- Host标题中有空格或控制字符
- 该CONNECT方法用于
此外,以下字符现在总是在代理URI中转义:",<,>,,^,`,{,|,}。
请注意,这些更改是主动安全增强,并非针对任何已知漏洞而进行的。
TCP/UDP应用程序重新加载时强制健康检查状态的持久性
NGINXPlus使用强制健康检查来确保添加到上游组的新服务器在客户端请求被代理到它们之前经过测试并且健康。在NGINXPlusR23及更早版本中,无论重新加载前的状态如何,上游服务器在配置重新加载后都被认为是不健康的。因此,NGINXPlus在第一次强制检查通过之前不会向服务器发送请求。
NGINXPlusR24为HTTP应用程序引入了跨重新加载的强制性健康检查状态的可选持久性。如果重新加载前的最后一次强制健康检查成功,NGINXPlus可以立即向服务器发送请求,而不必等待重新加载后强制健康检查成功。
NGINXPlusR25将此功能扩展到TCP/UDP应用程序(在stream上下文中)。对于HTTP,将persistent参数health_check与mandatory参数一起添加到指令中。
Failedloadinggisthttps://gist.github.com/9d8b15a48a382b77a44f2c35bc583ce6.json:timeout
对NGINXJavaScript模块的增强
NGINXJavaScript模块(njs)已更新至0.6.2版,其中包含多个错误修复和一些增强与JavaScriptES6兼容性的功能增强。
带有let和const关键字的变量声明
NGINXJavaScript现在支持使用let和const关键字声明作用域变量。以前版本的NGINXPlus和njs仅支持var用于声明和分配变量的关键字。这并没有提供仅限于特定block语句范围的变量,当不同的项目、编程语言和工程团队在共享代码库或库上进行协作时,通常需要这些变量来处理复杂性。
JavaScriptES6提供了let和const关键字来定义作用域变量:
- let变量仅限于block使用它的语句或表达式的范围。相比之下,var关键字在全局范围内或在整个函数的局部范围内声明一个变量,而不管块的作用域如何。
- const变量是块范围的,很像使用let关键字声明的变量。常量的值不能通过重新赋值来改变,也不能重新声明。
支持所有Promise构造方法
由于增加的Promise.all(),Promise.allSettled(),Promise.any(),和Promise.race()构造方法,NJS现在支持一整套在JavaScriptES6标准中定义构造函数方法。
升级或试用NGINXPlus
如果您正在运行NGINXPlus,强烈建议您尽快升级到NGINXPlusR25。您还将获得一些额外的修复和改进,这将有助于NGINX在您需要提出支持请求时为您提供帮助。
如果您还没有尝试过NGINXPlus,鼓励您尝试一下——用于安全性、负载平衡和API网关,或者作为具有增强监控和管理API的完全支持的Web服务器。您可以立即开始免费试用30天。