博客 | NGINX

宣布推出 NGINX Plus R23

NGINX-F5-horiz-black-type-RGB 的一部分
Liam Crilly 缩略图
利亚姆·克里利
2020 年 12 月 8 日发布


我们很高兴地宣布NGINX Plus Release 23 (R23)已经推出。 NGINX Plus 基于 NGINX 开源,是唯一的软件负载均衡器、反向代理和 API 网关。

NGINX Plus R23的新功能包括:

  • gRPC 健康检查——在发送请求之前主动测试 gRPC 服务是否能够处理请求,可以显著提高可靠性。
  • 非特权安装支持- NGINX Plus 现在可以由非特权(非root )用户安装和升级。 这种完全支持的解决方案符合零信任安全模型日益增长的趋势。
  • OpenID Connect PKCE 支持- NGINX Plus R23为 OpenID Connect 授权码流实现了代码交换证明密钥 (PKCE) 扩展。 PKCE 可以防止多种类型的攻击并支持与公共客户端进行安全的 OAuth 交换。

此版本完善了对 SSL/TLS 的更细粒度的控制、设置 cookie 标志的本机方法以及 Stream 模块中的变量设置。 NGINX Plus 生态系统的更新包括 NGINX JavaScript 模块的新缓冲区和查询字符串模块、Kerberos 动态模块的新 SPNEGO 以及 Prometheus‑njs 动态模块的增强功能。

行为方面的重要变化

  • 已弃用的模块– 第三方 Cookie-Flag 模块已弃用,并由新的proxy_cookie_flags指令取代。 该模块将在NGINX Plus R26中删除。 有关详细信息,请参阅设置 Cookie 标志的本机方法
  • 支持的新操作系统
    • Alpine 3.12(x86_64,aarch64)
    • Debian 10(aarch64;自NGINX Plus R17起已支持 x86_64)
  • 已删除或将要删除的旧操作系统:
    • Alpine 3.9 不再受支持;最早支持的版本是 3.10
    • CentOS/Oracle Linux/RHEL 6.5+ 不再受支持;最早支持的版本是 7.4
    • Ubuntu 19.10 不再受支持
    • Debian 9 将在NGINX Plus R24中删除

新功能详情

gRPC 健康检查

当部署为负载均衡器时,NGINX Plus 可以通过主动健康检查来监控后端(上游)服务器的健康状况。 NGINX Plus R23支持gRPC 健康检查协议,使其能够准确测试后端 gRPC 服务器是否能够处理新请求。 这在动态和容器化环境中尤其有价值。 启动 gRPC 服务的新实例时,重要的是仅在服务“完全启动”后发送请求。 这需要进行比查看 TCP 端口或验证 HTTP URI 可用性更深入的健康检查 - 服务本身可以指示它是否已准备好接收请求。

对于实现 gRPC 健康检查协议的 gRPC 服务,配置很简单。

此配置将所有请求负载平衡至grpc_backend上游组。 health_check指令包含type=grpc参数,用于调用每个上游服务器的Health服务的Check方法。 以SERVING进行响应的服务被认为是健康的。 强制参数确保当 NGINX Plus 启动或将新服务器引入上游组时,直到健康检查通过后才转发流量(否则,默认假定新服务是健康的)。

如果每个上游服务器上都公开了多个 gRPC 服务,那么可以通过将其名称指定为grpc_service参数的值来监控最重要的服务(具有依赖或从属服务的服务),如下例所示:

对于未实现 gRPC 健康检查协议的 gRPC 服务,我们可以测试上游服务器是否至少响应 gRPC 请求,因为在这种情况下它会响应Check方法发送错误状态代码。 通过grpc_health.conf中的配置,我们期望未实现 gRPC 协议的服务以状态代码进行响应12(未实施)

我们还可以检查 gRPC 服务是否能够响应传入的请求,而无需修改后端代码。 我们可以使用此方法来监控任何 gRPC 服务:

非特权用户安装

在以前的版本中,NGINX Plus 以特权用户root身份运行最少的进程。 例如, NGINX Plus 管理指南中的安装说明创建了以下流程:

$ ps auxf | grep nginx root…  9068888?  SS 21:44 0:00 nginx:主进程 nginx nginx...  9712 3572?  S 21:44 0:00 \_ nginx:工作进程

如图所示,master进程以root权限运行。 所有其他进程(工作进程和缓存管理)都使用非特权用户帐户nginx

处理敏感数据的关键系统可能不想使用root用户。 在这种情况下, NGINX Plus R23可以以非特权用户身份安装和运行。 我们在 GitHub 存储库中提供了安装脚本ngxunprivinst.sh ,可在以下操作系统上使用:

  • Alpine Linux
  • 亚马逊 Linux,亚马逊 Linux 2
  • CentOS、红帽企业 Linux
  • Debian、Ubuntu

笔记: 如果在 1024 以下的端口上配置了任何 NGINX Plus监听器(例如 80 或 443),则主进程必须具有root权限(但您仍然可以在非特权用户帐户下安装 NGINX Plus)。

要使用安装脚本,请运行以下命令。 (要查看所有可用的ngxunprivinst.sh命令,请运行不带命令名参数的脚本,或者查看 GitHub repo 中的脚本代码。)

  1. 下载脚本并确保其可执行:

    $ chmod + x ngxunprivinst.sh
  2. 将您的 NGINX Plus 证书和密钥( nginx-repo.crtnginx-repo.key )复制到本地目录。 所有ngxunprivinst.sh命令都包含‑c‑k选项以识别它们。
  3. 列出 NGINX Plus 仓库中可用的 NGINX Plus 版本。

    $ ./ngxunprivinst.sh 列表 -c nginx-repo.crt -k nginx-repo.key
    18-1
    18-2
    19-1
    20-1
    21-1
    22-1
    23-1
  4. 获取所需的包(这里我们获取NGINX Plus R23-1 )。 ‑p选项指定安装目录:

    $ ./ngxunprivinst.sh fetch -c nginx-repo.crt -k nginx-repo.key -p /home/nginxrun -v 23-1
  5. 安装您需要的软件包(这里我们安装 NGINX Plus 和 NGINX JavaScript 模块,njs)。

    $ ./ngxunprivinst.sh 安装 -c nginx-repo.crt -k nginx-repo.key -p /home/nginxrun -v 23.1 nginx-plus-23-1.el8.ngx.x86_64.rpm nginx-plus-module-njs-23%2B0.4.6-1.el8.ngx.x86_64.rpm
  6. 启动NGINX,包括-p选项指定路径, -c命名配置文件, -e命名错误日志。

    $ /home/nginxrun/usr/sbin/nginx -p /home/nginxrun/etc/nginx -c nginx.conf -e /home/nginxrun/var/log/error.log

    我们包含‑e选项来抑制否则出现的警告消息。 在 NGINX Plus 启动期间读取其配置之前,它会写入默认错误日志/var/log/nginx/error.log 。 非特权用户无权创建或写入此文件,因此会出现警告。 读取配置后, error_log指令会将错误日志设置为非特权用户可以写入的位置。

  7. (可选)要验证 NGINX Plus 是否以非root用户身份运行,请运行以下命令:

    $ ps auxf | grep nginx nginxrun…  9068888?  SS 21:55 0:00 nginx:主进程 nginxrun...  9712 3572?  S 21:55 0:00 \_ nginx:工作进程

OpenID Connect PKCE 支持

代码交换证明密钥 ( PKCE ) 是最近添加到 OpenID Connect (OIDC) 授权代码流的扩展,用于防止多种攻击并确保与公共客户端的 OAuth 交换安全。 对于NGINX Plus R23 ,我们更新了OpenID Connect 参考实现以支持该扩展。 PKCE 将成为OAuth 2.1 的强制性要求。

具体的变化是在代码挑战中用两个新值替换client_secret

  • 代码挑战
  • 代码验证器

为了应对不同的攻击,特别是针对移动设备的攻击,对令牌(无论是访问令牌、ID 令牌还是刷新令牌)的挑战已进行如下调整:

  1. NGINX Plus 生成(并记住)一个code_verifier
  2. NGINX Plus 将最终用户重定向至 OIDC 身份提供商 (IdP) 登录页面登录。 该请求包含一个称为code_challengecode_verifier的散列版本。
  3. IdP 将用户的auth_code发送给 NGINX Plus。
  4. 基于共享状态,NGINX Plus 能够找到生成的code_verifier并发送请求以从 IdP 的令牌端点交换授权码以获取令牌集。

在添加 PKCE 之前,NGINX Plus 只需与 IdP 共享静态客户端机密就足够了。
在更新的OIDC 参考实现中,NGINX Plus 能够处理 PKCE 和客户端秘密方法的授权码流。

以下是使用 PKCE 启用扩展授权码流程的示例配置:

新的$oidc_pkce_enable变量充当 PKCE 流的开关。 如果设置为1对于特定域,使用 PKCE 流。 如果设置为0(默认),使用非 PKCE 授权码流程。

NGINX Plus R23 中的其他增强功能

对 SSL/TLS 连接的细粒度控制

TLS v1.3 比以前的 TLS 版本具有更强的安全性,具有服务器之间以及服务器与客户端之间的端到端加密。 NGINX Plus R23提供对 OpenSSL 配置的直接访问,以便对 TLS v1.3 进行细粒度控制。

创建没有证书和密钥的默认 HTTPS 服务器

在以前的版本中,TLS 保护的 HTTPS 流量的默认服务器块必须包含ssl_certificatessl_certificate_key指令,要求您创建“虚拟”自签名证书和密钥。

ssl_reject_handshake指令消除了对证书和密钥的要求,如以下示例配置所示:

直接 OpenSSL 配置

NGINX Plus R23让您可以更细粒度地控制 NGINX Plus 如何使用 OpenSSL 1.0.2 及更高版本处理 SSL/TLS。

以下用例利用了新的控制级别:

  • ChaCha 密码- 当客户端(通常是移动设备)将该密码指定在其偏好列表的顶部时,NGINX Plus 使用 ChaCha20。 ChaCha20 明显提高了支持它的客户端的性能。

  • TLS v1.3 密码配置——在以前的版本中, ssl_ciphers指令用于设置 NGINX Plus 的首选 SSL/TLS 密码列表,如以下示例所示:

    但是,该指令不适用于 TLS v1.3,因为 TLS v1.3 的密码的 OpenSSL 实现与旧接口不兼容。 要设置 TLS v1.3 的密码列表,请使用新的ssl_conf_command指令,如以下示例所示:

    要为 TLS v1.2 和 v1.3 设置密码,请在配置中包含两个指令:

  • 升级代理连接——基于ssl_conf_command指令实现的密码配置机制, NGINX Plus R23为您提供对使用以下协议代理的连接的密码套件的相同控制:

  • 以下示例显示如何配置 NGINX Plus 以将使用旧 TLS 版本的客户端的请求升级为使用已知支持 TLS v1.3 的后端服务器。

缓存管理器可以监视可用磁盘空间

当 NGINX Plus 配置为缓存代理时,缓存管理器进程通过删除最近访问最少的内容来保证缓存大小不超过proxy_cache_path指令的max_size参数设置的限制。

使用NGINX Plus R23 ,缓存管理器还可以监视存储缓存的文件系统上的可用磁盘空间量,并在可用空间小于proxy_cache_path指令的新min_free参数时删除内容。

这意味着即使缓存与其他进程共享相同的文件系统,NGINX Plus 也能确保填充缓存不会无意中填满磁盘。

不安全的 cookie 仍然是一种高风险的攻击媒介。 正如Mozilla 开发者网络(MDN) 所述,确保 cookie 不被非预期方或脚本访问的一种方法是在Set-Cookie标头中设置HttpOnlySecure等标志。

在以前的版本中,我们为此目的提供了set_cookie_flag指令,如我们的动态模块库中提供的第三方Cookie-Flag 模块中实现的。 NGINX Plus R23引入了proxy_cookie_flags指令来替换该指令和模块。

已弃用的 Cookie‑Flag 模块将在NGINX Plus R26中被删除,因此我们建议您在配置中找到所有set_cookie_flag指令并尽快将其替换为proxy_cookie_flags指令。

下面是一个代理到简单后端应用的示例配置,该应用程序本身没有设置任何 cookie 保护标志:

在此示例中,我们添加了HttpOnlySecureSameSite标志来保护上游服务器创建的appcookie会话 cookie,NGINX Plus 使用该 cookie 进行会话持久性,如NGINX Plus 管理指南中所述。

使用curl命令或浏览器的开发人员工具,您可以看到现在为appcookie设置了HttpOnlySecureSameSite标志。

< HTTP/1.1 200 OK< 服务器:nginx/1.19.4
< 日期: 2020 年 12 月 8 日星期四 14:46:12 GMT
< 内容类型:应用/八位字节流
< 内容长度: 9
< 连接:保持活动
< 设置 Cookie:appcookie=appserver1;安全;HttpOnly;SameSite=Strict
< 内容类型:text/html

使用NGINX Plus R23 ,你还可以使用sticky指令将SameSite标志添加到 cookie 中,如下例所示(自NGINX Plus R6起已支持httponlysecure参数):

在流模块中设置变量

NGINX Plus R23引入了set指令,用于在 TCP/UDP 配置中设置变量,扩展了常用于HTTP 流量处理的功能。

这是一个从多个变量构造复杂复合值的示例。

更复杂的用例采用set指令来更新键值存储。 在这种 DNS 负载均衡配置中,键值存储记录每个客户端 IP 地址发出 DNS 请求的时间,并将每个记录保留 24 小时。

然后,您可以使用NGINX Plus API来了解每个客户端在过去 24 小时内何时发出最近的 DNS 请求。

$ curl http://localhost:8080/api/6/stream/keyvals/dns_timestamp { “172.17.0.1”: “2020-12-08T15:51:28 + 00:00”,“172.17.0.2”: “2020-12-08T12:36:08 + 00:00”,“172.17.0.7”: “2020-12-08T15:15:42 + 00:00” }

NGINX Plus 生态系统的更新

NGINX JavaScript 模块的增强功能

NGINX JavaScript 模块 (njs) 已更新为0.5.0。 此版本引入了Buffer 模块,它类似于Node.js 的 Buffer 模块。 缓冲区对象可以轻松处理二进制数据,而不必依赖于字符串。

该模块的其他显著增强功能是查询字符串模块,可轻松访问 URL 中传递的键值对,以及用于调试的行级回溯支持。

动态模块的变更

Kerberos 模块的新 SPNEGO

NGINX Plus动态模块存储库现在支持SPNEGO Kerberos 身份验证。 有关安装说明和更多信息,请参阅NGINX Plus 管理指南

弃用的 Cookie-Flags 模块

如上文设置 Cookie 标志的本机方法中所述,新的proxy_cookie_flags指令取代了第三方 Cookie-Flag 模块中实现的set_cookie_flag指令,该指令现在已被弃用并计划在NGINX Plus R26中删除。 如果您的配置包含set_cookie_flag指令,请尽快将其替换为proxy_cookie_flags

Prometheus-njs 模块更新

Prometheus‑njs 模块现在公开了额外的指标。 它还已升级以适应使用 NGINX JavaScript 模块 (njs) 的部署。 将 Prometheus‑njs 升级到 1.3.1 及以上版本时,务必更新 NGINX 配置文件,以避免引用已弃用的 njs 配置:

值得注意的错误修复

如果响应大于proxy_buffer_size指令的值,则使用match块中的require指令来测试变量不为空的健康检查可能无法检测到不健康的上游服务器。

升级或尝试 NGINX Plus

如果您正在运行 NGINX Plus,我们强烈建议您尽快升级到NGINX Plus R23 。 您还将获得一些额外的修复和改进,当您需要提出支持单时,它将帮助 NGINX 为您提供帮助。

如果您还没有尝试过 NGINX Plus,我们鼓励您尝试一下 – 为了安全、负载均衡和 API 网关,或者作为具有增强监控和管理 API 的完全支持的 Web 服务器。 您今天就可以开始享受30 天免费试用。 亲自了解 NGINX Plus 如何帮助您交付和扩展您的应用。


“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”