iptables 在阻止许多 IP 时会消耗大量 CPU

iptables 在阻止许多 IP 时会消耗大量 CPU

我在 AWS 上运行基于 UDP 的公共服务。几周前,警报响起,表明 UDP 洪水攻击正在发生。

几年前,由于之前的一次 DDOS 攻击,我更新了套接字代码以检测这些类型的攻击,并忽略任何试图用虚假请求淹没端口的 IP 的传入数据包。

快进到今天。新攻击的规模比以前见过的任何攻击都要大。因此,我启动了一些新实例以进行负载平衡,并调整了代码以更积极地进行节流。危机得以避免。

我也想到了尝试收集所有泛洪者的所有 IP,然后通过下面的 iptables 调用来阻止每个 IP。

sudo iptables -A INPUT -s 1.2.3.4 -j DROP

用实际 IP 地址替换了其中1.2.3.4的内容。然后我编写了一个脚本,该脚本将根据我运行过的其他脚本,对涉及洪水攻击的 2000 多个 IP 地址调用此命令。我在一个特定的 AWS 实例上执行了此操作,而其他实例则保持不变。这样做的目的是,在防火墙级别阻止有问题的 IP 地址比让服务器代码本身处理它更有效。

结果是,在具有所有 iptables 规则的实例上,CPU 使用率飙升(超过 50%)。其他机器依靠自己的软件代码来丢弃泛洪 IP,并且处于正常的 CPU 水平。我最终从这个特定实例中删除了规则。

我认为在表中查找 IP 地址的操作与使用合理大小的哈希表的操作相当O(1)。也许是线性的,或者只是因为 iptables 需要记录并记录每个被阻止的数据包。也许有更好的方法来批量阻止这么多 IP。

在不产生额外 CPU 开销的情况下阻止 2000 多个 IP 地址的最佳方法是什么?

答案1

您所编写的规则将被逐一查找,并需要时间来处理。您正在寻找的可能是 ipset。

ipset create banned-hosts hash:ip
ipset add banned-hosts 1.2.3.4
:
ipset add banned-hosts 2.4.6.8

并匹配它:

iptables -A INPUT -m set --match-set banned-hosts src -j DROP

答案2

您正在将 IP 地址作为单独的规则添加到链中,这意味着内核必须检查所有数据包的所有规则。

一些优化可能会有所帮助:

  1. 将规则添加DROP到 IPTablesraw表而不是普通filter表。这意味着不会为这些数据包创建连接跟踪条目,从而节省资源。使用iptables -t raw -A input -s 192.168.100.100 -j DROP添加到raw表。
  2. 使用 IPSet 功能可以在一条规则中匹配一组 IP 地址,从而避免遍历整个链。查看http://ipset.netfilter.org/了解更多信息。

答案3

针对大量 IP 列表,有一个解决方案

这是

ipset

相关内容