SYN Flood攻防下的内核TCP队列参数实战
上周线上边缘网关服务遭遇小规模SYN Flood攻击,仅配置iptables SYN包限速规则后服务仍出现大量建连超时,排查发现是内核TCP队列参数与防御规则未协同导致。以下是具体的原理分析与配置方案:
攻防场景下的内核TCP队列参数逻辑
TCP建连过程中,服务端收到客户端的SYN包后,会先将连接信息存入半连接队列(SYN队列),随后回复SYN+ACK包,待收到客户端的ACK确认包后,再将连接移入全连接队列,等待应用层调用accept接口取出处理。
SYN Flood攻击的核心逻辑是攻击者伪造大量虚假源IP发送SYN包,且不回复后续ACK包,导致半连接队列被无效条目占满,正常用户的SYN包无法入队被直接丢弃,最终表现为服务建连超时。此时若仅依赖iptables限速,仍会有大量SYN包穿透规则进入内核队列,需要配合内核参数做兜底:
- tcp_max_syn_backlog:半连接队列的最大长度,默认值通常为1024,若攻击速率超过队列处理能力,队列会在秒级被占满。
- tcp_synack_retries:服务端重发SYN+ACK包的次数,默认值为5,重试间隔从1s到32s呈指数增长,半连接条目最长会停留近2分钟,大幅降低队列周转效率。
- tcp_syncookies:半连接队列满时启用的兜底机制,不存储半连接条目,而是将连接信息编码在SYN+ACK的序列号中,等待客户端回复ACK时校验,无需占用队列空间,但会带来少量CPU计算开销。
防御规则与内核参数的协同落地
防御体系需要iptables网络层限速与内核参数兜底配合,避免单点失效。首先通过sysctl调整内核TCP相关参数,写入/etc/sysctl.d/99-tcp-defense.conf持久化生效:
# 开启SYN Cookie防御机制
net.ipv4.tcp_syncookies = 1
# 扩容半连接队列至2048,提升队列承载能力
net.ipv4.tcp_max_syn_backlog = 2048
# 减少SYN+ACK重试次数,加快无效半连接条目回收
net.ipv4.tcp_synack_retries = 2
# 扩容全连接队列,避免半连接条目快速入队后全连接队列溢出
net.core.somaxconn = 1024
# 扩容连接跟踪表容量,避免SYN包因conntrack满被丢弃
net.netfilter.nf_conntrack_max = 1000000
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 30
随后配置iptables规则限制单个源IP的SYN包速率,避免单IP占满队列:
# 允许单个源IP每秒最多10个SYN包,突发上限20个
iptables -A INPUT -p tcp --syn --dport 80 -m limit --limit 10/s --limit-burst 20 -j ACCEPT
# 其余SYN包直接丢弃
iptables -A INPUT -p tcp --syn --dport 80 -j DROP
配置生效后可通过hping3 -S -p 80 --flood <网关IP>模拟SYN Flood攻击,通过netstat -s | grep -E "SYN|SYN cookies"查看统计项:若攻击期间SYN cookies sent计数上涨,而SYNs to LISTEN sockets dropped计数无增长,说明配置生效。
需要额外注意:若业务为高频短连接场景,开启tcp_syncookies会带来约5%-8%的CPU额外开销,此时可适当调大tcp_max_syn_backlog至4096,同时将tcp_synack_retries设为1,仅在攻击发生时临时开启SYN Cookie;不要将tcp_abort_on_overflow设为1,该参数会在全连接队列满时直接发送RST包,导致正常用户建连失败,仅适用于专门抗攻击的防护节点。
- 点赞
- 收藏
- 关注作者
评论(0)