我需要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
现在,如果你有一个包含所有这些字符串的包,你将得到以下内容:
-m string --string "foobar"
命中 ---> 在数据包上设置标记 0x1-m string ! --string "roflbtc"
错过了 ---> 标记保持不变-m string ! --string "cafeface"
错过了 ---> 标记保持不变
现在数据包终于到达规则
iptables -A INPUT -m mark --mark 0x1/0x1 -j DROP
由于存在标记,因此规则匹配,并且数据包被丢弃。
但是,如果第二个字符串丢失了会发生什么?
-m string --string "foobar"
命中 ---> 在数据包上设置标记 0x1-m string ! --string "roflbtc"
是命中(字符串不在那里!)--->从数据包中删除标记 0x1-m string ! --string "cafeface"
错过了 ---> 标记保持不变
如上所述,数据包将到达上述丢弃规则,但-m mark --mark 0x1/0x1
由于没有标记,因此未命中。因此,数据包可以通过过滤器。
我们还来检查一下如果第一个字符串丢失会发生什么:
-m string --string "foobar"
未命中 ---> 标记未设置-m string ! --string "roflbtc"
错过了 ---> 标记保持不变-m string ! --string "cafeface"
错过了 ---> 标记保持不变
再次,由于其中一个条件未得到满足,标记首先没有被设置,因此如果最终达到丢弃规则,则为未命中并且数据包可能再次通过。
这是一种链接条件检查的简单方法,并且根据您设置或清除标记的方式,您几乎可以实现任何逻辑操作 - 而且由于标记值是 32 位宽,因此您可以通过这种方式检查最多 32 个条件。