LInux 的流量限制
一、相關概念
報文分組從輸入網卡(入口)接收進來,經過路由的查找, 以確定是發給本機的,還是需要轉發的。如果是發給本機的,就直接向上遞交給上層的協議,比如TCP,如果是轉發的, 則會從輸出網卡(出口)發出。網絡流量的控制通常發生在輸出網卡處。雖然在路由器的入口處也可以進行流量控制,Linux也具有相關的功能, 但一般說來, 由于我們無法控制自己網絡之外的設備, 入口處的流量控制相對較難。本文將集中介紹出口處的流量控制。流量控制的一個基本概念是隊列(Qdisc),每個網卡都與一個隊列(Qdisc)相聯系, 每當內核需要將報文分組從網卡發送出去, 都會首先將該報文分組添加到該網卡所配置的隊列中, 由該隊列決定報文分組的發送順序。
因此可以說,所有的流量控制都發生在隊列中,詳細流程圖見下圖。
二、TC原理介紹
????????Linux 操作系統中的流量控制器 TC(Traffic Control) 用于Linux內核的流量控制,它利用隊列規定建立處理數據包的隊列,并定義隊列中的數據包被發送的方式,從而實現對流量的控制。TC 模塊實現流量控制功能使用的隊列規定分為兩類,一類是無類隊列規定,另一類是分類隊列規定。無類隊列規定相對簡單,而分類隊列規定則引出了分類和過濾器等概念,使其流量控制功能增強。
????????無類隊列規定是對進入網絡設備(網卡)的數據流不加區分統一對待的隊列規定。使用無類隊列規定形成的隊列能夠接收數據包以及重新編排、延遲或丟棄數據包。這類隊列規定形成的隊列可以對整個網絡設備(網卡)的流量進行整形,但不能細分各種情況。常用的無類隊列規定主要有 pfifo_fast(先進先出)、TBF(令牌桶過濾器)、SFQ(隨機公平隊列)、ID(前向隨機丟包)等等。這類隊列規定使用的流量整形手段主要是排序、限速和丟包。
????????分類隊列規定是對進入網絡設備的數據包根據不同的需求以分類的方式區分對待的隊列規定。數據包進入一個分類的隊列后,它就需要被送到某一個類中,也就是說需要對數據包做分類處理。對數據包進行分類的工具是過濾器,過濾器會返回一個決定,隊列規定就根據這個決定把數據包送入相應的類進行排隊。每個子類都可以再次使用它們的過濾器進行進一步的分類。直到不需要進一步分類時,數據包才進入該類包含的隊列排隊。除了能夠包含其他隊列規定之外,絕大多數分類的隊列規定還能夠對流量進行整形。
二、規則
2.1 流量控制方式
流量控制包括以下幾種方式:
- SHAPING(限制): 當流量被限制,它的傳輸速率就被控制在某個值以下。限制值可以大大小于有效帶寬,這樣可以平滑突發數據流量,使網絡更為穩定。shaping(限制)只適用于向外的流量。
- SCHEDULING(調度): 通過調度數據包的傳輸,可以在帶寬范圍內,按優先級分配帶寬。SCHEDULING(調度)也只適于向外的流量。
- POLICING(策略): SHAPING用于處理向外的流量,而POLICIING(策略)用于處理接收到的數據。
- DROPPING(丟棄): 如果流量超過某個設定的帶寬,就丟棄數據包,不管是向內還是向外。
2.2 流量控制處理對象
流量的處理由三種對象控制,它們是:
- qdisc(排隊規則)
- class(類別)
- filter(過濾器)
2.2.1 qdisc(排隊規則)
QDisc(排隊規則)是queueing discipline的簡寫,它是理解流量控制(traffic control)的基礎。無論何時,內核如果需要通過某個網絡接口發送數據包,它都需要按照為這個接口配置的qdisc(排隊規則)把數據包加入隊列。然后,內核會盡可能多地從qdisc里面取出數據包,把它們交給網絡適配器驅動模塊。最簡單的QDisc是pfifo它不對進入的數據包做任何的處理,數據包采用先入先出的方式通過隊列。不過,它會保存網絡接口一時無法處理的數據包。 qdisc的類別如下:
- CLASSLESS QDisc(不可分類QDisc)
- [p|b]fifo: 使用最簡單的qdisc,純粹的先進先出。只有一個參數:limit,用來設置隊列的長度,pfifo是以數據包的個數為單位;bfifo是以字節數為單位。
- pfifo_fast: 在編譯內核時,如果打開了高級路由器(Advanced Router)編譯選項,pfifo_fast就是系統的標準QDISC。它的隊列包括三個波段(band)。在每個波段里面,使用先進先出規則。而三個波段(band)的優先級也不相同,band 0的優先級最高,band 2的最低。如果band0里面有數據包,系統就不會處理band 1里面的數據包,band 1和band 2之間也是一樣。數據包是按照服務類型(Type of Service,TOS)被分配多三個波段(band)里面的。
- red: red是Random Early Detection(隨機早期探測)的簡寫。如果使用這種QDISC,當帶寬的占用接近于規定的帶寬時,系統會隨機地丟棄一些數據包。它非常適合高帶寬應用。
- sfq: sfq是Stochastic Fairness Queueing的簡寫。它按照會話(session--對應于每個TCP連接或者UDP流)為流量進行排序,然后循環發送每個會話的數據包。
- tbf: tbf是Token Bucket Filter的簡寫,適合于把流速降低到某個值。
- 不可分類qdisc配置: 如果沒有可分類QDisc,不可分類QDisc只能附屬于設備的根。它們的用法如下:
要刪除一個不可分類QDisc,需要使用如下命令:
tc qdisc del dev DEV root一個網絡接口上如果沒有設置QDisc,pfifo_fast就作為缺省的QDisc。
- CLASSFUL QDISC(分類QDisc): 可分類的qdisc包括:
- CBQ: CBQ是Class Based Queueing(基于類別排隊)的縮寫。它實現了一個豐富的連接共享類別結構,既有限制(shaping)帶寬的能力,也具有帶寬優先級管理的能力。帶寬限制是通過計算連接的空閑時間完成的。空閑時間的計算標準是數據包離隊事件的頻率和下層連接(數據鏈路層)的帶寬。
- HTB: HTB是Hierarchy Token Bucket的縮寫。通過在實踐基礎上的改進,它實現了一個豐富的連接共享類別體系。使用HTB可以很容易地保證每個類別的帶寬,它也允許特定的類可以突破帶寬上限,占用別的類的帶寬。HTB可以通過TBF(Token Bucket Filter)實現帶寬限制,也能夠劃分類別的優先級。
- PRIO: PRIO QDisc不能限制帶寬,因為屬于不同類別的數據包是順序離隊的。使用PRIO QDisc可以很容易對流量進行優先級管理,只有屬于高優先級類別的數據包全部發送完畢,才會發送屬于低優先級類別的數據包。為了方便管理,需要使用iptables或者ipchains處理數據包的服務類型(Type Of Service,ToS)。
2.2.2 class(類)
某些QDisc(排隊規則)可以包含一些類別,不同的類別中可以包含更深入的QDisc(排隊規則),通過這些細分的QDisc還可以為進入的隊列的數據包排隊。通過設置各種類別數據包的離隊次序,QDisc可以為設置網絡數據流量的優先級。
2.2.3 filter(過濾器)
Filter(過濾器)用于為數據包分類,決定它們按照何種QDisc進入隊列。無論何時數據包進入一個劃分子類的類別中,都需要進行分類。分類的方法可以有多種,使用fileter(過濾器)就是其中之一。使用filter(過濾器)分類時,內核會調用附屬于這個類(class)的所有過濾器,直到返回一個判決。如果沒有判決返回,就作進一步的處理,而處理方式和QDISC有關。需要注意的是,filter(過濾器)是在QDisc內部,它們不能作為主體。
2.3 執行過程
類(Class)組成一個樹,每個類都只有一個父類,而一個類可以有多個子類。某些QDisc(例如:CBQ和HTB)允許在運行時動態添加類,而其它的QDisc(例如:PRIO)不允許動態建立類。允許動態添加類的QDisc可以有零個或者多個子類,由它們為數據包排隊。此外,每個類都有一個葉子QDisc,默認情況下,這個葉子QDisc使用pfifo的方式排隊,我們也可以使用其它類型的QDisc代替這個默認的QDisc。而且,這個葉子QDisc有可以分類,不過每個子類只能有一個葉子QDisc。 當一個數據包進入一個分類QDisc,它會被歸入某個子類。 我們可以使用以下三種方式為數據包歸類,不過不是所有的QDisc都能夠使用這三種方式:
- tc過濾器(tc filter): 如果過濾器附屬于一個類,相關的指令就會對它們進行查詢。過濾器能夠匹配數據包頭所有的域,也可以匹配由ipchains或者iptables做的標記。
- 服務類型(Type of Service): 某些QDisc有基于服務類型(Type of Service,ToS)的內置的規則為數據包分類。
- skb->priority: 用戶空間的應用程序可以使用SO_PRIORITY選項在skb->priority域設置一個類的ID。 樹的每個節點都可以有自己的過濾器,但是高層的過濾器也可以直接用于其子類。 如果數據包沒有被成功歸類,就會被排到這個類的葉子QDisc的隊中。相關細節在各個QDisc的手冊頁中。
2.4 命名規則
所有的QDisc、類和過濾器都有ID。ID可以手工設置,也可以有內核自動分配。ID由一個主序列號和一個從序列號組成,兩個數字用一個冒號分開。
- QDISC: 一個QDisc會被分配一個主序列號,叫做句柄(handle),然后把從序列號作為類的命名空間。句柄采用象10:一樣的表達方式。習慣上,需要為有子類的QDisc顯式地分配一個句柄。
- class: 在同一個QDisc里面的類分享這個QDisc的主序列號,但是每個類都有自己的從序列號,叫做類識別符(classid)。類識別符只與父QDisc有關,和父類無關。類的命名習慣和QDisc的相同。
- filter: 過濾器的ID有三部分,只有在對過濾器進行散列組織才會用到。詳情請參考tc-filters手冊頁。
2.5 單位
(注意:這里的字節單位的位,而我們平常看到的單位是字節,1字節=8位)
- 帶寬或流速單位:
-
kbps
千字節/s
mbps
兆字節/s
kbit
Kbit/s
mbit
Mbit/s
bps或者一個無單位數字
字節/s
- 數據數量單位:
-
kb或者k
千字節
mb或者m
兆字節
mbit
兆bit
kbit
千bit
b或者一個無單位數字
字節數
?
三、TC命令
????????tc可以使用以下命令對qdisc、類和過濾器進行操作:
????????add, 在一個節點里加入一個qdisc、類、或者過濾器。添加時,需要傳遞一個祖先作為參數,傳遞參數時既可以使用ID也跨越式直接傳遞設備的根。如果要建立一個qdisc或者過濾器,可以使用句柄(handle)來命名。如果要建立一個類,可以使用類識別符(classid)來命名。
????????remove, 刪除由某個句柄(handle)指定的qdisc,根qdisc(root)也可以刪除。被刪除qdisc上所有的子類以及附屬于各個類的過濾器都會被自動刪除。
?
????????change, 以替代的方式修改某些條目。除了句柄(handle)和祖先不能修改以外,change命令的語法和add命令相同。換句話說,change命令不能指定節點的位置。
?????????replace, 對一個現有節點進行近于原子操作的刪除/添加。如果節點不存在,這個命令就會建立節點。
????????link, 只適用于qdisc,替代一個現有的節點。????????tc命令的格式:???????
? ? ? ?
3.1 具體操作
?????????Linux流量控制主要分為建立隊列、建立分類和建立過濾器三個方面。
??????????基本實現步驟。
???????????????????1) 針對網絡物理設備(如以太網卡eth0)綁定一個隊列qdisc;
???????????????????2) 在該隊列上建立分類class;
???????????????????3) 為每一分類建立一個基于路由的過濾器filter;
???????????????????4) 最后與過濾器相配合,建立特定的路由表。
接下來具體為80,22端口設置限流:
1.使用命令ifconfig查看服務器上的網卡信息,比如網卡eth0是用來對外的網絡,也就是用戶通過該網卡連接到系統,那么我們就對這個網卡進行帶寬限制。
ifconfig
?
2.建立eth0隊列
tc qdisc add dev eth0 root handle 1: htb default 20
命令解釋:
add :表示要添加,
dev eth0 :表示要操作的網卡為eth0,
root :表示為網卡eth0添加的是一個根隊列,
handle 1: 表示隊列的句柄為1:,
htb :表示要添加的隊列為HTB隊列。
default 20: 是htb特有的隊列參數,意思是所有未分類的流量都將分配給類別1:20。
?
3.建立根分類
tc class add dev eth0 parent 1:0 classid 1:1 htb rate 3Mbit
命令解釋:
在隊列1:0上創建根分類1:1 限速,類別htb,限速3Mbit。
rate 3Mbit:表示系統將為該類別確保3Mbit的帶寬。
?
4.創建分類
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 2Mbit ceil 3Mbit
命令解釋:
以根分類1:1為父類創建分類1:11 ,限速 2Mbit ~3Mbit(htb可借用其它類帶寬)。
ceil 3Mbit:表示該類別的最高可占用帶寬為3mbit。
?
5.創建過濾器并制定handle
tc filter add dev eth0 parent 1:0 prio 1 protocol ip handle 11 fw flowid 1:11
prio 1:您可以設置額外的帶寬優先級,prio數值越低優先級越高。
protocol ip:表示該過濾器應該檢查報文分組的協議字段。
flowid 1:11: 表示將把該數據流分配給類別1:11。
?
6.使用iptable對端口綁定tc隊列
iptables -A OUTPUT -t mangle -p tcp --sport 80 -j MARK --set-mark 11
iptables -A OUTPUT -t mangle -p tcp --sport 22 -j MARK --set-mark 11
?
如果是對IP進行限流,則示例如下:?
tc filter add dev ens160 parent 1:0 protocol ip prio 10 ?u32 match ip dst 168.160.164.255 flowid 1:11
?
?
四、查看和刪除規則
1、 主要包括對現有隊列、分類、過濾器和路由狀況進行監視。
?顯示隊列的狀況 ? ?
## 詳細顯示指定設備(這里為eth0)的隊列狀況? ???tc -s qdisc ls dev eth0
## 詳細顯示指定設備(這里為eth0)的分類狀況 tc -s class ls dev eth0
## 顯示過濾器的狀況? tc -s filter ls dev eth0
2、刪除規則
1、刪除過濾器-路由映射??
ip route del ?192.168.5.100 dev ens33 via 192.168.5.250 realm 11
2、刪除過濾器
tc filter del dev eth0 parent 1:0 protocol ip prio 100 route to 10
3、刪除隊列?tc qdisc del dev eth0 root
?
總結
以上是生活随笔為你收集整理的LInux 的流量限制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA8 Swing 简单的桌面精灵(
- 下一篇: 设置InternetConnect的ht