IMQ 是中介隊列設備的簡稱,是一個虛擬的網卡設備,與物理網卡不同的是,通過它可以進行全局的流量整形,不需要一個網卡一個網卡地限速。這對有多個ISP接入的情況特別方便。配合 Iptables,可以非常方便地進行上傳和下載限速。
一、網絡環境簡介目的站點 (Internet)
IP: 218.x.x.x (用 TARGET_IP 表示)
路由器 (Router)
eth1_外網IP: 221.x.x.x (用INET_IP表示)
eth0_內網IP: 192.168.0.1 (用 GW_IP 表示)
內網客戶機 (PC)
IP: 192.168.0.2 (用 LAN_IP 表示)
二、數據包流程分析
要明白怎麼控制流量,在什麼地方控制,首先得弄清楚數據包從進網卡到出網卡這個過程中,內核對數據包做了哪些操作,具體可以看這裏的圖示:
http://www.docum.org/docum.org/kptd/
下面就客戶機上傳下載時,數據包的流程走向進行一些分析
下載流程
========
PC 向 Internet 發起數據下載請求
Internet 迴應相應數據
數據包通過 eth1 流入 Router [src: TARGET_IP, dst: INET_IP]
Router 重寫目的地址(DNAT) [src:TARGET_IP, dst: LAN_IP]
轉發到局域網網卡 eth0
通過 eth0 流出 Router, 進入局域網
PC 接收到數據
顯然,要控制 PC 的下載速率,在 DNAT 之後可以做到
小結: 下載控制, 控制外網向客戶機發送數據的速率
(在 DNAT之後, iptables 的 POSTROUTING 鏈)
上傳流程
========
Internet 向 PC 發起數據上傳請求
PC 迴應相應數據
數據包通過 eth0 流入 Router [src: LAN_IP, dst: TARGET_IP]
Router 重寫源標地址(SNAT) [src:INET_IP, dst: TARGET_IP]
轉發到廣域網網卡 eth1
通過 eth1 流出 Router, 進入 Internet
Internet 接收到數據
顯然,要控制 PC 的上傳速率,在 SNAT 之前可以做到
小結: 上傳控制, 控制客戶機向外網發送數據的速率
(在 SNAT之前, iptables 的 PREROUTING 鏈)
三、讓Linux支持 IMQ
Linux 內核以及 Iptables 並不直接支持 IMQ, 需要打補丁纔行.
我用的是 linux-2.6.18, iptables-1.3.6,可以從 http://www.linuximq.net/
或 http://www.digriz.org.uk/jdg-qos-script/ 下載到
打補丁的過程就不多說了....
內核支持 IMQ 後,通過 ip link show 可以看到有 imq0 這樣的設備
(有多少個取決於你編譯內核時的配置,默認有2個)
四、配合 Iptables 限速
假設 imq0 用於下載限速,imq1 用於上傳限速, 先設置好 imq 設備的隊列規定、過濾器之類的,如同真實網卡一樣
IMQ 規則定義好後,只需在 iptables 的 mangle 鏈中加入2條規則即可:
#### 下載限速, 出口 eth0
iptables -t mangle -A POSTROUTING -o eth0 -j IMQ --todev 0
#### 上傳限速,入口 eth0
iptables -t mangle -A PREROUTING -i eth0 -j IMQ --todev 1
五、單機限速
下載限速: 判斷數據包的目的 IP
上傳限速: 判斷數據包的來源 IP
提示: 由於上傳限速流控點是在 SNAT 之前,那是數據包裏面還含有局域網IP的信息,故可以直接根據IP源信息來定位,無需再通過 iptables 做 MARK.
TC 例子:
### 限制 192.168.0.2 下載 100K,最大 120K
tc class add dev imq0 parent 1:1 classid 1:10 htb \
rate 100kbps ceil 120kbps burst 10kb prio 2
tc qdisc add dev imq0 parent 1:10 handle 10 sfq perturb 10
tc filter add dev imq0 protocol ip parent 1:0 prio 100 u32 \
match ip dst 192.168.0.2 classid 1:10
### 限制 192.168.0.2 上傳 40K,最大 50K
tc class add dev imq1 parent 1:1 classid 1:10 htb \
rate 40kbps ceil 50kbps burst 10kb prio 2
tc qdisc add dev imq1 parent 1:10 handle 10 sfq perturb 10
tc filter add dev imq1 protocol ip parent 1:0 prio 100 u32 \
match ip src 192.168.0.2 classid 1:10