CentOS 4GB Ran 上的 iptables 中有 10,000 个条目,双核 2.3ghz?

CentOS 4GB Ran 上的 iptables 中有 10,000 个条目,双核 2.3ghz?

我正在运行安装了 FreePBX/Astrisk 的 Linux 机器。我使用 ip2location.com/blockvisitorsbycountry.aspx 网站上的列表屏蔽了中国和香港。我的 fail2ban 每隔 3-9 分钟就会屏蔽一次,现在我的尝试次数非常有限,通常每天只有 8-10 次左右。我很想屏蔽更多,但我担心如果我再向表中添加 10k,我可能会将系统限制回石器时代。您觉得呢?

答案1

别担心,最多也就是铁器时代的表现。(笑)

内核必须为每个数据包运行大量的 netfilter 规则,这将对系统性能和资源消耗(CPU 和内存)产生负面影响。好消息是,您可以使用许多技巧来最大限度地减少问题。

  1. 常见情况的“短路”规则:您收到的 90% 以上的数据包将属于现有已建立或相关连接。因此,您可以通过设置一个-m state --state ESTABLISHED,RELATED -j ACCEPT您的任何过滤列表规则。
  2. 仅过滤某些端口:如果您正在运行 Web 服务器,但实际上只担心 SSH 暴力攻击,则可以通过将过滤器列表放在单独的链中来避免处理通过过滤器列表的所有 HTTP 流量,然后仅通过过滤器发送端口 22 流量,如下所示:

    iptables -N geofilter
    iptables -I geofilter -s <ip range> -j DROP
    [etc etc etc]
    iptables -I INPUT -p tcp --dport 22 -j geofilter
    
  3. “树形结构”您的过滤规则:您可能有 10,000 条过滤规则,但其中只有一条会匹配。因此,您可以使用树形结构来减少任何数据包必须经过的规则数量,方法是将每个 /8 的所有规则放入其自己的链中。扩展上一个示例geofilter

    iptables -N geofilter_1
    iptables -N geofilter_2
    [etc etc etc all the way to geofilter_223]
    iptables -I geofilter -s 1.0.0.0/8 -j geofilter_1
    iptables -I geofilter -s 2.0.0.0/8 -j geofilter_2
    [etc etc etc]
    iptables -I geofilter_1 -s 1.2.3.0/24 -j DROP
    iptables -I geofilter_1 -s 1.5.9.0/18 -j DROP
    [etc etc etc for all rules in 1/8]
    iptables -I geofilter_2 -s 2.42.0.0/16 -j DROP
    [etc etc etc for all rules in 2/8]
    [continue pattern for all /8s]
    

    这意味着任何需要通过过滤规则的数据包最多需要遍历 223 条规则(所有规则geofilter)以及每个 /8 过滤器列表中的规则数量。(为什么链中有 223 条规则,而不是 254、255 或 256 条规则,geofilter留给精明的读者去练习吧)。您可以通过使用多级树来提高效率:在 /4 上拆分,然后在 /8 上拆分,然后在 /12 上拆分,或类似方式。您可以根据需要添加任意数量的级别以匹配您的成本/收益权衡。您甚至可以针对不同的链执行不同的操作:从在 /4 处进行单级拆分开始,然后是任何具有超过几百条规则的链,在 /8 处拆分,以及任何仍然有几百条规则,按 /12 分割。

  4. 聚合规则:我敢打赌,您使用的地址列表没有经过最佳聚合。即使它们只针对一个国家/地区,一旦您将多个国家/地区的列表放在一起,可能会有来自不同国家/地区的相邻块可以放在一起。例如,假设中国有人有192.0.2.0/25,香港有人有192.0.2.128/25(是的,不是现实的块,但 RFC5737 仅为我们提供了 /24 以供记录)。您可以将其聚合192.0.2.0/24并为自己节省一条规则。

    一旦你开始这样做,你就会发现你可以减少列表中的规则数量显著地。(与下一条规则结合,您可以将规则列表减少一半或更多。)实现聚合很容易;该netmask工具将获取任意块列表并返回最小 CIDR 块列表:

    netmask -c 192.0.2.0/25 192.0.2.128/25 192.0.3.0/24 192.0.1.0/25
      192.0.1.0/25
      192.0.2.0/23
    
  5. 负面规则:通常,你会发现大量的小块聚集成一个单一的,很多更大的区块,除了中间有一小块。在某些情况下,几乎整个 /8 或 /10 都分配给一个国家,除了一些小块 /22 不知何故逃到了世界其他地方。在这种情况下,您可以ACCEPT为这几个小块白名单块制定规则,然后DROP为覆盖较大的块制定规则。计算出最佳块需要一定程度的编程,但这并不是火箭科学。

需要注意的一点是:IP 地址块会定期更改其地理位置,尤其是在 IPv4 的“末日”时期。请确保不要只是一味地执行此规则集。获取地理列表的更新副本,并根据这些副本重建您的过滤列表。否则,有一天您会发现自己过滤的地址块已被您自己的 ISP 占用,并且您将无法访问自己的服务器,因为您之前阻止的 IP 地址已分配给您。(真实故事)

答案2

规则的主要问题iptables是它们按顺序执行,并且对于较大的规则集,在授予或拒绝数据包访问权限之前必须解析相当多的规则。

Womble 的回答已经解释了不少通过巧妙地排列规则来减少处理惩罚的策略,我同意其中最重要的是使用状态防火墙配置中仅根据完整规则集检查新连接,并且一旦建立该连接的初始数据包被检查并批准,则同一连接中的所有后续数据包都将被授予访问权限。

假设您现在有许多阻止访问者的 DROP 规则:

# Source: http://www.ip2location.com/free/visitor-blocker
iptables -A INPUT -s 1.0.1.0/24 -j DROP
iptables -A INPUT -s 1.0.2.0/23 -j DROP
iptables -A INPUT -s 1.1.0.0/24 -j DROP
iptables -A INPUT -s 1.1.2.0/23 -j DROP
iptables -A INPUT -s 1.1.8.0/21 -j DROP
iptables -A INPUT -s 119.15.136.0/21 -j DROP
iptables -A INPUT -s 119.16.0.0/16 -j DROP
iptables -A INPUT -s 119.18.192.0/20 -j DROP
iptables -A INPUT -s 119.18.208.0/21 -j DROP

这些规则可以简化为单个 iptables 规则通过使用ipset公用事业。

一个IP设置是内核维护的网络地址和/或范围的列表,并且匹配速度比 iptables 中的顺序匹配规则要快得多。

首先创建一个 IP 集(手动的建议使用随机大小的网络块类型hash:net):

ipset create blacklist-china hash:net hashsize 4096

添加您想要阻止的 CIDR 范围:

ipset add blacklist-china 1.0.1.0/24
ipset add blacklist-china 1.0.2.0/23
ipset add blacklist-china 1.1.0.0/24
ipset add blacklist-china 1.1.2.0/23
ipset add blacklist-china 1.1.8.0/21
ipset add blacklist-china 119.15.136.0/21
ipset add blacklist-china 119.16.0.0/16
ipset add blacklist-china 119.18.192.0/20
ipset add blacklist-china 119.18.208.0/21

您的防火墙配置现已减少到:

 iptables -m set --match-set blacklist-china src -j DROP

答案3

另一种方法是使用 iptablesxt_geoip模块。虽然我还没有测试过它的性能ipsets(如果我理解正确的话,源代码xt_geoip使用 d&c 二进制搜索,而ipsets使用哈希)。这样做的好处可能是易于更新。

例如 Ubuntu 默认在xtables-插件-dkms

相关内容