核心防护策略是:在conntrack表满前用nftables尽早丢弃无效、异常及高频连接,并调优内核参数控规模与生命周期;限新连速率防SYN洪泛,用hash:ip集合动态限速;prerouting链drop INVALID状态及畸形TCP包;调小nf_conntrack_max、established超时并启用liberal模式;禁用非必要ICMP响应。

核心思路是:在连接跟踪(conntrack)表被填满前,用 nftables 尽早丢弃无效、异常或高频的连接请求,同时配合内核参数控制 conntrack 表规模与生命周期。
限制新连接速率,防止SYN洪泛耗尽conntrack资源
攻击者常通过海量伪造源IP的TCP SYN包快速占满 conntrack 表。应在 prerouting 或 input 链最前端做速率限制:
- 对每个源IP每秒最多允许5个新建连接:
nft add rule inet firewall input @tcp-new-limit ip saddr @tcp-new-limit tcp flags & (fin | syn | rst | ack) == syn limit rate 5/second burst 10 packets accept - 更稳妥的做法是使用 hash:ip 类型的动态限速集合,避免规则膨胀:
nft add set inet firewall syn_per_ip { type ipv4_addr; flags timeout; }
nft add rule inet firewall input tcp flags & (fin | syn | rst | ack) == syn ct state invalid drop
nft add rule inet firewall input tcp flags & (fin | syn | rst | ack) == syn @syn_per_ip add @syn_per_ip timeout 60s
精准丢弃无效和异常连接状态
无效连接(INVALID)不进入 conntrack 表,但若已建立再变 INVALID,说明协议异常,应立即丢弃,避免后续误判:
- 在 mangle 表 prerouting 链尽早处理(性能最优):
nft add chain inet mangle prerouting '{ type filter hook prerouting priority -150; policy accept; }'
nft add rule inet mangle prerouting ct state invalid drop - 补充丢弃明显畸形包(如无标志位、重复FIN等),减少内核解析开销:
nft add rule inet mangle prerouting tcp flags & (fin | syn | rst | ack) == 0 drop
nft add rule inet mangle prerouting tcp flags & (fin | syn | rst | ack) == (fin | syn | rst | ack) drop
控制conntrack表容量与老化时间
nftables 只能过滤,真正防溢出要靠内核参数协同:
- 设置合理上限(按内存估算):
echo 'net.netfilter.nf_conntrack_max = 65536' >> /etc/sysctl.d/99-ddos.conf
建议从 64K 起步,监控 /proc/sys/net/nf_conntrack_count,再逐步调高 - 缩短已建立连接的老化时间(尤其对短连接服务):
echo 'net.netfilter.nf_conntrack_tcp_timeout_established = 300' >> /etc/sysctl.d/99-ddos.conf
默认 432000 秒(5天)太长,设为 300 秒(5分钟)可加速回收 - 启用自动清理机制(需内核支持):
echo 'net.netfilter.nf_conntrack_tcp_be_liberal = 1' >> /etc/sysctl.d/99-ddos.conf
帮助内核更积极识别并释放“半死”连接
关闭非必要ICMP响应,规避反射放大
ICMP 响应可能被用于 Smurf 或 ICMP Flood 攻击,间接加剧 conntrack 压力:
- 对外网接口禁用 echo-reply(保留请求入口即可):
echo 'net.ipv4.icmp_echo_ignore_all = 1' >> /etc/sysctl.d/99-ddos.conf - nftables 中仅放行必需的 ICMP 类型(如 traceroute 所需的 time-exceeded):
nft add rule inet firewall input ip protocol icmp icmptype { destination-unreachable, time-exceeded, parameter-problem } accept

















