tls重协商是已建立连接上重新握手的机制,因缺乏频次限制易被滥用导致dos攻击;nginx需升级openssl、禁用旧协议、配置强密钥交换并验证生效。

连接重协商(Renegotiation)是 TLS 协议中一项被设计用于“在已建立的加密连接上重新握手”的机制,初衷合理但实现风险突出。它不等于初始握手,而是在 HTTPS 连接保持活跃时,由客户端或服务器主动发起的一次新密钥协商过程。问题核心在于:客户端可无限制、低成本地反复触发该操作,而服务器必须为每次重协商执行完整非对称运算(如 RSA 解密或 ECDSA 验证),消耗大量 CPU 资源。这直接构成 CVE-2011-1473 所描述的拒绝服务(DoS)攻击面——一台普通电脑即可瘫痪未加固的 Nginx 服务。
为什么重协商会成为安全短板?
重协商本身不是漏洞,但协议设计未强制限制频次与上下文校验,导致其易被滥用:
- 攻击者建立一个合法 TLS 连接后,持续发送伪造的 ClientHello 重协商请求,服务器无法区分真假,只能逐个响应
- 每个重协商占用一个 worker 进程的连接槽位,并触发昂贵的密码学计算,CPU 不一定飙高,但连接资源迅速耗尽
- 现代浏览器和客户端已基本弃用该机制(TLS 1.3 彻底移除),但 Nginx 若使用旧版 OpenSSL(如 1.0.1e 之前)或未显式禁用,仍默认接受客户端发起的重协商
- 日志中常见特征:大量
SSL_do_handshake() failed、ssl handshake timeout或 worker 进程长时间处于SSL_read状态
Nginx 中禁用客户端重协商的实操配置
OpenSSL 自 1.0.1 版起已支持禁用客户端发起的重协商(SSL_OP_NO_TLSv1_1 类选项不相关,关键在运行时行为控制)。Nginx 本身不提供直接开关指令,需通过以下组合方式彻底阻断:
- 升级 OpenSSL 至 1.0.2k+ 或 1.1.0+(确认编译时启用
no-renegotiation支持) - 在 Nginx 的
http或server块中添加:ssl_protocols TLSv1.2 TLSv1.3;(排除 TLS 1.0/1.1,它们更易受重协商滥用影响) - 强制服务端主导密钥协商:
ssl_prefer_server_ciphers on; - 搭配强 cipher 列表,剔除所有支持重协商的弱套件(如含
SSLv3、RC4、MD5的组合) - 验证是否生效:用
openssl s_client -connect example.com:443 -reconnect测试,若返回SSL3 alert handshake failure或直接断开,说明重协商已被拒绝
配套加固:避免“禁用失效”的常见陷阱
仅改配置不验证,极易留下盲区:
- 检查 Nginx 编译信息:
nginx -V 2>&1 | grep -i openssl,确认链接的是安全版本(如 OpenSSL 1.1.1w 或 3.0.13) - 勿依赖
ssl_verify_client optional等看似相关的指令——它们控制证书验证,不影响重协商开关 - 若业务强依赖客户端证书认证(如金融网关),应改用 TLS 1.3 的 post-handshake 认证,而非 TLS 1.2 的重协商流程
- 配合全局限流:在
http块中启用limit_req_zone $binary_remote_addr zone=ssl_handshake:10m rate=5r/s;,对 SSL 握手类请求单独限速
重协商不是必须功能,生产环境应默认关闭。它不提升安全性,只增加攻击面。只要 TLS 版本、OpenSSL 和 cipher 配置三者协同到位,禁用动作本身并不复杂,但容易因版本混淆或验证缺失而形同虚设。











