nginx启用tls 1.3需同时满足openssl≥1.1.1编译支持、server块内显式配置ssl_protocols tlsv1.2 tlsv1.3和专用tls 1.3密码套件,缺一不可;否则即使版本达标也会静默降级至tls 1.2。

要在 Linux 上让 Nginx 真正启用现代加密套件与 TLS 协议,核心不是“加功能”,而是精准控制协议版本、密码套件、协商逻辑,并配合底层依赖验证。光改配置文件一行,不验证、不匹配、不覆盖所有 server 块,等于没做。
确认 OpenSSL 和 Nginx 支持 TLS 1.3
OpenSSL 版本决定上限:必须是 1.1.1 或更高(如 1.1.1w、3.0.x)。运行以下命令检查:
-
nginx -V 2>&1 | grep -i openssl—— 必须看到built with OpenSSL 1.1.1或类似字样 - 若显示
OpenSSL 1.0.2或1.1.0,哪怕 Nginx 是 1.22 也无法启用 TLS 1.3 - Ubuntu/Debian 用户建议添加
ppa:ondrej/nginx;CentOS/RHEL 7 需手动编译或换用 EPEL + nginx-mainline
在每个 HTTPS server 块中显式配置协议与套件
ssl_protocols 和 ssl_ciphers 必须写在 server { listen 443 ssl; ... } 块内,不能放在 http 或 location 中,否则完全无效。
- 协议行写法:
ssl_protocols TLSv1.2 TLSv1.3;(注意分号、空格、大小写) - 禁止出现
TLSv1、TLSv1.1—— 含任一旧版本,Nginx 就可能降级协商 - TLS 1.3 密码套件要单独指定:
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256; - 旧套件如
ECDHE-ECDSA-AES256-GCM-SHA384不可用于 TLS 1.3,混入会导致握手失败
加固协商行为与密钥交换
只设协议和套件还不够,客户端仍可能绕过你的偏好选择弱项,需主动干预协商流程:
- 开启服务端优先:
ssl_prefer_server_ciphers on;(对 TLS 1.2 及更早必需) - TLS 1.3 下该指令已失效,建议明确写为
ssl_prefer_server_ciphers off; - 禁用所有含
RC4、MD5、SHA1、DES、3DES的套件 - OCSP Stapling 推荐开启:
ssl_stapling on; ssl_stapling_verify on;,避免 Safari/iOS 连接延迟或警告
重载后必须实测,不能只靠语法检查
nginx -t 只校验语法是否合法,不验证实际连接行为。必须手工测试关键场景:
- 验证 TLS 1.1 被拒:
openssl s_client -connect example.com:443 -tls1_1 -servername example.com→ 应返回handshake failure - 验证 TLS 1.2 可用:
openssl s_client -connect example.com:443 -tls1_2 -servername example.com→ 应完成握手并显示证书信息 - 验证 TLS 1.3 可用:
openssl s_client -connect example.com:443 -tls1_3 -servername example.com→ 查看输出中Protocol是否为TLSv1.3 - 用 SSL Labs 测试页 全面扫描,确认评级达 A 或 A+











