13.8.6 连接耗尽与防护策略(slowloris、限速与限连接)

在高并发与恶意流量场景下,HAProxy常见的连接耗尽问题来自慢速读写(Slowloris)、长连接占用、突发洪峰与资源竞争。防护应覆盖连接建立、请求速率与会话持续三个层面,并与系统级限制联动,避免单点参数误配导致吞吐下降。

原理草图:连接耗尽与防护位置

文章图片

Slowloris 防护要点与示例配置
- 缩短请求头/请求体读取超时,减少慢速上传占用。
- 限制请求头大小与行数,降低内存压力。

/etc/haproxy/haproxy.cfg 关键段落:

global
  maxconn 50000
  tune.http.maxhdr 64
  tune.http.maxhdrlen 8192

defaults
  mode http
  timeout http-request 5s
  timeout http-keep-alive 10s
  timeout client 30s
  timeout server 30s
  timeout connect 3s
  timeout queue 5s

限速与限连接策略(完整可执行示例)

frontend fe_web
  bind *:80
  mode http
  maxconn 20000

  # 记录源IP当前连接数与10s请求速率
  stick-table type ip size 1m expire 30s store conn_cur,conn_rate(10s),http_req_rate(10s)
  tcp-request connection track-sc0 src

  acl too_many_conn sc0_conn_cur gt 50
  acl too_fast sc0_http_req_rate gt 200

  # 连接阶段拒绝,防止建连耗尽
  tcp-request connection reject if too_many_conn

  # 请求阶段拒绝,返回 429
  http-request deny deny_status 429 if too_fast

  default_backend bk_web

backend bk_web
  mode http
  server s1 10.0.0.11:8080 maxconn 5000
  server s2 10.0.0.12:8080 maxconn 5000

命令说明与预期效果

# 校验配置语法
haproxy -c -f /etc/haproxy/haproxy.cfg
# 预期:Configuration file is valid

# 重新加载配置(不中断连接)
systemctl reload haproxy

# 查看当前限制触发情况(示例使用 socket 管理)
echo "show info" | socat /run/haproxy/admin.sock stdio
# 关注 CurrConns、MaxConn、DeniedConn、DeniedReq

# 查看 stick-table 记录
echo "show table fe_web" | socat /run/haproxy/admin.sock stdio

慢速攻击模拟与排错

# 使用 slowhttptest 模拟 Slowloris(需安装)
# 安装(Debian/Ubuntu)
apt-get install -y slowhttptest
# 安装(RHEL/CentOS)
yum install -y slowhttptest

# 发送慢速头部(200并发,30秒)
slowhttptest -c 200 -H -g -o slow -i 10 -r 20 -t GET -u http://127.0.0.1/
# 预期:HAProxy超时限制生效,连接被快速释放,服务仍可用

系统层资源联动(避免FD耗尽)

# 查看当前打开文件数限制
ulimit -n

# 临时提高(需与 maxconn 匹配)
ulimit -n 200000

# systemd 持久化(/etc/systemd/system/haproxy.service.d/limits.conf)
[Service]
LimitNOFILE=200000

# 内核参数建议(/etc/sysctl.d/99-haproxy.conf)
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.ip_local_port_range = 1024 65000

常见排错清单
- 现象:正常用户被误伤,返回 429
处理:降低 sc0_http_req_rate 门限或放宽白名单;检查是否存在突发流量任务。
- 现象:连接瞬间堆积,qcur/qmax 快速增长
处理:检查后端健康与 timeout connect,适当增加后端并发 maxconn
- 现象:DeniedConn 持续增长但CPU低
处理:确认 maxconnulimit -n 匹配;检查 fullconn 是否触发。

练习
1. 将 timeout http-request 从 5s 调整为 2s,使用 slowhttptest 验证慢速攻击连接被更快回收。
2. 为 /api/login 路径设置更严格的限速(如 50 req/10s),其余路径保持 200 req/10s。
3. 手动降低 ulimit -n 到 1024,观察 MaxConn 与拒绝连接数的变化并恢复。

通过“超时控制 + 连接/速率限流 + 资源上限校准”的组合策略,可有效应对慢速攻击与连接耗尽风险,同时保持对正常业务流量的友好度与可用性。