講了filter、ct、nat 現在剩下最後一個知名模組mangle,但是自身雖然知道核心支援修改資料包的資訊,它主要用在策略路由和qos上.我們就具體分析一下.
mangle表主要用於修改資料包的TOS(Type Of Service,服務型別)、TTL(Time To Live,生存週期)指以及為資料包設定Mark標記,以實現Qos(Quality Of Service,服務質量)調整以及策略路由等應用,由於需要相應的路由裝置支援,因此應用並不廣泛
關於mangle模組,核心裡主要有三個功能模組: mark match、MARK target 、CONNMARK target。
1)CONNMARK target的選項
選項 功能
–set-mark value[/mask] 給連結跟蹤記錄打標記。
–save-mark [–mask mask] 將資料包上的標記值記錄到連結跟蹤記錄上。
–restore-mark [–mask mask] 重新設定資料包的nfmark值。
2)MARK target 的選項
選項 功能
–set-mark value 設定資料包的nfmark值。
–and-mark value 資料包的nfmark值和value進行按位與運算。
–or-mark value 資料包的nfmark值和value進行按或與運算。
3)MARK match的選項
選項 功能
[!] –mark value[/mask] 資料包的nfmark值與value進行匹配,其中mask的值為可選的
先說說CONNMARK和MARK的區別:
同樣是打標記,但CONNMARK是針對連線的,而MARK是針對單一資料包的
這兩種機制一般都要和ip rule中的fwmark聯用,實現對滿足某一類條件的資料包的策略路由
1.對連線打了標記,只是標記了連線,沒有標記連線中的每個資料包。標記單個資料包,也不會對整條連線的標記有影響。二者是相對獨立的
2. 路由判定(routing decision)是以單一資料包為單位的。或者說,在netfilter框架之外,並沒有連線標記的概念。或者說,ip命令只知道MARK, 而不知道CONNMARK是什麼。
3.關鍵在於:給所有要進行ip rule匹配的單一資料包打上標記。方法一般有二:用MARK直接打,或者用CONNMARK –restore-mark把打在連線上的標記轉移到資料包上。
下面就程式碼分析一下:
mangle它的模組程式碼在iptable_mangle.c中它的初始化工作和之前的filter、nat類似.Mangle作用在所有的hook點
1.首先iptable_mangle.c的主要工作就是註冊和初始化mangle表
註冊mangl鉤子函式.
2.其實我們發現除了ct的hook是單獨處理外,其他的filter、nat、mangle都是通過hook之後呼叫ipt_do_table來處理,要麼重點在match裡,要麼重點在target處理中.但是這個基本機制框架沒變. 即都是通過rules.
3.首先我們就看看 –j MARK –set-mark 1 這個target的執行
4.其實應該分析下規則的下發.
先看一條命令:
#iptables -t mangle -A PREROUTING -i eth0 -p tcp –dport 80 -j MARK –set-mark 1
即target MARK
核心裡是這樣的
1 2 3 4 5 6 7 8 |
static unsigned int mark_tg(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_mark_tginfo2 *info = par->targinfo; skb->mark = (skb->mark & ~info->mask) ^ info->mark; return XT_CONTINUE; } |
它就是設定了skb->mark而已,並沒有改變報文內容.
我們看看具體命令怎麼配置:
mark match:它依賴MARK target 先設定標記
#iptables -A POSTROUTING -t mangle -m mark ! –mark 0 -j ACCEPT
MARK target:
iptables -t mangle -A PREROUTING -i eth0 -p tcp –dport 80 -j MARK –set-mark 1
CONNMARK target:
#iptables -A POSTROUTING -t mangle -j CONNMARK –save-mark
然後我們看看幾種應用場景:
1. 策略路由
現要求對內網進行策略路由,所有通過TCP協議訪問80埠的資料包都從ChinaNet線路出去,而所有訪問UDP協議53號埠的資料包都從Cernet線路出去
打標記:
1 2 |
iptables -t mangle -A PREROUTING -i eth0 -p tcp --dport 80 -j MARK --set-mark 1 iptables -t mangle -A PREROUTING -i eth0 -p udp --dprot 53 -j MARK --set-mark 2 |
建表:
1 2 |
ip rule add from all fwmark 1 table 10 ip rule add from all fwmark 2 table 20 |
策略路由:
1 2 |
ip route add default via 10.10.1.1 dev eth1 table 10 ip route add default via 10.10.2.1 dev eth2 table 20 |
2. CONNMARK和MARK結合:
1 2 3 4 5 6 |
1.iptables -A POSTROUTING -t mangle -j CONNMARK --restore-mark 2.iptables -A POSTROUTING -t mangle -m mark ! --mark 0 -j ACCEPT 3.iptables -A POSTROUTING -m mark --mark 0 -p tcp --dport 21 -t mangle -j MARK --set-mark 1 4.iptables -A POSTROUTING -m mark --mark 0 -p tcp --dport 80 -t mangle -j MARK --set-mark 2 5.iptables -A POSTROUTING -m mark --mark 0 -t mangle -p tcp -j MARK --set-mark 3 6.iptables -A POSTROUTING -t mangle -j CONNMARK --save-mark |
1)第1條規則就是完成了將連結跟蹤上的標記記錄到該連線上的每一個資料包中;
2)第2條規則判斷資料包的標記,如果不為0,則直接ACCEPT。如果資料包上沒有被打標記,則交由後面的規則進行匹配並打標記。這裡為什麼會出現經過了CONNMARK模組,資料包仍未被打標記呢?可以想到,如果一條連結的第1個資料包經過第1條規則處理之後,由於ct->mark為0,所以其資料包的標記skb->nfmark應該仍舊為0,就需要進行後面規則的匹配。
3)第3~5條規則,則按照匹配選項對符合規則的資料包打上不同的標記
4)第6條規則,則是把之前打的標記資訊儲存到ct裡.
3.結合tc的應用:
1 2 |
#tc fi add dev eth0 parent 1: pref 1000 protocol ip handle 13 fw flowid 1:1 #iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST ACK -m length --length 40:60 -j MARK --set-mark 13 |
題外扯點其他東西:
mangle可以修改IP包頭的TTL值,修改ip報頭dscp值(QOS)
Iptables下MSS資料調整模組TCPMSS使用
比如說string模組其實挺強大的,本身已經支援過來報文data裡特徵碼,但是功能依然有缺陷所以才有了l7的外掛.
1 |
Iptables –A OUTPUT –m string –string “www.baidu.com” –algo bm –j DROP |
關於algo引數的查詢演算法 它在核心裡是通過textsearch_register註冊的
核心預設註冊了名字為fsm、bm 、kmp
簡單的就說這麼多,具體應用需求還需要我們自己去挖掘和開發.