Nginx 通过超时控制、连接限流、TLS优化和速率限制四层机制防御SSL DoS攻击:严控握手与连接超时,限制单IP并发连接数,禁用高开销密码套件,叠加请求速率限制,并协同内核参数加固。

Nginx 本身不直接处理 SSL/TLS 握手的底层加密运算,但它是 HTTPS 流量的第一道入口。SSL DoS(也称 TLS DoS 或 SSL 协商耗尽攻击)的核心目标不是打满带宽,而是耗尽服务器 CPU 或连接资源——比如发起大量不完成 TLS 握手的连接、发送畸形 ClientHello、或在握手完成后立即断开,反复触发昂贵的密钥交换(尤其是 RSA 密钥解密或 ECDSA 验签)。
这类攻击发生在网络层与传输层之间,Nginx 虽无法过滤原始 TCP 包,但可通过连接管理、超时控制和前置限流显著提升抗性。关键在于:让无效或低质量的 SSL 连接尽早失败,不进入证书验证和 HTTP 解析阶段。
一、严控 TLS 握手与连接生命周期
SSL DoS 往往依赖“半开连接”或“慢速握手”,Nginx 的连接级超时配置是第一道防线:
ssl_handshake_timeout 5s;
(仅 Nginx 1.19.0+ 支持)限制 TLS 握手必须在 5 秒内完成,超时即关闭连接。这是对抗 Slow-SSL 和畸形 ClientHello 最直接的手段。client_header_timeout 8s;
客户端必须在建立 SSL 连接后 8 秒内发完完整 HTTP 请求头。避免 TLS 建立后挂起、伪装成合法用户却长期不发请求。keepalive_timeout 25s;
降低长连接保持时间。过长的 keepalive 会累积大量空闲连接,被用于连接池耗尽攻击。设为 25 秒兼顾用户体验与资源回收效率。reset_timedout_connection on;
对超时连接直接发送 RST 包而非 FIN,更快释放内核连接状态,减少 TIME_WAIT 积压。
这些指令应放在 http 或 server 块中,全局生效:
http {
ssl_handshake_timeout 5s;
client_header_timeout 8s;
keepalive_timeout 25s;
reset_timedout_connection on;
}二、基于连接数的硬性防护(防连接耗尽)
SSL DoS 常伴随海量并发连接(如每秒数千个 TLS 握手请求),单靠超时不够,需主动限连:
- 使用
limit_conn限制每个客户端 IP 的最大并发 SSL 连接数:
http {
limit_conn_zone $binary_remote_addr zone=ssl_conn:10m;
server {
listen 443 ssl http2;
# 每个 IP 最多 20 个并发 SSL 连接
limit_conn ssl_conn 20;
# 整个 server 最多 5000 个 SSL 连接(根据 worker_connections 调整)
limit_conn_zone $server_name zone=server_ssl:10m;
limit_conn server_ssl 5000;
}
}⚠️ 注意:
limit_conn统计的是已成功建立 SSL 连接并进入 HTTP 处理流程的连接。它对纯 TCP 泛洪无效,但对真实 SSL DoS(即完成 handshake 后发请求)效果明确。
三、优化 TLS 配置降低计算开销
高成本的密码套件会放大 SSL DoS 效果。应禁用老旧、CPU 密集型算法:
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; ssl_ecdh_curve secp384r1; # 关键:禁用 RSA 密钥交换(避免私钥解密运算) ssl_certificate_key /path/to/key.pem; # 确保是 ECDSA 或 Ed25519 私钥
- TLS 1.3 默认禁用 RSA 密钥交换,大幅降低握手 CPU 开销;
- 使用
secp384r1曲线比prime256v1更抗侧信道,且性能可控; - 若必须支持 TLS 1.2,确保
ssl_ciphers中不含RSA套件(如ECDHE-RSA-*可保留,但RSA单独出现的套件如AES128-SHA必须剔除)。
四、结合请求速率限流(防御握手后的应用层放大)
部分 SSL DoS 会完成握手,再高频发起 /login 或 /api/token 等高开销接口调用(即 SSL + HTTP Flood)。此时需叠加 limit_req:
http {
limit_req_zone $binary_remote_addr zone=ssl_api:10m rate=3r/s;
server {
listen 443 ssl;
location /api/auth/ {
limit_req zone=ssl_api burst=6 nodelay;
limit_req_status 429;
proxy_pass https://backend;
}
}
}-
rate=3r/s防止单 IP 持续刷认证接口; -
burst=6允许短时交互(如页面加载带多个请求),但不纵容扫描; - 返回
429 Too Many Requests比503更符合语义,也便于前端做退避重试。
五、补充建议:系统层协同加固
Nginx 配置需与内核参数配合才能发挥最大效力:
- 调小
net.ipv4.tcp_fin_timeout = 30(默认 60),加速连接回收; - 启用
net.ipv4.tcp_tw_reuse = 1,允许 TIME_WAIT socket 重用(需net.ipv4.ip_local_port_range足够宽); - 设置
net.core.somaxconn = 65535和net.core.netdev_max_backlog = 5000,防止 SYN 队列溢出; - 若部署在云环境,务必开启平台级 DDoS 基础防护(如阿里云 Anti-DDoS、AWS Shield Standard),拦截网络层泛洪,让 Nginx 专注 7 层防护。
不复杂但容易忽略。


















