请教一下如何优雅的使用 TC 对大量的 IP 限速 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
Ansen
V2EX    Linux

请教一下如何优雅的使用 TC 对大量的 IP 限速

  •  
  •   Ansen 2024-07-20 15:14:16 +08:00 4350 次点击
    这是一个创建于 523 天前的主题,其中的信息可能已经有所发展或是发生改变。
    使用一台 ubuntu 22.04 为 100 个 IP 提供 nat 上网服务,目前我们需要对这 100 个 IP 进行限速

    假设总带宽为 1000mbit ,需要对每个 IP 的最大带宽限制为 10mbit ,且保证每个 IP 的带宽为 10mbit

    看了相关教程后,目前我能想到的是为每个 IP 都创建一个 rate 为 10mbit 的 htb 类配合 sfq 来进行限速
    这样就意味着 如果 3000 个 IP 就会有 3000 个 htb 子类和 sfq 规则, 这一点都不优雅了, 而且如此多的规则管理起来也是个麻烦事



    经过多次查找资料后, 有一个思路就是 将 N 个 IP 加到 ipset 集合里面中去, 然后在 mangle 中对这个集合添加 fwmark,

    然后 添加 tc filter 时匹配 该 fwmark, 理论上只需要添加一个 10mbit htb 类和 sfq 就行了


    但是根据我查到的资料, 同一个 htb 类下, 所有在线的成员平分该 htb 的 rate , 这就会导致 一个人使用时是 10mbi 带宽, 两个人同时使用就是 5mbit 的带宽了

    这就达不到最开始的需求了: 每个 IP 需要保证 10mbit 的带宽且最大仅可使用 10mbit 的带宽, 哪怕总带宽还有剩余


    PS: 隔壁公司装修, 吵得脑子都大了, 表述可能有点嗦了, 请见谅
    27 条回复    2024-08-09 14:41:07 +08:00
    zizon
        1
    zizon  
       2024-07-20 15:51:53 +08:00
    没什么不优雅吧.你的需求确实就是要对每个 IP 单独 quality...

    写个脚本或者工具去管理就是了...
    Ansen
        2
    Ansen  
    OP
       2024-07-20 15:53:22 +08:00
    @zizon #1 前期还好, 后面可能会有 10 几万 IP
    Ansen
        3
    Ansen  
    OP
       2024-07-20 15:57:14 +08:00
    @Ansen #2 如果能通过 ipset 配置, 我只需要按带宽等级创建一些规则就可以了, 比如 10 15 20 30 分别一个规则, 然后通过管理 ipset 列表 达到 控制客户端 IP 使用不同的带宽的目的
    blackeeper
        5
    blackeeper  
       2024-07-20 18:21:15 +08:00
    我觉得你可能需要一个路由器,比如 openwrt 、ikuai ?
    IP 限速不仅有 web 界面,操作也非常方便
    Ansen
        6
    Ansen  
    OP
       2024-07-20 18:23:40 +08:00
    @blackeeper 肯定是业务需要了, 上面还会跑其它相应的 ACL 程序
    blackeeper
        7
    blackeeper  
       2024-07-20 18:29:22 +08:00
    @Ansen 这些路由器也可以跑 ACL 的,都是 Linux 系统。
    而且这个路由器,你可以作为旁路由,不用替换掉你的 Ubuntu 服务器
    Ansen
        8
    Ansen  
    OP
       2024-07-20 18:36:45 +08:00 via iPhone
    @blackeeper 实际业务场景很复杂,qos 只是里面的一个功能
    datocp
        9
    datocp  
       2024-07-20 20:07:28 +08:00 via Android   2
    为什么你有 10 几万的 ip ???
    可不能教电信网管做坏事

    qos 最佳的学习从 tomato 入手。当你会 shell 写了 N 遍 tc 规则,就用 tomato 的 4 段 htb 就足够。

    再去研究下 iptables connbytes ,会发现又一片新大陆,原来可以以 1 秒抓到当前系统那些假定超过多少流量的 ip 。

    然后就看 shell 水平插值到 4 段 htb

    最终实现 100mbps
    将 60%的流量用于下载用户,高优先级
    将 100%的流量用于其他用户,实际怎么也还有 40%,次优先级
    上行用 1:2 限制了 p2p 到 80%无法淹没 20%的高优先级上行队列。
    通过用 shell 对下行变化的 ip 进行插值到 htb 树,就实现了动态限速,做到 100%的带宽利用。

    平时 100mps 吹牛带了 280+ip ,无视任何 p2p 存在。
    PTLin
        10
    PTLin  
       2024-07-20 20:59:36 +08:00   2
    tc 基于 ebpf 的 edt 方案看来可以,直接用 epbf map 管理 ip 。
    Ansen
        11
    Ansen  
    OP
       2024-07-21 10:14:53 +08:00 via iPhone
    @datocp 感谢指点,哈哈,具体业务不方便说,但是不是三大运营商
    Ansen
        12
    Ansen  
    OP
       2024-07-21 10:19:50 +08:00 via iPhone
    @PTLin 我也看到 edt 了,但是资料少的可怜(有可能是我没找到?) ,然后问 gpt ,又全是胡言乱语
    PTLin
        13
    PTLin  
       2024-07-21 16:04:06 +08:00   1
    @Ansen 有一篇字节跳动写的文章试了下,确实可以跑,就是限速不是太稳定以及限速公式搞不明白。https://blog.csdn.net/ByteDanceTech/article/details/120878281
    defunct9
        14
    defunct9  
       2024-07-21 16:51:47 +08:00
    开 ssh ,让我上去看看
    cslive
        15
    cslive  
       2024-07-21 18:39:11 +08:00 via Android
    openwrt 怎么实现的,参考下
    kalayygl001
        16
    kalayygl001  
       2024-07-21 22:14:00 +08:00
    直接 panabit 就好
    100M/100M 专线+1000M/50M pppoe 带 500 人
    做好应用分流
    相当流畅
    Ansen
        17
    Ansen  
    OP
       2024-07-21 22:30:23 +08:00
    @kalayygl001 #16 目前没办法用其它设备来限速了, 项目方案已经确定了, 只有在 linux 上想办法了
    Donaldo
        18
    Donaldo  
       2024-07-23 12:20:13 +08:00   1
    我没用过 tc ,之前用过 xdp 做防火墙,调研了一下说性能比 tc 好,考虑用 ebpf (可能结合 tc )么?这里找到了一个例子: https://github.com/xdp-project/xdp-cpumap-tc
    huangzhiyia
        19
    huangzhiyia  
       2024-07-23 17:06:36 +08:00
    tc qdisc del dev $1 root
    tc qdisc add dev $1 root handle 1: htb default 20
    tc class add dev $1 parent 1:0 classid 1:1 htb rate 10mbit burst 1000mbit
    tc qdisc add dev $1 parent 1:1 handle 10: sfq
    tc filter add dev $1 parent 1: protocol ip prio 16 u32 match ip dst 0.0.0.0/0 flowid 1:1

    直接对所有 IP 进行限速,速率为 10mbit 突发 1000mbit ,连空闲宽带都不想给,就把突发也改成 10 mbit 即可。
    Ansen
        20
    Ansen  
    OP
       2024-07-23 17:52:13 +08:00
    @zmaplex #19 这个脚本的实际效果是 所有 IP 加起来的速度不能超过 classid 1:1 中的 10mbit , 多个用户同时在线,每个用户的带宽就是 10mbit 除以 n
    这是我的测试结果

    Ansen
        21
    Ansen  
    OP
       2024-07-23 17:53:41 +08:00
    @Ansen #20 我想要达到的结果是, 所有用户都能独享且最多能 10mbit
    huangzhiyia
        22
    huangzhiyia  
       2024-07-23 21:48:37 +08:00   1
    @Ansen

    #!/bin/sh -e


    # 清除现有的 qdisc
    tc qdisc del dev ens33 root
    tc qdisc del dev ens33 ingress

    # 配置上传( egress )限速
    tc qdisc add dev ens33 root handle 1: htb default 30
    tc class add dev ens33 parent 1: classid 1:1 htb rate 10000kbit burst 15k

    # 限制特定 IP 地址的上传
    tc class add dev ens33 parent 1:1 classid 1:10 htb rate 10000kbit
    tc filter add dev ens33 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.102.134 flowid 1:10

    tc class add dev ens33 parent 1:1 classid 1:20 htb rate 10000kbit
    tc filter add dev ens33 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.102.135 flowid 1:20

    # 限制所有 IP 地址的上传
    tc class add dev ens33 parent 1:1 classid 1:30 htb rate 10000kbit
    tc filter add dev ens33 protocol ip parent 1:0 prio 2 u32 match ip dst 0.0.0.0/0 flowid 1:30

    # 配置下载( ingress )限速
    tc qdisc add dev ens33 handle ffff: ingress

    # 限制特定 IP 地址的下载
    tc filter add dev ens33 parent ffff: protocol ip prio 1 u32 match ip src 192.168.102.134 police rate 10000kbit burst 10k drop flowid :1
    tc filter add dev ens33 parent ffff: protocol ip prio 1 u32 match ip src 192.168.102.135 police rate 10000kbit burst 10k drop flowid :1

    # 限制所有 IP 地址的下载
    tc filter add dev ens33 parent ffff: protocol ip prio 2 u32 match ip src 0.0.0.0/0 police rate 10000kbit burst 10k drop flowid :1

    exit 0
    huangzhiyia
        23
    huangzhiyia  
       2024-07-23 21:49:54 +08:00
    我测试的时候,这个是只有 7 Mbits/sec 左右,然后把 10000kbit 改成 15mbit 的时候,测试差不多就是 10 Mbits/sec 了
    huangzhiyia
        24
    huangzhiyia  
       2024-07-23 21:51:44 +08:00
    @Ansen 不好意思,把特定 ip 写进去了,还是无效。看来没有太好的办法
    Ansen
        25
    Ansen  
    OP
       2024-07-23 22:11:27 +08:00
    @zmaplex #24 是的,目前 class 和 ip 一对一的情况下,是能做到我的需求的, 但是一旦 IP 数量多了,管理上就会变得很困难
    dode
        26
    dode  
       2024-08-08 09:34:33 +08:00
    一万个 IP 出去之前加一个交换机,交换机上设置 IP 限速
    Ansen
        27
    Ansen  
    OP
       2024-08-09 14:41:07 +08:00
    @dode #26 交换机拿不到隧道的 IP
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1018 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 35ms UTC 18:55 PVG 02:55 LAX 10:55 JFK 13:55
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86