防御TLS协议降级攻击需同步收紧协议层(仅ssl_protocols TLSv1.2 TLSv1.3)、密码层(显式配置PFS+AEAD强套件并剔除RC4/3DES/SHA1等弱算法)和协商控制层(ssl_prefer_server_ciphers on仅对TLSv1.2生效且须前置清理套件),并辅以HSTS与OCSP Stapling闭环防护。

协议降级攻击不是“偶发问题”,而是配置存在可利用缺口的明确信号。它本质是攻击者在 TLS 握手阶段干扰协商,诱使连接回落到 TLSv1.0、TLSv1.1 或弱加密套件(如 RC4、3DES、SHA1)。解决的关键不在于打补丁,而在于从协议层、密码层、协商控制层三方面同步收紧。
只保留 TLSv1.2 和 TLSv1.3
旧协议本身存在设计缺陷,无法靠单个指令修复。必须显式禁用所有不安全版本:
- 在 server 块中写明:ssl_protocols TLSv1.2 TLSv1.3;
- 严禁出现 TLSv1.0、TLSv1.1、SSLv3 等字样,哪怕带空格也会导致 Nginx 启动失败
- TLSv1.3 下
ssl_ciphers和ssl_prefer_server_ciphers自动失效,它的安全性由协议自身保障;真正需要你把关的是 TLSv1.2 场景
精简并锁定强加密套件
不能依赖模糊表达(如 HIGH、!aNULL:!MD5),必须显式列出仅支持前向保密(PFS)+ AEAD 模式的组合:
- 推荐 cipher list:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
- 逐项剔除含 RC4、DES、3DES、MD5、SHA1、EXPORT、NULL、CBC-SHA 的套件
- 避免静态 RSA 密钥交换(如
RSA-AES256-SHA),它不具备前向保密
强制服务端主导协商顺序
ssl_prefer_server_ciphers on 是关键控制点,但仅对 TLSv1.2 有效,且前提是 cipher list 本身已清理干净:
- 它让 Nginx 忽略客户端提出的弱 cipher 偏好,严格按你配置的顺序选择
- 若 cipher list 里还混着 RC4,开启该指令反而会“稳稳选中”它——所以必须先清套件,再开此开关
- 确保该指令与
ssl_ciphers、ssl_protocols同时存在于同一 server 块内,全局 http 块中设置无效
叠加 HSTS 与 OCSP Stapling 形成闭环
仅靠握手层加固仍有旁路风险,需补充应用层与证书层防护:
- HSTS:在 HTTPS server 块中添加 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;,防止用户首次访问 HTTP 被劫持后发起降级试探
-
OCSP Stapling:启用 ssl_stapling on; ssl_stapling_verify on; 并配置可靠 resolver(如
resolver 8.8.8.8 8.8.4.4 valid=300s;),避免攻击者阻断或伪造 OCSP 响应绕过吊销检查 - 隐藏服务指纹:server_tokens off; 减少攻击者识别 Nginx 版本后针对性利用漏洞的可能性
改完配置后务必实测:用 openssl s_client -connect yourdomain.com:443 -tls1_2 | grep "Cipher is" 确认实际协商结果,再跑一次 SSL Labs 扫描,重点看 “Handshake Simulation” 表格中各客户端是否全部落到强套件上。不验证的配置等于没配。











