linux:通过tc对ppp连接自动进行流量控制
tc是基于linux内核的,英文原形应该是Traffic Control,linux都是自带的,无需安装
?
一般服务器在接到客户端ppp连接的请求时,就需要去调用ppp进程来建立ppp连接,而ppp每次连接的时候,都会运行/etc/ppp/目录下的ip-up脚本(Centos、Ubuntu都是一样的),当连接断开的时候,也会调用该目录下的ip-down脚本。所以你就可以在这两个脚本中加入tc流控规则。
?
当然,tc规则都是基于ppp连接的,而不是基于服务器网卡的,所以就需要知道每个ppp连接的网卡名称(device name)。那ppp在调用ip-up和ip-down的时候,肯定都知道这些参数的
?
Centos的ip-up脚本里引用了$1、$6这两个参数
写道
LOGDEVICE=$6
REALDEVICE=$1
?
Ubuntu的ip-up脚本里引用了$1、$2、$3、$4、$5、$6
写道
PPP_IFACE="$1"
PPP_TTY="$2"
PPP_SPEED="$3"
PPP_LOCAL="$4"
PPP_REMOTE="$5"
PPP_IPPARAM="$6"
?
通过变量名称也大概可以知道这些位置参数基本上对应是什么了
最简单的方法,就是在ip-up脚本里加入一行代码
写道
echo "The arg of script ip-up is $*" >> /var/log/ip-up.log
?
然后进行vpn拨号一下,就会发现/var/log/ip-up.log有如下内容:
写道
echo ppp0 /dev/pts/3 115200 172.16.0.1 172.16.0.100 192.168.2.6
??????????????? $1???????? $2??????????? $3???????????? $4????????????? $5??????????????? $6
?
所以这些参数代表什么意思一目了然
$1:ppp连接的接口名称
$2:ppp连接的设备名称
$3:ppp连接的速率 (具体什么速率偶也不太清楚,有点像终端比特率的感觉)
$4:ppp连接的远程虚拟ip
$5:ppp连接的本地虚拟ip
$6:ppp连接客户端的真实IP
?
?
ok,了解这些之后,接下来就是服务器上直接修改了
?
一、修改ip-up文件
?
因为我的流控命令都放在另外一个脚本,所以在ip-up里是调用脚本的,而不是直接运行命令。在ip-up直接放置tc命令也可以。
在ip-up脚本里添加如下内容
写道
file_path=/etc/ppp/tcppp (tc流控脚本)
log_path=/var/log/tcppp (运行日志,所有输出都打印到这个文件里)
current_time=$(date +%F\ %T) (日志中加入时间)
{
if [ -x "$file_path" ];then
echo "$current_time The ppp connect $1 UP!"
echo "--------------> Gateway of $1 : $4"
echo "--------------> IP address of $1 : $5"
echo "--------------> Source ip of $1 : $6"
/bin/sh /etc/ppp/tcppp $1 (调用tc流控脚本,有$1作为参数)
else
echo "$current_time ERROR:The traffic control script $file_path was NOT FOUND!"
fi
} >> $log_path? (所有的echo输出都会重定向到这)
?
?
二、添加tc流控脚本
?
为了方便,就把流控脚本也放到了/etc/ppp目录下,脚本内容如下
写道
#!/bin/sh
#
# This shell script was used for traffic control of ppp connect
# For default the band width is 15 Mbit/s
#
eth=$1
band=2
current_time=$(date +%F\ %T)
NO_ARG=65
usage()
{
echo "USAGE:`basename $0` \$ppp"
echo "ERROR:You should input the name of ppp connect"
exit "$NO_ARG"
}
tc_rule()
{
echo "$current_time Begin traffic control rule."
echo "--------------> PPP Connect: $eth"
echo "--------------> Traffic band: $band Mbit"
tc qdisc del dev "$eth" root > /dev/null 2>&1???
(保险起见,再次删除之前的tc规则)
tc qdisc add dev "$eth" root handle 2: htb default 10??
(以ppp0为根,新建tc规则)
tc class add dev "$eth" parent 2: classid 2:1 htb rate 100mbit ceil 100mbit??
(意思一下总带宽,没太大作用)
tc class add dev "$eth" parent 2:1 classid 2:10 htb rate "$band"mbit burst "$band"mbit ceil "$band"mbit cburst "$band"mbit prio 1
?? (限制速度,rate:总链路忙碌时占用带宽? ceil:总链路空闲时占用带宽,限制带宽大小为变量band的值,这个脚本即2mbit)
echo "--------------> OK!"
exit 0
}
if [ -z "$eth" ];then
usage;
else
tc_rule;
fi
?
其实,关键tc命令就那么几条,起流控作用的就那三条,当然,也可以浓缩为两条
写道
tc qdisc add dev "$eth" root handle 1: htb default 1
tc class add dev "$eth" parent 1: classid 1:1 htb rate "$band"mbit burst "$band"mbit ceil "$band"mbit cburst "$band"mbit prio 1
?
没有tc filter过滤规则,通过default x来设置默认作用的规则。当