!!! 本文档基于截止 2023-08-25 测试,后续可能版本变更或失效 !!!

参考 nginx 官方文档

准备工作

  1. 一台已经安装了宝塔面板的服务器(本文基于ubuntu 20.04)
  2. 编译安装nginx 1.23(目前nginx-quic源编译的是1.23.4)
  3. 准备编译、下载的环境 apt install build-essential ca-certificates zlib1g-dev libpcre3 libpcre3-dev tar unzip libssl-dev wget curl git cmake ninja-build golang hgsubversion
  4. 下载boringssl git clone --depth=1 https://github.com/google/boringssl.git
  5. 下载nginx、准备nginx编译环境 hg clone -b quic https://hg.nginx.org/nginx && apt-get build-dep nginx
    本文下载的目录结构如下:
    root@ubuntu:/data/# tree -L 2
    .
    ├── nginx
    │ ├── auto
    │ ├── conf
    │ ├── contrib
    │ ├── src
    │ ├── ...
    └── boringssl
    ├── BUILDING.md
    ├── CMakeLists.txt
    ├── ...

环境配置

  1. 宝塔安装完后,不会自动配置luajit的环境,但宝塔nginx的编译是需要的,所以需要手动配置一下
    export LUAJIT_LIB=/usr/local/lib
    export LUAJIT_INC=/usr/local/include/luajit-2.1
  2. go联网可能有问题,配置 export GOPROXY=https://mirrors.cloud.tencent.com/go/

编译boringssl

  1. 进入boringssl目录,创建build目录 mkdir build && cd build
  2. 编译 cmake -GNinja .. && ninja
  3. 如果 ninja 编译失败,可以尝试 cmake ../ && make -j$(nproc)

编译nginx

  1. 先获取宝塔的nginx编译配置 nginx -V,删除--with-openssl=...配置,修改--with-pcre=pcre-8.43--with-pcre=/www/server/nginx/src/pcre-8.43
  2. 在最后添加 --with-debug --with-http_v3_module --with-cc-opt="-I../boringssl/include" --with-ld-opt="-L../boringssl/build/ssl -L../boringssl/build/crypto"
  3. 到nginx的源码目录下,./auto/configure,然后make -j$(nproc)
    root@ubuntu:/data/nginx# ./auto/configure --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge  --with-pcre=/www/server/nginx/src/pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --add-module=/www/server/nginx/src/ngx_http_substitutions_filter_module-master --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --add-module=/www/server/nginx/src/nginx-dav-ext-module --with-debug --with-http_v3_module --with-cc-opt="-I../boringssl/include" --with-ld-opt="-L../boringssl/build/ssl -L../boringssl/build/crypto"
    root@ubuntu:/data/nginx# make -j$(nproc)
    需要注意,objs/Makefile 中的 -Werror 可能会导致错误,可以尝试删除。并且切记,不要 make install
  4. 编译完成后,将编译好的nginx替换掉宝塔的nginx
    root@ubuntu:/data/nginx# cp objs/nginx /www/server/nginx/sbin/nginx
    root@ubuntu:/data/nginx# make upgrade

使用http3

参考 nginx 官方文档,有说明哪些参数用于http3

  1. listen 443 quic 用于启用quic;reuseport 用于启用多进程(只能同时在一个listen中使用)
  2. add_header Alt-Svc 'h3=":443"; ma=8600'; 用于通知浏览器可以使用HTTP/3

遗留问题

  1. 实际上,浏览器并不总是能够使用http3,但是目前还没有找到解决方案
  2. 至少有一个网站使用了listen 443 ssl http2后,才能够使用http3
  3. quic似乎和宝塔的https防窜站有冲突,开启后没有一次使用了quic

效果

http3-dnsquery效果
当前网页效果(不佳)

root@ubuntu:/data# netstat -lnp |grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 355445/nginx: maste
tcp 0 0 0.0.0.0:888 0.0.0.0:* LISTEN 355445/nginx: maste
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 355445/nginx: maste
udp 0 0 0.0.0.0:443 0.0.0.0:* 355445/nginx: maste
root@ubuntu:/data#