2-iptables mangle 規則

QOS的整個流程是:根據各種條件,如IP地址,數據包大小,上行,下行,這個信息在iptables裏面都可以捕獲到。然在iptables根據這些規則設置對應的mark,設置完mark,tc規則規則裏面根據不同的mark執行不同的內容,如隊列分配,限制帶寬,流量分配算法。

0 數據流向

  • -i 指定數據包進入 PREROUTING、INPUT、FORWARD鏈時經由的接口。
  • -o 指定數據包出去 FORWARD、OUTPUT、POSTROUTING鏈時經由的接口。

當我們開啓防火牆功能後,報文需要經過的路徑是有區別的,如下圖所示:
image.png

報文的流向:

  • 到本機某進程的報文:PREROUTING–>INPUT
  • 由本機轉發的報文:PREROUTING–>FORWARD–>POSTROUTING
  • 由本機某進程發出的報文:OUTPUT–>POSTROUTING

對於QOS我們要做的是對轉發的包進行規則處理,而內部的包不應該進行干預,另外我們的功能需求有總規則跟設備規則,設備規則要在總規則之前設置,這樣才能符合總規則的要求。
根據上面的需求,所以將設備規則放在FORWARD裏面,總規則放在POSTROUTING裏面。

iptables的底層就是netfilter,根據不同的鏈在2、3、4層進行分佈着,如prerouting在判斷是否爲本機地址前面,所以應該是在第2層,在上面的iptables數據流程都走完後,會走到底層的TC規則再走一次TC規則的數據流

一個鏈ACCEPT後,跳出這個鏈,可是接下去的鏈還是會經過,接着匹配

1.鏈初始化(標準鏈關聯QOS鏈)

腳本啓動後會調用ipt_first_setup,將mangle表裏面關於QOS的信息全部清楚一邊(-F -X),然後重新創建新的規則鏈(-N),將新的規則鏈接到對應的標準鏈上(-g)。

mangle表的5個鏈PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING

ipt_first_setup() {
    ipt -t mangle -F QOS_MARK_${IFACE}
    ipt -t mangle -X QOS_MARK_${IFACE}
    ipt -t mangle -N QOS_MARK_${IFACE}

    ipt -t mangle -F QOS_MARK_FORWARD_${IFACE}
    ipt -t mangle -X QOS_MARK_FORWARD_${IFACE}
    ipt -t mangle -N QOS_MARK_FORWARD_${IFACE}

    ipt -t mangle -F QOS_OUTPUT_${IFACE}
    ipt -t mangle -X QOS_OUTPUT_${IFACE}
    ipt -t mangle -N QOS_OUTPUT_${IFACE}

    ipt -t mangle -F QOS_INPUT_${IFACE}
    ipt -t mangle -X QOS_INPUT_${IFACE}
    ipt -t mangle -N QOS_INPUT_${IFACE}

    ipt -t mangle -F QOS_RULES_${IFACE}
    ipt -t mangle -X QOS_RULES_${IFACE}
    ipt -t mangle -N QOS_RULES_${IFACE}

    ipt -t mangle -F QOS_RULES_FORWARD_${IFACE}
    ipt -t mangle -X QOS_RULES_FORWARD_${IFACE}
    ipt -t mangle -N QOS_RULES_FORWARD_${IFACE}

    ipt -t mangle -A POSTROUTING -o ${IFACE} -g QOS_MARK_${IFACE}
    ipt -t mangle -A FORWARD -o ${IFACE} -g QOS_MARK_FORWARD_${IFACE}
    ipt -t mangle -A OUTPUT -o ${IFACE} -g QOS_OUTPUT_${IFACE}
    ipt -t mangle -A INPUT -i ${IFACE} -g QOS_INPUT_${IFACE}

    ipt -t mangle -A QOS_OUTPUT_${IFACE} -j MARK --set-mark ${HFSC_NO_QOS_MARK}${IPT_MASK_STRING}
    ipt -t mangle -A QOS_INPUT_${IFACE} -j MARK --set-mark ${HFSC_NO_QOS_MARK}${IPT_MASK_STRING}

    # FORWARD use to match mac-source
    ipt -t mangle -A QOS_MARK_FORWARD_${IFACE} -j CONNMARK \
    --restore-mark --nfmask ${IPT_MASK} --ctmask ${IPT_MASK}
    ipt -t mangle -A QOS_MARK_FORWARD_${IFACE} -m mark --mark 0x0${IPT_MASK_STRING} \
    -j QOS_RULES_FORWARD_${IFACE}

    ipt -t mangle -A QOS_MARK_${IFACE} -j CONNMARK \
    --restore-mark --nfmask ${IPT_MASK} --ctmask ${IPT_MASK}
    ipt -t mangle -A QOS_MARK_${IFACE} -m mark --mark 0x0${IPT_MASK_STRING} \
    -j QOS_RULES_${IFACE}
    ...

2.QOS鏈信息

使用iptables -t mangle -nvL可以查看mangle表下面的規則:

默認的5條鏈如下,會關聯到對應的target下面:

root@zihome:~# iptables -t mangle -nvL
Chain PREROUTING (policy ACCEPT 43144 packets, 12M bytes)
 pkts bytes target     prot opt in     out     source               destination
43166   12M fwmark     all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain INPUT (policy ACCEPT 31953 packets, 11M bytes)
 pkts bytes target     prot opt in     out     source               destination
20362 9418K QOS_INPUT_eth1  all  --  eth1   *       0.0.0.0/0            0.0.0.0/0           [goto]

Chain FORWARD (policy ACCEPT 12502 packets, 1631K bytes)
 pkts bytes target     prot opt in     out     source               destination
12505 1632K mssfix     all  --  *      *       0.0.0.0/0            0.0.0.0/0
 7990  568K QOS_MARK_FORWARD_eth1  all  --  *      eth1    0.0.0.0/0            0.0.0.0/0           [goto]

Chain OUTPUT (policy ACCEPT 33467 packets, 5201K bytes)
 pkts bytes target     prot opt in     out     source               destination
21999 2684K QOS_OUTPUT_eth1  all  --  *      eth1    0.0.0.0/0            0.0.0.0/0           [goto]

Chain POSTROUTING (policy ACCEPT 50234 packets, 7754K bytes)
 pkts bytes target     prot opt in     out     source               destination
31325 3361K QOS_MARK_eth1  all  --  *      eth1    0.0.0.0/0            0.0.0.0/0           [goto]

2.1 PREROUTING鏈關聯的target:
Chain PREROUTING (policy ACCEPT 43144 packets, 12M bytes)
 pkts bytes target     prot opt in     out     source               destination
43166   12M fwmark     all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain fwmark (1 references)
 pkts bytes target     prot opt in     out     source               destination

對於PREROUTING的數據都不做處理,該怎樣就怎樣。

2.2 INPUT鏈關聯的target:
Chain INPUT (policy ACCEPT 31953 packets, 11M bytes)
 pkts bytes target     prot opt in     out     source               destination
20362 9418K QOS_INPUT_eth1  all  --  eth1   *       0.0.0.0/0            0.0.0.0/0           [goto]

Chain QOS_INPUT_eth1 (1 references)
 pkts bytes target     prot opt in     out     source               destination
20362 9418K MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MARK xset 0xff/0xfffff

對於從eth1進來給內部進程的數據,全部goto到QOS_INPUT_eth1規則,改規則將進來的包都設置成0xff/0xfffff標記。

在tc規則裏面,0xff走no qos隊列,不做QOS處理。

2.3 OUTPUT鏈關聯的target:
Chain OUTPUT (policy ACCEPT 33467 packets, 5201K bytes)
 pkts bytes target     prot opt in     out     source               destination
21999 2684K QOS_OUTPUT_eth1  all  --  *      eth1    0.0.0.0/0            0.0.0.0/0           [goto]

Chain QOS_OUTPUT_eth1 (1 references)
 pkts bytes target     prot opt in     out     source               destination
21999 2684K MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MARK xset 0xff/0xfffff

對於從內部進程發生到eth1的數據,全部goto到QOS_OUTPUT_eth1規則,改規則將進來的包都設置成0xff/0xfffff標記。

在tc規則裏面,0xff走no qos隊列,不做QOS處理。

2.4 FORWARD鏈關聯的target:

FORWARD鏈屬於轉發規則,在POSTROUTING之前,所以用來限制設備終端的QOS,設置完了,再走POSTROUTING進行全局的校驗。

Chain FORWARD (policy ACCEPT 12502 packets, 1631K bytes)
 pkts bytes target     prot opt in     out     source               destination
12505 1632K mssfix     all  --  *      *       0.0.0.0/0            0.0.0.0/0
 7990  568K QOS_MARK_FORWARD_eth1  all  --  *      eth1    0.0.0.0/0            0.0.0.0/0           [goto]
 

如通過LAN口的PC要訪問外網的IP,那就是要通過eht1端口轉發的數據,所以要走QOS_MARK_FORWARD_eth1規則。

Chain mssfix (1 references)
 pkts bytes target     prot opt in     out     source               destination
 1896 98680 TCPMSS     tcp  --  *      eth1    0.0.0.0/0            0.0.0.0/0            tcp flags:0x06/0x02 /* wan (mtu_fix) */ TCPMSS clamp to PMTU
 
Chain QOS_MARK_FORWARD_eth1 (1 references)
 pkts bytes target     prot opt in     out     source               destination
 5123  670K ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            state NEW
 2886  152K ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            state NEW
    0     0 MARK       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x07/0x07 MARK xset 0xff/0xfffff
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0xff/0xfffff
18275 1140K CONNMARK   all  --  *      *       0.0.0.0/0            0.0.0.0/0            CONNMARK restore mask 0xfffff
 2972  238K QOS_RULES_FORWARD_eth1  all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0xfffff


Chain QOS_RULES_FORWARD_eth1 (1 references)
 pkts bytes target     prot opt in     out     source               destination
 3080  324K MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MAC 14:75:90:F7:97:7D MARK xset 0x101/0xfffff
 3177  329K CONNMARK   all  --  *      *       0.0.0.0/0            0.0.0.0/0            CONNMARK save mask 0xfffff

進入QOS_MARK_FORWARD_eth1規則後,可以看到前面有幾個ACCEPT的target,如果target爲ACCEPT則說明符合這個要求後,就跳出去,停止對下面規則的執行。

image.png

所以這邊代表,如果爲NEW的狀態,即新建立的鏈接則不需要再匹配qos規則了,會保存在skb數據表裏面,然後tc規則去匹配skb數據規則進行對應mark的執行。

下面的對於匹配到SYN的同步信息,則設置了MARK爲0xff/0xfffff,下一跳規則就馬上匹配到這個規則的時候就ACCEPT,進入到TC隊列的時候,進入no qos隊列。

再下面就爲CONNMARK,其實有點不一樣,這個是要經過重定向的,connmark最後save的時候會轉換成上面mark的形式,及轉成skb數據,再由tc規則去匹配。

所以CONNMARK要有初始化restore,要有保存save,最後redirect成skb。

先將mark restore,然後去匹配QOS_RULES_FORWARD_eth1裏面的規則,如匹配到mac地址爲14:75:90:F7:97:7D的數據,則set mark爲 0x101/0xfffff,然後再save mask,最後在tc裏面就可以匹配到該mark去執行對應的限速規則。

2.5 POSTROUTING鏈關聯的target:

POSTROUTING鏈屬於總規則,所以用來限制zqos_rule的條目

Chain POSTROUTING (policy ACCEPT 50234 packets, 7754K bytes)
 pkts bytes target     prot opt in     out     source               destination
31325 3361K QOS_MARK_eth1  all  --  *      eth1    0.0.0.0/0            0.0.0.0/0           [goto]

如通過LAN口的PC要訪問外網的IP,那就是要通過eht1端口轉發後,經過FORWARD,最終還是要走POSTROUTING規則,所以都是經過QOS_MARK_eth1規則。

Chain QOS_MARK_eth1 (1 references)
 pkts bytes target     prot opt in     out     source               destination
12540 1253K ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            state NEW
 5732  323K ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            state NEW
    0     0 MARK       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x07/0x07 MARK xset 0xff/0xfffff
32810 4403K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0xff/0xfffff
18275 1140K CONNMARK   all  --  *      *       0.0.0.0/0            0.0.0.0/0            CONNMARK restore mask 0xfffff
 2972  238K QOS_RULES_eth1  all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0xfffff
 
 
Chain QOS_RULES_eth1 (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 MARK       udp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 53,67,68 MARK xset 0xff/0xfffff
 2690  108K MARK       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:!0x17/0x02 multiport sports 0:65535 multiport dports 0:65535 length 0:100 MARK xset 0x22/0xfffff
   11   597 MARK       udp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport sports 0:65535 multiport dports 0:65535 length 0:100 MARK xset 0x22/0xfffff
 2909  233K MARK       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:!0x17/0x02 multiport sports 0:65535 multiport dports 25,80,443 MARK xset 0x33/0xfffff
   12  1975 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x0/0xfffff MARK xset 0x44/0xfffff
 2972  238K CONNMARK   all  --  *      *       0.0.0.0/0            0.0.0.0/0            CONNMARK save mask 0xfffff

進入QOS_MARK_eth1規則後,先將mark restore,然後去匹配QOS_RULES_eth1裏面的規則,如匹配到mac地址爲14:75:90:F7:97:7D的數據,則set mark爲 0x101/0xfffff,然後再save mask,最後在tc裏面就可以匹配到該mark去執行對應的限速規則。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章