gefieder 发表于 2015-4-28 09:32:54

关于 iptables 和 tc 的限速理解-02

本帖最后由 gefieder 于 2015-4-28 09:40 编辑

问题导读:
1、什么是tc(TC-Traffic Control)?
2、tc的测试流程介绍
3、如何建立tc策略?

static/image/hrline/4.gif

接上篇:关于 iptables 和 tc 的限速理解-01

关于 tc
TC--Traffic Control
TC 是 linux 中的流量控制模块,利用队列规定建立起数据包队列,并定义了队列中数据包的发送方式,从而实现对流量的控制。关键字:队列系统,包接收和传输。

    Traffic control is the name given to the sets of queuing systems and mechanisms by which packets are received and transmitted on a router. This includes deciding which (and whether) packets to accept at what rate on the input of an interface and determining which packets to transmit in what order at what rate on the output of an interface.

这里是官方翻译:http://my.oschina.net/guol/blog/82453?p=1
原版:http://www.tldp.org/HOWTO/Traffic-Control-HOWTO/

tc工作位置图:


在我使用的过程中,对于他的理解是有一些加深了:

[*]tc 就是看门的,like as a dog,所以这就可以解释了为什么要 iptables + tc 了,tc 能够和 iptables 合作,因为可以从图上看到各自工作的位置是不一样的,各施其职。
[*]tc 对于包一视同仁,专门负责包的排队分发,官方里面提到一个很经典的说法就是他是一个接收和传输的队列系统,tc 翻译为交通管制是很巧妙的,有鉴于此,我认为他的限速效果最好,无论你是 p2p 包还是什么加密包,只要是包就要受到约束,这样就可以避免了那些日新月异的封装加密之类的包被逃掉了。
[*]tc 主要是以 mark 的形式来匹配,所以使用的时候 mark 标记需要注意不要冲突,mark 标记是 iptables 里面提到的一个东西:
    6.5.5. MARK target

    用来设置 mark 值,这个值只能在本地的 mangle 表里使用,不能用在其他任何地方,就更不用说路由器或 另一台机子了。因为 mark 比较特殊,它不是包本身的一部分,而是在包穿越计算机的过程中由内核分配的和它相关联的一个字段。它可以和本地的高级路由功能联用,以使不同的包能使用不同的队列要求,等等。如 果你想在传输过程中也有这种功能,还是用 TOS target 吧。有关高级路由的更多信息,可以查看 Linux Advanced Routing and Traffic Control HOW-TO。

mark 只能存在于内核之中,不受三界法则影响,所以 mark 值我觉得是配置 tc 的特别需要注意的地方,尤其是如果你使用了 wifidog 之类的要玩 mark 的时候。
[*]tc 的类是树架构,有主干和叶这样很分明的区分的,这种层次是很容易理解的,不过文档的解释是相当的难理解,难理解的是怎么做,命令写法简直坑爹。
[*]涉及很多相当高深的队列算法,流控制模式其实略懂就行了,诸葛先生不也就略懂么。所以不是那种极端情况其实无须特别考虑这个。
[*]对于 tc 来说,上传和下载行为是这样区分的,上传,就是用户端发送数据包给服务器,假设路由器是双网卡,所以负责发送数据包给服务器的是外网网卡,所以限制上传速度在外网网卡处, 下载,就是服务器发送数据包给用户,因为路由器是双网卡的关系,所以负责发送数据包给用户的是内网网卡,所以限制下载速度是在内网网卡,因为 tc 是一个能够负责接收数据包的工具,所以限制上传速度其实就是限制外网网卡接收用户发送的数据包的速度,而限制下载速度其实就是限制内网网卡接收到要发送给用户的数据包的速度。

测试流程介绍
[*]首先需要建立 tc 策略
[*]然后由 iptables 来进行调用,主要通过 set mark,根据不同的 mark 标记来进行不同的 tc 策略调用
备注
[*]测试环境是 eth0 负责外网,p3p1 是负责内网
[*]考虑到特殊需求,tc 限制的是所有的包,所以需要 iptables 将发到内网服务器的包分开处理,以便实现访问外网能够限制网速,访问内网没有限制
上传清除 eth0 所有队列规则
tc qdisc del dev eth0 root 2>/dev/null定义最顶层(根)队列规则,并指定 default 类别编号,为网络接口 eth1 绑定一个队列,类型为 htb,并指定了一个 handle 句柄 1:0 用于标识它下面的子类,没有标识的会被分配到默认子类 123(默认值只是设置而已,可以不用)
tc qdisc add dev eth0 root handle 1:0 htb default 123用于为队列建一个主干类,带宽为 100 Mbit,最大速率为 100 Mbit,(这里是 bit,所以实际速度需要除以 8)优先级为 0,htb 的主干类不能互相借用带宽,但是一个父类的所有子类之间可以借用带宽,这里 parent 1:0 是刚才建立的 handle1:0 ,classid 是他的子类,分类号为 1:1,冒号前面是父类号,后面是子类号
tc class add dev eth0 parent 1:0 classid 1:1 htb rate 100Mbit ceil 100Mbit prio 0为主干类建立第一个叶分类,带宽为 10Mbit,最大速为 10 Mbit,优先级为1,所有叶分类的全部子类优先级低于主干类,以防止重要数据堵塞,主要还是避免逻辑混乱,10 Mbit 必须要有 96 kbit 的 burst 速度
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 10Mbit ceil 10Mbit prio 1 burst 96kbit设置调度,sfq 随机公平算法,这里的 parent 是指隶属于之前的子分类,你需要对哪一个子分类的条目做队列分配控制就需要在这里写对应的子分类 id 在每个类下面再附加上另一个队列规定,随机公平队列(SFQ),不被某个连接不停占用带宽,以保证带宽的平均公平使用:
    #SFQ(Stochastic Fairness Queueing,随机公平队列),SFQ的关键词是“会话”(或称作“流”) ,
    #主要针对一个TCP会话或者UDP流。流量被分成相当多数量的FIFO队列中,每个队列对应一个会话。
    #数据按照简单轮转的方式发送, 每个会话都按顺序得到发送机会。这种方式非常公平,保证了每一
    #个会话都不会没其它会话所淹没。SFQ之所以被称为“随机”,是因为它并不是真的为每一个会话创建
    #一个队列,而是使用一个散列算法,把所有的会话映射到有限的几个队列中去。
    #参数perturb是多少秒后重新配置一次散列算法。默认为10tc qdisc add dev eth0 parent 1:11 handle 111:0 sfq perturb 10设置过滤器 filter,对应之前配置的哪一个父类和子类,然后设置控制编号 handle,这里是跟 iptables 的 mark 相对应的,并且多个不同的filter注意 prio 不要相同。
tc filter add dev eth0 parent 1:0 protocol ip prio 1 handle 1001 fw classid 1:11
设置 iptables规则,在 mangle 表的 postroutingchain 上配置,源地址是 172.16.1.138 并且目标地址不是 192.168.0.10 ,从网卡eth0发出的包进行 mark,mark 号是 1001
iptables -t mangle -A POSTROUTING -s 172.16.1.138/32 ! -d 192.168.0.10 -o eth0 -j MARK --set-xmark 1001
设置 return 是为了加快包检查,return 的顺序是:子链——>父链——>缺省的策略,检查到源地址是 172.16.1.138 并且目标地址不是 192.168.0.10 的包就会跳到 postrouting 层,然后会继续检查其他这层的 chain,这样不用每个包都要检查一次这条 chain 的内容了,加快了一倍的速度
iptables -t mangle -A POSTROUTING -o eth0 -s 172.16.1.138 ! -d 192.168.0.10 -j RETURN下载tc qdisc del dev p3p1 root 2>/dev/null

tc qdisc add dev p3p1 root handle 1:0 htb default 123

tc class add dev p3p1 parent 1:0 classid 1:1 htb rate 100Mbit ceil 100Mbit prio 0

tc class add dev p3p1 parent 1:1 classid 1:11 htb rate 10Mbit ceil 10Mbit prio 1

tc qdisc add dev p3p1 parent 1:11 handle 111:0 sfq perturb 10

tc filter add dev p3p1 parent 1:0 protocol ip prio 1 handle 1000 fw classid 1:11这里用 I 的是 insert 一条配置,这样排序会放在前面,因为 iptables 是按顺序匹配的,并且为了跟 wifidog 的策略避免冲突
iptables -t mangle -I POSTROUTING -o p3p1 -d 172.16.1.138 ! -s 192.168.0.10 -j MARK --set-mark 1000
iptables -t mangle -I POSTROUTING -o p3p1 -d 172.16.1.138 ! -s 192.168.0.10 -j RETURNEOF完
引用:

[*]http://man.chinaunix.net/network/iptables-tutorial-cn-1.1.19.html
[*]http://linux.vbird.org/linux_server/0250simple_firewall.php
[*]http://www.tldp.org/HOWTO/Traffic-Control-HOWTO/
[*]http://my.oschina.net/guol/blog/82453?p=1
[*]http://www.lartc.org/howto/
[*]http://chuansongme.com/n/403831
[*]http://blog.sina.com.cn/s/blog_4b9633a6010007l7.html
[*]http://blog.sina.com.cn/s/blog_60244a2e0100d4t8.html
[*]http://wenku.baidu.com/view/cd450e82e53a580216fcfe59.html

资料来源:http://segmentfault.com/a/1190000000666869
原文出处:http://www.godblessyuan.com/2015/01/18/iptables_tc_bandwidth_limiting/

页: [1]
查看完整版本: 关于 iptables 和 tc 的限速理解-02