常见问题
业务指南
文档下载
意见投诉
ICP服务

iptable+tc进行带宽限制

 

#!/bin/bash

# 定义内网和外网的网卡
INET_IFACE="eth0"
LAN_IFACE="eth1"

# 脚本:用100mbps作为峰值速率
#Set the following values to somewhat lesss than your actual download and uplink speed.
DOWNLINK=12.5
UPLINK=12.5

k=35k

# 清空已有的队列,并把出错消息清空
# clean existing down and uplink qdiscs,put the errors to /dev/null
#tc qdisc del dev $INET_IFACE root 2> /dev/null
tc qdisc del dev $INET_IFACE root
tc qdisc del dev $INET_IFACE ingress
#tc qdisc del dev eth1 root

########################################uplink#################
# 建立HTB父类,默认数据由1:15这个类通走
# install root HTB,point default traffic to 1:15:
tc qdisc add dev $INET_IFACE root handle 1: htb default 15

# 设定uplink的最大速率。
#shape everything at $UPLINK speed -this prevents huge queues in your DSL modem which destroy

# main class
tc class add dev $INET_IFACE parent 1: classid 1:1 htb rate ${UPLINK}mbps ceil ${UPLINK}mbps burst ${k}

# 分类,1:11为最高优先级别(ssh) -> ftp-data -> stmp,pop3次之,网页浏览再次之。并对每个类限制了最高速率。
# high prio class 1:11:
tc class add dev $INET_IFACE parent 1:1 classid 1:11 htb rate 1mbps ceil 1mbps burst ${k} prio 0
tc class add dev $INET_IFACE parent 1:1 classid 1:12 htb rate 3mbps ceil ${UPLINK}mbps burst ${k} prio 2
tc class add dev $INET_IFACE parent 1:1 classid 1:13 htb rate 1mbps ceil ${UPLINK}mbps burst ${k} prio 1
tc class add dev $INET_IFACE parent 1:1 classid 1:14 htb rate 512kbps ceil ${UPLINK}mbps burst ${k} prio 1
#bulk & default class 1:15 -gets slightly more traffic,but a lower priority:
tc class add dev $INET_IFACE parent 1:1 classid 1:15 htb rate 6mbps ceil ${UPLINK}mbps burst ${k} prio 3

# 可以在类下面再附加上另一个队列规定,以保证带宽的公平使用:
# best get Stochastic Fairness:
tc qdisc add dev $INET_IFACE parent 1:12 handle 12: sfq perturb 10
tc qdisc add dev $INET_IFACE parent 1:13 handle 13: sfq perturb 10
tc qdisc add dev $INET_IFACE parent 1:14 handle 14: sfq perturb 10
tc qdisc add dev $INET_IFACE parent 1:15 handle 15: sfq perturb 10


# 分类 上面的队列处理中等于把所有发出的数据包都送给了1:15 -> (tc qdisc add dev $INET_IFACE root handle 1: htb default 15)
# TOS Mininum Delay (ssh,telnet) in 1:11:
tc filter add dev $INET_IFACE parent 1:0 protocol ip prio 1 handle 1 fw classid 1:11

# 80,8080,443 in 1:12
tc filter add dev $INET_IFACE parent 1:0 protocol ip prio 2 handle 2 fw classid 1:12

# ftp-data in 1:13
tc filter add dev $INET_IFACE parent 1:0 protocol ip prio 3 handle 3 fw classid 1:13

# smtp,pop3 in 1:14
tc filter add dev $INET_IFACE parent 1:0 protocol ip prio 4 handle 4 fw classid 1:14

tc filter add dev $INET_IFACE parent 1:0 protocol ip prio 5 handle 5 fw classid 1:15

# 丢掉那些太快到来的数据包,不让他们导致TCP/IP的速率高于我们期望的速率。因为我们不希望轻易地丢弃数据包,所以我们要配置"burst"来容纳突发传输
# install the ingress qdisc on the ingress
tc qdisc add dev $INET_IFACE handle ffff: ingress
# DROP everything that's coming in too fast:
tc filter add dev $INET_IFACE parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate ${DOWNLINK}mbps burst ${k} drop flowid :1

# demo 对内网的IP速率进行限制,把内网172.16.254.0段的速率限制成128kbit,所能借到的最大带宽384Kbit,允许突发流量为15Kbit,当然你可以修改改rate或ceil.
#tc qdisc add dev eth1 root handle 2: htb
#tc class add dev eth1 parent 2: classid 2:1 htb rate 512kbit
#tc class add dev eth1 parent 2:1 classid 2:20 htb rate 128kbit ceil 384kbit burst 15k
#tc qdisc add dev eth1 parent 2:20 handle 20: sfq
#tc filter add dev eth1 parent 2:0 protocol ip prio 4 u32 match ip dst 172.16.254.0/24 flowid 2:20


这是iptables的mangle部分

# 类1:
# 最小延迟的归第一类
$IPT -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j MARK --set-mark 0x1
$IPT -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j RETURN

# 这里是邮件(SMTP、pop3)相关和TOS要求最小成本的数据流
$IPT -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j MARK --set-mark 0x4
$IPT -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j RETURN

# 最后是路由器后面经过NAT进行大批量传输的机器。以保证他们不会妨碍正常服务
$IPT -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j MARK --set-mark 0x5
$IPT -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j RETURN

# tag all incoming SYN packets through eth0 as mark value
$IPT -t mangle -I PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 0x1
$IPT -t mangle -I PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN

# ftp控制放第1类,因为一般是小包
$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport ftp -j MARK --set-mark 0x1
$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport ftp -j RETURN
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport ftp -j MARK --set-mark 0x1
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport ftp -j RETURN

# 然后提高ssh数据包的优先权
#$IPT -t mangle -A PREROUTING -p tcp --dport ssh -j TOS --set-tos Minimize-Delay
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport 22 -j MARK --set-mark 0x1
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport 22 -j RETURN

# DNS放第一类
$IPT -t mangle -A PREROUTING -p udp -m udp --dport 53 -j MARK --set-mark 0x1
$IPT -t mangle -A PREROUTING -p udp -m udp --dport 53 -j RETURN

# 类2:用于放置大批量传输的类。用来处理浏览网页的数据包,目标端口80的包。
$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport 80 -j MARK --set-mark 0x2
$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport 80 -j RETURN
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport 80 -j MARK --set-mark 0x2
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport 80 -j RETURN

$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport 443 -j MARK --set-mark 0x2
$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport 443 -j RETURN
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport 443 -j MARK --set-mark 0x2
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport 443 -j RETURN

$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport 8080 -j MARK --set-mark 0x2
$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport 8080 -j RETURN
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport 8080 -j MARK --set-mark 0x2
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport 8080 -j RETURN


# 类3:ftp-data放在第3类,要求最大吞吐.
$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport ftp-data -j MARK --set-mark 0x3
$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport ftp-data -j RETURN

$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport ftp-data -j MARK --set-mark 0x3
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport ftp-data -j RETURN

$IPT -t mangle -A POSTROUTING -m helper --helper ftp -j MARK --set-mark 0x3
$IPT -t mangle -A POSTROUTING -m helper --helper ftp -j RETURN

# 类4:
# 邮件(SMTP、pop3)相关和TOS要求最小成本的数据流。
$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport 25 -j MARK --set-mark 0x4
$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport 25 -j RETURN
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport 25 -j MARK --set-mark 0x4
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport 25 -j RETURN

$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport 110 -j MARK --set-mark 0x4
$IPT -t mangle -A PREROUTING -p tcp -m tcp --dport 110 -j RETURN
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport 110 -j MARK --set-mark 0x4
$IPT -t mangle -A PREROUTING -p tcp -m tcp --sport 110 -j RETURN

# 类5:前面没有打过标记的数据包将交给1:15处理:
$IPT -t mangle -A PREROUTING -j MARK --set-mark 0x5

# 在OUTPUT链中再重复一遍上面的设置
$IPT -t mangle -A OUTPUT -m tos --tos Minimize-Delay -j MARK --set-mark 0x1
$IPT -t mangle -A OUTPUT -m tos --tos Minimize-Delay -j RETURN

$IPT -t mangle -A OUTPUT -m tos --tos Minimize-Cost -j MARK --set-mark 0x4
$IPT -t mangle -A OUTPUT -m tos --tos Minimize-Cost -j RETURN

$IPT -t mangle -A OUTPUT -m tos --tos Maximize-Throughput -j MARK --set-mark 0x5
$IPT -t mangle -A OUTPUT -m tos --tos Maximize-Throughput -j RETURN

$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport 22 -j MARK --set-mark 0x1
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport 22 -j RETURN

$IPT -t mangle -I OUTPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 0x1
$IPT -t mangle -I OUTPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN

$IPT -t mangle -A OUTPUT -p udp -m udp --dport 53 -j MARK --set-mark 0x1
$IPT -t mangle -A OUTPUT -p udp -m udp --dport 53 -j RETURN

$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport ftp -j MARK --set-mark 0x1
$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport ftp -j RETURN
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport ftp -j MARK --set-mark 0x1
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport ftp -j RETURN

$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport 80 -j MARK --set-mark 0x2
$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport 80 -j RETURN
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport 80 -j MARK --set-mark 0x2
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport 80 -j RETURN

$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport 443 -j MARK --set-mark 0x2
$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport 443 -j RETURN
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport 443 -j MARK --set-mark 0x2
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport 443 -j RETURN

$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport 8080 -j MARK --set-mark 0x2
$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport 8080 -j RETURN
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport 8080 -j MARK --set-mark 0x2
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport 8080 -j RETURN

$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport ftp-data -j MARK --set-mark 0x3
$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport ftp-data -j RETURN
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport ftp-data -j MARK --set-mark 0x3
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport ftp-data -j RETURN

$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport 25 -j MARK --set-mark 0x4
$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport 25 -j RETURN
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport 25 -j MARK --set-mark 0x4
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport 25 -j RETURN
$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport 110 -j MARK --set-mark 0x4
$IPT -t mangle -A OUTPUT -p tcp -m tcp --dport 110 -j RETURN
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport 110 -j MARK --set-mark 0x4
$IPT -t mangle -A OUTPUT -p tcp -m tcp --sport 110 -j RETURN

$IPT -t mangle -A OUTPUT -j MARK --set-mark 0x3

想把80端口访问留30M的样子,default留50M的样子,线路是100M的带宽,tc脚本中我全部换算成了Bytes,完了保证10M给ssh和要求延迟最小的数据包。

# 丢掉那些太快到来的数据包,不让他们导致TCP/IP的速率高于我们期望的速率。因为我们不希望轻易地丢弃数

这个后面的去掉看看,我只是在

iptables -t mangle -A OUTPUT -p tcp \
--sport 80 -j MARK --set-mark 1


中设置mark,你的iptables设置的好多阿...

另 -j RETURN ,你没有用自定义的链,何必用这个跳转?

btw: ceil 是最大可用带宽,应该设置为11,而不是upxxxx

单位拟可能也弄错了...
我的100M的限速版本

#!/bin/sh
service iptables stop

real_bw=100Mbit
ftp_bw=80Mbit

NIC='eth0'
k=35k
r2q=400

tc qdisc del dev "$NIC" root

tc qdisc add dev "$NIC" root handle 1: htb r2q ${r2q}

tc class add dev "$NIC" parent 1: classid 1:1 htb rate $real_bw ceil $real_bw burst ${k}

tc class add dev "$NIC" parent 1:1 classid 1:10 htb rate $ftp_bw ceil $ftp_bw burst ${k}

tc qdisc add dev "$NIC" parent 1:10 sfq perturb 10

tc filter add dev "$NIC" parent 1: protocol ip handle 1 fw flowid 1:10


iptables -t mangle -A OUTPUT -p tcp \
--sport 80 -j MARK --set-mark 1

上海电信漕宝机房 地址:漕宝路1600号 漕宝机房介绍 上海移动双线机房 机房地址: 金沙江路1340弄 双线机房介绍
公司地址:上海市普陀区清峪路368弄12号301 邮编:200333 电话 021-52691612 传真 021-52693626
《增值电信业务经营许可证》许可证编号: 沪ICP备05001352号 上海市互联网违法与违规信息举报中心
上海市互联网协会 上海市电子商务行业协会 DNS Stuff 公益性SEO 页面执行时间:31.250毫秒
上海纵智信息技术有限公司 版权所有 2004-2007 营业执照