使用 IPtables 或空路由将大约 100 万个 IP 地址列入黑名单?

tyl*_*erl 23 route iptables blacklist

我遇到过这样的情况,客户端需要将一组不到 100 万个单独的 IP 地址(无子网)列入黑名单,并且网络性能是一个问题。虽然我猜想 IPTables 规则对性能的影响比路由小,但这只是猜想。

有没有人有任何确凿的证据或其他理由支持 IPTables 或空路由作为将长 IP 地址列表列入黑名单的解决方案?在这种情况下,一切都是自动化的,因此易用性并不是真正的问题。

编辑 11 年 11 月 26 日

经过一些测试和开发,这些选项似乎都不可行。似乎路由查找和 iptables 都通过规则集进行线性搜索,并且处理这么多规则花费的时间太长。在现代硬件上,将 100 万个项目放入 iptables 黑名单会使服务器减慢到每秒大约 2 打数据包。所以IPTables和空路由都出来了。

ipset,正如 Jimmy Hedman 所推荐的那样,会很棒,只是它不允许您在一组中跟踪超过 65536 个地址,因此除非有人有任何想法,否则我什至无法尝试使用它。

显然,阻止这么多 IP 的唯一解决方案是在应用程序层中进行索引查找。不是这样吗?


更多信息:

此实例中的用例是阻止 IP 地址的“已知违规者”列表访问 Web 服务器上的静态内容。FWIW,通过 Apache 进行阻塞Deny from同样缓慢(如果不是更慢),因为它也进行线性扫描。


仅供参考:最终的工作解决方案是将 apache 的 mod_rewrite 与 berkeley DB 映射结合使用来对黑名单进行查找。伯克利数据库的索引性质允许列表以 O(log N) 性能扩展。

pQd*_*pQd 15

尝试使用 iptables 并构建多级树来减少查找次数。

iptables -N rules_0_0_0_0_2
iptables -N rules_64_0_0_0_2
iptables -N rules_128_0_0_0_2
iptables -N rules_192_0_0_0_2
iptables -N rules_0_0_0_0_4
iptables -N rules_16_0_0_0_4

iptables -A INPUT -p tcp --dport 80 -s 0.0.0.0/2 -j rules_0_0_0_0_2
iptables -A INPUT -p tcp --dport 80 -s 64.0.0.0/2 -j rules_64_0_0_0_2
iptables -A INPUT -p tcp --dport 80 -s 128.0.0.0/4 -j rules_128_0_0_0_2
iptables -A INPUT -p tcp --dport 80 -s 192.0.0.0/4 -j rules_192_0_0_0_2

iptables -A rules_0_0_0_0_2 -s 0.0.0.0/4 -j rules_0_0_0_0_4
iptables -A rules_0_0_0_0_2 -s 16.0.0.0/4 -j rules_16_0_0_0_4
Run Code Online (Sandbox Code Playgroud)

依此类推 - 添加嵌套级别;显然,您将需要一种自动构建规则的方式,并且您应该为有一个或多个违规者的网络设置链 - 通过这种方式,您可以显着减少必须进行的查找次数,我认为这可能实际上工作。

  • @pQd 在之前使用 iptables 等失败后,我使用 [RewriteMap](http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritemap) 和 Berkeley 数据库在 apache 中实现了一个解决方案。但是我在循环中使用 iptables 的最快机制每秒加载大约 100 条规则,而 iptables-restore 在大约 4 秒内完成了整个设置。这是在顶级台式计算机上。RewriteMap 机制对性能的影响小得无法察觉。 (3认同)

cst*_*mas 11

这正是ipset它的目的。

从其网站http://ipset.netfilter.org/

如果你想

  • 存储多个IP地址或端口号,一键匹配iptables的集合;
  • 针对 IP 地址或端口动态更新 iptables 规则而不会降低性能;
  • 使用单一的 iptables 规则表达基于复杂 IP 地址和端口的规则集,并从 IP 集的速度中受益

那么 ipset 可能是适合您的工具。

它是由 netfilter 核心团队成员 Jozsef Kadlecsik(他也编写了 REJECT 目标)编写的,所以这是我能想到的最佳选择。

它甚至包含在最近的内核中。

  • 如果您使用 hash:ip set 类型,您可以拥有非常多的地址。我尝试了1000000,性能相当不错。如果在检查集合之前设置 -m state --state ESTABLISHED 规则,则可以确保仅检查新连接上的集合,这会在处理大量数据包时提高性能。 (7认同)

Per*_*rgk 5

我自己没有测试过这个,但是当我听到你的问题描述时,我立刻想到了“ pf”(来自 OpenBSD)。

pf具有地址表的概念,这可能正是您正在寻找的。

根据我所做的一些非常粗略的研究,这似乎比ipset. 根据PF FAQ 关于运行时选项的章节,开箱即用,无需调整,pf 总共支持 1,000 个表,默认情况下所有表总共有 200,000 个条目。(如果系统物理内存小于 100MB,则为 100,000)。这让我相信至少值得考虑尝试测试它以查看它是否在任何有用的水平上工作。

当然,我假设你在 Linux 上运行你的服务器,所以你必须有一个单独的防火墙盒运行一些带有 pf 的操作系统(如 OpenBSD 或 FreeBSD)。您还可以通过完全取消任何类型的有状态数据包过滤来提高吞吐量。

  • 您不必将整个服务器架构转换为 BSD,构建一个防火墙放置在真实服务器之前就足够了。(在 VM 中很容易做到。) (2认同)