慢速攻击占满连接表,如何调整内核参数并验证无正常用户被误杀

解读

面试官想确认三件事:

  1. 能否快速识别“慢速攻击”在内核层面的表现——半开/全开连接表被耗尽,SYN Cookie、TIME_WAIT、keepalive 等机制是否生效;
  2. 是否熟悉 Linux 内核参数(net.ipv4.*)与 systemd 服务参数的组合调优,而不仅是背参数;
  3. 能否在压测环境里构造“慢速”特征(低带宽、超长间隔、分片报文),并用可量化的指标证明“正常用户”不受影响——这是国内甲方/银行/运营商现场最常问的风险回退验证。

知识点

  1. 慢速攻击类型:Slowloris、HTTP 慢体、慢读、TCP 空闲连接、SockStress;
  2. 内核三张表:半连接(SYN queue)、全连接(accept queue)、ESTABLISHED 连接表;
  3. 关键参数: net.ipv4.tcp_max_syn_backlog
    net.core.somaxconn
    net.ipv4.tcp_syncookies
    net.ipv4.tcp_slow_start_after_idle
    net.ipv4.tcp_keepalive_time/intvl/probes
    net.netfilter.nf_conntrack_max / buckets
    net.ipv4.ip_local_port_range
    UFW/iptables 的 conntrack 超时(tcp-established、tcp-fin、tcp-close);
  4. 观测工具:ss -s, nstat -az, conntrack -C, /proc/net/sockstat, perf top, ebpf trace;
  5. 误杀判定指标:正常并发下 95th RT 上涨 <10%,错误率 0,零 RST,零重传增长,业务黄金流程(登录、下单、支付)成功率 100%;
  6. 国内合规:等保 2.0 要求“具备连接数阈值告警与自动封禁”,但需“白名单可回退”,所以参数调整必须支持热回滚。

答案

一、攻击复现

  1. 在隔离压测网段用 slowhttptest -H -c 3000 -g -o slowloris -i 10 -r 200 -l 1200 占满 nginx 的 worker_connections;
  2. 同时用 iptables -A INPUT -p tcp --dport 443 -m conntrack --ctstate ESTABLISHED -j DROP 模拟 conntrack 表满场景,确认正常流量 502。

二、内核参数调整(CentOS 7/8、EulerOS、麒麟 V10 通用)

  1. 扩大半连接容量
    echo "net.ipv4.tcp_max_syn_backlog = 8192" >> /etc/sysctl.conf
  2. 防止 SYN flood 直接占满
    echo "net.ipv4.tcp_syncookies = 1"
  3. 提高 accept queue
    echo "net.core.somaxconn = 4096"
    并在 nginx/java 的 listen(backlog) 显式写 4096,保持一致;
  4. 缩短空闲连接存活时间,让慢速连接更快被回收
    echo "net.ipv4.tcp_keepalive_time = 30"
    echo "net.ipv4.tcp_keepalive_intvl = 10"
    echo "net.ipv4.tcp_keepalive_probes = 3"
  5. 关闭慢启动重启,减少 RTT 抖动
    echo "net.ipv4.tcp_slow_start_after_idle = 0"
  6. 放大端口池,避免源端口耗尽
    echo "net.ipv4.ip_local_port_range = 1024 65000"
  7. 针对 conntrack 表
    echo "net.netfilter.nf_conntrack_max = 1048576"
    echo "net.netfilter.nf_conntrack_tcp_timeout_established = 300"
    并写进 /etc/modprobe.d/nf_conntrack.conf 持久化;
  8. 对 systemd 服务增加 LimitNOFILE=1000000,确保 nginx/tomcat 打开文件句柄足够。

三、热加载与回滚
sysctl -p /etc/sysctl.conf 立即生效;
提前在 ansible 里写 rollback 任务:sysctl -w net.ipv4.tcp_max_syn_backlog=128,可在 30 秒内回退。

四、验证无正常用户被误杀

  1. 在同一压测集群起两套流量:
    A. 正常流量:JMeter 线程 500,TPS 1k,95th RT 基线 120 ms;
    B. 慢速攻击:slowloris 3000 连接,每秒发送 1 字节;
  2. 持续 30 min,观察:
    • ss -s 的 ESTAB 数量稳定在 12k,无暴涨;
    • conntrack -C 使用率 <60%;
    • JMeter 报告错误率 0%,95th RT 125 ms(上涨 4%),满足 SLA;
    • 业务黄金流程脚本(模拟用户登录-下单-支付)100% 成功;
    • 同时 tcpdump 抓取白名单 IP,无 RST 或重传突增;
  3. 出具《内核参数变更验证报告》,附测试环境拓扑、脚本、指标截图(面试时可口述细节),评审通过后再上生产。

五、生产加固

  1. 接入层 WAF 开启“慢速攻击”模型,阈值:单 IP 上行 <1KB/s 且连接时长 >300s,触发弹验证码;
  2. 交换机 ACL 限速 1Mbps/单 IP,防止单用户打满上行;
  3. 7×24 监控 Prometheus + Grafana:node_nf_conntrack_entries / node_nf_conntrack_entries_limit >0.8 立即告警;
  4. 每季度灰度演练,保持 ansible playbook 可一键回滚。

拓展思考

  1. IPv6 场景下没有 nf_conntrack,需改用 ip6tables raw 表 NOTRACK,或开启内核 CONFIG_NF_CONNTRACK_IPV6,参数如何对齐?
  2. 云原生环境,Pod 共享宿主机 conntrack,Sidecar Envoy 的 idle_timeout 与内核 keepalive 参数如何联动,才能既防慢速攻击又避免 502?
  3. 如果业务长连接是 WebSocket,心跳 60s,但运营商 NAT 超时 30s,调低 tcp_keepalive_time 会误杀正常 NAT 用户,如何设计双层心跳(应用层 25s、TCP 层 90s)来平衡?
  4. 在信创 ARM64 服务器上,发现开启 SYN Cookie 后 CPU ksoftirqd 飙高,如何用 perf 定位是哈希函数还是 cache 伪共享,给出优化 patch 思路。