必须先确认OpenSSL和Nginx编译绑定的版本均支持TLS 1.3,否则配置再正确也会静默降级至TLS 1.2;关键检查命令为nginx -V | grep -i openssl,须显示built with OpenSSL 1.1.1w或更高版本。

必须先确认 OpenSSL 和 Nginx 编译时绑定的版本是否真正支持 TLS 1.3,否则配置再正确也会静默降级到 TLS 1.2。
检查 OpenSSL 和 Nginx 是否真支持 TLS 1.3
很多人卡在“以为支持,其实不支持”这一步。nginx -v 只显示 Nginx 版本,没用;关键要看编译时链接的 OpenSSL:
- 运行
nginx -V 2>&1 | grep -i openssl,输出中必须含类似built with OpenSSL 1.1.1w—— 若是1.0.2u或1.1.0l,哪怕 Nginx 是 1.20 也无效 - 单独运行
openssl version看系统 OpenSSL 版本,只是参考;Nginx 运行时用的是它自己编译进来的那个,不是系统 PATH 下的 - Ubuntu/Debian 官方源的
nginx包默认用 OpenSSL 1.1.0 或更旧,得换装nginx-full(22.04+)或自编译;RHEL 7 需启用 EPEL 并装nginx-mod-http-ssl
server 块里必须写的 TLS 1.3 配置项
只加 ssl_protocols TLSv1.3 不够,OpenSSL 1.1.1+ 虽默认启用 TLS 1.3,但 Nginx 会因密码套件不匹配而静默失败,浏览器可能直接报 ERR_SSL_VERSION_OR_CIPHER_MISMATCH:
-
ssl_protocols TLSv1.2 TLSv1.3—— 必须同时写两个,不能只留TLSv1.3,否则老客户端连不上 -
ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256—— 这三组是 RFC 8446 正式定义的 TLS 1.3 套件,严禁混入任何ECDHE-或RSA 开头的 TLS 1.2 套件 -
ssl_prefer_server_ciphers off—— TLS 1.3 下该指令已失效,设为on反而干扰协商,建议显式关掉 - 删掉所有
ssl_ecdh_curve行(除非你明确要限制曲线),TLS 1.3 自动协商 X25519 或 P-256
Certbot 自动生成的配置需要手动补全
Certbot 1.20+ 会在 server 块里加 ssl_protocols TLSv1.2 TLSv1.3,但 ssl_ciphers 行仍沿用旧值(含 ECDHE-RSA-AES256-SHA 等),必须手动替换成纯 TLS 1.3 套件:
- 证书本身无协议绑定,RSA 2048、ECDSA secp256r1、ed25519 签发的都兼容 TLS 1.3
- OCSP Stapling 对 TLS 1.3 有效,但需确保
ssl_stapling on且ssl_trusted_certificate路径正确,否则 Safari 等浏览器可能拒绝连接 - LNMP 一键包用户注意:
lnmp.conf中的Enable_Nginx_Openssl='n'必须改为'y',并指定--with-openssl=路径重新编译
验证 TLS 1.3 是否真生效
别只信浏览器地址栏小锁图标,它不显示协议版本:
- Chrome / Edge:开发者工具 → Security 标签页 → 查看 “Connection” 下的 Protocol 字段,应为
TLS 1.3 - 命令行测试:
openssl s_client -connect example.com:443 -tls1_3 2>/dev/null | grep "Protocol",输出应为Protocol : TLSv1.3 - 线上工具推荐 SSL Labs 的测试页,它会明确标出是否协商成功、用了哪个密钥交换曲线、是否启用 0-RTT 等细节
最容易被忽略的是:即使 Nginx 配置全对,只要 nginx -V 里没看到 OpenSSL 1.1.1+,就等于没做;而一旦用了混杂密码套件,Nginx 不报错、不警告,只默默退回 TLS 1.2 —— 这种“静默失败”最耗排查时间。


















