use*_*223 8 networking ubuntu vpn openvpn
我有一组用户通过OpenVPN TCP 和 UDP(2 个服务)连接到我的服务器。这两种服务在运行tun0和tun1
我希望能够使用 TC 命令将每个用户的带宽限制为 5mb/s 上升和 5mb/s 下降。
这很容易用 PPTP 实现,因为每个用户都有自己的界面,所以我可以为该界面创建一个新的类/过滤器,使用以下内容将其限制为我想要的速度限制:
IF=<taken from up script, i.e. 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
Run Code Online (Sandbox Code Playgroud)
据我所知,OpenVPN 用户没有自己的接口,所有流量都通过主接口tun0和tun1接口。
所以我在这里有两个问题。
1) 由于某种原因,上面的脚本似乎不适用于 OpenVPN(将接口名称设置为tun0或tun1)我的测试用户仍然可以以他们互联网的最大速度下载。
2)我需要能够过滤每个源IP并将其添加到OpenVPN的up脚本中,同时维护其他过滤器/类并在down脚本中删除该过滤器/类,同样不会影响其他连接用户的限制(即我不能在用户每次连接时简单地删除 tun0 的 qdisc)。
搜索时我能找到的唯一帮助是
“你可以使用 TC”
但没有解释如何...
谢谢!
Oli*_*ver 11
我曾经做过这样的事情来单独为每个用户的连接设置防火墙。我已经使用learn-addressOpenVPN 中的脚本实现了它,该脚本在用户连接或断开连接时调用。我已根据您的用例对其进行了调整。
该脚本如下所示:
#!/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
Run Code Online (Sandbox Code Playgroud)
该脚本需要安装在您的 OpenVPN 的 server.conf 中,如下所示:
learn-address <path-to-script>
script-security 3
Run Code Online (Sandbox Code Playgroud)
script-security 3 是必要的,所以 OpenVPN 实际上调用了脚本。
当用户连接时,脚本被称为<path-to-script> add <ip> <username>,而且网络接口被放置在环境变量中$dev(例如tun0)。
该脚本为排队规则配置网络接口,并将必要的过滤器和类附加到它。它会跟踪为其安装过滤器和类的 IP,以便稍后在用户断开连接时将其删除。该状态保存在目录中/tmp,这可能应该更改。
请注意,我不确定我是否 100% 正确地掌握了交通控制方面的内容。下载流量整形(即从 OpenVPN 到用户)工作正常,但限制上传不是很精确,根据我的理解,这有点正常。也许您可以找到更好的方法并将其集成到脚本中。