Nginx无法直接拦截TLS重协商,防御需协同OpenSSL升级(≥1.1.0)、禁用不安全重协商、限制握手频率、前置防火墙节流及监控异常TLS行为。

Nginx 本身无法直接拦截或终止 SSL/TLS 层的重协商(Renegotiation)行为,因为 THC-SSL-DOS 这类攻击发生在 TLS 握手阶段,而 Nginx 在完成 TCP 连接建立后才开始处理 TLS 协商——此时加密计算已由 OpenSSL(或系统 TLS 库)承担,Nginx 并不参与 ServerHello、Certificate 等报文的加解密过程。因此,防御重点不在 Nginx 配置本身,而在于其前置环节与运行环境协同加固。
关闭 TLS 重协商(最直接有效)
THC-SSL-DOS 的核心是滥用客户端发起的 renegotiation 请求,让服务器反复执行高开销的密钥交换和证书签名验证。OpenSSL 自 1.1.0 起默认禁用客户端发起的重协商,但旧版本或显式启用时仍存在风险:
- 确认 OpenSSL 版本 ≥ 1.1.0(推荐升级至 1.1.1w 或 3.0.13+),并检查是否启用了
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION - 在 Nginx 的
ssl_protocols和ssl_ciphers配置之外,需通过 OpenSSL 配置或启动参数禁用不安全重协商;部分发行版可通过/etc/ssl/openssl.cnf添加:Options = UnsafeLegacyRenegotiation→ 改为注释或删除该行 - 若使用自定义编译的 OpenSSL,确保 configure 时未带
--enable-unsafe-renegotiation
限制握手频率与连接生命周期
虽不能阻止单次重协商,但可大幅提高攻击成本:
- 在 Nginx 的
http块中启用连接数与请求速率限制,针对 HTTPS 端口的/或所有location: limit_conn_zone $binary_remote_addr zone=ssl_conn:10m;limit_req_zone $binary_remote_addr zone=ssl_req:10m rate=3r/s;- 在
server { listen 443 ssl; ... }块中应用:limit_conn ssl_conn 5;limit_req zone=ssl_req burst=10 nodelay; - 配合缩短 TLS 会话超时,减少重用窗口:
ssl_session_timeout 2m;ssl_session_cache shared:SSL:10m;(避免缓存过大被滥用)
前置防护:防火墙与负载均衡层拦截
真正有效的防线通常不在 Nginx 本身:
- 在 Linux 内核层使用
iptables或nftables限制单 IP 新建 TLS 连接速率(SYN + ClientHello 频次):nft add rule ip filter input tcp dport 443 ct state new limit rate 5/minute burst 10 packets counter - 云厂商 WAF 或四层高防服务(如阿里云 Anti-DDoS Pro、腾讯云 BGP 高防)可识别异常 TLS 握手模式(如高频空 ClientHello、无 SNI、畸形扩展字段),并在流量进入服务器前清洗
- 若部署了 LVS 或硬件负载均衡器,可在其上配置 TLS 握手节流策略,将压力隔离在 Nginx 之前
监控与响应辅助手段
便于及时发现攻击迹象:
- 开启 Nginx 日志中的 TLS 相关变量(需编译时含
--with-http_ssl_module):log_format ssl_log '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $ssl_protocol $ssl_cipher $request_time'; - 关注
$ssl_protocol是否集中为老旧协议(如 TLSv1.0)、$ssl_cipher是否大量出现低强度套件(如 RC4-SHA)、$request_time是否普遍 >1s(暗示握手卡顿) - 结合
ss -s或netstat -s | grep -i "tls\|ssl"观察内核 TLS 统计异常增长


















