一个用tc+iptables实现的下载和上传带宽限制的脚本

发表于:2007-07-04来源:作者:点击数: 标签:
一个用tc+iptables实现的下载和上传带宽限制的脚本 这是我用的,新年献给大家。每个IP单独限制,好随时修改。如果是用拨号上网的,请把以下内容加到/etc/ppp/ip-up.local中,否则断线重拨后会没有上传限制,对BT光限制下载是不够的。 #!/bin/bash # #zyx@zyx

一个用tc+iptables实现的下载和上传带宽限制的脚本

这是我用的,新年献给大家。每个IP单独限制,好随时修改。如果是用拨号上网的,请把以下内容加到/etc/ppp/ip-up.local中,否则断线重拨后会没有上传限制,对BT光限制下载是不够的。


#!/bin/bash
#
# zyx@zyx.2288.org
#
#  定义上下带宽
#  注意是 Kbit
DOWNLOAD=800Kbit
UPLOAD=160Kbit
#  定义内网IP段
INET=192.168.0.
#  定义限制的IP范围
IPS=1
IPE=253
#  定义本服务器IP
ServerIP=254
#  定义进出设备
IDEV=eth0
ODEV=ppp0
#
#
#
/sbin/tc qdisc del dev $IDEV root handle 10:
/sbin/tc qdisc del dev $ODEV root handle 20:
#
/sbin/tc qdisc add dev $IDEV root handle 10: cbq bandwidth 100Mbit avpkt 1000
/sbin/tc qdisc add dev $ODEV root handle 20: cbq bandwidth 1Mbit avpkt 1000
#
/sbin/tc class add dev $IDEV parent 10:0 classid 10:1 cbq bandwidth 100Mbit rate 100Mbit allot 1514 weight 1Mbit prio 8 maxburst 20 avpkt 1000
/sbin/tc class add dev $ODEV parent 20:0 classid 20:1 cbq bandwidth 1Mbit rate 1Mbit allot 1514 weight 10Kbit prio 8 maxburst 20 avpkt 1000
#
# 不限制内网从本服务器下载。
# 注意如本服务器上有代理,用户可通过代理绕过带宽限制,
# 可取消以下三句限制从本服务器下载。
/sbin/tc class  add dev $IDEV parent 10:1 classid 10:10 cbq bandwidth 100Mbit rate 95Mbit allot 1514 weight 20Kbit prio 5 maxburst 20 avpkt 1000 bounded
/sbin/tc qdisc  add dev $IDEV parent 10:10 sfq quantum 1514b perturb 15
/sbin/tc filter add dev $IDEV parent 10:0 protocol ip prio 50 u32 match ip src $INET$ServerIP flowid 10:10
#
#限制下载速度
COUNTER=$IPS
while [ $COUNTER -le $IPE ]
do
#   以下三句限制各IP的下载带宽
    /sbin/tc class  add dev $IDEV parent 10:1 classid 10:1$COUNTER cbq bandwidth 100Mbit rate $DOWNLOAD allot 1514 weight 20Kbit prio 5 maxburst 20 avpkt 1000 bounded
    /sbin/tc qdisc  add dev $IDEV parent 10:1$COUNTER sfq quantum 1514b perturb 15
    /sbin/tc filter add dev $IDEV parent 10:0 protocol ip prio 100 u32 match ip dst $INET$COUNTER flowid 10:1$COUNTER
    COUNTER=` expr $COUNTER + 1 `
done
#
#限制上传速度
COUNTER=$IPS
while [ $COUNTER -le $IPE ]
do
#   以下三句限制各IP的上传带宽
    /sbin/tc class  add dev $ODEV parent 20:1 classid 20:1$COUNTER cbq bandwidth 1Mbit rate $UPLOAD allot 1514 weight 4Kbit prio 5 maxburst 20 avpkt 1000 bounded
    /sbin/tc qdisc  add dev $ODEV parent 20:1$COUNTER sfq quantum 1514b perturb 15
    /sbin/tc filter add dev $ODEV parent 20:0 protocol ip prio 100 handle $COUNTER fw classid 20:1$COUNTER
    COUNTER=` expr $COUNTER + 1 `
done
#特殊照顾的IP在以上范围的用户
NIP=78
#192.168.0.78 这家伙天天BT
ND=200Kbit
NU=50Kbit
/sbin/tc class change dev $IDEV  parent 10:1 classid 10:1$NIP bandwidth 100Mbit rate $ND allot 1514 weight 20Kbit prio 5 maxburst 20 avpkt 1000 bounded
/sbin/tc class change dev $ODEV parent 20:1 classid 20:1$NIP cbq bandwidth 1Mbit rate $NU allot 1514 weight 4Kbit prio 5 maxburst 20 avpkt 1000 bounded
#
NIP=1
# 192.168.0.1 增加我自已的带宽
ND=1500Kbit
NU=500Kbit
/sbin/tc class change dev $IDEV  parent 10:1 classid 10:1$NIP bandwidth 100Mbit rate $ND allot 1514 weight 20Kbit prio 5 maxburst 20 avpkt 1000 bounded
/sbin/tc class change dev $ODEV parent 20:1 classid 20:1$NIP cbq bandwidth 1Mbit rate $NU allot 1514 weight 4Kbit prio 5 maxburst 20 avpkt 1000 bounded
# ...................
#
#
#  修改防火墙,增加上传限制
COUNTER=$IPS
while [ $COUNTER -lt $IPE ]
do
    iptables -t mangle -A PREROUTING -i $IDEV -s $INET$COUNTER  -j MARK --set-mark $COUNTER
    COUNTER=` expr $COUNTER + 1 `
done
# 这里是NAT
iptables -t nat -A POSTROUTING -o $EXTIF -s 192.168.0.0/24 -j MASQUERADE

 zyx914 回复于:2005-01-04 10:41:39
没人感兴趣吗? :m01: 
自已顶一下。 :D

 阿辉 回复于:2005-01-04 11:30:50
很好,谢谢,不知你试用的结果怎么样?

 KindGeorge 回复于:2005-01-04 13:49:14
我也对tc+iptables有一段时间的研究, 我顶你.
问个问题: 1.你的adsl带宽上行和下行的带宽多少?
2.你内部网多少台机子一起上?

 bst 回复于:2005-01-04 16:56:44
支持原创

 zyx914 回复于:2005-01-04 17:44:08
1)俺们这电信象我这样的老用户是下150KB/s(1200Kbit) 上50KB/s(400Kbit),电信新装的用户现在是下200KB/s上50KB/s。
2)内网最多时8个用户,分给每一用户是下800Kbit(100KB)上320Kbit(40KB),对一个BT分子单独限制 18:00-02:00是400Kbit/80Kbit,其它时间内与其它人一样。
3)效果是内网上下本服务器FTP/SMB/Mail不受限(没开代理),从其它高速地方下时平均是100KB/s,上传也受限为平均40KB(10KB BT分子)。

 KindGeorge 回复于:2005-01-05 08:33:22
本人有一点愚见:
1.内网所有电脑肯定是共享这条线路出去的.所以当内网不是很饱和的情况下,是没问题的.
2.根据你上面3)说的,上传平均为40KB,但当一个人通过线路往外传ftp,或者发个大邮件时,就会占满了几乎整个上传带宽,如果经常有这样的人,其他人进行其他的服务,例如http,就会受到影响.
3.下行不见得有麻烦,关键的瓶颈在上行的一点点带宽里.我认为分协议共享较好.

 jsqyy 回复于:2005-01-05 21:50:51
请问如果有200台机器的时候,这个该如何修改呢?我想TC只是限制最大值吧

 sailboy 回复于:2005-01-06 18:32:07
谢谢,,,顶

 KindGeorge 回复于:2005-01-07 14:16:14
个人认为如果分端口号分配好些.
因为如果每个ip 是 UPLOAD=160Kbit ,但当用ftp时,ftp是占用大量的上传带宽,将严重影响交互性能或其他服务,例如ssh,dns,ack包等..
并且在网络很空闲时,某个ip不能得到更多的带宽,本来有50KB/s(400Kbit),你已经限定它在160kbit了,而你某个ip的全部服务是共享这160k

 happyhunter 回复于:2005-01-10 12:30:50
前几天看到这个帖子,很感兴趣,所以这两天做了一下研究,发现很多问题,提出来讨论一下:
我这个网络是用iptables +squid +nat带动上网的,内网节点500+,也想做基于ip的流控,关于是基于协议还是基于ip的流控主要看实际的要求,我认为没有讨论的必要。
第一个问题,我认为你用的cbq队列在真正的网络应用中无法发挥作用,因为cbq是通过计算硬件闲置时间来计算队列,硬件不同,差异就会很大,效果不好。
第二,像我这样的网络,500+,如果按你的方法,先打标记,再分类,首先prerouting链会变得很大,每一个包都要遍历整个链表,效率很低。
实际上我试了一下,做了上面的方案后,网络变得很慢,没法接受,所以我认为上面的方案有改进的必要,我的意见是,
首先将cbq换成htb,既简单效率也高,其次在mark时应加上return ,防止遍历整个链表,效果还没试。

 5417 回复于:2005-01-11 10:08:56
超酷~~~~~~~~~~楼主。
有TC的好资料共享给我,xiexie
fatboyslimww@hotmail.com

 jackylau 回复于:2005-01-11 14:06:15
TC还不知道怎么用呢?有没这方面的初学资料,最好也发下来,THANKS!

原文转自:http://www.ltesting.net