ubuntu – 使用TC限制/限制每个用户的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

据我所知,OpenVPN用户没有自己的接口,所有流量都通过主tun0和tun1接口.

所以这里有2个问题.

1)上面的脚本由于某种原因似乎不能与OpenVPN一起使用(将接口名称设置为tun0或tun1)我的测试用户仍然可以以互联网的最高速度下载.

2)我需要能够对每个源IP进行过滤,并在连接时将其添加到OpenVPN的up脚本中,同时保持其他过滤器/类并在向下脚本中删除该过滤器/类,同样不会影响其他连接用户的限制(即每次用户连接时我都不能简单地删除tun0的qdisc).

我在搜索时能找到的唯一帮助就是

“you can use TC for that”

但没有解释如何……

谢谢!

我曾经做过类似的事情来单独防火每个用户的连接.我使用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>添加< ip> < username>,此外网络接口放置在环境变量$dev(例如tun0)中.

该脚本为排队规则配置网络接口,并为其附加必要的过滤器和类.它会跟踪安装过滤器和类的IP,以便以后在用户断开连接时将其删除.该状态保存在目录/ tmp中,这应该可以更改.

请注意,我不确定我是否已将流量控制的东西100%正确.下载流量整形(即从OpenVPN到用户)工作正常,但限制上传不是很精确,这与我所理解的有些正常.也许你可以找到更好的方法并将其集成到脚本中.

相关文章

目录前言一、创建Hadoop用户二、更新apt和安装Vim编辑器三、...
原文连接:https://www.cnblogs.com/yasmi/p/5192694.html ...
电脑重启后,打开VirtualBox,发现一直用的虚拟机莫名的消失...
参见:https://blog.csdn.net/weixin_38883338/article/deta...
Ubuntu 18.04 LTS 已切换到 Netplan 来配置网络接口。Netpla...
介绍每个 Web 服务都可以通过特定的 URL 在 Internet 上访问...