必须写成listen 443 ssl http2,因HTTP/2在浏览器中强制要求TLS加密;需满足Nginx≥1.9.5、OpenSSL≥1.0.2e、启用http_v2_module和http_ssl_module模块、配置有效证书、TLSv1.2+及ALPN协商成功。

要在 Nginx 中真正支持 HTTP/2,不能只加 http2 参数,必须同时满足环境、编译、配置和 TLS 协商四方面条件。浏览器强制要求 HTTP/2 走加密通道,所以纯 listen 443 http2 是无效的,必须写成 listen 443 ssl http2。
确认底层是否支持 HTTP/2
HTTP/2 不是“一配即用”的功能,缺一不可:
- Nginx 版本 ≥ 1.9.5(推荐 1.20+):运行
nginx -v查看 - 编译时启用了
http_v2_module:运行nginx -V 2>&1 | grep http_v2,输出中必须含该模块 - OpenSSL 版本 ≥ 1.0.2e(建议 1.1.1 或更高):运行
nginx -V 2>&1 | grep -i openssl;再执行ldd $(which nginx) | grep ssl,确认链接的是新版 OpenSSL 库(如libssl.so.1.1) - SSL 模块也必须启用:
nginx -V 2>&1 | grep http_ssl_module应有输出
修改 server 块监听指令
在站点 HTTPS 的 server 块中,找到监听 443 的配置行,直接升级写法:
- IPv4:将
listen 443 ssl;改为listen 443 ssl http2; - IPv6:添加或改为
listen [::]:443 ssl http2; - 禁止拆成两行(例如
listen 443 ssl;+listen 443 http2;),必须合并为单条指令 - 保留原有
ssl_certificate和ssl_certificate_key路径,并确保文件存在且 Nginx 进程可读(如权限为644)
设置关键 TLS 协商参数
仅加 http2 不足以让浏览器成功协商,ALPN 依赖明确的安全策略:
- 强制启用 TLS 1.2 及以上:
ssl_protocols TLSv1.2 TLSv1.3;(务必移除TLSv1.0和TLSv1.1) - 使用现代加密套件(可选但推荐):
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...'; - 开启会话复用减少握手开销:
ssl_session_cache shared:SSL:10m; ssl_session_timeout 24h; - 彻底删除任何残留的
spdy相关指令(Nginx 1.9.5+ 已完全移除 SPDY 支持)
验证 HTTP/2 是否真正生效
别只信 nginx -t && systemctl reload nginx,要实测协议协商结果:
- 浏览器打开开发者工具 → Network 标签页 → 刷新页面 → 查任意请求的 “Protocol” 列,显示
h2才算成功 - 终端执行:
curl -I --http2 https://your-domain.com,返回头中应含HTTP/2 200,且无重定向 - 检查 ALPN 是否通告成功:
openssl s_client -alpn h2 -connect your-domain.com:443 2>/dev/null | grep ALPN,输出应为ALPN protocol: h2 - 查看 Nginx 错误日志:
/var/log/nginx/error.log,确认无ALPN negotiation failed类报错
注意 CDN 干扰:若使用 Cloudflare 免费版等中间代理,它可能终止 TLS 并以 HTTP/1.1 回源,此时 Nginx 配置再正确也无效。











