Linux TC 流量控制与排队规则 qdisc 树型结构详解(以HTB和RED为例)

1. 背景

Linux 操作系统中的流量控制器 TC (Traffic Control) 用于Linux内核的流量控制,它规定建立处理数据包的队列,并定义队列中的数据包被发送的方式,从而实现对流量的控制。

每个网络接口会有一个入队列(ingress)和一个出队列(egress),入队列功能较少。Linux流量控制主要是在输出接口进行处理和实现的。本文也都是基于出队列

TC 模块实现流量控制功能使用的排队规则分为两类:无分类排队规则分类排队规则。无分类排队规则相对简单,而分类排队规则则引出了分类和过滤器等概念,使其流量控制功能增强。

2. 流量控制组件

2.1 qdisc 排队规则

qdisc(队列规则,queueing discipline)是 Linux 流量控制系统的核心。实际就是一个队列上面附加的排队规则,下文有时也直接称为队列。

qdisc其实就是一个调度器,每个网络接口都会有一个调度器,qdisc会根据调度器的规则重新排列数据包进入队列的顺序。

  • 无类排队规则

    对进入网络设备(网卡)的数据流不加区分统一对待,能够接收数据包以及重新编排、延迟或丢弃数据包。可以对整个网络设备(网卡)的流量进行整形,但不能细分各种情况。

    • [p|b]fifo:简单先进先出
    • pfifo_fast:根据数据包的tos将队列划分到3个band,每个band内部先进先出
    • redRandom Early Detection,随机早期探测,带宽接近限制时随机丢包,适合高带宽应用
    • sfqStochastic Fairness Queueing,随机公平队列,按照会话对流量排序并循环发送每个会话的数据包
    • tbfToken Bucket Filter,令牌桶过滤器,只允许以不超过事先设定的速率到来的数据包通过 , 但可能允许短暂突发流量朝过设定值
  • 有类排队规则

    对进入网络设备的数据包根据不同的需求以分类的方式区分对待。对数据包进行分类的工具是过滤器,队列规定就根据过滤器的决定把数据包送入相应的类进行排队。每个子类都可以再次使用它们的过滤器进行进一步的分类。绝大多数分类的队列规定还能够对流量进行整形。这对于需要同时进行调度和流量控制的场合非常有用。

    • cbqClass Based Queueing,基于类别排队,借助EWMA(exponential weighted moving average, 指数加权移动均值 ) 算法确认链路的闲置时间足够长 , 以达到降低链路实际带宽的目的。如果发生越限 ,CBQ 就会禁止发包一段时间。
    • htbHierarchy Token Bucket,分层令牌桶,在tbf的基础上增加了分层
    • prio:分类优先算法并不进行整形 , 它仅仅根据你配置的过滤器把流量进一步细分。缺省会自动创建三个FIFO类。

Linux默认的排队规则是pfifo_fast,这是一种比FIFO稍微复杂一点的排队规则。一个网络接口上如果没有设置qdisc,pfifo_fast就作为缺省的qdisc。

由于项目需要这里主要讨论在输出口使用 RED 和 HTB。

2.2 class 分类

类(class)仅存在于可分类的 qdisc 之下,过滤器(filter)也只能附加在有分类排队规则上。

类组成一个树,理论上能无限扩展。一个类可以仅包含一个叶子qdisc(默认为pfifo_fast),也可以包含多个子类,子类又可以包含一个叶子qdisc或者多个子类。 这就给 Linux 流量控制系统予以了极大的可扩展性和灵活性。

每个 class 和有类 qdisc 都需要一个唯一的标识符,称为句柄(handle)。标识符由一个主编号和一个子编号组成,编号必须是数字。句柄仅供用户使用,内核会使用自己的一套编号来管理流量控制组件对象。习惯上,需要为有子类的qdisc显式的分配一个句柄。

qdisc 的子编号必须为0,而分类的子编号必须是非0值。同一个qdisc对象下所有子类对象的主编号必须相同。

例如 root qdisc句柄为 1:0(或者1:),它的子类句柄可以为 1:11:21:3等等。

特别地,ingress qdisc (入队列)的编号总是 ffff:0。

这个结构会在后面详细说明。

2.3 filter 过滤器

**过滤器(filter)**即根据数据包的某属性进行匹配,进行分类后送到不同的队列上。过滤器能与 有分类qdisc 相关联,也可以和 class 相关联。

树的每个节点都可以有自己的过滤器,但是高层的过滤器也可以直接用于其子孙类。所有的出站数据包首先会通过 root qdisc,接着被与 root qdisc 关联的过滤器进行分类,进入子分类,并被子分类下的过滤器继续进行分类。如果数据包没有被成功归类,就会被排到这个类的叶子qdisc的队中。或者也可以只对根分类提供一个过滤器,然后为每个子分类提供路由映射。

过滤器使用**分类器(classifier)**进行数据包匹配,最常用的分类器是 u32 分类器,它可以根据数据包中的各个字段对数据包进行分类,例如源IP等。

**决策器(policer)**只能配合 filter 使用。当流量高于用户指定值时执行一种操作,反之执行另一种操作。在 Linux 流量控制系统中,想要丢弃数据包只能依靠决策器。决策器可以把进入队列的数据包流速限定在一个指定值之下。另外,它也可以配合分类器,丢弃特定类型的数据包。

3. 树型结构详解

流量控制(Traffic Control, TC)以qdisc - class - filter的树形结构来实现对流量的分层控制。

当Linux内核接收数据包时,先根据过滤器进行分类,符合条件的数据包就被归为相应的类,而每一个类都对应一个相应的排队规则。如果一个数据包对于所有的过滤条件都不满足,则该数据包会被归为缺省类,将会使用缺省的队列规定对其进行处理(默认pfifo_fast)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S3pkYxAQ-1649134329043)(https://secure2.wostatic.cn/static/kGXFvdejZw5NEwN34Md44p/image.png)]

Linux在实现TC的时候,对“队列”进行了抽象,基本上它维护了两个回调函数指针,一个是enqueue入队操作,一个是dequeue出队操作。不管是enqueue还是dequeue,都并不一定真正将数据包排入队列,而仅仅是“执行一系列的操作”:

  1. 对于叶子节点,排入一个真实的队列或者从真正的队列拉出一个数据包;
  2. 递归调用其它抽象队列的enqueue/dequeue。

所以对于非叶子节点的qdisc,实际上是一个“不存在的队列”,数据包没有实际在此排队,只是递归调用子类的队列。只有在叶子节点上的队列才是真正能存放发出数据包的队列。

所以实际的树状结构如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hFM3C2XH-1649134329045)(https://secure2.wostatic.cn/static/hgTSFa9xT6E4D9BWCPHpRa/image.png)]

一般为有子类的qdisc显式的分配一个句柄,方便添加过滤器和子类。

root qdisc 只是一个抽象队列,句柄为1:0。一个类有且仅有一个叶子 qdisc(可不显示分配句柄),默认为pfifo_fast。这个qdisc也可自行设置,此时就与父节点不再是同一个 qdisc 对象,随后将进行递归调用。若这个类有其他子类,那数据包就会通过类的过滤器进行分类进入子类,如果没有被成功归类,就会被排到这个类的叶子 qdisc 中。

同一个 qdisc 对象中,父节点的 filter 可以直接作用于子孙类,例如图中 root qdisc 的过滤器直接调用句柄为 1:6 的类。

数据包流入过程如下:

  1. 如上图所示,数据包从网卡进入后,首先经过 root qdisc 1:0,此处根上的是可分类队列,则会经过filter分到对应子类中。
  2. 若进入 class 1:2,则此类的规则生效后,直接进入这个类的叶子 qdisc 排队(默认pfifo_fast)。
  3. 若进入 class 1:1,则此类的规则生效后,进入一个新的 qdisc 2:0,这个qdisc 也是可分类队列,所以数据包会经过filter进入子类,后续过程即递归调用。
  4. 若进入class 1:3,则规则生效后会经过filter进入此类的子类,注意这里和root qdisc属于同一个对象。如果没有满足的分类规则,数据包会进入此类的默认叶子qdisc排队。
  5. 数据包进入 class 1:4,这里就会进入新的 qdisc 4:0,此qdisc 是无分类队列,所以没有过滤器和子类。这个队列下也可直接接新的无分类队列 qdisc z:0(此处是叶子队列,没有显式分配具柄),或者像 class 1:5 一样,qdisc 5:0 后接新的可分类队列 qdisc 6:0

3. qdisc算法及使用

3.1 RED

随机早期探测(Random Early Detection,RED)是一种无分类qdisc

当队列达到特定的平均长度,入队列的报文会有一定的(可配置)概率会被丢弃,这个概率会线性地增加到某一点,称为最大平均队列长度。

这种方式在队列增长时就开始随机丢包,使队列不至于太长,可以避免在流量突增之后导致的丢包重传(而这些重传会导致更多的重传)。

如果使用 ecn 参数,则以某概率丢包改为以某概率做 ECN 标记,即把IP数据包的ECT CE位置为 11

用法

tc  qdisc ... red  limit BYTES [min BYTES] [max BYTES] avpkt BYTES [burst PACKETS] [probability PROBABILITY] [bandwidth KBPS] [ecn] [adaptive] [harddrop]

参数:

  • limit:真实队列的硬性限制,单位为字节,与 RED 算法无关。应当设置为大于最大队列长度与突发报文之和max + burst,超过此值后,接收到的报文都将被丢弃。RED正常工作的情况下,队列长度不会达到此值。
  • min:单位为字节。开始进行标记的平均队列大小,默认为 max/3
  • max:单位为字节。平均队列大小达到该值后,标记的概率达到最大(probability)。为了避免同步重传,应该至少是min的两倍,且大于最小的min值,默认为limit/4
  • Avpkt:单位是字节,与burst一起确定平均队列长度avg的时间常数。建议值1000(MTU为1500时)。
  • burst:桶大小,决定了计算平均队列长度avg在多大程度上受到实际队列长度的影响。较大的值会减慢avg更新的速度,从而允许在标记开始之前出现更多的突发流量。实际经验遵循(min+min+max)/(3*avpkt)
  • probability:标记的概率的最大值(队列长达到max时),为0.0到1.0之间的浮点数,默认为0.02
  • bandwidth:该速率用于在一段空闲时间之后计算平均队列的大小,设置为接口的带宽,但不会进行整流。默认值为10Mbit
  • ecn:允许RED对支持ECN的主机以报文标记的形式通知拥塞(除非队列达到limit的字节数),推荐使用。
  • harddrop**: 如果平均队列长度大于max字节数,则强制丢弃报文,而不是进行ECN标记。
  • adaptive:Adaptive-RED算法,旨在通过动态调整probability的值(范围:[0.01,0.50]),将队列长度维持在 (max-min)/2

通过计算最高可接受的基本排队延迟来设置min,并将其乘以带宽。例如,在 64kbit/s ISDN 链路上,想要 200 毫秒的基本排队延迟,因此我将min设置为 1600 字节

64 × 200 / 8 = 1600 64×200/8=1600 64×200/8=1600)。

设置 min 太小会降低吞吐量,太大会降低延迟。设置较小的最小值并不能替代降低慢速链路上的 MTU 以改善交互响应。

3.2 HTB

HTB(Hierarchy Token Bucket,分层令牌桶)是一种有分类排队规则,允许把一条物理链路模拟成几条更慢的链路,或者是把发出的不同类型的流量模拟成不同的连接。

它使用了令牌和桶的概念,并使用了基于类的系统和过滤器对流量进行复杂和细粒度的控制。通过一个复杂的借用模型,HTB可以实现各种复杂的流量控制技术。另一种最简单的方式是在整流时使用HTB。

用法

添加 htb qdisc:

... qdisc add ... htb [default N] [r2q N] [direct_qlen P]

  • default 未分类的流量出口,默认为0,这样未分类的流量会使用硬件速度出队列,不会经过附加到 root qdisc 的所有类。

  • r2q DRR quantums are computed as rate in Bps/r2q {10}

  • debug string of 16 numbers each 0-3 {0}

  • direct_qlen Limit of the direct queue {in packets}

添加类:

... class add ... htb rate R1 [burst B1] [mpu B] [overhead O]
                      [prio P] [slot S] [pslot PS]
                      [ceil R2] [cburst B2] [mtu MTU] [quantum Q]
  • rate 最低期望速度,叶类的保证带宽(此叶类还能借)。
  • ceil 流量的最大速度,可以认为其等同于"突发的带宽",借用模型会详细说明。默认等于rate
  • burst rate的桶大小,HTB在等待更多令牌前可以加入队列burst字节的数据,即最大突发流量。
  • cburst ceil 的桶大小。HTB在等待更多ctokens前可以加入队列cburst字节的数据。
  • quantum 用于控制借用的关键参数。通常HTB会用r2q计算一个 ,用户无需指定。修改该值会对竞争下的借用和整流造成巨大的影响(因为它会在流量超过rate(且低于ceil)的子类间对流量进行分割,并传输这些子类的报文)。
  • prio 叶子的优先级,越小优先级越高。默认为0。
  • mpu minimum packet size used in rate computations
  • overhead per-packet size overhead used in rate computations
  • linklay adapting to a linklayer e.g. atm
  • mtu max packet size we create rate map for {1600}

举例

HTB是典型的qdisc - class - filter树形结构来实现对流量的分层控制。以 eth0 网口为例,首先在根队列要建一个htb qdisc:

tc qdisc add dev eth0 root handle 1: htb

然后才能在之下建立子分类,这里为方便后续讲解手动设置quantum

tc class add dev eth0 parent 1:  classid 1:1  htb rate 100mibps
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 30mibps ceil 80mibps prio 0 burst 10kbit cburst 20kbit quantum 30000
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 20mibps ceil 50mibps prio 1 burst 10kbit cburst 20kbit quantum 20000
tc class add dev eth0 parent 1:10 classid 1:101 htb rate 10mibps ceil 80mibps prio 1 burst 10kbit cburst 20kbit quantum 10000
tc class add dev eth0 parent 1:10 classid 1:102 htb rate 5mibps ceil 40mibps prio 0 burst 10kbit cburst 20kbit quantum 5000

这些类的关系如下。随后可以使用filter和 u32 分类器把来自不同源 IP 的数据包送到不同的类。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uynGHvMW-1649134329046)(https://secure2.wostatic.cn/static/ZLwu5kVxVbCdgYHPZeWu5/image.png)]

所有数据包最后只能从叶子类(leaf class)排队,其他内部类(inner class)起到和子类共享带宽的作用。

当网卡比较空闲时,leaf class可以以高于rate的速率出包,但不能高于ceil。带宽闲时共享,忙时按照比例分配(这个比例由ratequantum共同决定)。prio优先级越高的类可以优先出流量。

原理

某个时刻每个类可以处于三种状态中的一种:

  • CAN_SEND(令牌充足,发送的网络包小于rate,例图中用绿色表示))
  • MAY_BORROW(没有令牌,但可向父类借用。发送速率大于rate小于ceil,例图中用黄色表示)
  • CANT_SEND(没有令牌且不可借用,发送速率大于ceil,例图中用红色表示)

htb是如何决策哪个类出包的?

  1. htb算法从类树的底部开始往上找CAN_SEND状态的class。如果找到某一层有CAN_SEND状态的类则停止.
  2. 如果该层中有多个class处于CAN_SEND状态则选取优先级最高(prio最小)的class。如果最高优先级还是有多个class,那就在这些类中轮询处理。每个类每发送自己的quantum个字节后,轮到下一个类发送. 。
  3. 只有leaf class才可以发包,上述步骤若最终选到了inner class,就顺着树往下找处于MAY_BORROW状态的leaf class。将自己富余的令牌借给该leaf class让其出包。同样,多个子孙leaf class处于MAY_BORROW状态时和步骤2一样。

多个子类共享父类带宽也就体现在这里了。假设父类富余了10MB,子类1的quantum为30000,子类2的quantum为20000。那么父类帮子类1发送30000byte,再帮子类2发送20000byte。依次循环,最终效果就是子类1借到了6MB,子类2借到了4MB。因此上文说,当子类之间共享带宽时,rate/quantum共同决定它们分得的带宽。rate决定处于CAN_SEND状态时能发送多少字节,quantum决定处于MAY_BORROW状态时可借用令牌发送多少字节。

实例

这里直接看这篇文章

参考

Traffic Control HOWTO
Random Early Detection (RED)
Linux TC(Traffic Control)框架原理解析
Linux流量控制TC中的HTB队列创建与过滤
linux网络流控-htb算法简析
RED队列tc设置
流量控制

[1]郑辉. 基于 Linux 下的简单网络行为管理–Tc流量控制[J]. 软件:教育现代化(电子版), 2013(5):2.
[2]倪飞. 流量控制工具TC原理及应用[J]. 计算机科学, 2006, 33(B12):3.

  • 20
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1 基于Linux 的防火墙技术研究 宋文功1 唐 琎2 (1.中南大学网络中心,湖南长沙510630;2.中南大学信息科学与工程学院,湖南长沙410075) 摘 要:介绍了防火墙的基本概念及其主要功能,分析了Linux 内核防火墙Netfilter 的架构、构建防火墙的工作原 理及其与内核的交互.最后给出了Netfilter 构建防火墙的一个实例。 关键词:防火墙 Linux Netfilter 包过滤 中图分类号:TN393 文献标识码:A Study of the technology of firewall based on Linux SONG Wen-gong1 Tang Jin2 (1.Central South University, Changsha 510630,China; 2. Central South University, Changsha 410075,China) Abstract:The basic concept and most functions of firewall were introduced here.It analysed the frame of netfilter,explained how to interact between kernel.Finally,a case study of using netfilter as a firewall was given. Key words:firewall;Linux; Netfilter;packet filtering 因特网的个人用户和集体用户正在快速增长,因特网在全世界范围内可共享的信息也越来越丰 富,同时随之而来的是信息系统的安全性显得越来越重要。特别是近来,黑客入侵和网络病毒大爆 发时有发生,各国政府都在加强在网络安全技术方面的研究。为了有效隔离来自Internet 的外部入 侵,防火墙(firewall)技术正在普及中。除了信息加密技术外,防火墙是当前最重要的一种网络安全 技术。 防火墙实际上是一种访问控制技术,主要作用是通过限制网络或某一特定区域的通信,阻止对信 息资源的非法访问和防止保密信息从受保护网络上非法输出。它是提供信息安全服务,实现网络和 信息安全的基础设施。 1 Linux 防火墙的功能 目前市场上有许多商用防火墙软件出售,但它们大多价格高昂,使许多个人及小企业用户难以承 受。Linux 的出现给了我们一个新的选择。它提供了一套完全免费的解决方案,其内置防火墙功能非 常强大,甚至超过了许多昂贵的商用软件。 1.1 包过滤功能 根据数据包的包头中某些标志性的字段,对数据包进行过滤。当数据包到达防火墙时,防火墙 根据包头中的某些字段中的一些或全部进行判断,决定接受还是丢弃数据包。包过滤可能发生在以 下几个时刻:接收到数据包时,发送数据包时以及转发数据包时。Linux 中过滤包的方法如下: (1)将包头和过滤规则逐一进行匹配。 (2)第一条与包匹配的规则将决定以下采取的行动:首先,此规则指定的策略将被应用到该包 上。应用在一个包的策略包括以下几种:接受(Accept),即允许包通过该过滤器;抛弃(Reject),即丢掉该 包并发一个“主机不可到达”的ICMP 报文回发送者;拒绝(Deny),即丢掉该包且不发任何返回信息。 其次,修改此规则对应的包和字节计数器的值;再次,一些关于包的信息会有选择性地被写入日志 中。有的规则中可能含有参数来定义如何改写包头的服务类型(TOS)字段,用于确定不同包的优先级。 (3)如果没有与包相匹配的过滤规则,则将对该包采取缺省的过滤规则Linux 的包过滤规则可 包含如下一些信息: ·源地址和目的地址以及子网掩码,其中子网掩码中的0 表示可以匹配任何地址; ·包的类型,可以是TCP,UDP,ICMP 或“any”; ·源和目的端口号,一条规则中可以指定10 个以上的端口,也允许指定端口范围; ·ICMP 报文类型; 基金项目:国家自然科学基金资助项目(60234030) 2 ·包中的ACK 和SYN 标志,这是为了防止在某个特定方向上建立新的链接; ·某块网卡的名字或IP 地址,这样可以指定在特定的网卡上进出包; ·指定是否修改包头的TOS 字段; ·用一个标志来确定包的一些基本信息是否要被写入日志中。 1.2 代理服务功能 一个完整的防火墙解决方案不仅包括包过滤器,而且应该包括某种类型的应用层代理服务器。所 谓代理服务,是指在防火墙上运行某种软件(称为代理程序),如果内部网需要与外部网通信,首先 要建立与防火墙上代理程序的连接,把请求发送到代理程序;代理程序接收该请求,建立与外部网 相应主机的连接,然后把内部网的请求通过新连接发送到外部网相应主机。反之亦然。概括的说, 就是内部网和外部网的主机之间不能建立直接的连接,而是要通过代理服务进行转发。代理服务器 具有用户级的身份验证,完备的日志记录和帐号管理等较包过滤器更加安全的功能。然而,许多代理机 制需要客户端修改软件或修改用户接口,使用户意识到正在使用代理服务器。而Linux 内核支持透明 代理服务功能,透明代理用一种完全透明的方式,将一个经过本防火墙的连接重定向到本地代理服务 器.客户端(用户和软件)完全不知道他们的连接被一个代理进程处理,他们认为自已在直接和指定的 服务器对话。 1.3 包伪装功能 Linux 核心提供了一个用于防火墙解决方案的附加功能:IP 包伪装。IP 包伪装是Linux 中的一 种网络功能,它只能用于TCP/UDP 包,它能使没有Internet 地址的主机通过有Internet 地址的主机访问 Internet。如果一台Linux 服务器用IP包伪装功能连接到Internet 上,那私接上它的电脑即使没有获 得正式指定的IP 地址也可以接入Internet.这些电脑可以隐藏在Linux 服务器后面存取Internet 上的信 息而不被发现,看起来就好象是服务器在使用Internet。Linux 服务器实现代理功能的方法如下:当一 个内部主机向外发包时, Linux 服务器在转发此 IP 包之前,用自已IP 地址替换此包的源IP 地址, 并临时产生一个本机端口号来替换此包的 TCP/UDP 头中的源端口号;同时,内核会记录下 此替换.当外部的返回包到来时(送往防火墙主机 的临时端口),服务器能自动识别它,将此返回包 的IP 地址和端口号替换成内部主机的地址和端 口号,发给内部主机。分组过滤方式如下图1 所示。 通过这种IP 包伪装方式, Linux 方便地实现 了“代理”功能。从外部看来,所有包的收发都 是针对此Linux 主机的,所以具有很好的安全性。 2 Linux 数据包过滤系统—Netfilter/Iptables Linux 在其2.4 内核中内置了一个基于网络层解决方案的防火墙系统—Netfilter/Iptables,它使得 用户能够很方便地在网络边界定制对数据包的各种控制,如有状态或无状态的包过滤、各种类型的网 络地址转换、流量控制及高级的包处理等。Netfilter/Iptables 系统采用模块化的架构方式,其主要模块 有:通用框架Netfilter、数据包选择系统、连接跟踪系统及NAT系统等等。 2.1 Netfilter/Iptables 系统工作原理 Netfilter/Iptables 系统所提供的数据包控制能力(包过滤、网络地址转换、包处理等)都是由内核 模块通过注册回调函数和“IP 表”来实现的。例如,iptable_filter.o 模块通过注册filter 表及3 个回调 函数(NF_IP_LOCAL_IN;NF_IP_FORWARD;NF_IP_LOCAL_OUT)来实现IPv4 包的过滤功 能。下面以iptable_filter.o 模块的工作流程为例简单介绍一下Netfilter/Iptables 系统是如何工作的。 当数据包进入系统时,系统首先根据路由表决定数据包的流向(即将数据包发往那个关键点),则可能 有三种情况: 图1 分组过滤示意图 3 如果数据包的目的地址是其它主机或网络,则系统将该包发往forward 关键点。此时,回调函数NF _IP_FORWARD 根据FORWARD 链(在filter 表中)中的规则对数据包进行检查,如果规则匹配,则回 调函数按规则所指定的动作来处理该包,否则丢弃该包。2)如果数据包的目的地址是本机,则系统将数 据包发往input 关键点。此时,回调函数NF_IP_LOCAL_IN 根据INPUT 链(在filter 表中)中的规则 对数据包进行检查,如果规则匹配,则回调函数就按规则所指定的动作来处理该包,否则丢弃该包。3) 如果该数据包的源地址是本机,则系统将该包发往output 关键点。此时,回调函数NF_IP_LOCAL_ OUT 根据OUTPUT 链(在filter 表中)中的规则对数据包进行检查,如果规则匹配,则回调函数按规则所 指定的动作来处理该包,否则丢弃该包。 2.2 Netfilter 内核框架 Netfilter 是Linux2.4.x 内核中用于包处理的抽象、通用化的框架,它为每种网络协议(IPv4、IPv6 等)定义一套钩子函数(hook),其中IPv4 定义了5 个钩子函数.内核的模块可以对每种协议注册多个钩 子,这样当某个数据包通过Netfilter 框架时,Netfilter 检测是否有任何模块对该协议和钩子函数进行了 注册.若有,则将该数据包传给这些模块处理.Netfilter 提供了数据包过滤(filter 表),网络地址转换(NAT 表)及数据包处理(mangle 表)三种数据包处理能力.下面以Filter 表为例加以简单介绍. Filter 表为系统 缺省,其结构如下图.该表中包含了输入(INPUT)、输出(OUTPUT)和转发(FORWARD)3 条链.所有目标 地址指向本机的数据包会遍历INPUT 链,本地发出的数据包将遍历OUTPUT 链,而被转发的数据包将 遍历FORWARD 链。每一条链中都可设 定一条或数条规则,每一条规则都是这 样定义的“如果数据包头符合这样的条 件,就这样处理这个数据包”.当一个数据 包到达一个链时,系统就会从第一条规 则开始检查,看是否符合该规则所定义 的条件.如果满足,系统将根据该条规则 所定义的方法处理该数据包;如果不满 足则继续检查下一条规则。最后,如果 该数据包不符合该链中任何一条规则的 话,系统就会根据该链预先定义的策略 (Policy)来处理该数据包。 Netfilter 提供了传递数据包到用户空间的Hook 函数,对数据包进行处理的代码不必运行在内核 空间,大大简化了编程.Netfilter 的框架结构,可方便地插入各种模块,易于扩展。 2.3 内核与用户的交互 防火墙除了内核里的机制外,还需要在应用层有相应的配置工具iptables,它是从三个默认的表 Filter、Nat、Mangle 而得名,每个表有几条链。一条链就是发生在包L 的一系列动作,例如Filter 表就有INPUT、FORWARD、OUTPUT 三个不同的默认链。如果包过滤需要检查IP 包,则netfilter 框架在网络层截获IP 包,这就需要与用户定义的规则做比较。而这些规则的添加修改是通过内核和 用户交互实现的,这就涉及一个如何与内核通信的问题。内核模块有三种办法与进程打交道:首先 是系统调用;第二种办法是通过设备文件;第三个办法便是使用proc 文件系统。netfilter 采用了第 一种修改系统调用的办法。ipables 在应用层调用setsockopt 进入内核,然后调用netfilter. c 又件中 nbetsockopt()实现交互,这样通过配置防火墙就可以按需要处理网络数据包。只有熟悉了iptables 提供的众多命令、选项等,在明白其工作原理的前提下,用户才能利用它未放心地创建大量的规则 记录和策略去控制内核数据包,才能正确有效地使用防火墙。这样即使在图形界而下使用防火墙, 通过点击你也明明白白内核里发生了什么。 3 防火墙配置实例 图2 filter 表结构 4 假设有一个局域网要连接到Internet 上,公共网络地址为202.101.2.25。内部网的私有地址采用C 类地址192.168.0.0~192.168.255.0 具体操作步骤如下:第一,一台Linux 主机上安装2 块网卡ech0 和ech1,给ech0 网卡分配一个 内部网的私有地址191.168.100.0,用来与Internet 相连;给ech1 网卡分配一个公共网络地址 202.101.2.25,用来与Internet 相连;第二, Linux 主机上设置进入、转发、外出和用户自定义链。本文 采用先允许所有信息可流入和流出,还允许转发包,但禁止一些危险包,如IP 欺骗包、广播包和ICMP 服务类型攻击包等的设置策略。具体设置如下: (1) 清除所有规则/sbin/ipchains-Fforward/sbin/ipchain s-Finput/sbin/ipchains-Foutput (2) 设置初始规则/sbin/ipchains-Ainput-jACCEPT/sbin/ip chains-Aoutput-jACCEPT/sbin/ipchains-AforwardjACCEPT (3) 设置本地环路规则/sbin/ipchains-Ainput-jACCEPT-ilo/s bin/ipchains-Aoutput-jACCEPT-ilo (4) 禁止IP欺骗/sbin/ipchains-Ainput-jDENY-iech1-s 192.168.100.0/24/ s b in/ i p c h a i n s-A i n p u t-j D E N Y-i e c h1- d 192.168.100.0/24/sbin/ipchains-Aoutput-jDENY-iech1-s 192.168.100.0/24/sbin/ipchains-Aoutput-jDENY-iech1-d 192.168.100.0/24/ s b in/ i p c h a i n s-A i n p u t-j D E N Y-i e c h1- s 202.101.2.25/32/sbin/ipchains-Aoutput-jDENY-iech1-d 202.101.2.25/32 (5) 禁止广播包/sbin/ipchains-Ainput-jDENY-iech0-s 255.255.255.255/sbin/ipchains-Ainput-jDENY-iech0-d0.0..0.0/s bin/ipchains-Aoutput-jDENY-iech0-s240.0.0.0/3 (6) 设置ech0 转发规则/sbin/ipchains-Aforword-jMASQ-ie ch0-s192.168.100.0/24 (7) 设置ech1 转发规则/sbin/ipchains-Aforword-jACCEPTiech1- s192.168.100.0/24/sbin/ipchains-Aforword-jACCEPTiech1- d192.168.100.0/24 通过以上各步骤的配置,可以建立一个基于Linux 操作系统的包过滤防火墙。它具有配置简单、 安全性高和抵御能力强等优点。 4 结束语 安全总是相对和无止境的,防火墙有其固有的局限性。人们必须时刻保持高度警惕去防止新的 攻击,动态跟踪系统的安全状况,开发新的功能和采取新的策略。本文通过分析netfilter 构建防火 墙的机制与技术,利用实例讲解了利用netfilter 框架编程实现新功能,这种分析有利于研究人员去 开发新的好的功能,用防火墙去努力保障主体的安全。 参考文献: [1] The netfilter framework in linux 2.4[EB/OL]. http://www.gnumonks.org/ [2] Linux 2.4 netfilter hacking HOWTO[EB/OL]. http:/ netfilter.kernelnotes.org/ [3] 徐辉,潘爱民,阳振坤.Linux 防火墙的原理与实现[J].计算机应用,2002,(1). [4] 梁如军.RedHat7.0 安装配置与管理[M].北京:清华大学出版社,2001. [5] RobertZiegler. 余青霞,周钢译.Linux防火墙[M].北京:人民邮电出版社,2000.10 [6] 黄允聪,严望佳,防火墙的选型、配置、安装和维护[M].北京:清华大学出版社,1999.45~108 [7] 原箐,卿斯汉.基于安全数据结构的防火墙[J]计算机科学,2001(8):56~60 5 作者简介(Author’s brief introduction): 1、宋文功(1966-),男,汉族,硕士(Male. Master.)。中南大学网络中心,工程师。 毕业院校:北京邮电学院。 研究方向:计算机通信(Researching for computer communications)。 通信地址:长沙市韶山南路22 号中南大学网络中心 邮编:510630 2、唐琎(1966-),男,汉族,博士(Male. Doctor.)。中南大学信息科学与工程学院,副教授。 研究方向:计算机应用 (Researching for computer applications)。 毕业院校:北京大学.
Linux令牌桶流量控制是一种网络流量控制机制,用于限制进入或离开系统的数据包速率。它基于一个令牌桶模型,在这个模型中,一个固定数量的令牌以固定速率被添加到令牌桶中。每当有一个数据包到达时,系统将从令牌桶中取出一个令牌,只有当令牌桶中有足够的令牌时才允许数据包通过。如果令牌桶中没有足够的令牌,那么数据包就会被丢弃或延迟。 通过配置Linux内核参数和使用工具如tc(Traffic Control),可以实现令牌桶流量控制。以下是一些关键步骤: 1. 启用Linux内核的Traffic Control子系统。这可以通过加载“sch_htb”模块实现。 ``` $ modprobe sch_htb ``` 2. 使用tc命令创建一个类别(class)和队列(qdisc)来实现流量控制。例如,以下命令将创建一个带宽为1mbps、延迟为10ms的队列。 ``` $ tc qdisc add dev eth0 root handle 1: htb default 1 $ tc class add dev eth0 parent 1: classid 1:1 htb rate 1mbit ceil 1mbit $ tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 10ms ``` 3. 根据需求,可以添加过滤规则(filter)以便仅对特定的流量应用流量控制。例如,以下命令将对源IP为192.168.0.1的流量应用限制。 ``` $ tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip src 192.168.0.1 flowid 1:1 ``` 通过以上步骤,你可以实现针对特定网络接口、IP地址或其他条件的流量控制。你可以根据具体需求进行调整和配置,以满足你的流量控制需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值