简介
之前我们已经介绍过扩展模块的简单使用,比如使用-m tcp/udp ,-m multiport参数通过--dports,--sports可以设置连续和非连续的端口范围。那么我们如何匹配其他的一些参数呢,比如源地址范围,目的地址范围,时间范围等,这就是我们这篇文章介绍的内容。
iprange扩展模块
在不使用任何扩展模块的情况下,使用-s选项或者-d选项即可匹配报文的源地址与目标地址,而且在指定IP地址时,可以同时指定多个IP地址,每个IP用”逗号”隔开,但是,-s选项与-d选项并不能一次性的指定一段连续的IP地址范围,如果我们需要指定一段连续的IP地址范围,可以使用iprange扩展模块。
iprange扩展模块中有两个扩展匹配条件可以使用,--src-range,--dst-range两个选项分别用于匹配报文的源地址所在范围与目标地址所在范围。


string扩展模块
使用string扩展模块,可以指定要匹配的字符串,如果报文中包含对应的字符串,则符合匹配条件。
为了更好的介绍效果,我现在我的Debian系统上安装web服务,以便更好的展示字符串匹配的效果。
安装apache2




配置string

在iptables命令中,当使用-m string模块时,可以使用--algo选项来指定搜索算法。这里有两个可选项:
--algo bm:指定使用Boyer-Moore算法进行搜索。
--algo kmp:指定使用Knuth-Morris-Pratt算法进行搜索。
Boyer-Moore(bm)算法:
1.是一种高效的字符串搜索算法,特别适用于长模式串的搜索。
2.通过预计算两个跳转表(坏后缀表和好后缀表)来减少不必要的比较,从而提高搜索效率。
3.在iptables的string模块中,这是默认的搜索算法。
Knuth-Morris-Pratt(kmp)算法:
1.也是一种高效的字符串搜索算法,由Donald Knuth、James H. Morris和Vaughan Pratt共同发明。
2.该算法利用已经部分匹配这个信息,避免重新检查字符的重复部分,从而在文本串中搜索一个词(或其他模式)的所有出现位置。
3.在iptables的string模块中,可以作为可选的搜索算法。
那么上述的配置会生效吗?


没有匹配到任何数据包,我们设置的策略没有生效的原因是因为,当我们通过140.248去访问140.250的时候,这是个request过程,也就是请求发送到140.250,然后140.250主机返回数据。也就是说数据包进入iptables的INPUT链的时候是请求数据包,请求中没有任何test相关参数。而主机响应的数据包是不通过INPUT链的。
我们可以回顾下前面文章描述的数据包处理过程:
上图中,是iptables处理数据包的过程由本机发出的数据包是不会经过input链的,所以我们配置的规则应用在INPUT链上是没有效果的。



time扩展模块
可以通过time扩展模块,根据时间段区匹配报文,如果报文到达的时间在指定的时间范围以内,则符合匹配条件。
-m time表示使用time扩展模块,--timestart选项用于指定起始时间,--timestop选项用于指定结束时间。

上面是基于时间的,可以设置基于星期的策略
通过--weekdays参数设置

星期可以和每天的具体时间联合使用,如下:

基于月份的策略
通过--monthdays设置

当然可以将月份和星期联合起来

设置日期范围
除了使用–weekdays选项与–monthdays选项,还可以使用–datestart 选项与-datestop选项,指定具体的日期范围

注意:在上述的参数中,只有--monthdays --weekdays可以前面增加!参数进行取反,其他的参数不能取反。更多的参数组合,需要大家根据自己的需求自行探索设置。
connlimit扩展模块
connlimit扩展模块,可以限制每个IP地址同时链接到server端的链接数量,注意:不用指定IP,其默认就是针对”每个客户端IP”,即对单IP的并发连接数限制。
通过-m connlimit进行对应的设置
-m connlimit 的一些常用参数及其说明:
--connlimit-above n #限制为多少个。这个参数用于指定超过多少个连接时,iptables 应该执行相应的动作(如 REJECT、DROP 等)。
--connlimit-mask bits #这组主机的掩码。默认是 --connlimit-mask 32,即每个 IP 地址都被单独考虑。通过减小掩码值,可以指定一个更大的 IP 地址范围,以便在这个范围内共享连接数限制。
--connlimit-upto n #如果现有连接数小于或等于设置的并发连接数值,那么就放行。




limit扩展模块
limit模块是对”报文到达速率”进行限制的。如果我想限制单位时间内流入的包的数量,就能用limit模块,可以以秒为单位进行限制,也可以以分钟、小时、天作为单位进行限制。
具体参数如下
-m limit 的参数解释和介绍:
主要参数
--limit
描述:设置最大平均匹配速率。
格式:--limit rate[/second|/minute|/hour|/day]
示例:
--limit 1000/s:设置最大平均匹配速率为每秒 1000 个数据包。
--limit 5/m:设置最大平均匹配速率为每分钟 5 个数据包。
--limit-burst
描述:表示一开始能匹配的数据包数量。一旦达到此数量,将开始应用 --limit 指定的速率限制。每匹配到一个数据包,--limit-burst 的值减 1。当值为 0 时,必须等待一段时间(基于 --limit 的速率),才能再次匹配数据包。
格式:--limit-burst number
要点:
--limit-burst 的值要比 --limit 的值大。
默认情况下,--limit-burst 的值会随时间恢复(基于 --limit 的速率)。
示例:--limit-burst 15:一开始能匹配的数据包数量为 15 个。
我们想要限制外部主机对本机进行ping操作时,本机最多每5秒中放行一个ping包,那么,我们可以进行如下设置



如果此时观察上面的图就会发现,为什么前面有6个数据包都是通的,我们不是设置了5个数据包匹配一次吗?
其实当我们配置了--limit参数后,会默认配置上一个--limit-burst,当该值匹配完成后才回轮到--limit进行匹配。


limit模块使用了令牌桶算法,我们这里简单说一下这个算法。
通过控制令牌产生的速率和令牌桶的容量,实现对数据流量的限制。我们可以想象一下,有一个桶,桶里面放了10块令牌,而且这个桶最多也只能放下10块令牌,所有报文如果想要进来,都必须要有桶中的令牌才行。然后这个桶可以自己生成令牌,就是每隔5秒钟会生成一块新的令牌,如果此时,桶中的令牌不足10块,那么新生成的令牌就存放在桶中,如果桶中已经存在10块令牌,新生成的令牌就只能溢出桶(令牌被丢弃),如果此时有10个报文想要进来,那么这10个报文就去桶里找令牌,正好一人一个,此时桶空了(真的空了吗?)。
请大家注意一个问题,每隔5秒会生成令牌,举例来说我1秒拿走一个令牌,到第5秒,桶里面剩下5个令牌,但是每5秒生成一个令牌,其实桶里还有6个令牌。那么按照顺序,我们继续拿令牌,再过5秒,我又拿走5个令牌,桶里剩下的应该是2个令牌。继续拿走令牌拿走2个,花费2秒,那么此时桶里没有令牌了,需要等待3秒钟才会有新的令牌,那么此时3秒数据包是无法进入的。
3秒钟后新的令牌产生,一个数据包拿走令牌后,桶里又没有令牌了,那么此时需要等待4秒,因为第5秒才会有新的令牌生成,也就是从此时开始,每隔4秒才能有一个数据包进入。
在我们这个例子中,我们有一个这个桶里最多可以放置多少个令牌就是通过--limit-burst来设置的,而给桶里放置令牌的速度是通过--limit来设置的
