Linux 服务器被大量 SYN 包淹没但 conntrack 表没满的几种隐藏攻击方式

9次阅读

SYN洪水但conntrack未满,说明攻击绕过连接跟踪机制:1.伪造IP+随机端口致SYN队列溢出;2.恶意TCP选项引发协议异常;3.双栈/隧道接口未加载对应conntrack模块;4.SYN混杂udp/ICMP碎片耗尽分片缓存。

Linux 服务器被大量 SYN 包淹没但 conntrack 表没满的几种隐藏攻击方式

SYN 洪水但 conntrack 未满:攻击绕过了连接跟踪机制

这通常说明攻击流量并未真正进入 ESTABLISHED 状态,也未在 conntrack 表中长期驻留。linuxconntrack 只跟踪已通过三次握手、或明确被内核判定为“需要状态跟踪”的连接(如 RELATED/ESTABLISHED)。而以下几种方式能让 SYN 包持续冲击服务器,却几乎不占用 conntrack 条目:

1. 源端口随机 + 源 IP 伪造(纯 SYN Flood)

攻击者用大量伪造的源 IP 和随机源端口发送 SYN,服务端回复 SYN-ACK 后收不到 ACK(因源 IP 不存在或被丢弃),连接卡在 SYS_RECV 状态。该状态由 tcp_max_syn_backlog 队列管理,不进入 conntrack 表。只要队列溢出,新 SYN 就被丢弃,但 conntrack 表看起来空空如也。

  • 检查命令:netstat -s | grep -i "SYN|listen|overflow",关注 times the listen queue of a socket overflowed
  • 关键参数:net.ipv4.tcp_max_syn_backlog(默认常为 128–1024)、net.core.somaxconnnet.ipv4.tcp_syncookies(开启可缓解)

2. TCP Options 恶意组合触发协议异常

某些构造异常的 TCP Options(如超长 SACK 块、重复 timestamp、非法 MSS)会让内核在 SYN 处理阶段反复解析、分配临时结构体,甚至引发 soft lockup 或内存碎片。这类包可能根本没走到 conntrack 插入逻辑,却持续消耗 CPU 和内存。

  • 现象:softirq CPU 占用高(top -H 查看 ksoftirqd/* 线程)、dmesg 出现 “TCP: too many orphaned sockets”“TCP: time wait bucket table overflow”
  • 应对:启用 net.ipv4.tcp_invalid_ratelimit 限制错误包日志频率;用 tcpdump -nn -s 64 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn' 抓包分析选项字段

3. 利用 ipv6/IPv4 双栈或隧道接口绕过 conntrack 规则

若服务器启用了 6to4、ISATAP、GRE 或 IPv6,而 conntrack 模块未加载对应协议支持(如 nf_conntrack_ipv6nf_conntrack_proto_gre),这些流量默认不被跟踪。攻击者可定向发 SYN 到隧道接口或 IPv6 地址,完全避开 conntrack 表限制。

  • 验证:运行 lsmod | grep nf_conntrack,确认是否加载了对应协议模块
  • 检查接口:用 ip -br a 查看是否有非主网卡的隧道/虚拟接口;用 conntrack -L | wc -l 对比 IPv4/IPv6 条目数(若 IPv6 条目极少但流量高,值得怀疑)

4. SYN 混合 UDP/ICMP 碎片攻击协同压制

单独发 SYN 效果有限,但配合大量伪造源的 UDP 碎片包(如 dns 反射放大)或 ICMP 超大载荷包,会快速耗尽内核 sk_buff 缓存和 nf_defrag_ipv4/6 分片重组队列。一旦分片重组失败,SYN 包即使合法也无法完成解析,更不会进入 conntrack 流程——此时 netstat 看不到 backlog 溢出,但连接建立成功率骤降。

  • 线索:cat /proc/net/nf_conntrack | wc -l 很低,但 netstat -s | grep -A5 "fragment" 显示大量 “reassembly failed”
  • 临时缓解:echo 1 > /proc/sys/net/ipv4/ipfrag_high_thresh(谨慎调高,需配合内存监控)

排查建议:别只盯 conntrack 表

真正瓶颈往往在协议栈更上层或更底层:SYN 队列长度软中断处理能力分片缓存socket 内存压力。用 ss -s 查总 socket 数量与内存使用,用 perf top -e 'syscalls:sys_enter_accept*' -p $(pgrep nginx|head -1) 看 accept 是否卡住,比单纯查 conntrack 更有效。

text=ZqhQzanResources