歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux TC基於HTB隊列的流量管理范例

Linux TC基於HTB隊列的流量管理范例

日期:2017/2/28 16:03:29   编辑:Linux教程

同樣要重復說明TC規則涉及到“隊列(QUEUE) 分類器(CLASS) 過濾器(FILTER)”三項。而且是控發不控收。今天我們就TC針對HTB隊列方式配合filter的set-mark功能再做流量管控演示。HTB被 很多人認為要比CBQ操作起來簡單很多,當然我也這樣認為。

假設環境:linux下有兩塊網卡,一個eth1是外網,另一塊eth0是內網.在eth0上做HTB。(注意:filter劃分標志位可用u32 打標功能或iptables的set-mark功能,如果用iptables來打標記的話,下行速度在eth0處控制,但打標應在進入eth0之前進行, 所以要在防火牆中設置“-i eth1"

主要命令就下面三句:

1.創建一個HTB的根

#tc qdisc add dev eth0 root handle 1: htb default 20

2.創建一個HTB的類,流量的限制就是在這裡限制的,並設置突發.

#tc class add dev eth0 parent 1: classid 1:1 htb rate 200kbit ceil 200kbit burst 20k(突發流量)

3.創建一個過濾規則把要限制流量的數據過濾出來,並發給上面的類來限制速度

#tc filter add dev eth0 parent 1: prio 1 protocol ip u32 match ip sport 80 0xfff flowid 1:1

說明:讓交互數據包保持較低的延遲時間,並最先取得空閒帶寬,比如:

ssh telnet dns quake3 irc ftp控制 smtp命令和帶有SYN標記的數據包,都應屬於這一類。為了保證上行數據流不會傷害下行流,還要把ACK數據包排在隊列前面,因為下行數據的ACK必須同上行流進行竟爭。

TC+IPTABLES+HTB+SFQ

1 tcp/ip 協議規定每個封包都需要有ACKNOWLEDGE訊息的回傳,也就是說,傳輸的資料需要有一個收到資料的訊息回復,才能決定後面的傳輸速度,並決定是否重 新傳輸遺失的資料,上行的帶寬一部分就是用來傳輸這些ACK資料的.上行帶寬占用大的時候,就會影響ACK資料的傳送速度,進而影響到下載速度,

2 試驗證明,當上傳滿載時,下載速度變為原來速度的40%,甚至更低,,因為上載文件(包括ftp上傳,發郵件SMTP),如果較大,一個的通訊量令帶寬超 向包和,那麼所有的數據包按照先進先出的原則進行排隊和等待,這就可以解釋為什麼網內其中有人用ftp上載文件或發送大郵件的時候,整個網速變得很慢的原 因.

解決速度之道:

為了解決這些速度問題,對經過線路的數據進行了有規則的分流.把本來在寬帶上的瓶頸轉移到我們的LINUX路由器上,可以把帶寬控制的比我們購買的帶寬小一點. 這樣,我們就可以方便的用tc技術對經過的數據進行分流與控制.

我們的想像就像馬路上的車道一樣,有高速道,還有小車道,大車道,需要高速的syn ack icmp ssh等走高速道,需要大量傳輸的ftp-data,smtp等走大車道,不能讓它堵塞整條馬路,各行其道.

linux下的TC(traffic control)就有這樣的作用,只要控制得當,一定會有明顯的效果。tc 和iptables結合是最好的方法.

我們設置過濾器以便用iptables對數據包進行分類,因為iptables更靈活,而且還可以為每個規則設置計數器,iptables用 mangle鏈來mark數據包,告訴了內核,數據包會有一個特定的FWMARK標記值(handle x fw) 表明它應該送給那個類(classid x:x),而prio是優先值,表明那些重要數據應該優先通過那個通道,首先選擇隊列(選擇htb),

一般系統默認的是fifo的先進先出隊列,就是說包是按照先來先處理的原則,如果有一個大的數據包在前面,那麼後面的包只能等前面的發完後才能接著發了,這樣就算後面既使是一個小小的ack包,也要等待了,這樣上傳就影響了下載,就算你有很大的下載帶寬也無能為力.

HTB(Hierarchical token bucket,分層的令牌桶),就像CBQ一樣工作,但是並不靠計算閒置時間來整形,它是一個分類的令牌桶過濾器.,它只有很少的參數.

結構簡圖: 1:

   ~~~~~~~~~~~~~~~~`~~~~~

  ~_________1:1~~~~~~~~~1:2________

  |~~~|~~~~|~~~~|~~~~~|~~~~~~~~|~~~~~~~~|~~~~~~~|

  1:11~~~1:12~~~~~~~~~~~~1:21~~~1:22~~~1:23~~1:24

  優先順序: 1:11 1:12 1:21 1:22 1:23 1:24

  根據上面的例子,開始腳本:

參數的說明:

  rate:是一個類保證得到的帶寬值,如果有不只一個類,請保證所有子類總和是小於或等於父類,

  ceil: ceil是一個類最大能得到帶寬值.

  prio: 是優先權的設置,數值越大,優先權越小,如果是分配剩余帶寬,就是數值小的會最優先取得剩余的空閒的帶寬權.

  一般大數據的話,控制在50%-80%左右吧,而ceil最大建議不超過85%,以免某一個會話占用過多的帶寬.

rate可按各類所需要分配:

 上行uplink 320K

  DEV="PPP0"

  UPLINK=300

  DOWNLINK=1500 下行downlink 3200K大概一半左右,以便能夠得到更多的關發連接.

  

1 增加一個根隊列,沒有進行分類的數據包都走這個1:24是缺省類:

  tc qdisc add dev $DEV parent 1: htb default 24

1.1 增加一個根隊下面主class1: 速率為300k

tc cladd add dev $DEV parent 1: classid 1:1 htb rate 300kbit ceil 300kbit prio 0

1.1.1 在主干類1下建立第一葉子類,這是一個最高優先權的類,需要高優先和高速的包走這條通道,比如SYN ACK ICMP等.

  tc class add dev $DEV parent 1:1 classid 1:11 htb rate 300kbit ceil 300kbit prio 1

  1:11是很小而且最重要的數據包通道,當然要多分點,甚至必要時先全部占用,不過一般不會的,所以給全速.

1.1.2 在主類1下建立第二葉子類,這是一個次高優先權的類,比如我們重要的CRM數據。

  tc class add dev $DEV parent 1:1 classid 1:12 htb rate 300-150kbit ceil 300-50kbit prio 2  

1:12是很重要的數據道,給多點,最少給一半,但需要時可以再多一點

 

rate規劃 1:2=1:21 +1:22 +1:23 +1:24 一般總在50%-80%左右.

1.2 在根類下建立次干類 classid 1:2 ,此次干類的下面全部優先權低於主干類,以防重要數據堵塞。

  tc class add dev $DEV parent 1: classid 1:2 htb rate 300-150kbit prio 3

1.2.1 在次干類下建立第一葉子類,可以跑例如http ,pop等。

  tc class add dev $DEV parent 1:2 classid 1:21 htb rate 100kbit ceil 300-150kbit prio 4

1:21 http,pop是最常用的啦,為了太多人用,而導致堵塞,我們不能給得太多,也不能太少.

1.2.2 在次干類下建立第二葉子類,不要太高的速度,以防發大的附件大量占用帶寬,便如smtp等。

  tc class add dev $DEV parent 1:2 classid 1:22 htb rate 30kbit ceil 300-160kbit prio

1:22 我打算給smtp用,優先低於1:21,以防發大的附件大量占用帶寬.

1.2.3 在次干類下建立第三葉子類,不要太高的帶寬,以防大量的數據堵塞網絡,例如:ftp-data.

  tc class add dev $DEV parent 1:2 classid 1:23 htb rate 15kbit ceil 300-170kbit prio 6

  1:23 我打算給ftp-data,和1:22一樣,很可能大量上傳文件,所以,rate不能給的太多,而當其他有剩時可以給大些,ceil設置大些.

1.2.4 在次干類下建立第四葉子類。無所謂的數據通道,無需要太多的帶寬,以防無所謂的人在阻礙正務。

  tc class add dev $DEV parent 1:2 classid 1:24 htb rate 5kbit ceil 300-250kbit prio 7

  1:24 是無所謂通道,就是一般不是我們平時工作上需要的通道,給小點防止這些人妨礙有正常工作需要的人.

在每個類下面再附加上另一個隊列規定,隨機公平隊列(SFQ),不被某個連接不停占用帶寬,以保證帶寬的平均公平使用。

  #SFQ(stochastic fairness queueing 隨機公平隊列),SFQ的關鍵詞是“會話”(或稱作流),主要針對一個TCP會話或者UDP流,流量被分成相當多數量的FIFO隊列中,每個隊列對應一個會話。

  數據按照簡單輪轉的方式發送,每個會話都按順序得到發送機會。這種方式非常公平,保證了每個會話都不會被其它會話所淹沒,SFQ之所以被稱為“隨機”,是因為它並不是真的為每個會話創建一個隊列,而是使用一個散列算法,把所有的會話映射到有限的幾個隊列中去。

  #參數perturb([pe`taib]使某人煩惱)是多少秒後重新配置一次散列算法,默認為10秒.

  tc qdisc add dev $DEV parent 1:11 handle 111: sfq perturb 5

  tc qidsc add dev $DEV parent 1:12 handle 112: sfq perturb 5

  tc qdisc add dev $DEV parent 1:21 handle 121: sfq perturb 10

  tc qidsc add dev $DEV parent 1:22 handle 122: sfq perturb 10

  tc qidsc add dev $DEV parent 1:23 handle 123: sfq perturb 10

  tc qidsc add dev $DEV parent 1:24 handle 124: sfq perturb 10

  設置過濾器,handle是iptables作mark的值,讓被iptables在mangle鏈做了mark的不同的值選擇不同的通道classid,而prio是過濾器的優先級別

tc filter add dev $DEV parent 1:0 protocol ip prio 1 handle 1 fw classid 1:11

  tc filter add dev $DEV parent 1:0 protocol ip prio 2 handle 2 fw classid 1:12

  tc filter add dev $DEV parent 1:0 protocol ip prio 3 handle 3 fw classid 1:21

  tc filter add dev $DEV parent 1:0 protocol ip prio 4 handle 4 fw classid 1:22

  tc filter add dev $DEV parent 1:0 protocol ip prio 5 handle 5 fw classid 1:23

  tc filter add dev $DEV parent 1:0 protocol ip prio 6 handle 6 fw classid 1:24

  ####################################################################################

下行的限制:

  # 設置入隊的規則,是因為把一些經常會造成下載大文件的端口進行控制,不讓他們來得太快,導致堵塞,來得太快,就直接drop,就不會浪費和占用機器時間和力量去處理了.

  1 把下行速率控制在大概1000-1500K(大約為帶寬的50%),因為這個速度已經夠用了,以便能夠得到更多的並發下載連接.

#tc qdisc add dev $DEV handle ffff: ingress

#tc filter add dev $DEV parent ffff: protocol ip prio 50 handle 8 fw police rate ${downlink}kbit burst 10k drop flowid :8

  如果內部網數據流不是很瘋狂的話,就不用做下載的限制了,用#符號屏蔽上面兩行既可.

  如果要對任何進來的數據進行限速的話,可以用下面這句.

  tc filter add dev $DEV parent ffff : protocol ip prio 10 u32 match ip src 0.0.0.0/0 police rate ${downlink}kbit burst 10k drop flowid :1

  ################################

開始給數據包打標記:

  把出去的不同類數據包(為dport)���mark上標記1---6,讓它走不同的通道.

  把進來的數據包(為sport)給mark上標記8,讓它受到下行的限制,以免速度太快而影響全局.

  每條規則下跟著return的意思是可以通過RETURN方法避免遍歷所有的規則,加快了處理速度.

  設置TOS的處理:

iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay(最小延時) -j MARK --set-mark 1

iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j RETURN

iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost(最小成本) -j MARK --set-mark 4

iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j RETURN

iptables -t mangle -A PREROUTING -m tos --tos Maximize-Throughput(最大吞吐量) -j MARK --set-mark 5

iptables -t mangle -A PREROUTING -m tos --tos Maximize-Througput -j RETURN

##提高TCP初始連接(也就是帶有SYN的數據包)的優先權是非常明智的.

iptables -t mangle -A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 1

iptables -t mangle -A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN

#想ICMP 想ping有良好的反應,放在第一類。

iptables -t mangle -A PREROUTING -p icmp -j MARK --set-mark 1

iptables -t mangle -A PREROUTING -P icmp -j RETURN

#small packets (probably just ACKS)長度小於64的小包通常是需要快些的,一般是用來確認tcp的連接的,讓它跟快些的通道吧。

iptables -t mangle -A PREROUTING -p tcp -m length --length :64 -j MARK --set-mark 2

iptables -t mangle -A PREROUTING -p tcp -m length --length:64 -j RETURN

#ftp放第二類,因為一般是小包,ftp-data放在第5類,因為一般是大時數據的傳送。

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport ftp -j MARK --set-mark 2

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport ftp -j RETURN

  iptables -t mangle -A PRETOUTING -p tcp -m tcp --dport ftp-data -j MARK --set-mark 5

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport -j RETURN

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport ftp -j MARK --set-mark 8

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport ftp -j RETURN

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport ftp-data -j MARK --set-mark 8

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport ftp-data -j RETURN

  ###提高SSH數據包的優先權:放在第1類,要知道SSH是交互式的和重要的,不容待慢:

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 22 -j MARK --set-mark 1

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport -j RETURN

  ##SMTP郵件,放在第4類,因為有時有人發送很大的郵件,為避免它堵塞,讓它跑第4道吧

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 25 -j MARK --st-mark 4

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 25 -j RETURN

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 25 -j MARK --set-mark 8

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 25 -j RETURN

  ##name-domain server:放在第1類,這樣連接帶有域名的連接才能快速找到對應有的地址,提高速度

  iptables -t mangle -A PREROUTING -p udp -m udp --dport 53 -j MARK --set-mark 1

  iptables -t mangle -A PREROUTING -P udp -m udp --dport 53 -j RETURN

  ###HTTP: 放在第3類,是最常用的,最多人用的

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 80 -j MARK --set-mark 3

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 80 -j RETURN

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 80 -j MARK --set-mark 8

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 80 -j RETURN

  ###pop郵件放在第3類:

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 110 -j MARK --set-mark 3

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dprot 110 -j RETURN

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 110 -j MARK --set-mark 8

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 110 -j RETURN

  ###MICSOSOFT-SQL-SERVE:放在第2類,我這裡認為較重要,一定保證速度和優先的

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 1433 -j MARK --set-mark 3

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 1433 -j RETURN

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 1433 -j MARK --set-mark 8

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 1433 -j RETURN

##https:放在第3類

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 443 -j MARK --set-mark 3

  iptables -t mangle -A PREROUTING -p tcpm -m tcp --dport 443 -j RETURN

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 443 -j MAKR --set-mark 8

  iptables -t mangle -A PREROUTING -P tcp -m tcp --sport 443 -j RETURN

  ###voip用,提高,語音要保持高速才不會斷續

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 1720 -j MARK--SET-MARK 1

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 1720 -j RETURN

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 1720 -j MAKR --set-mark 8

  iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 1720 -j RETURN

  ###VPN 用作voip的,也要走高速路,才不會斷續

  iptables -t mangle -A PREROUTING -p udp -m udp --dport 7707 -j MARK --set-mark 1

  iptables -t mangle -A PREROUTING -p udp -m udp --dport 7707 -j RETURN

  ###放在第1類,因為我覺得客觀存在要我心中很重要,優行:

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 7070 -j MARK --set-mark 1

  iptables -t mangle -A PREROUTING -p tcp -m tcp --dport -j RETURN

  ##提高本地數據包的優先權:放在第1類

  iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 22 -j MARK --set-mark 1

  iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 22 -j RETURN

  iptables -t mangle -A OUTPUT -p icmp -j MARK --set-mark 1

  iptables -t mangle -A OUTPUT -p icmp -j RETURN

  ###本地small packet (probably just ACKS)

  iptables -t mangle -A OUTPUT -p tcp -m length --length :64 --set-mark 2

  iptables -t mangle -A OUTPUT -p tcp -m length --length :64 -j RETURN

  #################################################

  ## 向PRETOUTRIN中添加完mangle規則後,用這條規則結束prerouting表:也就是說前面沒有打過標記的數據包就交給1:24來處理實際 上是不必要的,因為1:24是缺省類,但仍然打上標記是為了保持整個設置的協調一致,而且這樣,還能看到規則的數據包計數:

  iptables -t mangle -A PREROUTING -i $DEV -j MARK --set-mark 6

  ###對某人限制:iptables -t mangle -I PREROUTING 1 -s 192.168.xx.xx -j MAKR --set-mark 6

  ###iptables -t mangle -I PREROUTING 2 -s 192.168.xx.xx -j RETURN

  ###################################################

  u32的應用:

tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 ...... 這就是所謂的u32匹配,可以匹配數據包的任意部分.

根據源/目的地址:

match ip src 0.0.0.0/0  

match ip dst 1.2.3.0/24  

單個IP地址可以用/32來表示

根據源/目的端口可以這樣表示:

match ip sport 80 0xffff  

match ip dport 80 0xffff

根據IP協議:

match ip protocol (udp tcp icmp gre ipsec)

比如icmp協議是1 match ip protocol 1 0xff

舉例:

tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 match ip dst 4.3.2.1/32 flowid 10:1

tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 match ip src 4.3.2.1/32 match ip sport 80 0xffff flowid 10:1

Copyright © Linux教程網 All Rights Reserved