在 Nginx 中配置启用多域名站点的 HTTP/3 支持
- 前端开发
- -473分钟前
- 2热度
- 0评论
HTTP/3 是基于 QUIC 协议的新一代 HTTP 协议,具有高性能和可靠性的特点。Nginx 从 1.25.0 版本开始正式支持 HTTP/3。在基于源码编译安装 Nginx 时,增加 --with-http_v3_module 参数即可开启 HTTP/3 支持。
1 编译与配置 Nginx 支持 HTTP/3
首先下载 nginx 最新稳定版源码:
wget https://nginx.org/download/nginx-1.30.0.tar.gz
tar -zxvf nginx-1.30.0.tar.gz
cd nginx-1.30.0
然后解压进入 nginx 源码目录,编译安装 Nginx。示例:
# 安装依赖
sudo apt-get install -y build-essential libpcre3 libpcre3-dev zlib1g-dev openssl-dev
# 配置编译参数。注意:这里的 openssl 路径需要替换为实际的路径,openssl 版本需大于 3.5.1
/configure \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_v3_module \
--with-http_stub_status_module \
--with-stream \
--with-stream_ssl_module \
--with-openssl=/path/to/openssl
# 编译与安装
make test # 测试
make
make install
接着配置 Nginx 站点启用 HTTP/3。示例:
http {
server {
# 配置域名
server_name lzw.me www.lzw.me;
listen 443 ssl;
listen [::]:443 ssl; # ipv6 支持
# 启用 QUIC 以启用 HTTP/3
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
# 配置 SLL 证书
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
# 添加 alt-svc header,告知访问客户端战站点已启用 HTTP/3
add_header Alt-Svc 'h3=":443"; ma=86400';
location / {
root /var/www/html;
index index.html;
}
}
}
以上即是开启 HTTP/3 的基本配置。
2 Nginx 多站点配置支持 HTTP/3 问题
当同一台服务器按照上述方法配置了多个站点时,nginx 配置重载会报如下错误:
nginx: [emerg] duplicate listen options for 0.0.0.0:443
2.1 报错根源:HTTP/3 的监听逻辑特殊性
与基于 TCP 的 HTTP/1.1 和 HTTP/2 不同,HTTP/3 采用 UDP 协议传输数据。在 Nginx 中,UDP 端口的监听规则更为严格:同一个 IP 和端口组合(如 0.0.0.0:443),quic 和 reuseport 等高级监听选项只能在一个 server 块中声明一次。
如果您为每个域名单独配置 listen 443 ssl http2 quic reuseport;,Nginx 会认为这些高级选项重复绑定,从而抛出 duplicate listen options 错误。这并非 Nginx 的设计缺陷,而是 UDP 协议的特性要求——单个 QUIC 监听器即可通过 SNI(服务器名称指示)自动区分不同域名的流量。
2.2 解决方案一:合并 Server 块(最简单易懂,但配置耦合)
如果多个站点的配置逻辑相似(如使用同一套 SSL 证书、基础路由规则一致),可以将所有域名合并到同一个 server 块中。这种方式不仅能避免监听冲突,还能简化配置维护。
配置示例:
server {
# 标准 HTTPS 监听(TCP,兼容 HTTP/2 和 HTTP/1.1)
listen 443 ssl http2;
listen [::]:443 ssl http2;
# HTTP/3 监听(UDP,仅需声明一次)
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
# 定义所有需要启用 HTTP/3 的域名
server_name example.com www.example.com blog.example.com;
# SSL 证书配置(支持通配符证书或多域名证书)
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
# 强制启用 TLS 1.3(HTTP/3 协议要求)
ssl_protocols TLSv1.3;
# 告知客户端支持 HTTP/3(关键响应头)
add_header Alt-Svc 'h3=":443"; ma=86400';
# 通用路由配置
location / {
root /usr/share/nginx/html;
index index.html;
# 可选:根据域名区分根目录
if ($host = 'blog.example.com') {
root /var/www/blog;
}
}
}
配置要点:
- 监听指令唯一性:
quic和reuseport仅在 UDP 监听中声明一次,TCP 监听保持常规配置。 - 多域名绑定:通过
server_name同时绑定多个域名,Nginx 会自动根据请求域名分发流量。 - Alt-Svc 响应头:必须添加该头部,告知浏览器当前站点支持 HTTP/3,否则浏览器不会主动发起 HTTP/3 请求。
2.3 解决方案二:独立 Server 块
特别注意:该方案仅理论参考,个人实际配置实践时发现,会导致所有站点在基于 H3 请求时都变成访问配置了 quic reuseport 的站点!!!
如果您的多个站点配置差异较大(如使用不同 SSL 证书、独立的日志规则或复杂路由),可以保留独立的 server 块,但需严格遵循监听规则:仅在一个 server 块中声明 quic 和 reuseport,其他站点仅保留基础监听配置。
配置示例
主站点(承载 QUIC 监听器)
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
# 仅在主站点声明 HTTP/3 监听
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.pem;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.3;
add_header Alt-Svc 'h3=":443"; ma=86400';
location / {
root /var/www/example.com;
index index.html;
}
}
副站点(无需声明 QUIC 监听)
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
# 注意:此处不要添加 quic 和 reuseport 参数
server_name blog.example.com;
ssl_certificate /etc/nginx/ssl/blog.example.com.pem;
ssl_certificate_key /etc/nginx/ssl/blog.example.com.key;
ssl_protocols TLSv1.3;
# 副站点也必须添加 Alt-Svc 响应头
add_header Alt-Svc 'h3=":443"; ma=86400';
location / {
root /var/www/blog.com;
index index.html;
}
}
配置要点:
- 监听器唯一性:仅在主站点的
server块中声明quic reuseport,其他站点仅保留 TCP 监听。 - SNI 自动分发:Nginx 的 QUIC 监听器会自动根据请求的 SNI 信息,将流量转发到对应的
server块,无需额外配置。 - 全局 Alt-Svc:所有站点都必须添加
Alt-Svc响应头,否则浏览器只会对主站点发起 HTTP/3 请求,副站点仍会使用 HTTP/2。
3 配置 HTTP/3 后的关键检查
1. 防火墙配置
HTTP/3 使用 UDP 443 端口,务必确保服务器防火墙开放该端口:
- Ubuntu/UFW:
sudo ufw allow 443/udp - CentOS/Firewalld:
sudo firewall-cmd --permanent --add-port=443/udp && sudo firewall-cmd --reload - 云服务器:在云服务商的安全组规则中,添加 UDP 443 端口的入站许可。
2. 配置验证
修改配置后,先测试语法正确性,再重载 Nginx:
# 测试配置语法sudo nginx -t
# 重载配置(无需重启服务)sudo systemctl reload nginx`
3. HTTP/3 可用性验证
- 浏览器验证:打开 Chrome 开发者工具 → Network 面板 → 刷新页面 → 查看 "Protocol" 列,若显示
h3则表示 HTTP/3 已生效。 - 命令行验证:使用支持 HTTP/3 的 curl 版本测试:
curl -I --http3 https://example.com若返回
HTTP/3 200状态码,则说明配置成功。
4 常见问题解答
Q:为什么副站点没有使用 HTTP/3?
A:请检查副站点是否添加了 Alt-Svc 响应头。浏览器需要通过该头部判断站点是否支持 HTTP/3,否则会默认使用 HTTP/2。
Q:可以为不同站点配置不同的 HTTP/3 端口吗?
A:可以,但不推荐。HTTP/3 默认使用 443 端口,使用非标准端口会增加用户端的配置复杂度,且大多数浏览器优先尝试 443 端口的 HTTP/3 连接。
Q:Nginx 1.30.0 之前的版本支持多站点 HTTP/3 吗?
A:Nginx 1.25.0 开始原生支持 HTTP/3,但 1.30.0 之前的版本可能存在一些兼容性问题,建议升级到最新稳定版。
5 总结
Nginx 1.30.0 多站点 HTTP/3 配置的核心是理解 UDP 监听的特殊性:单个 QUIC 监听器即可处理多个域名的流量。通过合并 server 块或保留单个 QUIC 监听器的方式,即可轻松解决 duplicate listen options 报错。
无论选择哪种方案,都需确保所有站点添加 Alt-Svc 响应头,并开放 UDP 443 端口。HTTP/3 带来的低延迟体验,将为您的用户带来更流畅的访问体验,同时提升网站的核心竞争力。 (AI生成)
相关参考:
- https://quic.nginx.org
- https://www.echo.cool/docs/middleware/nginx/nginx-advanced-features/nginx-http3-support/