我遇到过这样的情况:客户需要将一组不到 100 万个独立 IP 地址(无子网)列入黑名单,而网络性能令人担忧。虽然我推测 IPTables 规则对性能的影响会小于路由,但这只是推测。
是否有人有任何确凿的证据或其他理由支持使用 IPTables 或空路由作为将长 IP 地址列入黑名单的解决方案?在这种情况下,一切都是自动化的,因此易用性并不是真正的问题。
编辑 2011 年 11 月 26 日
经过一些测试和开发,似乎这些选项都不可行。路由查找和 iptables 似乎都通过规则集进行线性搜索,处理这么多规则需要的时间实在太长了。在现代硬件上,将 1M 个项目放入 iptables 黑名单会使服务器速度减慢到每秒大约 24 个数据包。因此 IPTables 和空路由都行不通。
ipset
,正如 Jimmy Hedman 所推荐的那样,会很棒,只是它不允许你在一组中跟踪超过 65536 个地址,所以除非有人有任何想法,否则我甚至无法尝试使用它。
显然,阻止这么多 IP 的唯一解决方案是在应用层进行索引查找。不是吗?
更多信息:
本例中的用例是阻止“已知违规者”IP 地址列表访问 Web 服务器上的静态内容。FWIW,通过 Apache 进行阻止Deny from
同样很慢(如果不是更慢的话),因为它也进行线性扫描。
仅供参考:最终的解决方案是使用 apache 的 mod_rewrite 和 Berkeley DB 映射来查找黑名单。Berkeley DB 的索引特性允许列表以 O(log N) 性能扩展。
答案1
尝试使用 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
等等 - 添加嵌套级别;显然,您需要一种自动的方式来构建规则,并且您应该只为有一个或多个罪犯的网络设置链条 - 这样,您可以大大减少必须进行的查找次数,我认为它可能真的有效。
答案2
这正是ipset
目的所在。
来自其网站http://ipset.netfilter.org/:
如果你想
- 一次性存储多个IP地址或端口号,并通过iptables进行集合匹配;
- 动态更新针对 IP 地址或端口的 iptables 规则,而不会影响性能;
- 使用单个 iptables 规则表达基于复杂 IP 地址和端口的规则集,并受益于 IP 集的速度
那么 ipset 可能是适合您的工具。
它是由 netfilter 核心团队成员 Jozsef Kadlecsik(他还编写了 REJECT 目标)编写的,所以这是我能想到的最佳选择。
它甚至包含在最新的内核中。
答案3
我自己没有测试过这个,但是当我听到你的问题描述时我立即想到了“ pf
”(来自 OpenBSD)。
pf
有以下概念地址表这可能正是您所寻找的。
据一些非常根据我所做的粗略研究,这似乎比 更具潜力ipset
。根据PF FAQ 中有关运行时选项的章节,无需调整,开箱即用,pf 总共支持 1,000 个表,默认情况下所有表总共有 200,000 个条目。(如果系统的物理内存小于 100MB,则为 100,000)。这让我相信,至少值得考虑尝试测试一下,看看它是否在任何有用的层面上起作用。
当然,我假设您在 Linux 上运行服务器,因此您必须有一个单独的防火墙盒,运行带有 pf 的某些操作系统(如 OpenBSD 或 FreeBSD)。您也可以通过完全取消任何类型的状态数据包过滤来提高吞吐量。
答案4
对于后代:根据ipset
文档,集合的默认大小是 65536,可以通过选项进行更改。
maxelem 该参数对所有哈希类型集合的创建命令有效。它定义了集合中可以存储的最大元素数,默认为 65536。例如:
ipset create test hash:ip maxelem 2048.
我把它放在这里因为我还不能发表评论。