如何使用iptables或tc来限制每个客户端的数据包。

我有一些问题的networking客户端发送数据太快。

我想慢下来,使用iptables,或者可能tc。

我见过的iptables解决scheme如:

sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 50/second --limit-burst 50 -j ACCEPT

但我认为限制适用于符合规则的所有内容,而不是每个客户的地址。

有没有办法使这个规则限制每个客户端地址的数据包?

你可以用简单的方法解决这个问题,试着用iptables最近的模块,最近跟踪源地址:

 iptables -m recent -h recent match options: [!] --set Add source address to list, always matches. [!] --rcheck Match if source address in list. [!] --update Match if source address in list, also update last-seen time. [!] --remove Match if source address in list, also removes that address from list. --seconds seconds For check and update commands above. Specifies that the match will only occur if source address last seen within the last 'seconds' seconds. --reap Purge entries older then 'seconds'. Can only be used in conjunction with the seconds option. --hitcount hits For check and update commands above. Specifies that the match will only occur if source address seen hits times. May be used in conjunction with the seconds option. --rttl For check and update commands above. Specifies that the match will only occur if the source address and the TTL match between this packet and the one which was set. Useful if you have problems with people spoofing their source address in order to DoS you via this module. --name name Name of the recent list to be used. DEFAULT used if none given. --rsource Match/Save the source address of each packet in the recent list table (default). --rdest Match/Save the destination address of each packet in the recent list table. --mask netmask Netmask that will be applied to this recent list. 

阻止SSH蛮力的例子:

 iptables -A INPUT -i eth0 -p tcp --syn --dport 22 -m recent --name ssh --set iptables -A INPUT -i eth0 -p tcp --syn --dport 22 -m recent --name ssh --rcheck --seconds 30 --hitcount 2 -j DROP 

我使用TC和iptables hashlimit的组合完成了这个工作。 我在LAN接口上创build了一个出站的TC带宽限制器(将目标下载stream量)设置为5 Mbits /秒。 然后,我在接口的输出mangle链中使用iptables hashlimit模块,以便如果数据包速率超过某个阈值,在任意两个不同的源和目标IP地址之间,它将开始将这些数据包分类为TC 5 Mbit / sstream量整形类。

但是,您必须正确设置数据包阈值,并且基于我的MTU是1500字节的事实,所以用这个数来计算每秒创build一个1.5 Mbps的阈值(每秒1000个数据包/秒) )。 再加上在hashlimit iptables模块(在我的设置上,它似乎是10,000)设置尽可能高的突发值,所有这一切的结果是短的下载全速运行,但较长的下载开始减速,因为一些数据包通过了TC的带宽限制类,这明显降低了数据包的速率等等。这有点破解,但是令人惊讶的是它起作用,而且效果很好。 而且由于使用了TC,所以不会有数据包被丢弃 – 只要达到数据包速率,就会被延迟进入TC类。

这是在CentOS 6盒子上。 我认为更现代的东西允许hashlimit模块支持每秒字节数,而不仅仅是每秒数据包,这甚至更好,但我试着在我的设置,它只是恢复到每秒使用数据包。

我刚刚在手机上,所以不能粘贴任何configuration,但如果你想要一些例子,让我知道,我会编辑这个答案。 我非常喜欢这个解决scheme,因为我所使用的限制是基于源IP和目标IP。 因此,系统将每个不同的src + dst IP组合视为自己的数据包stream进行限制。 hashlimit模块还支持源端口和目的端口(基本上是源IP,源端口,目的IP,目的端口的任意组合),所以甚至可以在源IP +端口和目的IP +端口之间的每个会话基础上进行限制。

UPDATE

所以下面大概是你如何做到这一点; 实验将是必需的。

TC:

 /sbin/tc qdisc add dev eth0 root handle 1: htb /sbin/tc class add dev eth0 parent 1: classid 1:1 htb rate 5Mbit 

iptables的:

 #!/bin/bash [[ "$1" =~ ^[ADI]$ ]] || exit 1 for IPT in /sbin/ip{,6}tables do $IPT -t mangle -$1 POSTROUTING -o eth0 -m hashlimit --hashlimit-above 1000/second --hashlimit-burst 10000 --hashlimit-mode srcip,dstip --hashlimit-name limiter -j CLASSIFY --set-class 1:1 done 

您可以使用connlimit模块来解决这个问题:

http://www.cyberciti.biz/faq/iptables-connection-limits-howto/