BLOG | NGINX

NGINX QUIC+HTTP/3 预览版的二进制包现已发布

NGINX-Part-of-F5-horiz-black-type-RGB
Robert Haynes 缩略图
Robert Haynes
Published February 08, 2023

我们很高兴宣布,NGINX QUIC+HTTP/3 预览版现提供以下两个发行版的预构建二进制包:

  • Red Hat Enterprise Linux 9 及其二进制兼容版
  • Ubuntu 22.04

这些二进制文件可以从独立的 nginx-quic 仓库(托管预览版)quic 分支下载。和之前一样,您仍可下载和编译含有 QUIC+HTTP/3 的 NGINX 开源版源码,,并可以选择支持 QUIC 的 SSL/TLS 库。虽然目前这些代码还被标记为实验性代码,但一些社区成员表示,他们在生产环境中成功使用了 nginx-quic

为了用户更快速、更轻松地测试含有 QUIC+HTTP/3 的 NGINX,我们发布预编译二进制文件。这些二进制文件不需要从源代码编译,并可使用标准包管理工具进行安装。

在撰写本文时,公认的开源 SSL/TLS 标准 OpenSSL 并不支持 QUIC。因此,我们使用 了quictls 库包(作为依赖包自动安装)构建二进制发行版。之所以选择 quictls,是因为它是目前堪称稳定性、兼容性和特性的最佳组合。

如欲获取二进制发行版的安装说明,请访问 NGINX QUIC 网站

 

针对 QUIC+HTTP/3 的 NGINX 配置

您可以使用一些新的指令来针对 QUIC+HTTP/3 配置 NGINX,并能够轻松地将其与现有虚拟服务器配置块 (server{})中的 HTTP/1.1 和 HTTP/2 指令结合起来。

对于最基本的功能配置,您只需在 server{}配置块以及子 location{}配置块中添加以下三个指令:

指令描述
listen 443 quic reuseport;

添加一个带 quic 参数的新 listen 指令,表示 NGINX 在侦听 HTTP/1.1 和 HTTP/2 连接的相同端口上同时侦听 HTTP/3 连接,此处为 443 端口。

当存在多个 NGINX 工作进程时,需要使用 reuseport 参数来确保正确运行。它允许内核为不同的进程分发接收到的 HTTP/3 连接。

ssl_protocols TLSv1.3;

按照 QUIC 的要求,需要将 TLS 1.3 纳入可接受的协议列表。(此指令可能已存在于配置中,请在必要时添加。)

要支持全部浏览器,您可能还需要添加旧版 TLS。有关 TLS 1.3 浏览器支持的更多信息,请参阅“我能否使用 TLS 1.3?

add_header Alt-Svc 'h3=":$server_port"; ma=86400';

添加此指令,让 NGINX 添加一个响应头,告知浏览器可以升级到 QUIC 以及连接哪个端口。

按照惯例,该端口(此处由 $server_port 变量表示)与 HTTP/1.1 和 HTTP/2 的 TLS 所使用的端口相同。

ma 的值是客户端可有把握地认为 NGINX 通过 UDP 接受 HTTP/3 流量的秒数:超过这个时间后,客户端需要恢复为 TCP。此处指定的值相当于 24 小时。

server{} 块示例如下:

server {    # 为了提高兼容性,我们建议对 QUIC 和 TCP 使用相同的端口号
    listen 443 quic reuseport; # QUIC
    listen 443 ssl;             # TCP

    ssl_certificate     certs/example.com.crt;
    ssl_certificate_key certs/example.com.key;
    ssl_protocols       TLSv1.3;

    location / {
        # 通告 QUIC 在所配置的端口上可用
        add_header Alt-Svc 'h3=":$server_port"; ma=86400';
                
        #proxy_pass <upstream_group>; 
        #root       /<root_directory>; 
    }
}

现有多个新的与 HTTP/3 相关的可选指令和变量(代码片段中未显示),包括:

  • $http3—(变量)在 HTTP/3 会话期间发送请求时设置为 h3(否则为空字符串)。
  • quic_retry—(指令)当设置为 on 时,指示 NGINX 给请求者发送一个 QUIC 重试消息,指定要使用的新连接 ID,以验证请求者的 IP 地址。QUIC 重试数据包在一定程度上弥补了无法使用 TCP 三次连接握手来验证连接的不足(因为 QUIC 基于 UDP 来运行的)。
  • ssl_early_data —(指令)设置为 on, ,表示在一个新的 TLS 1.3 连接建立时,NGINX 可以从第一个请求中就获取业务数据,前提是之前已建立过与该客户端的连接。这被称为零往返时间 (0‑RTT) 连接恢复。支持“早期数据”的发送是 TLS 1.3 的一项特性,可消除 TLS 握手所需的额外往返消息交互,从而提高 QUIC+HTTP/3 的性能。

    注:0‑RTT 连接恢复可能会带来安全风险,因为如果采用了除 GET. 以外的 HTTP 请求方法,则早期数据会受到重放攻击。详情请参阅我们的博文“NGINX Plus R17 详解”中 关于 TLS 1.3 的部分

该图揭示了使用 QUIC+HTTP/3 的 0‑RTT 连接恢复如何帮助提高性能,因为客户端在恢复与 NGINX 的 QUIC 连接时可在其第一条消息中发送 HTTP 请求。相比之下,对于使用 TLS 的 TCP 连接,客户端必须与 NGINX 执行新的 TLS 握手,方可建立安全连接,这需要多次额外的数据包交互。

有关所有新指令和变量的信息,请参阅 nginx-quic README 的“3. 配置”部分。

 

测试包含 QUIC+HTTP/3 的 NGINX

如上文所述,我们发布预编译二进制文件的一个目的是为了更轻松地测试 NGINX 是否正确处理 HTTP/3 流量。对于简单的命令行测试,您可以构建支持 HTTP/3 的 curl 命令或使用预构建的容器。此外,大多数新版浏览器都支持 QUIC+HTTP/3。

要验证您支持 QUIC 的站点是否满足浏览器的 HTTP/3 连接请求,您可以使用浏览器的开发者工具来检查 NGINX 返回的 HTTP 响应头。如果 NGINX 在响应浏览器通过 TCP 发出的初始 HTTP 请求时包含上述 Alt-Svc 响应头,那么就说明 QUIC+HTTP/3 可以正常运行。

此时,支持 QUIC 的浏览器在 Alt-Svc 指令中指定的端口上建立 QUIC 连接,后续的 HTTP 请求和响应都基于 QUIC 进行。验证是否正在使用 QUIC+HTTP/3 的另一种方法是添加另一个 add_header 指令,将自定义 HTTP 标头的值设置为 $server-protocol 变量捕获的协议。您可以通过追踪改响应头的值来判断使用的协议,当响应头从 HTTP/1.x(建立 QUIC 连接之前)变为 HTTP/3.0(使用 QUIC 时)时,就证明目前使用了 QUIC。

下面是一个 location 配置块的示例,其中自定义了 HTTP 响应头为 X-protocol

location / {     # 通告 QUIC 在配置端口上可用  
    add_header Alt-Svc 'h3=":$server_port"; ma=86400'; 
       
    # 指示我们是否在使用 QUIC+HTTP/3
    add_header X-protocol $server_protocol always;        
    
    #proxy_pass <upstream_group>; 
    #root /<root_directory>; 
}

另外,还有一些工具,如 Chrome HTTP Indicator 扩展插件,它可以直观地显示正在使用的协议。(请注意,这不代表我们对任何浏览器扩展插件的推荐,您应知晓在具体情况下扩展插件可能带来的任何安全隐患)。

 

下一步计划

我们将持续提供 QUIC+HTTP/3 解决方案,并在未来几周内提供更多 NGINX 优化示例。同时,请分享您的测试结果,以供我们参考。您可以在 NGINX 开发邮件列表和 NGINX 官方微信群中分享反馈意见。

如欲了解关于 QUIC+HTTP/3 相关工作的最新动态,包括下一个重要里程碑(将 nginx-quic 仓库合并到主线 NGINX 开源版分支),请订阅 NGINX 公告邮件列表


"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."