client_header_timeout不防慢速TLS握手,仅作用于TLS完成后的HTTP请求头读取阶段;防慢速TLS握手须用ssl_handshake_timeout,它控制TCP建连后至TLS握手完成的最大等待时间,超时即断连释放资源。

client_header_timeout 不用于防范慢速 TLS 握手,它完全不介入 TLS 协商阶段。
这个指令只在 TCP 连接已建立、且 TLS 握手已完成的前提下才开始计时——准确来说,是从 Nginx 收到客户端发来的第一个 HTTP 请求字节(例如 G in GET / HTTP/1.1)起,到完整收到请求头(含结尾的 \r\n\r\n)为止。TLS 握手失败、卡住或被拖慢,发生在更底层,此时 Nginx 甚至还没进入 HTTP 解析流程。
防慢速 TLS 握手,该用 ssl_handshake_timeout
这才是专治“恶意慢速握手”的参数:
- 它控制的是:从 TCP 连接建立成功后,到 SSL/TLS 握手完成的最大允许时间
- 超时后 Nginx 主动关闭连接,不占用 worker 进程、不进入请求处理队列
- 默认值通常为 60 秒(部分版本无默认,依赖系统 socket 超时),对防御扫描器过长
✅ 推荐配置:
ssl_handshake_timeout 10s;
- 10 秒足以覆盖绝大多数正常客户端(包括弱网重试),又能快速中断每秒只发几个 TLS 记录字节的恶意握手(如
sslsplit类探测或自定义慢握手工具) - 若服务面向老旧设备或高丢包链路,可放宽至 15 秒;内网或可信终端环境可压至 5–7 秒
必须同步收紧的配套项
单设 ssl_handshake_timeout 效果有限,需组合加固:
-
禁用老旧协议,减少握手往返
ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; # 启用 TLS 1.3 的 1-RTT/0-RTT 优势
-
限制新建连接速率(防握手洪泛)
limit_conn_zone $binary_remote_addr zone=sslhandshake:10m; limit_conn sslhandshake 5; # 单 IP 每秒最多 5 次新握手
启用
multi_accept+ 调高worker_connections
避免握手积压阻塞 accept 队列,尤其在高并发入口层-
记录并监控异常握手
在error_log中开启warn或更高级别,关注:SSL_do_handshake() failed no suitable signature algorithm client sent invalid compressed data
结合
$ssl_protocol、$remote_addr做 fail2ban 封禁
如何验证是否生效?
用 openssl s_client 模拟慢握手(需配合工具如 slowhttptest 或自写脚本):
# 模拟握手延迟 >10 秒 → 应被 Nginx 主动断开,而非等待超时 slowhttptest -c 10 -H -g -o slowhttp-report -i 15 -r 1 -t GET -u https://your-site.com/ -x 10
同时检查 Nginx error log 是否出现:
*xx* ssl handshake timeout while SSL handshaking
且 netstat -ant | grep :443 | grep SYN_RECV 不再长期堆积大量连接。
它和 client_header_timeout 是两条平行防线:
前者守加密通道建立关,后者守HTTP 头部送达关,各司其职,不可替代。


















