# 使用nginx-quic开启HTTP/3

QUIC是什么博主已经在以前的文章中提到过了,故不在赘述
本次使用nginx-quic开启HTTP/3支持,基于ubuntu 22.04LTS系统和宝塔面板

# 开始之前的准备

你的宝塔nginx必须是1.22版本或更高版本,如果不是请卸载->编译安装
记得备份nginx主配置文件(/www/server/nginx/conf/nginx.conf),下面开始安装前置库:

apt install build-essential ca-certificates zlib1g-dev libpcre3 libpcre3-dev tar unzip libssl-dev wget curl git cmake ninja-build golang

随后执行:

apt install hgsubversion

如果报错,更改为:

apt install mercurial

# 编译boringssl

众所周知,openssl已经把QUIC支持扔到一边了,所以本次使用boringssl提供ssl支持
执行下列指令编译boringssl:

下列指令需要gcc支持C++14或更高标准,建议升级为gcc9以上版本

git clone --depth=1 https://github.com/google/boringssl.git 
# github速度问题自行解决
cd boringssl
mkdir build
cd build
cmake -GNinja ..
ninja
cd ../..

如果出现了网络问题,执行如下命令:

go env -w GOPROXY=https://goproxy.cn,direct

如果站点的SSL配置使用了OSCP装订(ssl_stapling)请直接注释
boringssl不支持OSCP装订,会导致后续步骤无法执行

# 获取并编译nginx-quic

# 获取nginx-quic

使用hg获取nginx-quic的代码:

hg clone -b quic https://hg.nginx.org/nginx-quic
apt-get build-dep nginx

获取nginx编译参数:

nginx -V #或/www/server/nginx/sbin/nginx -V

结果应该类似于下面:

nginx version: nginx/1.22.0
built by gcc 11.2.0 (Ubuntu 11.2.0-19ubuntu1) 
built with OpenSSL 1.1.1o
TLS SNI support enabled
configure arguments: --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 --add-module=/www/server/nginx/src/nginx-sticky-module --with-openssl=/www/server/nginx/src/openssl --with-pcre=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 --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

configure arguments记住并做更改: 将--with-openssl参数删除,修改--with-pcre=pcre-8.43--with-pcre=/www/server/nginx/src/pcre-8.43
添加下列参数在末尾: --with-http_v3_module --with-stream_quic_module --with-cc-opt=-I../boringssl/include --with-ld-opt='-L../boringssl/build/ssl -L../boringssl/build/crypto'(boringssl路径注意一下)

# 编译nginx-quic

执行下列命令:

cd nginx-quic
./auto/configure "你的configure arguments"

等到配置结束后,删除objs/Makefile中的-Werror参数
随后更改nginx模块源码,让部分模块适配nginx 1.23
打开/www/server/nginx/src/lua_nginx_module/src/ngx_http_lua_headers_in.c文件,转到162行,将cookies更改为cookie
更改后的代码如下:

offsetof(ngx_http_headers_in_t, cookie),

打开/www/server/nginx/src/nginx-sticky-module/ngx_http_sticky_module.c文件,转到207行,将代码更改为如下内容:

if (ngx_http_parse_multi_header_lines(r, r->headers_in.cookie, &iphp->sticky_conf->cookie_name, &route) != NULL) {

随后开始编译:

make -j8 # -j后为你的CPU核心数乘以2

# 替换nginx

开始替换原本的nginx:

mv /www/server/nginx/sbin/nginx{,.bak}
cp objs/nginx /www/server/nginx/sbin
make upgrade

# 配置HTTP/3

打开站点配置文件,在listen 443 ssl http2后增加:

listen 443 quic reuseport;

添加后所有站点都会开启HTTP/3,不要重复配置(会报错)

root xxx之后添加:

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

随后开启防火墙udp(推荐使用宝塔防火墙应用),将443端口更改为tcp/udp
服务器安全组也需要开启UDP443端口

# 检验HTTP/3是否生效

edge浏览器进入edge://flags/,搜索Experimental QUIC protocol调整为enable即可打开
建议安装http-indicator,当小闪电变成橙色时HTTP/3就开启了
也可以使用网络面板,如果资源为h3协议,代表开启了HTTP/3

# 常见问题

Q: 出现nginx: [warn] "ssl_stapling" ignored, not supported导致make upgrade无法运行
A: 调整站点配置文件/www/server/panel/vhost/nginx/*.conf,将ssl_staplingssl_stapling_verify删除

Q: 出现无原因的nginx conf test failed
A: 卸载宝塔nginx防火墙后应该会解决

# 参考文章

教程:宝塔编译Nginx开启HTTP/3
make it compatible with nginx 1.23