Linux 網(wǎng)絡瑞士軍刀 iptables 基本原理 —— 高端必備

Netfilter 可能了解的人比較少,但是 iptables 用過 Linux 的都應該知道。本文主要介紹 Netfilter 與 iptables 的原理,而下一篇將會介紹 Netfilter 與 iptables 的實現(xiàn)。
什么是 Netfilter
Netfilter 顧名思義就是網(wǎng)絡過濾器,其主要功能就是對進出內(nèi)核協(xié)議棧的數(shù)據(jù)包進行過濾或者修改,有名的 iptables 就是建立在 Netfilter 之上。
Netfilter 通過向內(nèi)核協(xié)議棧中不同的位置注冊 鉤子函數(shù)(Hooks) 來對數(shù)據(jù)包進行過濾或者修改操作,這些位置稱為 掛載點,主要有 5 個:PRE_ROUTING、LOCAL_IN、FORWARD、LOCAL_OUT 和 POST_ROUTING,如下圖所示:

這 5 個 掛載點 的意義如下:
PRE_ROUTING:路由前。數(shù)據(jù)包進入IP層后,但還沒有對數(shù)據(jù)包進行路由判定前。LOCAL_IN:進入本地。對數(shù)據(jù)包進行路由判定后,如果數(shù)據(jù)包是發(fā)送給本地的,在上送數(shù)據(jù)包給上層協(xié)議前。FORWARD:轉發(fā)。對數(shù)據(jù)包進行路由判定后,如果數(shù)據(jù)包不是發(fā)送給本地的,在轉發(fā)數(shù)據(jù)包出去前。LOCAL_OUT:本地輸出。對于輸出的數(shù)據(jù)包,在沒有對數(shù)據(jù)包進行路由判定前。POST_ROUTING:路由后。對于輸出的數(shù)據(jù)包,在對數(shù)據(jù)包進行路由判定后。
從上圖可以看出,路由判定是數(shù)據(jù)流向的關鍵點。
第一個路由判定通過查找輸入數(shù)據(jù)包
IP頭部的目的IP地址是否為本機的IP地址,如果是本機的IP地址,說明數(shù)據(jù)是發(fā)送給本機的。否則說明數(shù)據(jù)包是發(fā)送給其他主機,經(jīng)過本機只是進行中轉。第二個路由判定根據(jù)輸出數(shù)據(jù)包
IP頭部的目的IP地址從路由表中查找對應的路由信息,然后根據(jù)路由信息獲取下一跳主機(或網(wǎng)關)的IP地址,然后進行數(shù)據(jù)傳輸。
通過向這些 掛載點 注冊鉤子函數(shù),就能夠對處于不同階段的數(shù)據(jù)包進行過濾或者修改操作。由于鉤子函數(shù)能夠注冊多個,所以內(nèi)核使用鏈表來保存這些鉤子函數(shù),如下圖所示:

如上圖所示,當數(shù)據(jù)包進入本地(LOCAL_IN 掛載點)時,就會相繼調用 ipt_hook 和 fw_confirm 鉤子函數(shù)來處理數(shù)據(jù)包。另外,鉤子函數(shù)還有優(yōu)先級,優(yōu)先級越小越先執(zhí)行。
正因為掛載點是通過鏈表來存儲鉤子函數(shù),所以掛載點又被稱為 鏈,掛載點對應的鏈名稱如下所示:
LOCAL_IN掛載點:又稱為INPUT鏈。LOCAL_OUT掛載點:又稱為OUTPUT鏈。FORWARD掛載點:又稱為PORWARD鏈。PRE_ROUTING掛載點:又稱為PREROUTING鏈。POST_ROUTING掛載點:又稱為POSTOUTING鏈。
什么是 iptables
iptables 是建立在 Netfilter 之上的數(shù)據(jù)包過濾器,也就是說,iptables 通過向 Netfilter 的掛載點上注冊鉤子函數(shù)來實現(xiàn)對數(shù)據(jù)包過濾的。iptables 的實現(xiàn)比較復雜,所以先要慢慢介紹一下它的一些基本概念。
表
從 iptables 這個名字可以看出,它一定包含了 表 這個概念。表 是指一系列規(guī)則,可以看成是規(guī)則表。iptables 通過把這些規(guī)則表掛載在 Netfilter 的不同鏈上,對進出內(nèi)核協(xié)議棧的數(shù)據(jù)包進行過濾或者修改操作。
iptables 定義了 4 種表,每種表都有其不同的用途:
1. Filter表
Filter表 用于過濾數(shù)據(jù)包。是 iptables 的默認表,因此如果你配置規(guī)則時沒有指定表,那么就默認使用 Filter表,它分別掛載在以下 3 個鏈上:
INPUT鏈OUTPUT鏈PORWARD鏈
2. NAT表
NAT表 用于對數(shù)據(jù)包的網(wǎng)絡地址轉換(IP、端口),它分別掛載在以下 3 個鏈上:
PREROUTING鏈POSTOUTING鏈OUTPUT鏈
3. Mangle表
Mangle表 用于修改數(shù)據(jù)包的服務類型或TTL,并且可以配置路由實現(xiàn)QOS,它分別掛載在以下 5 個鏈上:
PREROUTING鏈INPUT鏈PORWARD鏈OUTPUT鏈POSTOUTING鏈
4. Raw表
Raw表 用于判定數(shù)據(jù)包是否被狀態(tài)跟蹤處理,它分別掛載在以下 2 個鏈上:
PREROUTING鏈OUTPUT鏈
我們通過下圖來展示各個表所掛載的鏈:

上圖展示了,數(shù)據(jù)包從網(wǎng)絡中進入到內(nèi)核協(xié)議棧的過程中,要執(zhí)行的 iptables 規(guī)則,如果在執(zhí)行某條 iptables 規(guī)則失敗后,會直接把數(shù)據(jù)包丟棄,不會繼續(xù)執(zhí)行下面的規(guī)則。
拿其中一個鏈來看,如下圖所示:

也就是說,當數(shù)據(jù)包從網(wǎng)絡中進入到內(nèi)核協(xié)議棧后,在路由判定前會分別執(zhí)行 Raw表、Mangle表 和 NAT表 中的規(guī)則。如果在執(zhí)行規(guī)則時,某一條規(guī)則拒絕了數(shù)據(jù)包,那么數(shù)據(jù)包便會被丟棄,從而不會繼續(xù)執(zhí)行下面的規(guī)則。
添加 iptables 規(guī)則
上面介紹了 iptables 的原理,下面主要介紹怎么向 iptables 中添加規(guī)則。要向 iptables 中添加規(guī)則,可以使用 iptables 命令,其使用格式如下:
iptables [選項 參數(shù)] ...可選的選項如下:
-t <表>:指定要操縱的表;
-A <鏈>:向規(guī)則鏈中添加條目;
-D <鏈>:從規(guī)則鏈中刪除條目;
-I <鏈>:向規(guī)則鏈中插入條目;
-R <鏈>:替換規(guī)則鏈中的條目;
-L:顯示規(guī)則鏈中已有的條目;
-F:清楚規(guī)則鏈中已有的條目;
-Z:清空規(guī)則鏈中的數(shù)據(jù)包計算器和字節(jié)計數(shù)器;
-N:創(chuàng)建新的用戶自定義規(guī)則鏈;
-P:定義規(guī)則鏈中的默認目標;
-h:顯示幫助信息;
-p:指定要匹配的數(shù)據(jù)包協(xié)議類型;
-s:指定要匹配的數(shù)據(jù)包源ip地址;
-j <動作>:指定要進行的動作行為;
-i <網(wǎng)絡接口>:指定數(shù)據(jù)包進入本機的網(wǎng)絡接口;
-o <網(wǎng)絡接口>:指定數(shù)據(jù)包要離開本機所使用的網(wǎng)絡接口。
--dport <端口>:匹配目標端口號。
--sport <端口>:匹配來源端口號。
iptables 規(guī)則的選項比較多,一般來說,一條 iptables 規(guī)則主要由四個部分組成,如下圖所示:

第一部分可以通過
-t選項來指定操作的表,如filter、nat、mangle或raw。第二部分可以通過
-A、-D、-I或-R選項來指定操作的鏈,如INPUT、OUTPUT、FORWARD、PREROUTING或POSTOUTING。第三部分主要設置規(guī)則的匹配條件,如匹配源IP地址或者端口等。
第四部分主要設置規(guī)則匹配成功后進行的動作,如接收或拒絕等。
第一和第二部分比較簡單,我們詳細介紹一下第三和第四部分。
匹配條件
匹配條件 分為 基本匹配條件 與 擴展匹配條件,基本匹配條件包括 源IP地址 和 目標IP地址 等,擴展匹配條件包括 源端口 和 目標端口 等。
處理動作
處理動作 是指當匹配條件成功后要進行的一系列操作過程,動作也可以分為 基本動作 和 擴展動作。
此處列出一些常用的動作:
ACCEPT:允許數(shù)據(jù)包通過。DROP:直接丟棄數(shù)據(jù)包,不給任何回應信息。REJECT:拒絕數(shù)據(jù)包通過,必要時會給數(shù)據(jù)發(fā)送端一個響應的信息,客戶端剛請求就會收到拒絕的信息。SNAT:源IP地址轉換。MASQUERADE:是SNAT的一種特殊形式,適用于動態(tài)IP上。DNAT:目標IP地址轉換。REDIRECT:在本機做端口映射。LOG:在/var/log/messages文件中記錄日志信息,然后將數(shù)據(jù)包傳遞給下一條規(guī)則,也就是說除了記錄以外不對數(shù)據(jù)包做任何其他操作,仍然讓下一條規(guī)則去匹配。
下面我們通過幾個簡單的例子來闡明 iptables 命令的使用:
1. 允許本地回環(huán)接口(即運行本機訪問本機)
iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT # 不指定表名時, 默認為filter表2. 允許訪問80端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT3. 禁止數(shù)據(jù)轉發(fā)
iptables -A FORWARD -j REJECT4. 禁止IP段訪問
iptables -I INPUT -s 124.45.0.0/16 -j DROP # 禁止IP段從123.45.0.1到123.45.255.254訪問5. 查看已添加的 iptables 規(guī)則
iptables -L -n -v總結
本文主要介紹了 Netfilter 與 iptables 的原理,并且還介紹了 iptables 命令的簡單使用。由于 iptables 是一個復雜的系統(tǒng),所以本文不能完整的介紹其所有功能,有興趣的可以繼續(xù)查閱其他相關的資料。
