带有 AND 条件的 IPTABLES

带有 AND 条件的 IPTABLES

我需要iptables使用--string选项应用规则。我需要匹配 1 个--hex或 2 个不位于同一区域的 ASCII 字符串。

我尝试的每个样本都只删除两个字符串中的一个,因此我得到了假阳性。我需要删除两个字符串,但是当我只有 1 个字符串或另一个字符串时,我不想删除。

因此,我正在寻找的规则是围绕的 AND 规则iptables

因此,我尝试了:

iptables -I INPUT -j DROP -m string --string "TEST1" --algo bm -m string --string "TEST2" --algo bm

不起作用,看起来我有 2 条不同的规则,因此它会阻止 TEST1 或 TEST2,但不会阻止 TEST1 和 TEST2:所以是误报

iptables -N my_chain
iptables -A my_chain -j DROP
iptables -A my_chain -j QUEUE ! -f -m string --string "TEST2" --algo bm
iptables -A INPUT -j my_chain ! -f -m string --string "TEST1" --algo bm

不起作用,看起来我有 2 条不同的规则,因此它会阻止 TEST1 或 TEST2,但不会阻止 TEST1 和 TEST2:所以是误报

关于如何实现这一点有什么建议吗?

答案1

您是否考虑过跳转到另一个用户定义的表?

例如

iptables -A INPUT -p udp -m string --string "TEST1" --algo bm -j secondarystring

iptables -N secondarystring
iptables -A secondarystring -m string --string "TEST2" --algo bm -j DROP

在这种情况下,只有符合第一个条件的数据包才应跳入“secondarystring”表。然后,符合第二个条件(AND)的数据包应被丢弃。

答案2

这可能是一个老问题,但使用数据包标记实际上可以提供帮助。您需要考虑如何设置 iptables 规则(当条件满足时,第一个规则会被触发,而当您正在检查的条件不满足时,任何后续规则都会被触发)。这巧妙地实现了逻辑 AND。

iptables -t mangle -A INPUT -m string --string "pattern1" --algo bm -j MARK --or-mark 0x1
iptables -t mangle -A INPUT -m string ! --string "pattern2" --algo bm -j MARK --and-mark 0xFFFFFFFE
[...]

请注意第二条规则和任何后续规则中的 !,它们会反转条件以及 --and-mark 和反转的位掩码,以清除匹配时的所需位。

然后,为了进行过滤,检查标记是否存在:

iptables -A INPUT -m mark --mark 0x1/0x1 -j DROP

关键在于处理不同表中的链的顺序。您在这里所做的是检查给定数据包中的几个字符串,因为它会遍历 mangle 表(通过发布-t mangle到 iptables 来选择),该表在处理 filter 表(不需要-t filter,因为这是默认表)之前进行处理。

检查完条件后,您肯定知道已经找到了给定数据包中的所有 n 个条件(在这种情况下标记仍然存在),因此过滤表中的规则会被命中并丢弃该数据包。

假设您要检查以下三个字符串:foobar roflbtc cafeface

您必须设置如下规则:

iptables -t mangle -A INPUT -m string --string "foobar" --algo bm -j MARK --or-mark 0x1
iptables -t mangle -A INPUT -m string ! --string "roflbtc" --algo bm -j MARK --and-mark 0xFFFFFFFE
iptables -t mangle -A INPUT -m string ! --string "cafeface" --algo bm -j MARK --and-mark 0xFFFFFFFE

现在,如果你有一个包含所有这些字符串的包,你将得到以下内容:

  1. -m string --string "foobar"命中 ---> 在数据包上设置标记 0x1
  2. -m string ! --string "roflbtc"错过了 ---> 标记保持不变
  3. -m string ! --string "cafeface"错过了 ---> 标记保持不变

现在数据包终于到达规则

iptables -A INPUT -m mark --mark 0x1/0x1 -j DROP

由于存在标记,因此规则匹配,并且数据包被丢弃。

但是,如果第二个字符串丢失了会发生什么?

  1. -m string --string "foobar"命中 ---> 在数据包上设置标记 0x1
  2. -m string ! --string "roflbtc"是命中(字符串不在那里!)--->从数据包中删除标记 0x1
  3. -m string ! --string "cafeface"错过了 ---> 标记保持不变

如上所述,数据包将到达上述丢弃规则,但-m mark --mark 0x1/0x1由于没有标记,因此未命中。因此,数据包可以通过过滤器。

我们还来检查一下如果第一个字符串丢失会发生什么:

  1. -m string --string "foobar"未命中 ---> 标记未设置
  2. -m string ! --string "roflbtc"错过了 ---> 标记保持不变
  3. -m string ! --string "cafeface"错过了 ---> 标记保持不变

再次,由于其中一个条件未得到满足,标记首先没有被设置,因此如果最终达到丢弃规则,则为未命中并且数据包可能再次通过。

这是一种链接条件检查的简单方法,并且根据您设置或清除标记的方式,您几乎可以实现任何逻辑操作 - 而且由于标记值是 32 位宽,因此您可以通过这种方式检查最多 32 个条件。

相关内容