nginx 1.25.0+ 编译启用 --with-http_v3_module 和 --with-stream_quic_module、配置 tls 1.3 + udp 监听 + alt-svc 头才能运行 http/3;默认 apt 安装包不支持,须自行编译或换用官方 mainline 镜像。

直接说结论:Nginx 1.25.0+ 编译时启用 --with-http_v3_module 和 --with-stream_quic_module,再配好 TLS 1.3 + UDP 监听 + Alt-Svc 头,就能跑 HTTP/3;但默认不带 QUIC 支持的二进制包(比如 apt 安装的)根本不行,必须自己编译或换镜像。
确认 Nginx 是否真支持 HTTP/3 模块
很多人卡在这一步就以为配好了,其实 nginx -V 输出里没看到 --with-http_v3_module 就等于没支持。官方 mainline 包(如 nginx.org 的 deb)从 1.25.0 起才带该模块,但 Ubuntu/Debian 默认源里的 nginx 通常还是 1.18 或 1.22,压根不含这个 flag。
- 运行
/usr/sbin/nginx -V 2>&1 | grep http_v3_module,有输出才说明模块存在 - 如果用的是 Docker,别信“latest”标签——查清基础镜像是否基于 1.25.0+ 且编译参数含
--with-http_v3_module - OpenSSL 版本也得 >= 3.0,否则即使模块在,
listen 443 quic会启动失败并报错unknown directive "quic"
listen 443 quic reuseport 是关键,不是加个 http3 on 就完事
Nginx 的 HTTP/3 不是开关式配置,它依赖真实的 UDP 端口监听。TCP 的 listen 443 ssl 和 UDP 的 listen 443 quic reuseport 必须共存于同一个 server 块,缺一不可。漏掉 quic 这行,浏览器永远收不到 HTTP/3 升级提示。
-
reuseport强烈建议加上——它让多个 worker 进程能同时绑定 UDP 443,避免单点瓶颈;内核需 >= 3.9,现代发行版基本满足 - 不能写成
listen 443 ssl http2 quic:HTTP/2 是 TCP 协议,QUIC 是 UDP,二者协议栈完全不同,语法上不兼容 - 端口可以不是 443(比如测试用 8443),但客户端必须能访问该 UDP 端口——防火墙要放行
udp/443,而不仅是tcp/443
Alt-Svc 头必须手动加,且路径和有效期要对
Alt-Svc 是浏览器决定是否切到 HTTP/3 的唯一依据。Nginx 不自动发这个头,也不校验你写的格式是否合法——写错就等于没写。
- 标准写法是
add_header Alt-Svc 'h3=":443"; ma=86400';,注意引号嵌套和冒号位置:h3=":443"不能写成h3="443"或h3="https://example.com:443" -
ma=86400表示缓存时间(秒),太小会导致频繁重协商;设为 0 浏览器会忽略该头 - 这个头只在 HTTPS 响应中有效,HTTP 请求里加了也白加;且必须出现在
server或location块里,不能只放在http全局 - Chrome 地址栏输入
chrome://net-internals/#quic可实时查看 Alt-Svc 是否被识别、是否已缓存
TLS 配置比 HTTP/2 更严格,TLSv1.3 + early_data 是刚需
HTTP/3 强制要求 TLS 1.3,且很多优化特性(如 0-RTT)依赖底层加密库。OpenSSL 3.0+ 可用,但若想稳定用 ssl_early_data on,推荐 BoringSSL 或 QuicTLS。
-
ssl_protocols TLSv1.3;必须显式声明,删掉TLSv1.2——混用会触发连接降级,QUIC 无法建立 -
ssl_early_data on;开启后,客户端可复用会话密钥发首帧数据,但服务端需配合检查$http3变量或日志字段,否则可能重复处理请求 -
ssl_session_tickets off;是 QUIC 场景下的常见建议——因为会话票证机制与 QUIC 的连接迁移逻辑冲突,留着反而增加握手失败概率
真正容易被忽略的是 UDP 网络路径:中间任何一跳设备(包括云厂商 SLB、家用路由器、企业防火墙)若丢弃 UDP 443 包,HTTP/3 就彻底不可达,而浏览器 fallback 到 HTTP/2 时完全无感知。上线前务必用 sudo tcpdump -i any udp port 443 在服务器抓包,确认 UDP 流量真实进出。











