我们很高兴地宣布,NGINX Plus Release 29(R29)现已发布。NGINX Plus基于NGINX Open Source,将软件Web服务器、负载均衡器、反向代理、内容缓存和API网关功能集于一体。
NGINX Plus R29新增和增强的功能包括:
- 支持MQTT协议:消息队列遥测传输(MQTT)是一种轻量级协议,用于物联网(IoT)设备之间的通信。NGINX Plus R29通过Preread和Filter模块支持MQTT协议。这些模块引入了多项新指令和变量,有助于管理和保护MQTT流量。
- 支持使用SAML进行身份验证和授权,安全断言标记语言(SAML)是一种成熟的协议,可为Web应用提供单点登录(SSO)。现在可将NGINX Plus配置为SAML服务提供商(SP),通过SAML身份提供商(IdP)对用户进行身份验证。
- 原生OpenTelemetry。OpenTelemetry(OTel)是一个框架,能够以不依赖特定供应商的方式生成、收集和导出来自远程源的遥测数据(跟踪、指标和日志)。新的NGINX OTel动态模块为NGINX Plus HTTP请求跟踪提供高性能的OTel实现。
- 实验性QUIC+HTTP/3软件包:现已提供支持QUIC+HTTP/3的NGINX Plus R29预览版软件包。NGINX Plus R29 QUIC软件包支持HttpContext以及一系列新指令,用于管理QUIC连接和HTTP/3流量。
重要行为变更
注意:如果从NGINX Plus R28以外的版本升级,请务必查看重要行为变更部分,具体内容请参阅之前的版本公告博客,并检查当前版本与此版本之间的所有版本。
软件包存储库变更
旧软件包存储库plus-pkgs.nginx.com已随NGINX Plus R29的发布立即停用。此存储库自NGINX Plus R25以来一直未更新,强烈建议使用pkgs.nginx.com软件包存储库,该存储库于NGINX Plus R24中引入。
平台支持变更
新增支持的操作系统:
- Amazon Linux 2023
已移除旧版操作系统:
- Alpine 3.13,已于2022年11月1日终止生命周期(EOL)
已弃用并计划在NGINX Plus R30中移除的旧版操作系统:
- Ubuntu 18.04,将于2023年6月终止支持
- Alpine 3.14,将于2023年5月终止支持
应对ModSecurity终止支持公告
根据ModSecurity生命周期终止公告,NGINX Plus R29不再支持ModSecurity软件包。如果您是使用ModSecurity软件包的NGINX Plus客户,很快便可选择参加从ModSecurity迁移至NGINX App Protect的置换计划。相关详情即将公布。如需了解更多信息,请联系您的F5联系人。
新功能详解
支持MQTT协议
MQTT(消息队列遥测传输)是一种广泛使用的轻量级发布-订阅消息传递协议,非常适合通过互联网连接物联网设备和应用程序(客户端)。客户端可以向特定主题发布消息,也可以订阅其他主题。订阅客户端会收到发布到相应主题的所有消息,从而在众多设备和服务之间实现高效且具备容错能力的数据交换。
MQTT架构的核心是代理服务器。代理服务器负责跟踪客户端及其订阅的主题、处理消息,并将消息路由到相应的系统。NGINX Plus R29支持MQTT 3.1.1和MQTT 5.0。它充当客户端与代理服务器之间的代理,有助于简化系统架构、卸载任务并降低成本。
初始MQTT功能集支持:
- MQTT代理服务器负载均衡
- 会话持久性(将重新连接的客户端连接到同一代理)
- TLS终止
- 客户端证书身份验证
- CONNECT消息解析和重写
MQTT协议定义了多种消息类型,包括CONNECT、PUBLISH和SUBSCRIBE。NGINX Plus R29可以主动解析和重写MQTT CONNECT消息的部分内容,从而支持此前只能通过自定义脚本实现的配置场景。
必须在NGINX配置文件的Stream上下文中定义MQTT消息解析和重写,此功能由ngx_stream_mqtt_preread_module
和ngx_stream_mqtt_filter_module模块实现。
MQTT示例
修改MQTT设备发送的默认客户端标识符后,NGINX可以隐藏设备序列号等敏感信息。在第一个示例中,该标识符将被重写为设备的IP地址。
注意:不建议在生产环境中使用设备的IP地址作为MQTT客户端标识符。
stream { mqtt on;
server {
listen 1883;
proxy_pass 10.0.0.8:1883;
mqtt_set_connect clientid '$remote_addr';
}
}由于MQTT客户端具有临时性,不能仅依靠设备的主机名或IP地址,为负载均衡后的代理建立粘性会话。在此示例中,设备的MQTT客户端标识符用作哈希键,以便将连接持久绑定到负载均衡集群中的各个MQTT代理:
stream { mqtt_preread on;
upstream brokers{
zone tcp_mem 64k;
hash $mqtt_preread_clientid consistent;
server 10.0.0.7:1883; # mqtt broker 1
server 10.0.0.8:1883; # mqtt broker 2
server 10.0.0.9:1883; # mqtt broker 3
}
server {
listen 1883;
proxy_pass brokers;
proxy_connect_timeout 1s;
}
}后续步骤
NGINX Plus中MQTT的未来开发可能包括解析其他MQTT消息类型,以及对CONNECT消息进行更深入的解析,从而支持以下功能:
- 其他身份验证和访问控制机制
- 通过对“频繁通信”的客户端实施速率限制来保护代理服务器
- 消息遥测和连接指标
我们期待了解您对最关注功能的反馈。欢迎在评论区分享您的看法。
支持使用SAML进行身份验证和授权
SAML(安全断言标记语言)是一种开放式联合身份验证标准。它允许身份提供商(IdP)对访问资源的用户进行身份验证(确保最终用户确实是其所声称的身份),并将身份验证信息及用户对该资源的访问权限传递给服务提供商(SP),以进行授权。
SAML长期以来一直为身份数据交换提供安全方式,是一种广泛采用的协议,用于在IdP与SP之间交换身份验证和授权信息。
企业和政府机构选择采用SAML的主要原因包括:
- 有效管理大量身份
- 为客户和员工提供更强大、一致且统一的身份安全保障
- 通过标准化身份管理流程,提高运营效率
- 高效满足监管合规要求
SAML还具有以下几项优势:
- 更出色的用户体验:通过集成SSO并在IdP进行单点身份验证,SAML让用户只需完成一次身份验证,即可访问所有已连接的服务。这不仅改善了用户体验,还能节省时间,因为用户无需再记住不同应用的多组凭据。
- 增强安全性:根据贵组织的安全和身份验证策略,用户可以使用SSO身份验证方案,通过SP界面登录(SP发起的SSO),也可以直接通过IdP界面登录(IdP发起的SSO)。这有助于降低因密码强度不足和/或重复使用密码而产生的安全风险。
- 降低管理成本:SAML可帮助组织将身份管理职责交由可信的IdP承担,从而降低账户信息维护成本及相关费用。
- 标准化协议:SAML的设计原则是尽可能使安全机制独立于应用逻辑。作为一种标准化协议,几乎所有IdP和访问管理系统都支持SAML。它将安全框架与平台架构及特定供应商的实现分离,从而实现稳健的安全防护和可靠的系统间集成。
当前的SAML参考实现使用SAML 2.0,并基于NGINX JavaScript(njs)框架构建。在此实现中,NGINX Plus充当SAML SP,因此可以参与使用SAML IdP的SSO配置。当前实现还依赖键值存储。这是NGINX Plus的一项现有功能,因此如不进行额外修改,则不适用于NGINX Open Source。
NGINX Plus的SAML支持以参考实现的形式在GitHub上提供。该GitHub代码仓库包含示例配置,以及有关安装、配置和针对特定用例进行微调的说明。
原生OpenTelemetry
OpenTelemetry(OTel)是一项可用于监控、跟踪、故障排除和优化应用的技术和标准。OTel通过从已部署应用堆栈中的代理、应用或其他服务等各种来源收集遥测数据来发挥作用。
作为可感知协议的反向代理和负载均衡器,NGINX非常适合发起遥测调用,以跟踪应用请求和响应。虽然第三方OTel模块推出已有一段时间,但我们很高兴地宣布,NGINX Plus现可通过新的动态模块原生支持OTel。
新模块“ngx_otel_module”可使用“安装”nginx-plus-module-otel软件包,相较于第三方模块,该模块提供了多项重要改进,包括:
- 性能更优:启用追踪后,大多数OTel实现会使请求处理性能最多下降50%。我们的新原生模块可将这一影响控制在约10%至15%。
- 轻松配置,可直接在NGINX配置文件中设置和配置遥测数据收集。
- 全动态变量采样,可通过Cookie或令牌跟踪特定会话,并通过NGINX Plus API和键值存储模块动态控制该模块。
有关OTel动态模块的更多详细信息,请参阅NGINX文档。
OTel追踪示例
以下示例展示了如何对由NGINX直接提供服务的应用进行基本的OTel追踪:
load_module modules/ngx_otel_module.so; events {}
http {
otel_exporter {
endpoint localhost:4317;
}
server {
listen 127.0.0.1:8080;
otel_trace on;
otel_span_name app1;
}
}在下一个示例中,我们从传入请求继承跟踪上下文,并且仅当父跨度被采样时才记录跨度。我们还会将跟踪上下文和采样决策传播到上游服务器。
load_module modules/ngx_otel_module.so; http {
server {
location / {
otel_trace $otel_parent_sampled;
otel_trace_context propagate;
proxy_pass http://backend;
}
}
}在这个基于比例的示例中,跟踪配置为针对一定比例的流量(本例中为10%):
http { # trace 10% of requests
split_clients "$otel_trace_id" $ratio_sampler {
10% on;
* off;
}
# or we can trace 10% of user sessions
split_clients "$cookie_sessionid" $session_sampler {
10% on;
* off;
}
server {
location / {
otel_trace $ratio_sampler;
otel_trace_context inject;
proxy_pass http://backend;
}
}
}在这个由API控制的示例中,通过/api端点操作键值存储来启用跟踪:
http { keyval "otel.trace" $trace_switch zone=name;
server {
location / {
otel_trace $trace_switch;
otel_trace_context inject;
proxy_pass http://backend;
}
location /api {
api write=on;
}
}
}实验性QUIC+HTTP/3软件包
继我们发布 NGINX Open Source 预览版二进制软件包的公告之后,我们很高兴地宣布推出适用于 NGINX Plus R29 的实验性 QUIC 软件包。借助这些软件包,可以使用 NGINX Plus 测试和评估 HTTP/3。
HTTP/3采用新的底层协议栈,将UDP和QUIC引入传输层。QUIC是一种加密传输协议,旨在通过提供连接多路复用并解决队头阻塞等问题来改进TCP。它重新实现并增强了HTTP/1.1和HTTP/2中的多项TCP功能,包括连接建立、拥塞控制和可靠传输。QUIC还将TLS作为不可或缺的组成部分,这与将TLS作为独立层的HTTP/1.1和HTTP/2不同。这意味着HTTP/3消息默认通过加密连接发送,因此本身具有安全性。
通常,NGINX Plus依赖OpenSSL来实现安全通信和加密功能,并使用操作系统随附的SSL/TLS库。不过,截至本文撰写时,OpenSSL尚不支持QUIC的TLS接口,因此需要使用第三方库来提供HTTP/3所需但目前缺失的TLS功能。
为解决这一问题,我们开发了适用于QUIC的OpenSSL兼容层,无需再构建和交付quictls、BoringSSL和LibreSSL等第三方TLS库。这有助于在NGINX中管理端到端的QUIC+HTTP/3体验,既不必承担自定义TLS实现带来的负担,也不必依赖第三方库的时间表和路线图。
注意:实验性NGINX Plus QUIC+HTTP/3软件包中包含OpenSSL兼容层,需要OpenSSL 1.1.1或更高版本才能提供TLSv1.3(QUIC协议要求使用该版本)。该兼容层尚未实现0-RTT。
QUIC+HTTP/3 配置示例
下面来看一下NGINX Plus中QUIC+HTTP/3的示例配置:
http { log_format quic '$remote_addr - $remote_user [$time_local]'
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$http3"';
access_log logs/access.log quic;
server {
# for better compatibility it's recommended
# to use the same port for quic and https
listen 8443 quic reuseport;
listen 8443 ssl;
ssl_certificate certs/example.com.crt;
ssl_certificate_key certs/example.com.key;
location / {
# required for browsers to direct them into quic port
add_header Alt-Svc 'h3=":8443"; ma=86400';
}
}
}与我们的HTTP/2实现类似,当NGINX Plus充当代理时,QUIC+HTTP/3连接在客户端建立,并在连接后端和上游服务时转换为HTTP/1.1。
NGINX Plus QUIC+HTTP/3实验性软件包可从单独的软件仓库获取,并可使用现有的NGINX Plus证书和密钥访问。实验性QUIC软件包的安装过程与标准的NGINX Plus安装类似。请务必按照安装步骤中的突出说明使用QUIC软件仓库。
有关如何为QUIC+HTTP/3配置NGINX的更多信息,请参阅《为QUIC+HTTP/3配置NGINX》。有关所有新指令和变量的信息,请参阅nginx-quic README的“配置”部分。
后续步骤
近期,我们计划将QUIC+HTTP/3代码合并到NGINX主线分支。之后,支持QUIC+HTTP/3的最新NGINX主线版本将合并到后续的NGINX Plus版本中。预计今年晚些时候将发布公告,宣布NGINX Plus正式支持QUIC+HTTP/3。
NGINX Plus R29 的其他增强功能
OpenID Connect 变更
NGINX Plus R15引入了OpenID Connect(OIDC)支持,后续版本对其进行了显著增强。NGINX Plus R29继续增强OIDC,新增功能如下。
支持访问令牌
访问令牌用于基于令牌的身份验证,使OIDC客户端能够代表用户访问受保护的资源。用户成功完成身份验证并授权访问后,NGINX Plus会接收访问令牌,并将其存储在键值存储中。NGINX Plus可以在HTTP Authorization标头中将该令牌作为持有者令牌传递给发送至下游应用程序的每个请求。
注意:NGINX Plus不会像验证ID令牌那样,在每次请求时验证访问令牌的有效性,因此无法确定访问令牌是否已过期。如果访问令牌的有效期短于ID令牌,则必须启用proxy_intercept_errors指令。该指令会拦截401 Unauthorized响应并将其重定向到NGINX,以刷新访问令牌。
有关使用NGINX Plus进行OpenID Connect和JSON Web Token(JWT)验证的更多信息,请参阅《使用OpenID Connect和NGINX Plus对现有应用程序的用户进行身份验证》。
OIDC身份验证端点中新增的参数
某些身份提供商(例如Keycloak)允许在身份验证请求中添加额外的查询字符串参数,以启用其他功能。例如,Keycloak允许通过在身份验证请求中添加kc_idp_hint参数来指定默认IdP。此项增强支持为OIDC授权端点指定其他参数。
Prometheus-njs模块中的扩展SSL计数器
在NGINX Plus R28中,我们新增了更多SSL计数器支持,用于统计HTTP和Stream模块中客户端及服务器端连接的握手错误和证书验证失败。我们的Prometheus-njs模块可将NGINX Plus指标转换为符合Prometheus规范的格式,现已支持这些计数器。
新增internal_redirect指令
新的internal_redirect指令和模块支持在检查请求处理限制、连接处理限制和访问限制后执行内部重定向。
以下是一个internal_redirect配置示例:
http { limit_req_zone $jwt_claim_sub zone=jwt_sub:10m rate=1r/s;
server {
location / {
auth_jwt "realm";
auth_jwt_key_file key.jwk;
internal_redirect @rate_limited;
}
location @rate_limited {
internal;
limit_req zone=jwt_sub burst=10;
proxy_pass http://backend;
}
}
}在上述示例中,JWT身份验证在location块中执行。如果令牌有效,请求将传递给内部内容处理程序@rate_limited,并根据sub声明值应用请求速率限制。此过程在请求传递给上游服务之前通过JWT完成。
此配置可防止这样一种拒绝服务(DoS)攻击:攻击者发送大量包含可读取JWT的请求,并将特定用户编码为sub字段。这些请求无法通过身份验证,但会计入速率限制。先对JWT进行身份验证,再将请求传递给内容处理程序,可确保只有有效请求才会计入速率限制。
继承自NGINX Open Source的更改
NGINX Plus R29基于NGINX Open Source 1.23.4,并继承了NGINX Plus R28发布后(NGINX 1.23.3至1.23.4)所做的功能变更和错误修复。
变更
- The TLSv1.3协议现已默认启用,并且是以下指令的默认值:
ssl_protocols(HTTP,Stream,Mail)proxy_ssl_protocols(HTTP,Stream)grpc_ssl_protocolsuwsgi_ssl_protocolszone_sync_ssl_protocols- 现在,如果重新定义监听套接字的协议参数,NGINX会发出警告。
- 如果客户端使用了流水线机制,NGINX现在会延迟关闭连接。
- data length too long、length too short、bad legacy version、no shared signature algorithms、bad digest length、missing sigalgs extension、encrypted length too long、bad length、bad key update、mixed handshake and non-handshake data、ccs received early、data between ccs and finished、packet length too long、too many warn alerts、record too small和got a fin before a ccs等SSL错误的日志记录级别已从crit降至info。
功能
- 现在支持在
ngx_http_gzip_static_module中使用字节范围。
错误修复
- 修复了 listen 指令中端口范围无效的问题。
- 修复了以下问题:如果配置中使用了超过255个字符的前缀location,系统可能会错误地选择其他location来处理请求。
- 修复了Windows文件名中的非ASCII字符问题,此前以下模块和指令不支持此类字符:
ngx_http_autoindex_module、ngx_http_dav_module和include指令。 - 修复了使用HTTP/2和
error_page指令重定向错误代码为400的错误时偶尔发生的套接字泄漏问题。 - 修复了有关记录到
syslog时发生错误的消息,此前这些消息未说明错误是在记录到syslog时发生的。 - 修复了proxy -r中客户端读取事件被阻塞时的处理问题。
- 修复了读取包含大量TLV的PROXY协议版本2标头时偶尔出现的错误。
- 修复了使用SSI处理其他模块创建的子请求时,工作进程中有时会发生的段错误。
- 修复了在无缓冲代理期间使用与后端的SSL连接时,NGINX可能占用大量CPU的问题。
解决方法
zip filter failed to use pre-allocated memory使用zlib-ng时,日志中出现了相关警报。- 当
listen指令中使用的主机名解析为多个地址时,NGINX现在会忽略其中的重复地址。
有关从这些版本继承的新增功能、变更、错误修复和解决方法的完整列表,请参阅CHANGES文件。
NGINX JavaScript Module 的变更
NGINX Plus R29整合了NGINX JavaScript(njs)模块0.7.9至0.7.12版本中的变更。njs新增了多项实用功能,包括:
- 扩展的Fetch API支持
- 扩展的Web Crypto API
- XML文档支持
- XML文档解析
- 用于修改XML文档的XMLNode API
- Zlib模块压缩支持
有关njs 0.7.9至0.7.12版本的所有功能、变更和错误修复的完整列表,请参阅njs变更日志。
扩展的Fetch API支持
Headers()、Request()和Response()构造函数已添加到Fetch API中,同时还进行了其他增强:
async function makeRequest(uri, headers) { let h = new Headers(headers);
h.delete("bar");
h.append("foo", "xxx");
let r = new Request(uri, {headers: h});
return await ngx.fetch(r);
}扩展的 Web Crypto API
Web Crypto API已扩展为支持JSON Web Key(JWK)格式,importKey()现在可接受JWK格式的密钥作为输入:
async function importSigningJWK(jwk) { return await crypto.subtle.importKey('jwk', jwk,
{name: "RSASSA-PKCS1-v1_5"},
true, ['sign']);
}
njs 0.7.10还新增了generateKey()和exportKey()方法。generateKey()方法可为对称算法生成新密钥,或为公钥算法生成密钥对。exportKey()方法以CryptoKey对象作为输入,并以可移植的外部格式返回密钥。该方法支持JWK格式,可将密钥导出为JSON对象。
有关更多详细信息,请参阅“Web Crypto API”。
XML文档支持
njs 0.7.10 中新增了 XML 模块,为处理 XML 文档提供原生支持。
XML文档解析
现在可以将字符串或缓冲区解析为XML文档,并返回一个表示已解析XML文档的XMLDoc包装器对象:
const xml = require("xml"); let data = `<note><to b="bar" a= "foo">Tove</to><from>Jani</from></note>`;
let doc = xml.parse(data);
console.log(doc.note.to.$text) /* 'Tove' */
console.log(doc.note.to.$attr$b) /* 'bar' */
console.log(doc.note.$tags[1].$text) /* 'Jani' */用于修改XML文档的XMLNode API
njs 0.7.11中新增了XMLNode API,用于修改XML文档:
Const xml = require("xml"); let data = `<note><to b="bar" a="foo">Tove</to><from>Jani</from></note>`;
let doc = xml.parse(data);
doc.$root.to.$attr$b = 'bar2';
doc.$root.to.setAttribute('c', 'baz');
delete doc.$root.to.$attr$a;
console.log(xml.serializeToString(doc.$root.to))
/* '<to b="bar2" c="baz">Tove</to>' */
doc.$root.to.removeAllAttributes();
doc.$root.from.$text = 'Jani2';
console.log(xml.serializeToString(doc))
/* '<note><to>Tove</to><from>Jani2</from></note>' */
doc.$root.to.$tags = [xml.parse(`<a/>`), xml.parse(`<b/>`)];
doc.$root.to.addChild(xml.parse(`<a/>`));
console.log(xml.serializeToString(doc.$root.to))
/* '<to><a></a><b></b><a></a></to>' */
doc.$root.to.removeChildren('a');
console.log(xml.serializeToString(doc.$root.to))
/* '<to><b></b></to>' */有关所有XML相关增强功能的更多详细信息,请参阅XML文档。
Zlib模块压缩支持
zlib模块在njs 0.7.12中新增,可使用deflate和inflate算法提供压缩功能。
Const zlib = require('zlib'); zlib.deflateRawSync('αβγ').toString('base64')
/* "O7fx3KzzmwE=" */
zlib.inflateRawSync(Buffer.from('O7fx3KzzmwE=', 'base64')).toString()
/* "αβγ" */有关zlib的更多详细信息,请参阅zlib文档。
升级或试用 NGINX Plus
如果您正在运行NGINX Plus,我们强烈建议尽快升级到NGINX Plus R29。除了各项实用的新功能外,升级后还可获得多项修复和改进;保持使用最新版本也有助于NGINX在您需要提交支持工单时提供帮助。
如果您尚未试用过NGINX Plus,建议立即体验。它可用于安全防护、负载均衡和API网关,也可作为获得全面支持的Web服务器,并提供增强的监控和管理API。立即开始30天免费试用。
相关博客文章
NGINX Plus R26 正式发布
NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。
使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。
Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。
NGINX Plus R19 正式发布
NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。
NGINX现已正式加入F5
NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。
