IPTABLES-特定传入IP的限制速率


103

我不希望限制特定服务的费率。我的目标是仅根据传入的IP地址限制速率。例如,使用伪规则:

john.domain.local (192.168.1.100) can only download from our httpd/ftp servers at "10KB/s" (instead of 1MB/s)

如何根据传入IP地址对IPTables进行限制等级?

Answers:


165

IPTables并非用于此类工作,在这种情况下,需要分析很多数据包才能做出这些决定。IPTables是部分答案!

真正的答案是Linux中强大而未充分利用的流量控制功能。请注意,在不知道发生了什么情况的情况下弄乱它可能会导致您失去与计算机的网络连接!你被警告了!

假设eth0是传出设备,则需要创建一个基于类的流量控制队列,默认情况下它将通过“快速”队列输出大多数流量,并将特定的人员列表放入“慢速”队列。

这样做的好处是,您可以创建一种情况,允许慢速用户使用大量出站流量,除非上级类需要带宽,但是此示例不会这样做(将始终为慢速用户提供10kbps)。排队系统将如下所示:

                         Inbound traffic
                              +
                              |
                              |
                              v
                     +------------------+
                     |   Class 1:1      |
                     |------------------|
                     |  Root (all flows)|
                     |       100mbit    |
                     +-----+-----+------+
                           |     |
                           |     |
                           |     |
                           |     |
                           |     |
          +----------+     |     |     +----------+
          |    1:11  +-----+     +-----+    1:12  |
          |----------|                 |----------|
          | Default  |                 | Slow     |
          |100mb-80kb|                 |   80kb   |
          +----------+                 +----------+

为此,首先,您需要在内核中设置排队规则。以下将为您执行此操作 .. 您必须将其作为一个完整的脚本运行

#!/bin/bash
tc qdisc add dev eth0 parent root handle 1: hfsc default 11
tc class add dev eth0 parent 1: classid 1:1 hfsc sc rate 100mbit ul rate 100mbit
tc class add dev eth0 parent 1:1 classid 1:11 hfsc sc rate 99920kbit ul rate 100000kbit
tc class add dev eth0 parent 1:1 classid 1:12 hfsc sc rate 80kbit ul rate 80kbit

tc qdisc add dev eth0 parent 1:11 handle 11:1 pfifo
tc qdisc add dev eth0 parent 1:12 handle 12:1 pfifo

“默认值11”很重要,因为它告诉内核如何处理未分类的流量。

完成此操作后,您便可以设置iptables规则来对符合特定条件的数据包进行分类。如果您打算将很多人放入这个缓慢的规则中,则更适合使用ipset规则(我认为应该在rhel6上可用)。

因此,创建一个ipset数据库来针对...进行匹配

ipset create slowips hash:ip,port

然后创建iptables规则进行匹配。

iptables -t mangle -I OUTPUT -m set --match-set slowips dst,src -j CLASSIFY --set-class 1:12

这指示内核,如果将目标IP与集合中的源端口进行匹配,则将其分类为使用流量控制设置的慢​​速队列。

现在,终于,每当您要降低IP速度时,都可以使用ipset命令将ip添加到该集合中,如下所示:

ipset add slowips 192.168.1.1,80
ipset add slowips 192.168.1.1,21
...

您可以使用命令“ tc -s class show dev eth0”测试它是否正常工作,并且您会在其中看到指示将数据包重定向到慢速队列的统计信息。

请注意,此操作唯一真正的缺点是可以使其在重启后仍然能够正常运行。我认为没有任何初始化脚本可用于在重新启动时从转储中创建ipset(并且它们也必须 iptables规则之前创建),而且我敢肯定没有初始化脚本可在重新启动时重置流量控制规则。如果您不打扰,则可以通过调用rc.local中的脚本来重新创建整个过程。


3
好吧,我感激不尽。这是非常描述性和非常有益的。后来我意识到需要具备TC知识,因此我开始对此进行研究。再次感谢!
詹姆斯

哦,至于失去联系。从VPS移到主机之前,我要确保已关闭配置。另外,我可以通过VPN访问ETH0上的专用网络。我只会在ETH1上工作,所以从理论上讲我不会有问题。但是听到警告!
詹姆斯

2
我不能告诉你我已经阅读过几次类似的教程,这是第一个有意义的教程
RC1140,2012年

5
附带说明一下,它通常更适合在控制组中进行这样的资源限制(同样,也是可能的,也没有得到充分利用,而且非常出色),因为您可以在集中化的“策略存储”中定义每个应用程序对cpu,内存,IO和网络的限制'。但是尚未看到提出这样一个问题的答案。
马修·伊夫

2
如果您不喜欢这种tc语法,可以尝试一下tcng,它会增加一些用户友好的语言来生成tc命令。我已经习惯了像这样的shell脚本:echo '... multi line tcng configuration ...' | tcng | sh
Mattias Wadman'5

5

这就像采取限速规则并添加-s开关一样简单。该-s交换机的IP传入匹配。例如iptables -A INPUT -s 1.1.1.1,然后结束该规则的首选速率限制方法。


感谢您的迅速答复。不幸的是,我的主要问题是下半场。我研究了--limit,但还没有发现任何可让我根据KB / s进行限制的内容-您能指出什么方向?
詹姆斯

1
@James我会尽快和您联系的,但我必须出门到朋友家。刚回来,我发现MIfe做得很好。=)
韦斯利2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.