##linux下使用iptables和tc限制速度
linux下使用iptables和tc限制速度的方法,记录一下。
假设本地搭建了PPTPD服务,又或者有多个网卡,需要对其中一些接口做限速处理的情况,非常有用. 本文基于CentOS 6.4 64bit。 详细参考@zhukun __
###1、初始配置
yum install /sbin/tc
vim /etc/sysctl.conf
修改net.ipv4.ip_forward = 1
sysctl -p
#清除原来的mangle表规则
iptables -t mangle -F
#加载sch_htb模块
modprobe sch_htb
echo "modprobe sch_htb" >> /etc/rc.local
###2、TC限速设置
- 假设现在有两块网卡
- eth0:xx.xx.xx.xx(外网上网地址)
- eth1:192.168.2.9(内网网关地址)
####下载限速配置 因为tc框架对数据包的控制是:控发不控收。因此下载限速要在eth1上面做,判断数据包的目的地址来做限制。tc包括三部分:队列、类、过滤器。我使用了htb方式去限制速度,也可以使用cbq,但cbq配置比较复杂一点,而且据说性能没htb好。
#删除原来的tc规则队列
/sbin/tc qdisc del dev eth1 root
#添加tc规则队列
/sbin/tc qdisc add dev eth1 root handle 10: htb default 256
#生成根类
/sbin/tc class add dev eth1 parent 10: classid 10:1 htb rate 100mbit ceil 100mbit
#支类列表用于限制速度
#这里的rate指的是保证带宽,ceil是最大带宽。
/sbin/tc class add dev eth1 parent 10:1 classid 10:10 htb rate 400kbps ceil 400kbps prio 1
#添加支类规则队列
#采用sfq伪随机队列,并且10秒重置一次散列函数。
/sbin/tc qdisc add dev eth1 parent 10:10 handle 101: sfq perturb 10
#建立网络包过滤器,设置fw。
/sbin/tc filter add dev eth1 parent 10: protocol ip prio 10 handle 1 fw classid 10:10
- 分类数据包到对应的队列里,目前我使用两种方法
- 在iptables里面设定mark值,与上面的handle值对应
- 在iptables里设定set-class 为叶子节点1:10
- 标记mark值
iptables -t mangle -A POSTROUTING -d 192.168.2.130 -j MARK --set-mark 1 iptables -t mangle -A POSTROUTING -d 192.168.2.130 -j RETURN
- 标记classid
iptables -t mangle -A POSTROUTING -d 192.168.2.130 -j CLASSIFY --set-class 1:10 iptables -t mangle -A POSTROUTING -d 192.168.2.130 -j RETURN
通过上面的代码就可以限制172.16.44.130这台机子的下载速度到400kbps。
需要注意的是:
1,172.16.44.130也可以写成网段的形式,例如172.16.44.0/24
2,这里的kbps实际上就是KB/S(每秒千字节),另一个单位是kbit,这个才是每秒千比特。
####上传限速配置 上传限速的原理其实跟下载的差不多,只不过限制的网卡不同,要在eth0上过滤来源地址去限制。
##下面是我做qos的脚本代码,贴上来,有需要的可以参考一下
#!/usr/bin/env bash
# qos test script
addtc() {
DEV=eth1
#加载sch_htb模块
modprobe sch_htb
# 创建调度器
#添加tc规则队列
tc qdisc add dev $DEV root handle 1: htb default 256
# class 1:1, which is direct descendant of root(1:),
# this class gets assigned also an HTB qdisc, and then it sets a max rate of 6mbits,
# whith a burst of 15k
# sc: 限制带宽
# ul:
#生成根类
tc class add dev $DEV parent 1: classid 1:1 htb rate 100kbps ceil 2000kbps
#tc class add dev $DEV parent 1: classid 1:10 htb rate 10kbps burst 1k
#支类列表用于限制速度
#这里的rate指的是保证带宽,ceil是最大带宽。
tc class add dev $DEV parent 1:1 classid 1:10 htb rate 50kbps ceil 200kbps prio 1
#添加支类规则队列
#采用sfq伪随机队列,并且10秒重置一次散列函数。
tc qdisc add dev $DEV parent 10:10 handle 101: sfq perturb 10
#tc qdisc add dev $DEV parent 1:2 handle 2: sfq perturb 10
#tc qdisc add dev $DEV parent 1:30 handle 30: sfq perturb 10
}
deltc() {
tc qdisc del dev eth1 root
#iptables -t mangle -F
}
init() {
iptables -t mangle -N QOS
iptables -t mangle -N QOS_LAN
iptables -t mangle -I POSTROUTING -j QOS
iptables -t mangle -I QOS -j NDPI
iptables -t mangle -A QOS -o eth1 -j QOS_LAN
}
qos_exist_ndpi() {
exist=`iptables -t mangle -S QOS | grep NDPI | wc -l`
if [ "0" == $exist ]; then
return 1
else
return 0
fi
}
add() {
qos_exist_ndpi || iptables -t mangle -I QOS -j NDPI
iptables -t mangle -A QOS_LAN -m ndpi --protos "$1" -j CLASSIFY --set-class 1:10
iptables -t mangle -A QOS_LAN -m ndpi --protos "$1" -j RETURN
}
clean() {
iptables -t mangle -F QOS_LAN 2> /dev/null
iptables -t mangle -D QOS -j NDPI 2> /dev/null
iptables -t mangle -F 2> /dev/null
iptables -F FORWARD 2> /dev/null
}
show() {
iptables -t mangle -S QOS -v
iptables -t mangle -S QOS_LAN -v
iptables -S FORWARD -v
}
ban() {
iptables -I FORWARD -m ndpi --protos "$1" -j DROP
}
case "$1" in
init)init ;;
tc) addtc ;;
deltc) deltc ;;
add) add "$2" ;;
ban) ban "$2" ;;
del) del "$2" ;;
clean) clean ;;
show) show ;;
*) echo "no thing to do" ;;
esac