前言

在 Nginx 上开启 HTTP/3 能带来不少性能和安全上的提升,这主要得益于其底层使用的 QUIC 协议(一种基于 UDP 的现代传输协议)。下面我用一个表格梳理了一下:

好处类型 具体说明 主要原因/技术
性能提升 降低延迟减少网络拥塞适应高并发场景 基于UDP、0-RTT连接重用、多路复用、改进的拥塞控制
用户体验优化 页面加载更快移动网络体验更顺畅弱网环境下更稳定 连接迁移、更好的丢包恢复机制
安全增强 默认加密减少中间人攻击风险 内置 TLS 1.3、放大攻击防御机制
技术优势 解决队头阻塞面向未来 QUIC 流级别多路复用、协议发展趋势

注意事项

虽然 HTTP/3 好处很多,但在 Nginx 上启用时也需要考虑以下几点:

  • Nginx 版本与编译需求:需要使用 Nginx 1.25.0 或更高版本

  • 实验性功能:目前 Nginx 中的 HTTP/3 支持在某些版本中可能仍标记为实验性(experimental)。生产环境部署前务必充分测试。

  • 客户端支持:主流现代浏览器(Chrome、Firefox、Edge 等)均已支持 HTTP/3,但仍需考虑旧版客户端或特定网络环境(如某些防火墙可能拦截 UDP)的兼容性问题。

  • UDP 端口开放:确保服务器的 UDP 443 端口(或其他你使用的端口)已在防火墙中打开。

  • 多服务器配置:如果一台服务器配置了多个域名,在配置 HTTP/3 监听时可能需要特别注意 reuseport 参数的使用,以避免端口冲突。

准备

官方的建议是使用 OpenSSL 3.5.1+ 的版本,或者 boringssl - Git at GoogleGitHub - quictls/openssl: TLS/SSL and crypto library with QUIC APIs

根据自身的需求,下载最新版本的SSL以及最新版的Nginx:nginx: download

截止到今天(2025年9月15日),通过包管理器安装到Nignx为 1.24.0 ,该版本不支持http3,需 1.25.0+ 才行。

如果想简单点的话,可以通过 add-apt-repository ppa:ondrej/nginx 添加Ondřej Surý 维护的 Nginx 官方 PPA (Personal Package Archive) 仓库,接下来直接使用 apt install nginx 即可升级到 1.28.0 版本,与目前最新的 1.29.1 都能支持http3,就不用进行编译了。

安装编译所需的基础工具:

1
apt install build-essential libpcre3-dev zlib1g-dev git mercurial cmake golang ninja-build perl libperl-dev libxml2-dev libxslt1-dev libexpat-dev 

编译

基于OpenSSL

一:下载OpenSSL以及Nginx

1
2
3
4
wget https://github.com/openssl/openssl/releases/download/openssl-3.5.2/openssl-3.5.2.tar.gz
tar -zxvf openssl-3.5.2.tar.gz
wget https://nginx.org/download/nginx-1.29.1.tar.gz
tar -zxvf nginx-1.29.1.tar.gz

二:编译配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
cd nginx-1.29.1

./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/run/nginx.pid \
--lock-path=/run/nginx.lock \
\
--with-threads \
--with-file-aio \
--with-pcre \
--with-pcre-jit \
\
--with-openssl=../openssl-3.5.2 \ # 指向openssl的目录
--with-http_ssl_module \
--with-http_v2_module \
--with-http_v3_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_degradation_module \
--with-http_slice_module \
--with-http_auth_request_module \
\
--with-mail \
--with-mail_ssl_module \
--with-stream \
--with-stream_realip_module \
--with-stream_ssl_module \
\
--user=www-data \
--group=www-data

出现这个提示说明配置成功了:

三:编译和安装

1
2
make -j$(nproc)
sudo make install

基于BoringSSL

一:下载BoringSSL以及Nginx

BoringSSL 用国内网络下载可能比较麻烦,不过用国内镜像就行。

1
2
3
git clone https://gitee.com/mirrors/boringssl.git
wget https://nginx.org/download/nginx-1.29.1.tar.gz
tar -zxvf nginx-1.29.1.tar.gz

二:编译BoringSSL

1
2
3
4
cd boringssl
mkdir build && cd build #创建构建目录
cmake .. -DCMAKE_BUILD_TYPE=Release # 使用 cmake 编译
make -j$(nproc)

编译完成后,关键文件:

  • 头文件:boringssl/include/

  • 静态库:boringssl/build/libssl.a 和 boringssl/build/libcrypto.a

三:编译配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
cd nginx-1.29.1

./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/run/nginx.pid \
--lock-path=/run/nginx.lock \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_v3_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-pcre \
--with-pcre-jit \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_degradation_module \
--with-http_slice_module \
--with-http_auth_request_module \
--with-mail \
--with-mail_ssl_module \
--with-stream \
--with-stream_realip_module \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-cc-opt="-I/root/boringssl/include" \ #最重要的就是这两行,写绝对路径
--with-ld-opt="-L/root/boringssl/build -L/root/boringssl/build/crypto -lssl -lcrypto -lstdc++ -lpthread -lm" \
--user=www-data \
--group=www-data \
--with-threads \
--with-file-aio \
--with-compat

出现这个提示说明配置成功了:

四:编译和安装

1
2
make -j$(nproc)
sudo make install

创建系统服务

1
vim /etc/systemd/system/nginx.service

粘贴以下内容(根据你的实际路径调整):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[Unit]
Description=nginx - high performance web server
After=network.target network-online.target
Documentation=https://nginx.org/en/docs/
Wants=network-online.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/usr/sbin/nginx -s stop
PrivateTmp=true
Restart=always

[Install]
WantedBy=multi-user.target

创建必要的目录和权限(如果不存在):

1
2
mkdir -p /var/cache/nginx /var/log/nginx
chown -R www-data:www-data /var/cache/nginx /var/log/nginx
1
2
3
4
systemctl daemon-reload
systemctl enable nginx
systemctl start nginx
systemctl status nginx

基于OpenSSL 3.5.2

基于BoringSSL

大功告成!

测试

注意:HTTP/3基于UDP 443端口,确保防火墙放行!

1:创建自签名证书(测试用)

1
2
3
4
5
6
7
8
# 创建证书目录
sudo mkdir -p /etc/nginx/certs

# 生成私钥和自签名证书(有效期 365 天)
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/nginx/certs/example.com.key \
-out /etc/nginx/certs/example.com.crt \
-subj "/CN=localhost"

2:简单配置

编辑/etc/nginx/nginx.conf ,在http块中添加内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
# for better compatibility it's recommended
# to use the same port for http/3 and https
listen 443 ssl;
listen 443 quic reuseport;

http2 on;

index index.htm index.html index.nginx-debian.html;

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

location / {
# used to advertise the availability of HTTP/3
add_header Alt-Svc 'h3=":443"; ma=86400';
}
}

3:重新载入nginx

1
systemctl reload nginx

4:访问网页

这里有个奇怪的现象,HTTP/3 并不是100%能够握手成功,不同浏览器反应的情况也不一样。

这次测试下来:

Safari浏览器成功显示HTTP/3协议

Edge显示HTTP/2协议

Chrome也显示的HTTP/2

最后

发表一下我的个人看法。

这两天其实一直在测试HTTP/3,从使用ondrej库安装,到自行编译,后来尝试了不同版本的OpenSSL,再尝试了官网涉及的BoringSSL,从本地测试,再到服务器上测试,过程不算坎坷,但是结果非常不稳定,相同的步骤、相同的配置,最终有显示HTTP/3的,大多数还是HTTP/2,而且,有一点非常令我困惑,成功握手HTTP/3后,打开页面的速度非常慢,远远不如HTTP/2。

这两天也查了很多关于HTTP/3的资料,非常有限,更多的推荐还是把网站代理到Cloudflare来支持HTTP/3。

至今也没搞懂,如果有懂的兄弟希望能帮我解惑。

记录一下这篇文章,等HTTP/3确定可行后,可以再来更新。


参考

Module ngx_http_v3_module

Support for QUIC and HTTP/3