琐碎笔记

支持 QUIC 的 NGINX 官方预览版部署体验

佩佩 · 7月1日 · 2020年 · · · · · · · · · · · 本文共7570个字 · 预计阅读26分钟17793次已读

前言

2020 年 6 月 10 日 Nginx 官方博客发文《Introducing a Technology Preview of NGINX Support for QUIC and HTTP/3》,同时对外发布了 QUICNginx 的分支传送,部署说明传送喜欢尝鲜的我自然是要体验一下的。

CloudFlare 官方 quiche 补丁版推荐

操作环境

准备工作

  • 安装相关依赖
# CentOS
sudo yum install mercurial psmisc net-tools wget curl build-essential lsb-release cmake golang libunwind-dev git libpcre3-dev zlib1g-dev

# Ubuntu
sudo apt-get install mercurial golang libgeoip-dev libunwind-dev libgoogle-perftools-dev
hg clone -b quic https://hg.nginx.org/nginx-quic --insecure
# 这里我直接使用的是 Google 的 BoringSSL 作为 ssl 库
git clone https://boringssl.googlesource.com/boringssl

注意:官方的 OpenSSL 目前是不支持 QUICHTTP/3 的,但经过第三方修改而支持的有:

  • BoringSSL 分支
git clone https://boringssl.googlesource.com/boringssl
  • tatsuhiro-t 分支
git clone --depth 1 -b OpenSSL_1_1_1g-quic-draft-29 https://github.com/tatsuhiro-t/openssl
  • akamai 分支
git clone --depth 1 --branch master-quic-support https://github.com/akamai/openssl
  • 编译 BoringSSL
# 进入 BoringSSL 目录
cd /www/server/nginx/src/boringssl

# 创建用到的目录
mkdir -p build .openssl/lib .openssl/include

# 建立软链接 
ln -sf /www/server/nginx/src/boringssl/include/openssl /www/server/nginx/src/boringssl/.openssl/include/openssl

# 生成库文件
touch /www/server/nginx/src/boringssl/.openssl/include/openssl/ssl.h

# 预编译
cmake -B/www/server/nginx/src/boringssl/build -H/www/server/nginx/src/boringssl

# 编译 
make -C /www/server/nginx/src/boringssl/build

# 拷贝编译好的库文件
cp /www/server/nginx/src/boringssl/build/crypto/libcrypto.a /www/server/src/nginx/boringssl/build/ssl/libssl.a /www/server/nginx/src/boringssl/.openssl/lib
  • 准备 Nginx 模块
# 打补丁,使得 Nginx 使用 BoringSSL 时支持 OCSP Stapling
curl https://raw.githubusercontent.com/kn007/patch/master/Enable_BoringSSL_OCSP.patch | patch -p1

# jemalloc
git clone https://github.com/jemalloc/jemalloc.git
pushd jemalloc
./autogen.sh
make -j$(nproc --all)
touch doc/jemalloc.html
touch doc/jemalloc.3
sudo make install
echo '/usr/local/lib' | sudo tee /etc/ld.so.conf.d/local.conf
sudo ldconfig
popd

# zlib (Cloudflare)
git clone https://github.com/cloudflare/zlib.git
pushd zlib
./configure
popd

# libatomic_ops
git clone https://github.com/ivmai/libatomic_ops.git
pushd libatomic_ops
./autogen.sh
./configure
make -j$(nproc --all)
make install
sudo ldconfig
popd

# pcre
wget https://ftp.pcre.org/pub/pcre/pcre-8.44.zip
unzip pcre-8.44.zip&&rm pcre-8.44.zip
pushd pcre-8.44
./configure
popd

# ngx_brotli
# 支持使用包管理器安装的 brotli 库
git clone https://github.com/eustas/ngx_brotli.git
pushd ngx_brotli
git submodule update --init
popd

# ngx_pegespeed
git clone https://github.com/apache/incubator-pagespeed-ngx.git
mv incubator-pagespeed-ngx ngx-pagespeed
pushd ngx-pagespeed
wget https://dl.google.com/dl/page-speed/psol/1.13.35.2-x64.tar.gz
tar -xzvf 1.13.35.2-x64.tar.gz
popd

# 安装LuaJIT
wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz
tar -xzvf LuaJIT-2.0.5.tar.gz
pushd LuaJIT-2.0.5
make && make install
popd

# redis2-nginx-module
wget https://github.com/openresty/redis2-nginx-module/archive/v0.14.tar.gz
tar xf v0.14.tar.gz
mv redis2-nginx-module-0.14 redis2-nginx-module

# 其它杂项
git clone https://github.com/arut/nginx-python-module.git
git clone https://github.com/alibaba/nginx-http-footer-filter.git
git clone https://github.com/openresty/replace-filter-nginx-module.git
git clone https://github.com/AirisX/nginx_cookie_flag_module
git clone https://github.com/aperezdc/ngx-fancyindex.git
git clone https://github.com/simplresty/ngx_devel_kit.git
git clone https://github.com/arut/nginx-dav-ext-module.git
git clone https://github.com/leev/ngx_http_geoip2_module.git
git clone https://github.com/sto/ngx_http_auth_pam_module.git
git clone https://github.com/openresty/headers-more-nginx-module.git
git clone https://github.com/wandenberg/nginx-sorted-querystring-module.git
git clone https://github.com/yaoweibin/ngx_http_substitutions_filter_module.git

编译安装

关于 Nginx 其它模块或详见博客其它相关文章

相关推荐

  • 这是官方的
./auto/configure --with-debug --with-http_v3_module       \
                       --with-cc-opt="-I../boringssl/include"   \
                       --with-ld-opt="-L../boringssl/build/ssl  \
                                      -L../boringssl/build/crypto"
make
  • 这是整合了官方后的我的编译配置
# 进入源码目录
cd /www/server/nginx/nginx-quic

# 预编译
./auto/configure --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/redis2-nginx-module --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/ngx-pagespeed --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --add-module=/www/server/nginx/src/ngx_brotli --add-module=/www/server/nginx/src/nginx-http-concat --add-module=/www/server/nginx/src/nginx-sorted-querystring-module --add-module=/www/server/nginx/src/ngx_http_substitutions_filter_module --add-module=/www/server/nginx/src/headers-more-nginx-module --with-http_stub_status_module --with-pcre=/www/server/nginx/src/pcre-8.44 --with-zlib=/www/server/nginx/src/zlib --with-http_slice_module --with-http_ssl_module --with-http_v2_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_random_index_module --with-http_secure_link_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-google_perftools_module --with-http_geoip_module --with-http_v3_module --with-http_quic_module --with-stream_quic_module --with-ld-opt=-ljemalloc --with-cc-opt="-I../boringssl/include" --with-ld-opt="-L../boringssl/build/ssl -L../boringssl/build/crypto"

# 执行编译指令
make -j$(nproc --all)

# 复制新的编译好的执行文件 nginx,覆盖替换旧版本执行文件 nginx
mv /www/server/nginx/sbin/nginx /www/server/nginx/sbin/nginx.bak
cp /www/server/nginx/src/nginx-quic/objs/nginx /www/server/nginx/sbin/nginx

# 无痛升级
make upgrade

# 或
make install

配置文件

# 以官方配置为例
server {
            # for better compatibility it's recommended
            # to use the same port for quic and https
            listen 443 http3 quic reuseport;;
            listen 443 ssl http2;

            ssl_certificate     certs/example.com.crt;
            ssl_certificate_key certs/example.com.key;
            ssl_protocols       TLSv1.3;
            quic_retry on;
            ssl_early_data on;
            http3_max_table_capacity 50;
            http3_max_blocked_streams 30;
            http3_max_concurrent_pushes 30;
            http3_push 10;
            http3_push_preload on;

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

可能遇到的异常

  • 异常信息
./auto/configure: error: certain modules require OpenSSL QUIC support.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using --with-openssl=<path> option.
  • 解决办法
# 可能你没有执行上面的这一步
cp /www/server/nginx/src/boringssl/build/crypto/libcrypto.a /www/server/nginx/src/boringssl/build/ssl/libssl.a /www/server/nginx/src/boringssl/.openssl/lib

# 或将编译好的库libcrypto.a和libssl.a手动拷贝到/usr/local/lib目录下,执行
touch ../boringssl/.openssl/include/openssl/ssl.h

# 然后重新执行
make -j$(nproc --all)

测试

这里以 Windows 平台 Chrome v85 版 Edge 为例,快捷方式右键-属性,在目标末尾加上运行参数“--enable-quic --quic-version=h3-27”,记得以空格隔开。经自测,目前 Google Chrome Canary 最新版 v91.0.4455.0 只需要在配置里开启 QUIC 支持,无需额外添加启动参数即可直接支持 QUIC(最低h3-27)。

支持 QUIC 的 NGINX 官方预览版部署体验

以该快捷方式启动 Edge,访问支持 QUIC 的网站测试,如 Nginx 官方测试页 https://quic.nginx.org/ ,有如下提示说明当前浏览器已成功建立了 QUIC 连接。

支持 QUIC 的 NGINX 官方预览版部署体验

最后打开我的博客 https://www.nange.cn/F12 查看下,协议类型为 h3-27,说明当前支持的是草案 27 版本。如果协议不是 h3,可多刷新几次。其它浏览器本次并未测试。

支持 QUIC 的 NGINX 官方预览版部署体验

说明

目前 Nginx 官版 QUIC 支持草案 29,28,27,默认为草案 27,不支持草案 27 之前的版本。如需支持草案 28 或草案 29,需要修改 Nginx 源码 src/event/ngx_event_quic.h 中的草案版本号,然后重新编译即可。目前官方 Nginx 预览版最高支持 QUIC 草案 2734。以下代码已在新版本中移除。

/* Supported drafts: 27, 28, 29*/
#ifndef NGX_QUIC_DRAFT_VERSION
#define NGX_QUIC_DRAFT_VERSION               29
#endif

本文所说的 HTTP/3 指的是 IETF QUIC,而非 Google QUIC,这两个,现阶段是完全不同的分支。文中说的 Nginx 官版QUIC 包括本博客其它文章之前提到的 Cloudflarequiche 补丁只支持 IETF QUIC,还没有支持 Google QUIC所以 IETF QUICGoogle Chrome 浏览器中并不被很好地支持,需要指定启动项,当然它自家的 Google QUIC 倒是支持的很好。最新版火狐是直接走 IETF QUICHTTP/3 的,且支持得很好。目前经自测 Google Chrome Canary 最新版 v91.0.4455.0 只需要在配置里开启 QUIC 支持,无需额外添加启动参数即可直接支持 QUIC(最低 h3-27)。

由于当前 NGINX 官版 QUIC 还不太稳定,故本站已切回 CloudFlare 的 Quiche 版的 QUIC。

结束

Enjoy it !


本文作者:佩佩
原文链接:https://www.nange.cn/quic-http3-for-nginx-official.html
版权声明:若无特殊注明,文章均为本站【楠格】原创,并以《知识共享署名-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》协议进行许可,转载时请以超链接形式标明文章原始出处和作者信息,否则谢绝转载!

22 条回应
  1. BRO.BIRD2021-10-24 · 22:39

    新版本的 nginx-quic 可以使用 https://github.com/quictls/openssl 直接编译了,博主可以试一下

  2. BRO.BIRD2020-10-10 · 21:19

    尝试用akamaiopenssl静态编译,一直提示

    ./auto/configure: error: certain modules require OpenSSL QUIC support.
    
    You can either do not enable the modules, or install the OpenSSL library
    
    into the system, or build the OpenSSL library statically from the source
    
    with nginx by using --with-openssl= option.

    难道不能静态编译吗?

    • 佩佩2020-10-10 · 22:00

      akamai的我没试过,我直接用的BoringSSL。我也不清楚。可能需要你手动开启QUIC支持,你编译的时候加上参数,类似于”--with-openssl-opt=enable-xxx” 的参数试试。

      • BRO.BIRD2020-10-10 · 23:14

        看了下github的README,默认是开启的QUIC

        • 佩佩2020-10-11 · 1:04

          我忽然发现我文中已经给出了解决方法,请自行查看文中异常部分。

          • BRO.BIRD2020-10-11 · 1:41

            之前似乎试过,并没有编译成功,请问您在Akamai_Openssl环境下试过吗?我稍后再试试……

          • BRO.BIRD2020-10-11 · 16:06

            试过了,还是提示一样的内容,似乎boringsslopenssl的编译步骤并不能通用……

            • 佩佩2020-10-12 · 19:33

              这个解决方法本来就是OpenSSL的解决方法,只不过是tatsuhiro-t分支的。如果还未果,那就把你系统自带的OpenSSL编译升级为此次要用的版本。我在最初也同样遇到了该情况,谷歌了一番才以此解决。要善用搜索引擎,虽然有很多雷同且无用的答案,但只要耐心,还是能找到解决之法的。

  3. huihui2020-9-7 · 0:30

    按照你的编译依旧不能启用http3返回状态为 ERR_INVALID_CHUNKED_ENCODING

  4. XMapst2020-8-27 · 8:59
    /usr/bin/ld: objs/src/core/nginx.o: relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a PIE object; recompile with -fPIC
    /usr/bin/ld: objs/src/core/ngx_log.o: relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a PIE object; recompile with -fPIC
    /usr/bin/ld: objs/src/core/ngx_palloc.o: relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a PIE object; recompile with -fPIC
    /usr/bin/ld: objs/src/core/ngx_hash.o: relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a PIE object; recompile with -fPIC
    .....
    /usr/bin/ld: module/boringssl/build/crypto/libcrypto.a(e_rc4.c.o): relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIC
    /usr/bin/ld: module/boringssl/build/crypto/libcrypto.a(obj_xref.c.o): relocation R_X86_64_32S against `.rodata' can not be used when making a PIE object; recompile with -fPIC
    /usr/bin/ld: module/boringssl/build/crypto/libcrypto.a(asn1_gen.c.o): relocation R_X86_64_32 against `.text' can not be used when making a PIE object; recompile with -fPIC
    /usr/bin/ld: module/boringssl/build/crypto/libcrypto.a(x509_att.c.o): relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIC
    /usr/bin/ld: module/boringssl/build/crypto/libcrypto.a(v3_akey.c.o): relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIC
    /usr/bin/ld: module/boringssl/build/crypto/libcrypto.a(v3_bitst.c.o): relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIC
    /usr/bin/ld: module/boringssl/build/crypto/libcrypto.a(v3_extku.c.o): relocation R_X86_64_32 against `.text' can not be used when making a PIE object; recompile with -fPIC
    /usr/bin/ld: module/boringssl/build/crypto/libcrypto.a(v3_ia5.c.o): relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIC
    /usr/bin/ld: final link failed: Nonrepresentable section on output
    collect2: error: ld returned 1 exit status
    make[1]: *** [objs/Makefile:423: objs/nginx] Error 1

    我参考你的编译,但是提示这个错误,该如何解决

    • 佩佩2020-8-27 · 15:19

      很明显,你的BoringSSL没编译。

      • XMapst2020-8-28 · 9:07
        cd $(pwd)/module/boringssl
        mkdir -p build .openssl/lib .openssl/include
        ln -sf $(pwd)/include/openssl $(pwd)/.openssl/include/openssl
        touch $(pwd)/.openssl/include/openssl/ssl.h
        cmake -B$(pwd)/build -H$(pwd)
        make -C $(pwd)/build
        cp $(pwd)/build/crypto/libcrypto.a $(pwd)/build/ssl/libssl.a $(pwd)/.openssl/lib
        cd ../../

        有编译的呀

  5. Lucifer2020-8-11 · 14:08

    博主,我在

    ./auto/configure

    之后,显示下面的东西,是还缺少什么嘛

    adding module in /www/server/nginx/src/lua_nginx_module
    ./auto/configure: error: no /www/server/nginx/src/lua_nginx_module/config was found
  6. chj2020-7-23 · 17:57

    博主您好!请问nginx配置里的ssl_certificatekey是需要自己申请证书吗,能详细讲一下这块怎么申请呢。。我用openssl申请的证书可以吗,域名需要填哪一个呢

    • 佩佩2020-7-23 · 18:10

      openssl自签证书是不被信任的,你需要申请受信任的 SSL 证书,目前免费的 SSL 证书有 Let's SSL 和亚洲诚信的 SSL,你可以到这里申请 SSL 免费证书,传送。其它相关的 Nginx 如何配置证书的,你可以网上搜一下,这类教程还是很多的。

  7. tenny2020-7-11 · 19:41

    博主,编译nginx-quic,遇到这个情况咋弄感谢感谢。

    • 佩佩2020-7-11 · 19:44

      什么错误?

      • tenny2020-7-11 · 19:48
        -o objs/src/event/modules/ngx_epoll_module.o \
        	src/event/modules/ngx_epoll_module.c
        cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
        	-o objs/src/os/unix/ngx_linux_sendfile_chain.o \
        	src/os/unix/ngx_linux_sendfile_chain.c
        cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
        	-o objs/src/event/ngx_event_openssl.o \
        	src/event/ngx_event_openssl.c
        cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
        	-o objs/src/event/ngx_event_openssl_stapling.o \
        	src/event/ngx_event_openssl_stapling.c
        cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
        	-o objs/src/event/ngx_event_quic.o \
        	src/event/ngx_event_quic.c
        cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
        	-o objs/src/event/ngx_event_quic_transport.o \
        	src/event/ngx_event_quic_transport.c
        src/event/ngx_event_quic_transport.c: In function ‘ngx_quic_create_stream’:
        src/event/ngx_event_quic_transport.c:54:9: error: comparison is always true due to limited range of data type [-Werror=type-limits]
              : ((uint32_t) value) type);
                       ^
        cc1: all warnings being treated as errors
        make[1]: *** [objs/src/event/ngx_event_quic_transport.o] Error 1
        make[1]: Leaving directory `/root/nginx-quic'
        make: *** [build] Error 2
        • 佩佩2020-7-11 · 19:53

          参考这篇文章《Nginx 配置启用 QUIC 和 HTTP/3.0》中出错四的解决方法。

          • tenny2020-7-11 · 19:58

            博主你好,这个是执行./configure的结果,是否有问题,https://www.nihaoshijie.com.cn/mypro/others/log.txt

            • 佩佩2020-7-13 · 18:59

              你没复制完呐,不过我看没啥问题。

  8. tenny2020-7-11 · 19:35

    博主 ,编译nginx-quic,这个错误啥情况,感谢感谢