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

Jam*_*mes 103 iptables rhel6

我不想限制特定服务的费率。我的目标是仅根据传入的 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 进行速率限制?

Mat*_*Ife 167

IPTables 不是为这种工作而设计的,在这种工作中,需要分析大量数据包才能做出这些决定。IPTables 是部分答案!

对此的真正答案是 Linux 中令人敬畏且未充分利用的流量控制设施。请注意,在不知道发生了什么的情况下乱搞可能会导致您失去与机器的网络连接!你被警告了!

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

这样做的好处是,您可以创建一种情况,除非覆盖类需要带宽,否则您可以为慢速用户允许大量出站流量,但本示例不会这样做(将始终为慢速用户提供 10kbps)。排队系统看起来像这样:

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

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

#!/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
Run Code Online (Sandbox Code Playgroud)

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

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

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

ipset create slowips hash:ip,port
Run Code Online (Sandbox Code Playgroud)

然后创建 iptables 规则来进行匹配..

iptables -t mangle -I OUTPUT -m set --match-set slowips dst,src -j CLASSIFY --set-class 1:12
Run Code Online (Sandbox Code Playgroud)

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

现在,无论何时你想减慢一个 IP,你都可以使用 ipset 命令将 IP 添加到集合中,如下所示:

ipset add slowips 192.168.1.1,80
ipset add slowips 192.168.1.1,21
...
Run Code Online (Sandbox Code Playgroud)

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

请注意,唯一真正的缺点是使其在重新启动后仍然存在。我认为没有任何 init 脚本可用于在重新启动时从转储创建 ipsets(并且它们也必须iptables 规则之前创建)并且我确定没有 init 脚本可以在重新启动时重置流量控制规则。如果您不介意,您可以通过调用 rc.local 中的脚本重新创建整个过程。

  • 作为旁注,它通常更适合在控制组中进行这样的资源限制(同样,也可能并且未充分利用和很棒),因为您可以在集中的“策略存储”中定义每个应用程序对 CPU、内存、IO 和网络的限制'。但是还没有看到有人提出这样一个问题来提供答案。 (5认同)
  • 好吧,我怎么感谢你都不为过。这是非常具有描述性和信息量的。后来我意识到需要 TC 的知识,从那时起我就开始研究这个。再次感谢! (3认同)
  • 我不能告诉你我读过多少次类似的教程,这是第一个有意义的 (2认同)
  • 如果你不喜欢 `tc` 语法,你可以尝试一下 [tcng](http://tcng.sourceforge.net/),它添加了一些更用户友好的语言来生成 `tc` 命令。我曾经在 shell 脚本中喜欢这样:`echo '...多行 tcng 配置...' | tcng | sh`。 (2认同)

Wes*_*ley 5

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