我们很高兴地宣布 NGINX Plus Release 29(R29)已经推出。 NGINX Plus 基于 NGINX 开源,是唯一集 Web 服务器、负载均衡器、反向代理、内容缓存和 API 网关于一体的软件。
NGINX Plus R29 的新增功能和增强功能包括:
笔记: 如果您要从 NGINX Plus R28 以外的版本升级,请务必检查以前的公告博客中的“行为的重要变化”部分,了解当前版本和此版本之间的所有版本。
随着 NGINX Plus R29 的发布,旧的软件包存储库plus-pkgs.nginx.com将立即退役。 自 NGINX Plus R25 以来,此存储库尚未更新,强烈建议您使用NGINX Plus R24 中引入的pkgs.nginx.com软件包存储库。
支持的新操作系统:
已删除旧操作系统:
NGINX Plus R30 中已弃用并计划删除的旧操作系统:
根据ModSecurity EOL 公告,NGINX Plus R29 删除了对 ModSecurity 包的支持。 如果您是使用 ModSecurity 软件包的 NGINX Plus 客户,您很快就能选择加入 ModSecurity 和NGINX App Protect之间的以旧换新计划。 有关此详细信息将很快公布,您可以联系 F5 联系人获取更多信息。
MQTT(消息队列遥测传输)是一种流行且轻量级的发布-订阅消息协议,非常适合通过互联网连接物联网设备和应用(客户端)。 它允许客户端向特定主题发布消息并订阅其他主题。 订阅的客户端会接收发布到该主题的所有消息,从而实现许多设备和服务之间高效、容错的数据交换。
MQTT 架构的核心是代理。 代理是一种服务器,负责跟踪客户端及其订阅的任何主题、处理消息并将这些消息路由到适当的系统。 NGINX Plus R29 支持MQTT 3.1.1和MQTT 5.0 。 它充当客户端和经纪人之间的代理,简化系统架构,减轻任务负担并降低成本。
初始 MQTT 功能集支持:
MQTT 协议定义了几种消息类型,包括 CONNECT、PUBLISH 和 SUBSCRIBE。 NGINX Plus R29 可以主动解析和重写 MQTT CONNECT 消息的部分内容,从而实现以前只能通过自定义脚本实现的配置场景。
MQTT 消息解析和重写必须在 NGINX 配置文件的 Stream 上下文中定义,并且可以通过ngx_stream_mqtt_preread_module
实现
和ngx_stream_mqtt_filter_module
模块。
MQTT 示例
修改 MQTT 设备发送的默认客户端标识符使 NGINX 能够隐藏敏感信息,例如设备的序列号。 在第一个例子中,标识符被重写为设备的 IP 地址。
笔记: 在生产环境中不建议使用设备的 IP 地址作为 MQTT 客户端标识符。
流 { mqtt 开启;
服务器 { 监听 1883; proxy_pass 10.0.0.8:1883; mqtt_set_connect clientid '$remote_addr'; } }
鉴于 MQTT 客户端的短暂性,您不能简单地依靠设备的主机名或 IP 地址来建立粘性会话来负载平衡代理。 在此示例中,设备的 MQTT 客户端标识符充当与负载平衡集群中的各个 MQTT 代理保持连接的哈希键:
流 { mqtt_preread 开启;
上游代理{区域 tcp_mem 64k;哈希 $mqtt_preread_clientid 一致;
服务器 10.0.0.7:1883; # mqtt 代理 1 服务器 10.0.0.8:1883; # mqtt 代理 2 服务器 10.0.0.9:1883; # mqtt 代理 3 }
服务器 { 监听 1883; proxy_pass 代理; proxy_connect_timeout 1s; } }
NGINX Plus 中 MQTT 的未来发展可能包括解析其他 MQTT 消息类型,以及更深入地解析 CONNECT 消息以实现如下功能:
我们很乐意听到您对最关心的功能的反馈。 请在评论中告诉我们您的想法。
SAML(安全断言标记语言)是一种开放联合标准,允许身份提供者 (IdP) 对用户进行资源访问权限验证(确保最终用户确实是他们所声称的那个人),并将该身份验证信息连同用户对该资源的访问权限一起传递给服务提供商 (SP) 进行授权。
SAML 在提供交换身份数据的安全方式方面有着悠久的历史,是 IdP 和 SP 之间交换身份验证和授权信息时广泛采用的协议。
企业和政府机构选择采用 SAML 的主要原因包括:
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 repo包含一个示例配置,其中有关于安装、配置和针对特定用例进行微调的说明。
OpenTelemetry(OTel)是一种可用于监控、跟踪、故障排除和优化应用的技术和标准。 OTel 通过从各种来源(例如代理、应用或已部署的应用堆栈中的其他服务)收集遥测数据来工作。
作为协议感知的反向代理和负载均衡器,NGINX 非常适合启动遥测调用来跟踪应用请求和响应。 虽然第三方 OTel 模块已经推出一段时间了,但我们很高兴地宣布 NGINX Plus 通过新的动态模块对 OTel 提供原生支持。
新的模块ngx_otel_module
可以使用nginx-plus-module-otel
包进行安装,并为第三方模块提供了几项关键改进,包括:
有关 OTel 动态模块的更多详细信息,请参阅NGINX 文档。
OTel 追踪示例
以下是 OTel 对 NGINX 直接提供服务的应用进行基本跟踪的示例:
加载模块/ngx_otel_module.so;
事件 {}
http { otel_exporter { 端点 localhost:4317; }
服务器 { 监听 127.0.0.1:8080;
otel_trace 开启; otel_span_name app1; } }
在下一个示例中,我们从传入的请求中继承跟踪上下文,并且仅当对父跨度进行采样时才记录跨度。 我们还将跟踪上下文和采样决策传播到上游服务器。
加载模块/ngx_otel_module.so;
http { 服务器 { 位置 / { otel_trace $otel_parent_sampled; otel_trace_context propagate; proxy_pass http://backend; } } }
在这个基于比率的示例中,跟踪配置为按流量百分比进行(在本例中为 10%):
http { # 跟踪 10% 的请求 split_clients "$otel_trace_id" $ratio_sampler { 10% 开启;* 关闭;}
# 或者我们可以追踪 10% 的用户会话
split_clients "$cookie_sessionid" $session_sampler { 10% 开启;* 关闭;}
服务器 { 位置 / { otel_trace $ratio_sampler; otel_trace_context 注入;
代理密码 http://后端; } } }
在这个 API 控制的示例中,通过 /api 端点操作键值存储来启用跟踪:
http { keyval "otel.trace" $trace_switch zone=name;
服务器 { 位置 / { otel_trace $trace_switch; otel_trace_context 注入; proxy_pass http://backend; }
位置 /api { api write=on; } } }
继我们宣布推出 NGINX 开源二进制包预览版之后,我们很高兴地宣布推出适用于 NGINX Plus R29 的实验性 QUIC 包。 这使得使用 NGINX Plus 测试和评估 HTTP/3 成为可能。
HTTP/3 通过新的底层协议栈,将 UDP 和 QUIC 引入传输层。 QUIC 是一种加密传输协议,旨在通过提供连接多路复用和解决队头阻塞等问题来改进 TCP。 它重新实现并增强了 HTTP/1.1 和 HTTP/2 的许多 TCP 功能,包括连接建立、拥塞控制和可靠传送。 QUIC 还将 TLS 作为一个整体组件,而 HTTP/1.1 和 HTTP/2 将 TLS 作为单独的层。 这意味着 HTTP/3 消息本质上是安全的,因为它们默认通过加密连接发送。
通常,为了实现安全通信和加密功能,NGINX Plus 依赖于OpenSSL ,并利用操作系统附带的 SSL/TLS 库。 但是,由于在撰写本文时 OpenSSL 不支持 QUIC 的 TLS 接口,因此需要第三方库来提供 HTTP/3 所需的缺失的 TLS 功能。
为了解决这一问题,我们为 QUIC 开发了 OpenSSL 兼容层,从而无需构建和运送第三方 TLS 库(如 quictls、BoringSSL 和 LibreSSL)。 这有助于管理 NGINX 中的端到端 QUIC+HTTP/3 体验,而无需自定义 TLS 实现的负担,也无需依赖第三方库的计划和路线图。
笔记: OpenSSL 兼容层包含在实验性的 NGINX Plus QUIC+HTTP/3 包中,并且需要 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 日志/access.log quic;
服务器 { # 为了更好的兼容性,建议 # 对 quic 和 https 使用相同的端口 listen 8443 quic repeatport; listen 8443 ssl;
ssl_certificate certs/example.com.crt; ssl_certificate_key certs/example.com.key;
location / { # 需要浏览器将其引导至 quic 端口 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 repo,如安装步骤中突出显示的那样。
您可以参考为 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。
OpenID Connect(OIDC)支持在 NGINX Plus R15 中引入,并在后续版本中得到显著增强。 NGINX Plus R29 继续增强 OIDC,并增加了以下内容。
支持访问令牌
访问令牌用于基于令牌的身份验证,以允许 OIDC 客户端代表用户访问受保护的资源。 在用户成功验证并授权访问后,NGINX Plus 会收到访问令牌,然后将其存储在键值存储中。 NGINX Plus 可以将 HTTP 授权标头上的令牌作为Bearer 令牌传递给发送到下游应用的每个请求。
笔记: NGINX Plus 不会在每次请求时验证访问令牌的有效性(就像它对 ID 令牌所做的那样),并且无法知道访问令牌是否已经过期。 如果访问令牌的有效期短于 ID 令牌的有效期,则必须使用proxy_intercept_errors
on 指令。 这将拦截并将401 未授权
响应重定向到 NGINX,并刷新访问令牌。
有关使用 NGINX Plus 进行 OpenID Connect 和 JSON Web Token (JWT) 验证的更多信息,请参阅使用 OpenID Connect 和 NGINX Plus 对现有applications的用户进行身份验证。
在 OIDC 身份验证端点中添加参数
一些身份提供者(例如Keycloak )允许在身份验证请求中添加额外的查询字符串参数以启用附加功能。 例如,Keycloak 允许通过在身份验证请求中添加kc_idp_hint
参数来指定默认 IdP。 作为此增强功能的一部分,用户可以向 OIDC 授权端点指定附加参数。
在 NGINX Plus R28 中,我们为客户端和服务器端连接的 HTTP 和 Stream 模块中的握手错误和证书验证失败添加了额外的 SSL 计数器支持。 我们的Prometheus-njs模块将 NGINX Plus 指标转换为符合 Prometheus 的格式,现在支持这些计数器。
internal_redirect
指令 新的internal_redirect
指令和模块允许在检查请求处理限制、连接处理限制和访问限制后进行内部重定向。
以下是internal_redirect
配置的示例:
http { limit_req_zone $jwt_claim_sub 区域=jwt_sub:10m 速率=1r/s;
服务器 { 位置 / { auth_jwt “领域”; auth_jwt_key_file key.jwk;
内部重定向@rate_limited; }
位置@rate_limited {内部;limit_req zone=jwt_sub burst=10;
代理密码http://后端; } } }
在上面的例子中,JWT 身份验证在位置块执行,如果令牌有效,则请求将传递到内部内容处理程序@rate_limited,其中根据子声明值应用请求速率限制。 这发生在请求传递给上游服务之前在 JWT 中。
这种特殊的配置可以防止拒绝服务 (DoS) 攻击,攻击者发送大量包含可读 JWT 的请求,并使用特定用户作为子字段进行编码。 大量请求不会通过身份验证,但会计入速率限制。 通过在将请求传递给内容处理程序之前对 JWT 进行身份验证,您可以确保只有有效的请求才计入速率限制。
NGINX Plus R29 基于 NGINX Open Source 1.23.4,继承了自 NGINX Plus R28 发布以来(在 NGINX 1.23.3 至 1.23.4 中)所做的功能更改和错误修复。
更改
ssl_protocols
( HTTP ,流,邮件) proxy_ssl_protocols
( HTTP ,流) grpc_ssl_协议
uwsgi_ssl_协议
zone_sync_ssl_protocols
特稿
ngx_http_gzip_static_module
现在支持字节范围。问题修复
ngx_http_autoindex_module
、 ngx_http_dav_module
和 include 指令不支持这些字符。error_page
指令通过代码重定向错误时有时会发生的套接字泄漏400
。syslog
错误的消息,该消息不包含记录到syslog
时发生的错误的信息。解决方法
zlib-ng
时,日志中出现zip 过滤器无法使用预分配内存
警报。 listen
指令中使用的主机名解析为多个地址时,NGINX 现在会忽略这些地址内的重复项。有关从这些版本继承的新功能、更改、错误修复和解决方法的完整列表,请参阅CHANGES文件。
NGINX Plus R29 吸收了 NGINX JavaScript (njs) 模块版本 0.7.9 至 0.7.12 的变化。 njs 增加了几个令人兴奋的功能,包括:
有关 njs 版本 0.7.9 至 0.7.12 的所有功能、更改和错误修复的完整列表,请参阅njs 更改日志。
Headers()
、 Request()
和Response()
构造函数已添加到 Fetch API,以及其他增强功能:
异步函数 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 已扩展为支持 JSON Web Key (JWK) 格式,并且 importKey() 现在接受 JWK 格式的密钥作为输入:
异步函数 importSigningJWK(jwk) { 返回等待 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 。
njs 0.7.10 中添加了 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' */
XMLNode API 修改 XML 文档
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');
删除 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 模块是在 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 R29。 除了所有出色的新功能之外,您还将获得一些额外的修复和改进,并且保持更新将有助于 NGINX 帮助您提出支持单。
如果您还没有尝试过 NGINX Plus,我们鼓励您尝试一下 – 为了安全、负载均衡和 API 网关,或者作为具有增强监控和管理 API 的完全支持的 Web 服务器。 立即开始30 天免费试用。
“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”