HTTP3 正式发布,很快哦,安排上!

2022-07-29 08:35:13 浏览数 (1)

QUIC

互联网工程任务组(IETF)近期发布了 HTTP/3 的 RFC,这是超文本传输协议 HTTP 的第三版。

根据 IETF 的原文中所述:

QUIC 传输协议具有 HTTP 传输所需的几个特性,例如多路复用、每个流的流控制和低延迟连接。该文档还确定了 QUIC 包含的 HTTP/2 功能,并描述了如何将 HTTP/2 扩展移植到 HTTP/3。

官方文档

简要简介一下 QUIC:

QUIC 是英文“Quick UDP Internet Connections”的简写,由 Google 创建并于 2013 年发布。Google 开发 QUIC 是为了解决传输控制协议 (TCP) 需要多次来回建立连接并开始传输数据的问题。因此,它会产生很长的往返时间,这可能会转化为糟糕的用户体验。 QUIC 改为使用用户数据报协议 (UDP) 来传输流量。UDP 减少了客户端和服务器之间的往返次数,因此加快了速度。这在移动网络上很重要,因为移动网络仍然是一个非常有争议的资源,任何可以加速它们的东西都是受欢迎的。

谷歌非常喜欢 QUIC,以至于在 2020 年,这家巨头将其嵌入到自己的 Chrome 浏览器中,并在自己的服务中启用。微软也非常喜欢 QUIC,它创建了自己的版本并将其开源。

尽管 QUIC 的普及率有所提高,但世界上的大部分数据流量仍然通过依赖于 TCP 的 HTTP/2 传输。因此,早在 2016 年,当网络专家开始考虑 HTTP/3 时,将其映射到 QUIC 作为一种加速网络的方式是有意义的。但他们也确保 HTTP/3 和 HTTP/2 可以共存。

HTTP3 和 HTTP2 之间的区别

下图中,我总结了 HTTP3 和 HTTP2 之间的区别:

在这里插入图片描述

在 Nginx 中配置 HTTP3

准备

目前要让 NGINX 支持 HTTP/3,需要从源代码构建来支持。

首先,命令行中运行如下命令:

代码语言:javascript复制
wget -O /etc/apt/trusted.gpg.d/nginx_signing.asc https://nginx.org/keys/nginx_signing.key
echo deb-src https://nginx.org/packages/mainline/debian bullseye nginx >> /etc/apt/sources.list
echo -e 'Package: *nPin: origin nginx.orgnPin: release o=nginxnPin-Priority: 900' > /etc/apt/preferences.d/99nginx
apt-get update
apt-get upgrade
apt-get build-dep nginx
apt-get install cmake git golang libunwind-dev mercurial rsync

获取 NGINX 及其 QUIC 分支的源代码

接着,获取 NGINX 及其 QUIC 分支的源代码。运行这些命令:

代码语言:javascript复制
apt-get source nginx
mv nginx-1.21.4 nginx
hg clone -b quic https://hg.nginx.org/nginx-quic
rsync -r nginx-quic/ nginx
cd nginx

请注意,NGINX 的版本可能不同。

然后我们需要获取 BoringSSL 源代码并将其构建为一个模块。但是,NGINX 的 OCSP 实现与 BoringSSL 不兼容,那就可能需要 OCSP 补丁。你可以使用以下命令,通过补丁并解决问题:

代码语言:javascript复制
wget https://raw.githubusercontent.com/kn007/patch/master/Enable_BoringSSL_OCSP.patch
patch -p1 < Enable_BoringSSL_OCSP.patch

接着,运行这些命令来处理 BoringSSL。

代码语言:javascript复制
mkdir debian/modules
cd debian/modules
git clone https://github.com/google/boringssl
mkdir boringssl/build
cd boringssl/build
cmake ..
make -j$(nproc)
cd ../..

你可能还想添加 Brotli 压缩支持。只需运行此命令:

代码语言:javascript复制
git clone --recursive https://github.com/google/ngx_brotli

编辑构建规则

编辑 nginx/debian 中的规则文件:

代码语言:javascript复制
cd ..
nano rules

找到 config.env.nginx 并设置 CFLAGS="-Wno-ignored-qualifiers"

然后在 --sbin-path=/usr/sbin/nginx 之后添加 --add-module="

确保删除原始的 --with-cc-opt--with-ld-opt 并替换为上述内容。

构建为 deb 包

上述工作做的都差不多的话,你可以将代码构建为 Debian 软件包。运行这些命令:

代码语言:javascript复制
cd ..
dpkg-buildpackage -b

然后安装它(请注意,包的名称可能不同):

代码语言:javascript复制
dpkg -i nginx_1.21.4-1~bullseye_amd64.deb

当需要使用 Debian Bullseye 使另一台 PC 具有支持 HTTP/3 的 NGINX 时,只需复制该软件包并使用 dpkg 安装它,无需再次构建。因此可以保留那个包,因为你将来可能需要它。

编辑 Nginx 配置文件

这是官方给出的配置信息: https://quic.nginx.org/readme.html

代码语言:javascript复制
Experimental QUIC support for nginx
-----------------------------------

1. Introduction
2. Installing
3. Configuration
4. Clients
5. Troubleshooting
6. Contributing
7. Links

1. Introduction

    This is an experimental QUIC [] / HTTP/ [] support for nginx.

    The code is developed in a separate "quic" branch available
    at https://hg.nginx.org/nginx-quic.  Currently it is based
    on nginx mainline 1.21.x.  We merge new nginx releases into
    this branch regularly.

    The project code base is under the same BSD license as nginx.

    The code is currently at a beta level of quality and should not
    be used in production.

    We are working on improving HTTP/ support with the goal of
    integrating it to the main NGINX codebase.  Expect frequent
    updates of this code and don't rely on it for whatever purpose.

    We'll be grateful for any feedback and code submissions however
    we don't bear any responsibilities for any issues with this code.

    You can always contact us via nginx-devel mailing list [].

    What works now:

    We support IETF QUIC version 1.  Internet drafts are no longer supported.

    nginx should be able to respond to HTTP/ requests over QUIC and
    it should be possible to upload and download big files without errors.

      The handshake completes successfully
      One endpoint can update keys and its peer responds correctly
      -RTT data is being received and acted on
      Connection is established using TLS Resume Ticket
      A handshake that includes a Retry packet completes successfully
      Stream data is being exchanged and ACK'ed
      An H transaction succeeded
      One or both endpoints insert entries into dynamic table and
      subsequently reference them from header blocks
      Version Negotiation packet is sent to client with unknown version
      Lost packets are detected and retransmitted properly
      Clients may migrate to new address

2. Installing

    You will need a BoringSSL [] library that provides QUIC support

    $ hg clone -b quic https://hg.nginx.org/nginx-quic
    $ cd nginx-quic
    $ ./auto/configure --with-debug --with-http_v_module         
                       --with-cc-opt="-I../boringssl/include"     
                       --with-ld-opt="-L../boringssl/build/ssl    
                                      -L../boringssl/build/crypto"
    $ make

    Alternatively, nginx can be configured with QuicTLS []

    $ ./auto/configure --with-debug --with-http_v_module         
                       --with-cc-opt="-I../quictls/build/include" 
                       --with-ld-opt="-L../quictls/build/lib"

    When configuring nginx, you can enable QUIC and HTTP/ using the
    following new configuration options:

        --with-http_v_module     - enable QUIC and HTTP/
        --with-stream_quic_module - enable QUIC in Stream

3. Configuration

    The HTTP "listen" directive got a new option "http3" which enables
    HTTP/ over QUIC on the specified port.

    The Stream "listen" directive got a new option "quic" which enables
    QUIC as client transport protocol instead of TCP or plain UDP.

    Along with "http3" or "quic", you also have to specify "reuseport"
    option [] to make it work properly with multiple workers.

    To enable address validation:

        quic_retry on;

    To enable -RTT:

        ssl_early_data on;

    Make sure that TLS 1.3 is configured which is required for QUIC:

        ssl_protocols TLSv.3;

    To enable GSO (Generic Segmentation Offloading):

        quic_gso on;

    To limit maximum UDP payload size on receive path:

        quic_mtu <size>;

    To set host key for various tokens:

        quic_host_key <filename>;


    By default, GSO Linux-specific optimization [] is disabled.
    Enable if your network interface is configured to support GSO.

    A number of directives were added that configure HTTP/:

        http_stream_buffer_size
        http_max_concurrent_pushes
        http_max_concurrent_streams
        http_push
        http_push_preload
        http_hq (requires NGX_HTTP_V_HQ macro)

    In http, an additional variable is available: $http.
    The value of $http is "h3" for HTTP/ connections,
    "hq" for hq connections, or an empty string otherwise.

    In stream, an additional variable is available: $quic.
    The value of $quic is "quic" if QUIC connection is used,
    or an empty string otherwise.

Example configuration:

    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 http3 reuseport;
            listen 8443 ssl;

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

            location / {
                # required for browsers to direct them into quic port
                add_header Alt-Svc 'h3=":8443"; ma=86400';
            }
        }
    }

4. Clients

    * Browsers

        Known to work: Firefox   and Chrome   (QUIC version )

        Beware of strange issues: sometimes browser may decide to ignore QUIC
        Cache clearing/restart might help.  Always check access.log and
        error.log to make sure you are using HTTP/ and not TCP https.

    * Console clients

        Known to work: ngtcp, firefox's neqo and chromium's console clients:

        $ examples/client 127.0.0.1  https://example.com:/index.html

        $ ./neqo-client https://127.0.0.1:/

        $ chromium-build/out/my_build/quic_client http://example.com:


   If you've got it right, in the access log you should see something like:

   127.0.0.1 - - [/Apr/:::  ] "GET / HTTP/3"   "-"
                                         "nghttp3/ngtcp2 client" "quic"


5. Troubleshooting

    Here are some tips that may help you to identify problems:

      Ensure you are building with proper SSL library that supports QUIC

      Ensure you are using the proper SSL library in runtime
      (`nginx -V` will show you what you are using)

      Ensure your client is actually sending requests over QUIC
      (see "Clients" section about browsers and cache)

      We recommend to start with simple console client like ngtcp
      to ensure you've got server configured properly before trying
      with real browsers that may be very picky with certificates,
      for example.

      Build nginx with debug support [] and check your debug log.
      It should contain all details about connection and why it
      failed. All related messages contain "quic " prefix and can
      be easily filtered out.

      If you want to investigate deeper, you may want to enable
      additional debugging in src/event/quic/ngx_event_quic_connection.h:

        #define NGX_QUIC_DEBUG_PACKETS
        #define NGX_QUIC_DEBUG_FRAMES
        #define NGX_QUIC_DEBUG_ALLOC
        #define NGX_QUIC_DEBUG_CRYPTO

6. Contributing

    If you are willing to contribute, please refer to
    http://nginx.org/en/docs/contributing_changes.html

7. Links

    [] https://datatracker.ietf.org/doc/html/rfc
    [] https://datatracker.ietf.org/doc/html/rfc
    [] https://mailman.nginx.org/mailman/lists/nginx-devel.nginx.org/
    [] https://boringssl.googlesource.com/boringssl/
    [] https://github.com/quictls/openssl
    [] https://nginx.org/en/docs/http/ngx_http_core_module.html#listen
    [] https://nginx.org/en/docs/debugging_log.html
    [] http://vger.kernel.org/lpc_net_talks/willemdebruijn-lpc-udpgso-paper-DRAFT-1.pdf
    ```

要启用 Brotli,只需添加 brotli on; 在 NGINX 配置的 http 上下文中。

对于 OCSP 补丁,使用 ssl_stapling_file。 可以通过运行以下命令来创建它:openssl ocsp -no_nonce -issuer /path/to/intermediate -cert /path/to/cert -url "$(openssl x509 -in /path/to/cert -noout -ocsp_uri)" -respout /path/to/ocsp

最后,你可以测试一下是否配置成功。

测试 HTTP3

这个网站可以用来测试你的域名是否支持 HTTP 3:

https://http3check.net/

0 人点赞