掌握Linux网络:深入理解TC —— 你的流量控制利器

简介: 目前需要做一款关于Linux下对于某IP限制的一个工具(QOS),在网上寻找了许多关于TC的教程,大多数都是一些比较基础的教学,且多数都是对网口的一些限制,然后自己研究了一段时间,最后有一些小小的了解,故在此分享给大家。

       

目录

简单概述:

qdisc(队列):

 举例:

 Bash        

整形队列算法:

FIFO (First-In-First-Out)

PFIFO (Priority FIFO)

SFQ (Stochastic Fair Queuing)

RED (Random Early Detection)

HTB (Hierarchical Token Bucket)

TBF (Token Bucket Filter)

NETEM (Network Emulator)

CBQ (Class-based Queueing)

整形队列流量方向管理:

Class(类) 和 Filter(过滤器):

创建 class

使用 class 和 filter

问题:

带宽或者流速单位:

问题解决方法:

限制IP为1.1.1.3上传速度实例:

 创建虚拟网卡并启用,暂定虚拟网卡名为ifb0

 创建Ingress队列并进行导流

  对ifb0进行限速即可

限制IP为1.1.1.3下载速度实例:

u32匹配:

u32匹配器的特点

限速总结:  


目前需要做一款关于Linux下对于某IP限制的一个工具(QOS),在网上寻找了许多关于TC的教程,大多数都是一些比较基础的教学,且多数都是对网口的一些限制,然后自己研究了一段时间,最后有一些小小的了解,故在此分享给大家。

首先我们可以先假设把TCP包的架构设成这样,方便我们后续去了解限速的规则。这里一定要记好了。

[source-ip] | [source-port] | [other-data] | [destination-ip] | [destination-port]

简单概述:

TC,即 Traffic Control,是 Linux 内核提供的一种用于网络流量管理和质量服务(Quality of Service, QoS)的工具。它允许网络管理员对网络接口上的数据包进行精细的控制,包括但不限于:

  1. SHAPING(限制)
  • 当流量被限制时,其传输速率被控制在预设的阈值之下。这种限制可以显著减少突发流量,有助于维持网络的稳定性和预测性。SHAPING 主要应用于向外的流量控制。
  1. SCHEDULING(调度)
  • 调度涉及在可用带宽范围内,按优先级分配带宽资源。这确保了关键应用和服务可以得到优先处理,从而提高了网络的整体效率。SCHEDULING 同样适用于向外的流量。
  1. POLICING(策略)
  • POLICING 通常用于控制入站流量,当检测到流量超出预设规则时,可以采取行动,如丢弃超额的数据包,以维持网络政策的一致性。
  1. DROPPING(丢弃)
  • 当流量超出设定的带宽限制时,DROPPING 策略将直接丢弃过量的数据包。这一策略适用于入站和出站流量。

tc 命令的基本结构如下:

Bash

1tc [ OPTIONS ] COMMAND [ @id ] dev DEV [ parent qdisc-id ] [ index INDEX ]

image.gif

其中 COMMAND 可以是 qdisc, filter, class, action 等不同的子命令,用于执行不同的流量控制任务。

  • qdisc(排队规则)
  • qdisc 定义了数据包在接口上排队和调度的策略。它决定了数据包如何被存储和发送,是流量控制的核心机制。qdisc 可分为 CLASSLESS QDISC 和 CLASSFUL QDISC。
  • CLASSLESS QDISC
  • 包括简单的 FIFO(First-In-First-Out)队列,如 pfifo 和 bfifo,以及更复杂的策略如 pfifo_fast、red、sfq 和 tbf。
  • pfifo/bfifo:简单的 FIFO 队列,前者基于数据包计数,后者基于字节数。
  • pfifo_fast:在高级路由器配置中作为默认 qdisc,具有三个优先级队列。
  • red:随机早期检测,用于预防拥塞。
  • sfq:基于概率的公平队列,适用于多流场景。
  • tbf:令牌桶过滤器,用于限速和整形。
  • CLASSFUL QDISC
  • 提供更细粒度的控制,允许创建基于类别的队列,如 HTB 和 CBQ,用于复杂的服务质量策略。
  • class(类别)
  • 类别用于组织和划分流量,允许为不同类型的流量分配特定的带宽和优先级。
  • filter(过滤器)
  • 过滤器用于识别和分类数据包,基于 IP 地址、端口、协议等属性,将数据包导向特定的 qdisc 或 class。

qdisc(队列):

  1. 带宽分配:限制或保证数据流的带宽。
  2. 延迟控制:通过缓存机制控制数据包的发送时间,从而影响网络延迟。
  3. 丢包策略:当队列满时决定哪些数据包被丢弃的策略,以防止拥塞。
  4. 公平性:确保多个数据流之间的公平带宽分配。
 举例:
 Bash        
tc qdisc add dev ens18 handle fff: htb default 22

image.gif

  其中fff:就相当于这条队列的特定标识符,也相当于唯一ID。

       谈到队列大家可能有些熟悉,是数据结构中的队列吗?先进先出的那个?当然不是,这是由Linux做的一款流量整形队列,你可以把它看作一条支流,对,小溪那种。

        在我们正常使用的情况下,其实LInux就已经给我们的网卡分配了一些队列,应该也是用来整形稳定的一种。当我们对网口设置了一个新的队列后,这个队列就会被我的这个队列给顶替下去。

        image.gif 编辑

整形队列算法:

FIFO (First-In-First-Out)

这是最简单的队列纪律类型,没有额外的管理机制。数据包按照它们到达的顺序被发送出去。FIFO 不做任何排序或优先级处理,因此所有数据流都被平等对待。这在大多数情况下是默认的行为,但如果网络负载很高,可能会导致一些数据包的延迟或丢失。

PFIFO (Priority FIFO)

PFIFO 提供了有限数量的优先级队列,通常为三个:高、中、低。这允许网络管理员根据数据包的类型或来源为其分配不同的优先级,从而确保关键数据包(如语音或视频流)得到优先处理。然而,PFIFO 仍然依赖于简单的先进先出原则,只是在不同的优先级队列中。

SFQ (Stochastic Fair Queuing)

SFQ 是一种更复杂的队列管理算法,旨在为每个数据流提供公平的带宽分配,即使在高负载情况下也能保持良好的响应时间。它使用基于概率的算法来分类数据包,然后将它们放入不同的队列中,确保即使小流量的数据流也能获得一定的带宽。

RED (Random Early Detection)

RED 是一种主动丢包机制,用于预防网络拥塞。当队列接近其最大容量时,RED 开始随机丢弃一些数据包,而不是等到队列完全填满。这种提前丢弃数据包的策略有助于平滑网络流量,减少拥塞的发生,从而改善整体网络性能。

HTB (Hierarchical Token Bucket)

HTB 是一种非常灵活的队列纪律,支持复杂的带宽分配和优先级管理。它可以创建层次化的令牌桶,允许网络管理员为不同的数据流设定具体的带宽限制和优先级。HTB 特别适用于需要精细控制网络资源分配的场景,如企业网络和数据中心。

TBF (Token Bucket Filter)

TBF 是基于令牌桶算法的流量整形工具,主要用于限速和流量整形。它允许指定一个固定的带宽速率,确保数据流不会超过这个速率,这对于避免网络拥塞和保证服务质量非常有用。

NETEM (Network Emulator)

NETEM 是一个网络仿真工具,用于模拟各种网络状况,如延迟、丢包和重复。它非常适合在开发和测试环境中模拟真实世界的网络条件,帮助验证应用程序在网络问题下的表现。

CBQ (Class-based Queueing)

CBQ 是早期版本中常用的队列纪律,类似于 HTB,但功能较少且配置更为复杂。它也支持基于类的队列,允许为不同的数据流设置不同的优先级和带宽限制。然而,由于 HTB 的出现,CBQ 在现代系统中的使用已大大减少。

image.gif 编辑

上方这些算法中,如果你想进行一些简单的流量控制,那么FIFO和PFIFO即可,如果想要进行真正管理级,逻辑稍微复杂一些的流量整控我推荐用HTB,关于HTB它可以进行优先级限制,src和dst IP限制,是一个功能非常强大的算法。SFQ的话是当你建立了多条类的话,用于流量平分用。比如果你从队列里面开出了三条类,也可以理解为引出来了三条小溪流,害怕每条小溪流的水不一样多怎么办?这时候就给每条小溪都设上一个SFQ。

wondershaper源码为例:

image.gif 编辑

这里其他算法就不过多赘述了,专于对HTB算法进行详细讲解。

整形队列流量方向管理:

  • Ingress:表示数据包进入网络设备的方向。当数据包从网络接口接收进来时,这个过程被称为 ingress。在这个阶段,设备可以执行诸如数据包过滤、流量整形、优先级标记等操作。
  • Egress:表示数据包离开网络设备的方向。当数据包被发送到另一个网络或设备时,这个过程被称为 egress。在 egress 方向,设备也可能执行类似的操作,如基于策略的路由、QoS 保障、流量限速等。

在 Linux 的 Traffic Control (tc) 工具中,ingress 和 egress 通常用来描述数据包在网卡或网络设备上的流动方向。例如,当使用 tc 进行流量控制时,你可以分别对 ingress 和 egress 方向的流量应用不同的队列纪律和过滤规则。这点其实是非常重要的,因为TC实际上是管发不管收的。也就是如果我们通过TC只能限制别人对我们的下载速度,没办法限制别人对我们的上传速度。

这个东西在前期确实让人很头痛,那岂不是我们没有办法在自己的机器上对别人进行上传限速?当然不是,Ingress和Egress就可以解决这个问题。这个在后续应用实例的时候去讲。

Class(类) 和 Filter(过滤器):

classtc 中扮演了组织者和控制器的角色。它允许你创建多个类别,每个类别都可以有自己的带宽限制、优先级和调度策略。通过将数据包分配到不同的 class 中,你可以实现以下目标:

  1. 带宽分配:为每个 class 设置不同的带宽上限,确保每个数据流都得到公平或预定的带宽份额。
  2. 优先级控制:为关键数据流分配更高的优先级,确保它们在拥塞时仍能快速传输。
  3. QoS 改善:通过精细调整 class 参数,改善整个网络的服务质量,特别是对于实时应用如 VoIP 和视频会议。

创建 class

class 的创建和配置通常与 qdisc 相结合。首先,你需要在根 qdisc 下创建一个父 class,然后可以创建子 class 来进一步细分流量。例如,使用 htb(Hierarchical Token Bucket)作为 qdisc 时,你可以这样创建一个 class

Bash

# 创建父 qdisc
tc qdisc add dev <interface> root handle 1: htb default 11
# 创建父 class
tc class add dev <interface> parent 1: classid 1:1 htb rate <rate>
# 创建子 class
tc class add dev <interface> parent 1:1 classid 1:11 htb rate <rate> ceil <max_rate>

image.gif

在上述命令中,<interface> 是你想要控制的网络接口,<rate> 是你想要分配给该 class 的带宽速率,<max_rate> 是该 class 可以使用的最大带宽。

使用 classfilter

为了将特定的数据包分配到正确的 class,你需要使用 filterfilter 根据数据包的属性(如源/目的IP、端口号、协议类型等)将它们导向特定的 class。例如:

Bash

tc filter add dev <interface> protocol ip parent 1:0 prio 1 u32 match ip dst <destination_ip>/32 flowid 1:11

image.gif

此命令创建了一个 filter,将目的地为 <destination_ip> 的所有 IP 数据包导向 class 1:11

问题:

此时以文章最开始的包结构为例,这里的destination_ip就是我们包结构里面的 [destination-ip]。假如由1.1.1.2给1.1.1.3发消息,那我们在1.1.1.3中收到的这个包的目标IP就是1.1.1.3,所以此时我们如果对1.1.1.3进行限速也就是对1.1.1.3进行限速。那如果我直接这个包的SRC进行限速呢?这不就完成了对客户端上传速度的限制?但是大家别忘了,TC是一个管发不管收的工具,既然不管收,那怎么对客户端进行限速呢?

带宽或者流速单位:

image.gif 编辑

image.gif 编辑

问题解决方法:

   我们可以去将Ingress的流量进行一个导流,然后把导流的流量重定向到一个网卡上,为了稳定这个采用一个虚拟网卡,然后对虚拟网卡上的流量进行限速,就可以解决对收包进行限速了。

限制IP为1.1.1.3上传速度实例:

 创建虚拟网卡并启用,暂定虚拟网卡名为ifb0

 Bash

modprobe ifb numifbs=1;
ip link set dev ifb0 up;

image.gif

 创建Ingress队列并进行导流

  Bash

tc qdisc add dev ens18 handle ffff: ingress
tc filter add dev ens18 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0;

image.gif

  对ifb0进行限速即可
tc qdisc add dev ifb0 root handle 2: htb default 22;
tc class add dev ifb0 parent 2: classid 2:22 htb rate 10000mbit ceil 10000mbit burst 10000mbit cburst 10000mbit;
tc class add dev ifb0 parent 2: classid 2:1 htb rate 10mbit ceil 10mbit  burst 10mbit  cburst 10mbit ;
tc filter add dev ifb0 protocol ip parent 2: prio 1 u32 match ip src 1.1.1.3 flowid 2:1;

image.gif

如果想要限制其他的IP将IP改一下即可。

限制IP为1.1.1.3下载速度实例:

正常创建Htb队列,default 22 就是如果没有合适的filter去匹配的话,那就就去找classid为22的类去限速。

tc qdisc add dev ens18 root handle 1:0 htb default 22

image.gif

创建限速类,这里22限制为10GB每秒,相当于未限速,然后对1.1.1.3限速为10mbit每秒。

tc class add dev ens18 parent 1:0 classid 1:1 htb rate 10mbit ceil 10mbit
tc class add dev ens18 parent 1:0 classid 1:22 htb rate 10000mbit ceil 10000mbit
            
 # dst->src
tc filter add dev ens18 parent 1:0 protocol ip  prio 1 u32 match ip dst 1.1.1.3 flowid 1:1

image.gif

u32匹配:

在Linux的tc(Traffic Control)工具中,u32是一种匹配器类型,用于基于数据包头部的信息来过滤和分类网络流量。u32匹配器非常灵活,可以依据各种字段(如IP地址、端口号、协议类型等)来创建复杂的匹配规则,是实现高级流量控制策略的关键组件。

u32匹配器的特点

  1. 灵活性u32匹配器可以基于多种数据包头部字段进行匹配,包括但不限于IP源地址、目的地址、TCP/UDP源端口、目的端口、协议类型等。
  2. 复杂规则支持u32支持逻辑运算,如AND、OR、NOT,允许创建复合的匹配规则,以适应复杂的网络策略需求。
  3. 性能高效u32匹配器设计得非常高效,能够快速处理大量的数据包,即使在高负载的网络环境下也能保持良好的性能
  1. 基于IP地址匹配
  • 源IP地址匹配:
    Bash
sudo tc filter add dev [interface] protocol ip parent 1:0 prio 1 u32 match ip src [source_ip] flowid 1:1
  • image.gif
  • 目的IP地址匹配:
    Bash
sudo tc filter add dev [interface] protocol ip parent 1:0 prio 1 u32 match ip dst [destination_ip] flowid 1:1
  • image.gif
  1. 基于端口号匹配
  • TCP源端口号匹配:
    Bash
sudo tc filter add dev [interface] protocol tcp parent 1:0 prio 1 u32 match tcp sport [source_port] flowid 1:1
  • image.gif
  • TCP目的端口号匹配:
    Bash
sudo tc filter add dev [interface] protocol tcp parent 1:0 prio 1 u32 match tcp dport [destination_port] flowid 1:1
  • image.gif
  • UDP源端口号匹配:
    Bash
sudo tc filter add dev [interface] protocol udp parent 1:0 prio 1 u32 match udp sport [source_port] flowid 1:1
  • image.gif
  • UDP目的端口号匹配:
    Bash
sudo tc filter add dev [interface] protocol udp parent 1:0 prio 1 u32 match udp dport [destination_port] flowid 1:1
  • image.gif
  1. 基于协议类型匹配
  • 匹配TCP协议:
    Bash
sudo tc filter add dev [interface] protocol tcp parent 1:0 prio 1 u32 flowid 1:1
  • image.gif
  • 匹配UDP协议:
    Bash
sudo tc filter add dev [interface] protocol udp parent 1:0 prio 1 u32 flowid 1:1
  • image.gif
  • 匹配ICMP协议:
    Bash
sudo tc filter add dev [interface] protocol icmp parent 1:0 prio 1 u32 flowid 1:1
  • image.gif

限速总结:  

    对于上传和下载下载的规律是不变的,后续filter跟的一些匹配协议就由大家自由发挥了,例如端口,源端口,协议类型等一些东西都是非常多的,在此我也不一一列举了,由大家自由发挥。


相关文章
|
3天前
|
网络协议 安全 Ubuntu
7 个有用的免费 Linux 网络隧道
【7月更文挑战第4天】
16 0
7 个有用的免费 Linux 网络隧道
|
2天前
|
网络协议 Linux 开发工具
配置Linux固定IP地址,为什么要固定IP,因为他是通DHCP服务获取的,DHCP服务每次重启都会重新获取一次ip,VMware编辑中有一个虚拟网络编辑器
配置Linux固定IP地址,为什么要固定IP,因为他是通DHCP服务获取的,DHCP服务每次重启都会重新获取一次ip,VMware编辑中有一个虚拟网络编辑器
|
4天前
|
监控 算法 Linux
Linux下工具tc详细讲解及限制IP和端口实例
TC (Traffic Control) 是Linux内核中提供的一个用于控制和管理网络流量的强大工具,它允许用户实现QoS(Quality of Service)策略,包括带宽限制、优先级控制、延迟保证等。TC基于内核的队列 discipline (qdisc) 和流量类别(class) 体系结构,允许对进入或离开网络接口的数据流进行复杂的整形和过滤。
|
5天前
|
监控 网络协议 安全
Linux基本指令之网络通信命令
Linux基本指令之网络通信命令
|
5天前
|
缓存 网络协议 Linux
Linux、Python、计算机网络中的常见知识点
Linux、Python、计算机网络中的常见知识点
|
5天前
|
域名解析 网络协议 Linux
linux网络-- 手动配置ip地址
linux网络-- 手动配置ip地址
|
10天前
|
存储 Linux
深入了解Linux设备管理:字符、块和网络设备文件
深入了解Linux设备管理:字符、块和网络设备文件
15 0
|
10天前
|
监控 安全 Linux
虚拟专用网络(VPN):远程访问与点对点连接及其在Linux中的IPSec实现与日志管理
虚拟专用网络(VPN):远程访问与点对点连接及其在Linux中的IPSec实现与日志管理
28 0
|
10天前
|
运维 网络协议 Linux
Linux与Windows下追踪网络路由:traceroute、tracepath与tracert命令详解
Linux与Windows下追踪网络路由:traceroute、tracepath与tracert命令详解
22 0
|
1月前
|
网络协议 算法 Linux
【嵌入式软件工程师面经】Linux网络编程Socket
【嵌入式软件工程师面经】Linux网络编程Socket
46 1

热门文章

最新文章