我有一组用户通过OpenVPN TCP和UDP连接到我的服务器(2个服务)。 这两个服务在tun0和tun1
我希望能够使用TC命令将每个用户的带宽限制为5mb / s和5mb / s。
这是很容易实现与PPTP每个用户有自己的接口,所以我可以创build一个新的类/filter的接口限制到我想要的速度限制使用这样的事情:
IF=<taken from up script, ie ppp1> tc qdisc del dev $IF root tc qdisc add dev $IF root handle 1: cbq avpkt 1000 bandwidth 100mbit tc class add dev $IF parent 1: classid 1:1 cbq rate 10mbit allot 1500 prio 5 bounded isolated tc filter add dev $IF parent 1: protocol ip prio 16 u32 match ip src 0.0.0.0/0 flowid 1:1 tc qdisc add dev $IF parent 1:1 sfq perturb 10
据我所知,OpenVPN用户没有自己的界面,所有的stream量都通过主要的tun0和tun1接口。
所以我在这里有两个问题。
1)由于某些原因,上面的脚本似乎不能与OpenVPN一起工作(将接口名称设置为tun0或tun1 ),我的testing用户仍然可以以他们的互联网最高速度下载。
2)我需要能够过滤这个每个来源的IP,并将其添加到OpenVPN的up脚本,当他们连接,同时维护其他filter/类,并删除该filter/类在down脚本,而不会影响其他连接的用户的限制即我不能简单地删除每个用户连接tun0 qdisc)。
唯一的帮助,我可以find时search
“你可以用TC来做那个”
但没有解释如何…
谢谢!
我曾经做过这样的事情,单独防火墙每个用户的连接。 我已经使用OpenVPN中的learn-address脚本实现了它,当用户连接或断开连接时,脚本被调用。 我已经适应了你的用例。
该脚本如下所示:
#!/bin/bash statedir=/tmp/ function bwlimit-enable() { ip=$1 user=$2 # Disable if already enabled. bwlimit-disable $ip # Find unique classid. if [ -f $statedir/$ip.classid ]; then # Reuse this IP's classid classid=`cat $statedir/$ip.classid` else if [ -f $statedir/last_classid ]; then classid=`cat $statedir/last_classid` classid=$((classid+1)) else classid=1 fi echo $classid > $statedir/last_classid fi # Find this user's bandwidth limit # downrate: from VPN server to the client # uprate: from client to the VPN server if [ "$user" == "myuser" ]; then downrate=10mbit uprate=10mbit elif [ "$user" == "anotheruser"]; then downrate=2mbit uprate=2mbit else downrate=5mbit uprate=5mbit fi # Limit traffic from VPN server to client tc class add dev $dev parent 1: classid 1:$classid htb rate $downrate tc filter add dev $dev protocol all parent 1:0 prio 1 u32 match ip dst $ip/32 flowid 1:$classid # Limit traffic from client to VPN server tc filter add dev $dev parent ffff: protocol all prio 1 u32 match ip src $ip/32 police rate $uprate burst 80k drop flowid :$classid # Store classid and dev for further use. echo $classid > $statedir/$ip.classid echo $dev > $statedir/$ip.dev } function bwlimit-disable() { ip=$1 if [ ! -f $statedir/$ip.classid ]; then return fi if [ ! -f $statedir/$ip.dev ]; then return fi classid=`cat $statedir/$ip.classid` dev=`cat $statedir/$ip.dev` tc filter del dev $dev protocol all parent 1:0 prio 1 u32 match ip dst $ip/32 tc class del dev $dev classid 1:$classid tc filter del dev $dev parent ffff: protocol all prio 1 u32 match ip src $ip/32 # Remove .dev but keep .classid so it can be reused. rm $statedir/$ip.dev } # Make sure queueing discipline is enabled. tc qdisc add dev $dev root handle 1: htb 2>/dev/null || /bin/true tc qdisc add dev $dev handle ffff: ingress 2>/dev/null || /bin/true case "$1" in add|update) bwlimit-enable $2 $3 ;; delete) bwlimit-disable $2 ;; *) echo "$0: unknown operation [$1]" >&2 exit 1 ;; esac exit 0
该脚本需要安装在您的OpenVPN的server.conf中,如下所示:
learn-address <path-to-script> script-security 3
script-security 3是必要的,所以OpenVPN实际上调用脚本。
当用户连接时,脚本被称为<path-to-script> add <ip> <username> ,而且networking接口被放置在环境variables$dev (例如tun0 )中。
该脚本configurationnetworking接口排队纪律,并附加必要的filter和类。 它跟踪为其安装筛选器和类的IP,以便稍后在用户断开连接时将其删除。 该状态保存在/tmp ,可能应该更改。
请注意,我不确定我是否已经把交通pipe制的东西100%的权利。 下载stream量整形(即从OpenVPN到用户)工作正常,但限制上传不是很精确,这是从我所了解的有点正常。 也许你可以find一个更好的方法,并将其整合到脚本中。