前段時間學習了docker容器網(wǎng)絡中bridge模式,linux下端口轉(zhuǎn)發(fā)(iptables)和網(wǎng)絡命名空間ip netns中跨主機通信部分。這三個場景下都涉及到一個工具:iptables,這么強大的工具,竟然說不清楚。那么我們今天就搞個清楚搞個明白。
期望收獲:iptables是什么?為什么要引入iptables?同類工具還有哪些?iptables的架構?iptables的編寫說明及其注意事項
iptables是位于“用戶空間”的防火墻管理工具,用戶通過這個“工具”,將用戶的安全設定執(zhí)行到對應的“安全框架”中,這個“安全框架”就是位于“內(nèi)核空間”的實現(xiàn)了防火墻功能的netfilter。
iptables調(diào)用netfilter的接口來對存放在內(nèi)核內(nèi)存中的XXtables(netfilter的配置表)進行修改。這個XXtables由表tables、鏈chains、規(guī)則rules組成,iptables在應用層負責修改這個規(guī)則文件。類似的應用程序還有 firewalld 。
netfilter是按規(guī)則(rules)來處理數(shù)據(jù)包的,規(guī)則就是人為預先定義的“條條框框”,存儲在內(nèi)核空間的“信息包過濾表”中,規(guī)則需指定源地址、目的地址、傳輸協(xié)議(如ICMP、TCP、UDP)和服務類型(如FTP、HTTP、SMTP)等。netfilter安全框架中制定了數(shù)據(jù)包的5個回調(diào)函數(shù)(hook),分別是PRE_ROUTING、INPUT、OUTPUT、FORWARD、POST_ROUTING。
網(wǎng)口數(shù)據(jù)包由底層的網(wǎng)卡接收,通過數(shù)據(jù)鏈路層的解包之后(去除數(shù)據(jù)鏈路幀頭)到達網(wǎng)絡層,此時netfilter會主動調(diào)用回調(diào)函數(shù),根據(jù)規(guī)則所定義的方法,在數(shù)據(jù)包路由的時候改變它們的方向和內(nèi)容,最后轉(zhuǎn)發(fā)到待調(diào)用的系統(tǒng)。

netfilter涉及5種默認規(guī)則鏈的介紹
INPUT鏈:當接收到防火墻本機地址的數(shù)據(jù)包(入站)時,應用此鏈中的規(guī)則。
OUTPUT鏈:當防火墻本機向外發(fā)送數(shù)據(jù)包(出站)時,應用此鏈中的規(guī)則。
FORWARD鏈:當接收到需要通過防火墻發(fā)送給其他地址的數(shù)據(jù)包(轉(zhuǎn)發(fā))時,應用此鏈中的規(guī)則。
PREROUTING鏈:在對數(shù)據(jù)包作路由選擇之前,應用此鏈中的規(guī)則,如DNAT。
POSTROUTING鏈:在對數(shù)據(jù)包作路由選擇之后,應用此鏈中的規(guī)則,如SNAT。
其中INPUT、OUTPUT鏈更多的應用在“主機防火墻”中,主要針對服務器本機進出數(shù)據(jù)的安全控制;而FORWARD、PREROUTING、POSTROUTING鏈更多的應用在“網(wǎng)絡防火墻”中,特別是防火墻服務器作為網(wǎng)關使用時的情況。
Linux數(shù)據(jù)包路由原理(netfilter處理)

1) 當一個數(shù)據(jù)包進入網(wǎng)卡時,數(shù)據(jù)包首先進入PREROUTING鏈,在PREROUTING鏈中我們有機會修改數(shù)據(jù)包的DestIP(目的IP),然后內(nèi)核的”路由模塊”根據(jù)”數(shù)據(jù)包目的IP”以及”內(nèi)核中的路由表”判斷是否需要轉(zhuǎn)送出去(注意,這個時候數(shù)據(jù)包的DestIP有可能已經(jīng)被我們修改過了)
2) 如果數(shù)據(jù)包就是進入本機的(即數(shù)據(jù)包的目的IP是本機的網(wǎng)口IP),數(shù)據(jù)包就會沿著圖向下移動,到達INPUT鏈。數(shù)據(jù)包到達INPUT鏈后,任何進程都會-收到它
3) 本機上運行的程序也可以發(fā)送數(shù)據(jù)包,這些數(shù)據(jù)包經(jīng)過OUTPUT鏈,然后到達POSTROTING鏈輸出(注意,這個時候數(shù)據(jù)包的SrcIP有可能已經(jīng)被我們修改過了)
4) 如果數(shù)據(jù)包是要轉(zhuǎn)發(fā)出去的(即目的IP地址不再當前子網(wǎng)中),且內(nèi)核允許轉(zhuǎn)發(fā),數(shù)據(jù)包就會向右移動,經(jīng)過FORWARD鏈,然后到達POSTROUTING鏈輸出(選擇對應子網(wǎng)的網(wǎng)口發(fā)送出去)
上圖可以看到有4張表:filter、nat、mangle、raw。這4張是干嘛用的呢?
1) filter表主要用于對數(shù)據(jù)包進行過濾,根據(jù)具體的規(guī)則決定是否放行該數(shù)據(jù)包(DROP 、ACCEPT、REJECT、LOG)。filter 表對應的內(nèi)核模塊為iptable_filter,包含三個規(guī)則鏈:INPUT鏈、FORWARD鏈、OUTPUT鏈。
2) nat表主要用于修改數(shù)據(jù)包的IP地址、端口號等信息(SNAT、DNAT、MASQUERADE 、REDIRECT)。屬于一個流的包(因為包的大小限制導致數(shù)據(jù)可能會被分成多個數(shù)據(jù)包)只會經(jīng)過這個表一次。如果第一個包被允許做NAT或Masqueraded,那么余下的包都會自動地被做相同的操作,也就是說,余下的包不會再通過這個表。表對應的內(nèi)核模塊為 iptable_nat,包含三個鏈:PREROUTING、OUTPUT和POSTROUTING。
3) mangle表主要用于修改數(shù)據(jù)包的TOS (Type Of Service,服務類型)、TTL(Time To Live,生存周期)以及為數(shù)據(jù)包設置Mark標記,以實現(xiàn)Qos(Quality Of Service,服務質(zhì)量)調(diào)整以及策略路由等應用,由于需要相應的路由設備支持,因此應用并不廣泛。包含五個規(guī)則鏈:PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING。
4) raw表自1.2.9以后版本的iptables新增的表,主要用于決定數(shù)據(jù)包是否被狀態(tài)跟蹤機制處理。在匹配數(shù)據(jù)包時,raw表的規(guī)則要優(yōu)先于其他表。包含兩條規(guī)則鏈:PREROUTING和OUTPUT。
跟蹤raw表的4種不同狀態(tài):
NEW:該包想要開始一個連接(重新連接或?qū)⑦B接重定向)
RELATED:該包是屬于某個已經(jīng)建立的連接所建立的新連接。例如:FTP的數(shù)據(jù)傳輸連接就是控制連接所 RELATED出來的連接?!猧cmp-type 0 ( ping 應答) 是icmp-type 8? (ping 請求)所RELATED出來的。
ESTABLISHED :只要發(fā)送并接到應答,一個數(shù)據(jù)連接從NEW變?yōu)镋STABLISHED,而且該狀態(tài)會繼續(xù)匹配這個連接的后續(xù)數(shù)據(jù)包。
INVALID:數(shù)據(jù)包不能被識別屬于哪個連接或沒有任何狀態(tài)比如內(nèi)存溢出,收到不知屬于哪個連接的ICMP錯誤信息,一般應該DROP這個狀態(tài)的任何數(shù)據(jù)。
iptables規(guī)則編寫
1) 編寫參數(shù)介紹

[-t 表名]:該規(guī)則所操作的哪個表,可以使用filter、nat等,如果沒有指定則默認為filter
-A:新增一條規(guī)則,到該規(guī)則鏈列表的最后一行
-I:插入一條規(guī)則,原本該位置上的規(guī)則會往后順序移動,沒有指定編號則為1
-D:從規(guī)則鏈中刪除一條規(guī)則,要么輸入完整的規(guī)則,或者指定規(guī)則編號加以刪除
-R:替換某條規(guī)則,規(guī)則替換不會改變順序,而且必須指定編號。
-P:設置某條規(guī)則鏈的默認動作
-nL:-L、-n,查看當前運行的防火墻規(guī)則列表
chain名:指定規(guī)則表的哪個鏈,如INPUT、OUPUT、FORWARD、PREROUTING等
[規(guī)則編號]:插入、刪除、替換規(guī)則時用,—line-numbers顯示號碼
[-i|o 網(wǎng)卡名稱]:i是指定數(shù)據(jù)包從哪塊網(wǎng)卡進入,o是指定數(shù)據(jù)包從哪塊網(wǎng)卡輸出
[-p 協(xié)議類型]:可以指定規(guī)則應用的協(xié)議,包含tcp、udp和icmp等
[-s 源IP地址]:源主機的IP地址或子網(wǎng)地址
[--sport 源端口號]:數(shù)據(jù)包的IP的源端口號
[-d目標IP地址]:目標主機的IP地址或子網(wǎng)地址
[--dport目標端口號]:數(shù)據(jù)包的IP的目標端口號
-m:extend matches,這個選項用于提供更多的匹配參數(shù),如:
? ? -m state --state ESTABLISHED,RELATED
? ? -m tcp —dport 22
? ? -m multiport —dports 80,8080
? ? -m icmp —icmp-type 8
<-j 動作>:處理數(shù)據(jù)包的動作,包括ACCEPT、DROP、REJECT等
2) 處理數(shù)據(jù)包的動作:
ACCEPT:允許數(shù)據(jù)包通過
DROP:直接丟棄數(shù)據(jù)包,不回應任何信息
REJECT:拒絕數(shù)據(jù)包通過,必要時會給數(shù)據(jù)發(fā)送端一個響應的信息。
SNAT:源地址轉(zhuǎn)換。在進入路由層面的route之前,重新改寫源地址,目標地址不變,并在本機建立NAT表項,當數(shù)據(jù)返回時,根據(jù)NAT表將目的地址數(shù)據(jù)改寫為數(shù)據(jù)發(fā)送出去時候的源地址,并發(fā)送給主機。解決內(nèi)網(wǎng)用戶用同一個公網(wǎng)地址上網(wǎng)的問題。
? ? ? MASQUERADE,是SNAT的一種特殊形式,適用于像adsl這種臨時會變的ip上
DNAT:目標地址轉(zhuǎn)換。和SNAT相反,IP包經(jīng)過route之后、出本地的網(wǎng)絡棧之前,重新修改目標地址,源地址不變,在本機建立NAT表項,當數(shù)據(jù)返回時,根據(jù)NAT表將源地址修改為數(shù)據(jù)發(fā)送過來時的目標地址,并發(fā)給遠程主機??梢噪[藏后端服務器的真實地址。
? ? ? ? REDIRECT:是DNAT的一種特殊形式,將網(wǎng)絡包轉(zhuǎn)發(fā)到本地host上(不管IP頭部指定的目標地址是啥),方便在本機做端口轉(zhuǎn)發(fā)。
LOG:在/var/log/messages文件中記錄日志信息,然后將數(shù)據(jù)包傳遞給下一條規(guī)則
除去最后一個LOG,前3條規(guī)則匹配數(shù)據(jù)包后,該數(shù)據(jù)包不會再往下繼續(xù)匹配了,所以編寫的規(guī)則順序極其關鍵。
3) 配置iptables的注意事項如下:
3.1) 規(guī)則的順序非常重要
規(guī)則是有序號的,數(shù)據(jù)包報文通過是按照規(guī)則順序處理的。針對相同服務的規(guī)則,更嚴格的規(guī)則應該放在前面。若不同類別的規(guī)則則被匹配次數(shù)多的、匹配頻率高的規(guī)則放在前面。
3.2) 當規(guī)則中有多個匹配條件時,條件之間默認存在”與”的關系
如果一條規(guī)則中包含了多個匹配條件,那么報文必須同時滿足這個規(guī)則中的所有匹配條件時,報文才能被這條規(guī)則處理。
3.3) 在配置iptables,若默認策略設置為ACCEPT,最后設置REJECT規(guī)則,那么將實現(xiàn)名單機制。但若將默認策略設置為DROP,則嚴禁執(zhí)行flush清空所有規(guī)則,否則管理員的請求也將會被DROP掉,此時只能登錄console去解決故障了。
3.4) 當iptables所在主機作為網(wǎng)絡防火墻時,建議至少內(nèi)外2塊網(wǎng)卡,在配置規(guī)則時,應著重考慮方向性,雙向都要考慮,從外到內(nèi),從內(nèi)到外。
參考
馬哥運維的iptables防火墻原理知多少。