Back
Featured image of post NGINX 的 HTTP/3 尝试

NGINX 的 HTTP/3 尝试

利用 Cloudflare 开源的 quiche 项目给 NGINX 添加 HTTP/3 支持

前言

2019 年 9 月 26 日,Cloudflare 正式启用了 HTTP/3,详情见 HTTP/3: the past, the present, and the future。随后 10 月 17 日 Cloudflare 放出了基于 quiche 项目 的 NGINX patch,详情见 Experiment with HTTP/3 using NGINX and quiche。也正是这个 Patch 才会有这篇水文,而关于 HTTP/3 的介绍不再赘述,有兴趣的可以去 HTTP / 3:从头到脚的介绍 看看。

安装

参照 给 NGINX 添加 TLSv1.3 支持 准备除 OpenSSL 相关的依赖(OpenSSL 本体和三个 patch)
注意:同时打 HTTP/3 patch 和 hakasenyang 的 HPACK patch 需要手动解决冲突 (auto/options 文件),或者可以先打 HTTP/3 patch 然后再打 我修改过的 HPACK patch

另外虽然 Cloudflare 的文章里说该 patch 只在 NGINX 1.16.x 可用,但实测 1.17.x 也没什么问题。

Note that the HTTP/3 and QUIC patch only works with the 1.16.x release branch (the latest stable release being 1.16.1).

quiche

git clone --recursive https://github.com/cloudflare/quiche
cd nginx-1.17.6
patch -p1 < ../quiche/extras/nginx/nginx-1.16.patch

P.s. 指定 commit 的原因是最近 Cloudflare 的几个提交添加了 h3-24 草案的支持,但会导致浏览器端的 h3-23 无法正常使用以及 http3check.net 的测试结果不正常。 最新 commit 修好了。

编译

configure 配置参照 给 NGINX 添加 TLSv1.3 支持 去除 --with-cc-opt--with-ld-opt 以及 --with-openssl-opt 部分。然后添加以下参数,最后照常编译、测试、安装到系统。

    --build="quiche-$(git --git-dir=../quiche/.git rev-parse --short HEAD)" \
   	--with-http_v3_module \
   	--with-openssl=../quiche/deps/boringssl \
   	--with-quiche=../quiche

配置 NGINX

确保 ssl_protocols 包含 TLSv1.3,然后将 quicreuseport 选项添加到单独的 listen 配置里,并添加对应的 alt-svc 头。
注意:有多个站点时 reuseport 参数只需要添加一次,否则 NGINX 会报错。

events {
    worker_connections  1024;
}

http {
    server {
        # Enable QUIC and HTTP/3.
        listen 443 quic reuseport;

        # Enable HTTP/2 (optional).
        listen 443 ssl http2;

        ssl_certificate      cert.crt;
        ssl_certificate_key  cert.key;

        # Enable all TLS versions (TLSv1.3 is required for QUIC).
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

        # Add Alt-Svc header to negotiate HTTP/3.
        add_header alt-svc 'h3-27=":443"; ma=86400, h3-25=":443"; ma=86400, h3-24=":443"; ma=86400, h3-23=":443"; ma=86400';
    }
}

客户端测试

浏览器

查看 HTTP/3 支持表:Can I use…

由此表可知 Firefox 需要 72+ 并在 about:config 内 打开 network.http.http3.enabled 而 Chrome 需要 79+ 并自行添加 --enable-quic(这个参数如果已经使用 flags 开启了则可忽略)和 --quic-version=h3-23 启动命令,我这里使用 Microsoft Edge 稳定版演示。

edge-command
edge-command

添加完参数后,打开支持 HTTP/3 (h3-23) 的站点,使用开发者工具的网络功能可以看到如果 HTTP/3 成功连接,协议会显示为 http/2+quic/99(暂时)

edge-developer-tools-network
edge-developer-tools-network

curl

拉取 quiche 和 BoringSSL

git clone --recursive https://github.com/cloudflare/quiche

编译 BoringSSL

cd quiche/deps/boringssl
mkdir build
cd build
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=on ..
make
cd ..
mkdir -p .openssl/lib
cp build/crypto/libcrypto.a build/ssl/libssl.a .openssl/lib
ln -s $PWD/include .openssl

编译 quiche

cd ../..
QUICHE_BSSL_PATH=$PWD/deps/boringssl cargo build --release --features pkg-config-meta

拉取并编译 curl

cd ..
git clone https://github.com/curl/curl
cd curl
./buildconf
./configure LDFLAGS="-Wl,-rpath,$PWD/../quiche/target/release" --with-ssl=$PWD/../quiche/deps/boringssl/.openssl --with-quiche=$PWD/../quiche/target/release --with-libssh2 --enable-alt-svc --with-librtmp --enable-tls-srp --with-gssapi --enable-doh
make
sudo make install

测试

 π curl master ❯ /usr/local/bin/curl -I --http3 https://love4taylor.com
HTTP/3 200
server: nginx/1.17.6
date: Wed, 04 Dec 2019 03:08:01 GMT
content-type: text/html
content-length: 10740
vary: Accept-Encoding
etag: "5de3d7e3-29f4"
strict-transport-security: max-age=31536000; includeSubDomains; preload
alt-svc: h3-23=":443"; ma=86400
accept-ranges: bytes

curl-http3
curl-http3

采用知识共享署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 许可协议进行许可
最后更新于 Sep 15, 2020 08:08 +0800
Built with Hugo
Theme Stack designed by Jimmy