tc端口流量控制(带宽限速)
tc qdisc add dev ens192 root handle 1: htb
tc class add dev ens192 parent 1: classid 1:1 htb rate 80mbit
tc filter add dev ens192 protocol ip parent 1:0 prio 1 u32 match ip dst 0.0.0.0/0 flowid 1:1
sudo tc qdisc del root dev ens192
tc端口流量控制
tc真的是个巨坑,搞了一天才明白问题出在哪,记录一下。
tc前置
首先强调一下,tc只管发包,不管收包的事。tc只管发包,不管收包的事。tc只管发包,不管收包的事。重要的事说三遍,坑就出在这里,很容易给绕晕过去。换言之,tc只管出站(出网卡)的流量,不管进来的流量,当然这句话也不完全是,因为即使是本地回环lo,也是这么一回事。
更具体地说,我们将包简单的解构为:[source-ip] | [source-port] | [other-data] | [destination-ip] | [destination-port]
这对后面的说明和理解会有较大的帮助。这个包显然是由 source-ip 机器的 source-port 发送出去的,经由的是 source 机器的网卡。因此如果要做限流,在 destination 机器上的网卡设置规则是没有意义的,只能在 source 机器的网卡上限制规则。
具体操作
首先简单了解一下tc的三大功能,其他可以忽略,当然要想深入可以去看参考资料的demo。这三个就可以简单完成端口流量控制的目标了,重点其实是后两个。
tc-qdisc:队列规则。后面用的是htb层次令牌桶的队列。队列是用来管理消息进出和分发的。
tc-class:定义队列规则类。每个类可以简单理解成一个子队列,有着独立的规则。
tc-filter:定义过滤器。端口控流就用得到了,如果和iptables配合还可以专门过滤出带有特殊标志的包。实际上就是将包过滤到特定class的队列去。
来一遍实操就懂了,这里默认对外的网卡是enp8s0,本地回环是lo,这两个都可以实现端口控流。
先删除root已有的队列规则(del是delete,root是根队列,dev是device,enp8s0是网卡名,可以通过ip addr查看):
sudo tc qdisc del root dev enp8s0
重建root队列规则(handle可以简单理解为处理句柄,类似C那种,1:其实是1:0,即缺省是0,所以这个队列的‘名字’就是1:0了,htb是层次令牌桶,即所用的队列类型,default 3指的是如果进来的包没有指定要去的子类,就默认去1:3子类的队列,显然,这里的1是一个大类的公共前缀,而0和3就是小类或者称父类、子类的专属后缀):
sudo tc qdisc add root dev enp8s0 handle 1: htb default 3
在这个队列的基础上建一个子类,设置带宽上限实现该子类的控流(parent用于指定父类,classid与上面的handle类似,用于指定这个子类的名字,rate用于控流,由于ceil和rate默认是一致的,所以如果只是控制流量稳定在一个值,可以不用额外再写ceil,这里控制带宽上限为20mbps):
sudo tc class add dev enp8s0 parent 1: classid 1:1 htb rate 20mbit
接着可以在这个子类上再建两个子类(注意带宽不能超过父类1:1的20mbps):
sudo tc class add dev enp8s0 parent 1:1 classid 1:2 htb rate 10mbit
sudo tc class add dev enp8s0 parent 1:1 classid 1:3 htb rate 5mbit
到这里就可以知道,包如果分发给了1:2的子类队列,带宽最高是10mbps,如果没有分发给特定的子类队列,那就会按照默认设置的3,分发给1:3的子类队列,带宽最高是5mbps。
如何分发就涉及到了过滤器了(protocol是协议类别,ip就可以了,其他还有指定tcp,udp等。prio是优先级别。sport是source port的意思,也可以设定dport,即destination port。0xffff是用于设置端口范围的,或者说偏移量,这里的效果是单个端口。flowid就是满足过滤器条件的包分发到哪个流,这里将包分发到1:2的子类队列):
sudo tc filter add dev enp8s0 protocol ip parent 1:0 prio 1 u32 match ip sport 12345 0xffff flowid 1:2
到这里就完成了12345端口的限流,不过注意是发出的包限流,而不是收到的包限流。如果要将收到的包限流,只有两种方式,1)一个是做一个中转网卡,让那个网卡收到的包再发给enp8s0这个网卡,然后将规则设定到那个中转网卡上,那么本质上控制的就是中转网卡的发包,进而影响到enp8s0的收包。2)在对接的服务端的网卡上设置规则,本地客户端收到的包自然也就是限流后的了。
至于过滤器的sport和dport的意义,我们还是拿之前提到的包的结构来说明。比如sport 12345指的是这个包是从本地的12345端口发出的包,满足这类条件的包就能通过这个过滤器。而dport 12345指的是这个包是本地发出的包(不管是哪个端口的),且包发往的目的端口是12345,满足这类条件的包可通过过滤器,而不是本地收到的发到12345端口的包,即使是本地发到本地12345端口的包,也是在发送的时候就限流了。此外过滤器还能设置目的ip,只要是发往那个ip地址的包就会通过过滤器,这里就不细说了。可以发现这里提到的全部都是发包,这也就是为什么前面一直在强调tc影响的是发包而不是收包了。
测试结果
前置环境装个iperf3就可以了:sudo apt-get install iperf3
我们假定有两个机器,ip地址分别是192.168.1.101和192.168.1.102。
将上述tc规则设置在101机器的enp8s0网卡上。
接着在101机器上的12345端口设置服务端(s是server,p是port):
pc101: iperf3 -s -p 12345
在102机器上设置客户端,并从服务端收取数据(c是client,后接对接服务端的ip。R代表反向,即从服务端接收数据,不加-R选项则是客户端往服务端发数据。i是interval,代表发送间隔,t是time,代表测试时长):
pc102: iperf3 -c 192.168.1.101 -p 12345 -R -i 1 -t 3
可以发现从192.168.1.101的12345端口发出的包被限流到10mbps了。iperf3不能设置client的端口,所以这里用了-R来间接完成从12345端口发包。
当然也可以把12345端口设为目的端口,即之前tc的filter的条件设为(将sport改成dport,还是在101机器上设置,记得先用tc filter delete删掉原有条件):
pc101: sudo tc filter add dev enp8s0 protocol ip parent 1:0 prio 1 u32 match ip dport 12345 0xffff flowid 1:2
不过这时候反过来,让102机器作为服务端,并设置端口为12345。
pc102: iperf3 -s -p 12345
然后用101机器作为客户端发送数据到服务端,测试带宽(不用带-R选项了!):
pc101: iperf3 -c 192.168.1.102 -p 12345 -i 1 -t 3
可以发现发包带宽也是被限制在10mbps左右(肯定是会有波动的,但会在10mbps附近一个小范围内)。
不管是哪种方式,tc限流最终都是落在发包上。
在一台机器上做tc限流
跟之前提到的具体操作几乎没有任何区别,只需要把设备名从enp8s0改成lo即可,因为本地端口之间的通信走的都是lo回环。
设置完tc规则和filter条件后,用两个终端或者tmux开启多窗口的方式来用iperf3分别开服务端和客户端。
后续操作和原理与之前在两台机器上的完全一致,就不多说了。
查看网卡的规则
再给一些查看网卡规则的指令,有时候也可以确认规则是否生效,以及流量是否被分配到某一个子类规则队列中,流量和包数有多少等等。
简单查看(设备可以换成lo等等,查看的除了qdisc也可以换成class,filter等):
tc qdisc ls dev enp8s0
详细查看(还可以看class的流量和包数等):
tc -s qdisc ls dev enp8s0
其他-利用iptables完成相同工作
也可以用iptables完成分发,前面步骤还是一样的,只有最后的filter不太一样(这里的handle 10以及后续的参数指的是将标志为10的包分发给classid为1:2的flow):
tc filter add dev enp8s0 parent 1:0 protocol ip prio 1 handle 10 fw classid 1:2
然后用iptables对指定端口的包设置特殊的标志,完成端口绑定tc队列(只要保证--set-mark的值和handle的值一致就可以了)。
iptables -A OUTPUT -t mangle -p tcp --sport 12345 -j MARK --set-mark 10
由于这些规则还是基于本机的tc设置的,因此控制的还是发包(sport指定的是本机发包的source端口,即使改成dport也是这个包发往的目的端口号)。
参考资料
tc控制端口带宽
tc高级控流demo
tc参数/manpage
tc端口流量控制(带宽限速)的更多相关文章
- 【转】 LINUX中IPTABLES和TC对端口的带宽限制 端口限速
不管是iptables还是tc(traffic control)功能都很强大,都是与网络相关的工具,那么我们就利用这两个工具来对端口进行带宽的限制. 1.使用命令ifconfig查看服务器上的网卡信息 ...
- centos tc 端口限速
#http://www.fx114.net/qa-178-108967.aspx#http://professor.blog.51cto.com/996189/1569481/#http://blog ...
- TC命令流量控制测试(针对具体IP和具体进程)
TC命令流量控制测试 这里测试系统为Linux操作系统,通过简单的TC命令来实现对带宽的控制. 1对具体IP地址的流量控制 这里采用iperf来进行带宽的测试,首先在服务器和客户端都安装上iperf软 ...
- TC命令流量控制测试(针对具体IP地址和IP协议)
这里测试系统为Linux操作系统,通过简单的TC命令来实现对带宽的控制. 1对具体IP地址的流量控制 这里采用iperf来进行带宽的测试,首先在服务器和客户端都安装上iperf软件,通过该软件下的命令 ...
- 在Cisco Catalyst 3750端口做策略限速 QOS
今天任务是在3750上限制端口的速率,本来以为是很简单的事,speed命令搞定,敲进去才知道speed命令只能叫端口速率改成10M或100M,也就是说只能起到端口高低速率的切换功能,不能自定义速率,后 ...
- 基于TC做流量控制
1 模拟延迟传输简介 netem 与 tc: netem 是 Linux 2.6 及以上内核版本提供的一个网络模拟功能模块.该功能模块可以用来在性能良好的局域网中,模拟出复杂的互联网传输性能,诸如低带 ...
- 锐捷S2126交换机端口限速
一.对于S21的进入(上行)的数据的限速,可以用Qos做到. ip access-list extended acl_1 配置ACLpermit ip 172.16.41 ...
- OpenvSwitch系列之七 meter表限速
Open vSwitch系列之一 Open vSwitch诞生 Open vSwitch系列之二 安装指定版本ovs Open vSwitch系列之三 ovs-vsctl命令使用 Open vSwit ...
- [转载]抓包,端口镜像,monitor session命令(转)
原文地址:抓包,端口镜像,monitor session命令(转)作者:浮云皓月 一.SPAN简介 SPAN技术主要是用来监控交换机上的数据流,大体分为两种类型,本地SPAN和远程SPAN. --Lo ...
- EtherChannel Cisco 端口聚合详解
冗余连接及其实现 无论什么设备都无法保障运行的绝对稳定性,即使再优秀的产品也无法保证24×7不间断的工作.除去设备或模块损坏.传输线路中断等硬件故障原因以外,还可能由于网络流量过载.任务负荷过大而导致 ...
随机推荐
- 高通Perflock
高通的Perflock是Qualcomm公司开发的一项技术,用于优化设备性能和功耗管理.Perflock是一种锁定机制,允许操作系统或应用程序在需要时对处理器的性能状态进行控制,从而确保在关键任务或高 ...
- electron的两个进程
electron 有两个类别的进程,一个是主进程,另一个是渲染进程 主进程: 启动后一直存在的,相当于一个树的主干并不会展示出来,是看不到的所有跟系统资源交互的操作都在这里进行操控渲染进程,新建或销毁 ...
- 04 Transformer 中的位置编码的 Pytorch 实现
1:10 点赞 16:00 我爱你 你爱我 1401 class PositionalEncoding(nn.Module): def __init__(self, dim, dropout, max ...
- 三、Spring Boot集成Spring Security之securityFilterChain过滤器链详解
二.默认过滤器链 1.默认配置系统启动日志 2.默认配置的过滤器及顺序如下 org.springframework.security.web.session.DisableEncodeUrlFilte ...
- vscode中整合豆包MarsCode编程助手
豆包MarsCode是字节跳动旗下的一款AI工具,最近在刷帖子时看到已经可以在vscode中通过插件安装MarsCode工具,接下来我们来看下操作流程以及使用效果. 第一步:首先需要注册下豆包账号 豆 ...
- 这些HTTP协议状态码你知道吗?
使用ASP.NET/PHP/JSP 或者javascript都会用到http的不同状态,一些常见的状态码为: 200 – 服务器成功返回网页 404 – 请求的网页不存在 503 – 服务不可用 1x ...
- Vulhub 安装运行
前言 vulhub是利用docker技术做的一个漏洞复现平台,可以一键搭建对应的配置.在下载好对应的代码包后,不需要安装,只需要解压并利用3条命令,就可以简单的创建关闭对应漏洞环境.最好是购买一台阿里 ...
- Unity6 URP17使用初探
1.简介 随着Unity6的发布,URP17也已经可以上手使用,相对旧的版本改动较大的是加入了 RenderGraph.STP.Foveated rendering.GPU Resident Draw ...
- IntelliJ IDEA 2024.1 安装激活 (亲测有效!)
第一步:下载 IDEA 安装包 访问 IDEA 官网,下载 IDEA 2024.1.4 版本的安装包,下载链接如下 : idea官方链接 也可以在这里点击下载idea下载idea 第二步: 安装 ID ...
- @Transactional事务,太坑了吧!
前言 对于从事java开发工作的同学来说,spring的事务肯定再熟悉不过了. 在某些业务场景下,如果一个请求中,需要同时写入多张表的数据.为了保证操作的原子性(要么同时成功,要么同时失败),避免数据 ...