Netfilter & iptables 原理

語言: CN / TW / HK

Netfilter 可能瞭解的人比較少,但是 iptables 用過 Linux 的都應該知道。本文主要介紹 Netfilter iptables 的原理,而下一篇將會介紹 Netfilter iptables 的實現。

什麼是 Netfilter

Netfilter 顧名思義就是網絡過濾器,其主要功能就是對進出內核協議棧的數據包進行過濾或者修改,有名的 iptables 就是建立在 Netfilter 之上。

Netfilter 通過向內核協議棧中不同的位置註冊 鈎子函數(Hooks) 來對數據包進行過濾或者修改操作,這些位置稱為 掛載點 ,主要有 5 個: PRE_ROUTING LOCAL_IN FORWARD LOCAL_OUT POST_ROUTING ,如下圖所示:

這 5 個 掛載點 的意義如下:

  • PRE_ROUTING :路由前。數據包進入IP層後,但還沒有對數據包進行路由判定前。

  • LOCAL_IN :進入本地。對數據包進行路由判定後,如果數據包是發送給本地的,在上送數據包給上層協議前。

  • FORWARD :轉發。對數據包進行路由判定後,如果數據包不是發送給本地的,在轉發數據包出去前。

  • LOCAL_OUT :本地輸出。對於輸出的數據包,在沒有對數據包進行路由判定前。

  • POST_ROUTING :路由後。對於輸出的數據包,在對數據包進行路由判定後。

從上圖可以看出,路由判定是數據流向的關鍵點。

  • 第一個路由判定通過查找輸入數據包 IP頭部 的目的 IP地址 是否為本機的 IP地址 ,如果是本機的 IP地址 ,説明數據是發送給本機的。否則説明數據包是發送給其他主機,經過本機只是進行中轉。

  • 第二個路由判定根據輸出數據包 IP頭部 的目的 IP地址 從路由表中查找對應的路由信息,然後根據路由信息獲取下一跳主機(或網關)的 IP地址 ,然後進行數據傳輸。

通過向這些 掛載點 註冊鈎子函數,就能夠對處於不同階段的數據包進行過濾或者修改操作。由於鈎子函數能夠註冊多個,所以內核使用鏈表來保存這些鈎子函數,如下圖所示:

如上圖所示,當數據包進入本地( LOCAL_IN 掛載點)時,就會相繼調用 ipt_hook fw_confirm 鈎子函數來處理數據包。另外,鈎子函數還有優先級,優先級越小越先執行。

正因為掛載點是通過鏈表來存儲鈎子函數,所以掛載點又被稱為 ,掛載點對應的鏈名稱如下所示:

  • LOCAL_IN 掛載點:又稱為 INPUT鏈

  • LOCAL_OUT 掛載點:又稱為 OUTPUT鏈

  • FORWARD 掛載點:又稱為 PORWARD鏈

  • PRE_ROUTING 掛載點:又稱為 PREROUTING鏈

  • POST_ROUTING 掛載點:又稱為 POSTOUTING鏈

什麼是 iptables

iptables 是建立在 Netfilter 之上的數據包過濾器,也就是説, iptables 通過向 Netfilter 的掛載點上註冊鈎子函數來實現對數據包過濾的。 iptables 的實現比較複雜,所以先要慢慢介紹一下它的一些基本概念。

iptables 這個名字可以看出,它一定包含了 這個概念。 是指一系列規則,可以看成是規則表。 iptables 通過把這些規則表掛載在 Netfilter 的不同鏈上,對進出內核協議棧的數據包進行過濾或者修改操作。

iptables 定義了 4 種表,每種表都有其不同的用途:

1. Filter表

Filter表 用於過濾數據包。是 iptables 的默認表,因此如果你配置規則時沒有指定表,那麼就默認使用 Filter表 ,它分別掛載在以下 3 個鏈上:

  • INPUT鏈

  • OUTPUT鏈

  • PORWARD鏈

2. NAT表

NAT表 用於對數據包的網絡地址轉換(IP、端口),它分別掛載在以下 3 個鏈上:

  • PREROUTING鏈

  • POSTOUTING鏈

  • OUTPUT鏈

3. Mangle表

Mangle表 用於修改數據包的服務類型或TTL,並且可以配置路由實現QOS,它分別掛載在以下 5 個鏈上:

  • PREROUTING鏈

  • INPUT鏈

  • PORWARD鏈

  • OUTPUT鏈

  • POSTOUTING鏈

4. Raw表

Raw表 用於判定數據包是否被狀態跟蹤處理,它分別掛載在以下 2 個鏈上:

  • PREROUTING鏈

  • OUTPUT鏈

我們通過下圖來展示各個表所掛載的鏈:

上圖展示了,數據包從網絡中進入到內核協議棧的過程中,要執行的 iptables 規則,如果在執行某條 iptables 規則失敗後,會直接把數據包丟棄,不會繼續執行下面的規則。

拿其中一個鏈來看,如下圖所示:

也就是説,當數據包從網絡中進入到內核協議棧後,在路由判定前會分別執行 Raw表 Mangle表 NAT表 中的規則。如果在執行規則時,某一條規則拒絕了數據包,那麼數據包便會被丟棄,從而不會繼續執行下面的規則。

添加 iptables 規則

上面介紹了 iptables 的原理,下面主要介紹怎麼向 iptables 中添加規則。要向 iptables 中添加規則,可以使用 iptables 命令,其使用格式如下:

iptables [選項 參數] ...

可選的選項如下:

-t <表>:指定要操縱的表;
-A <鏈>:向規則鏈中添加條目;
-D <鏈>:從規則鏈中刪除條目;
-I <鏈>:向規則鏈中插入條目;
-R <鏈>:替換規則鏈中的條目;
-L:顯示規則鏈中已有的條目;
-F:清楚規則鏈中已有的條目;
-Z:清空規則鏈中的數據包計算器和字節計數器;
-N:創建新的用户自定義規則鏈;
-P:定義規則鏈中的默認目標;
-h:顯示幫助信息;
-p:指定要匹配的數據包協議類型;
-s:指定要匹配的數據包源ip地址;
-j <動作>:指定要進行的動作行為;
-i <網絡接口>:指定數據包進入本機的網絡接口;
-o <網絡接口>:指定數據包要離開本機所使用的網絡接口。
--dport <端口>:匹配目標端口號。
--sport <端口>:匹配來源端口號。

iptables 規則的選項比較多,一般來説,一條 iptables 規則主要由四個部分組成,如下圖所示:

  • 第一部分可以通過 -t 選項來指定操作的表,如 filter nat mangle raw

  • 第二部分可以通過 -A -D -I -R 選項來指定操作的鏈,如 INPUT OUTPUT FORWARD PREROUTING POSTOUTING

  • 第三部分主要設置規則的匹配條件,如匹配源IP地址或者端口等。

  • 第四部分主要設置規則匹配成功後進行的動作,如接收或拒絕等。

第一和第二部分比較簡單,我們詳細介紹一下第三和第四部分。

匹配條件

匹配條件 分為 基本匹配條件 擴展匹配條件 ,基本匹配條件包括 源IP地址 目標IP地址 等,擴展匹配條件包括 源端口 目標端口 等。

處理動作

處理動作 是指當匹配條件成功後要進行的一系列操作過程,動作也可以分為 基本動作 擴展動作

此處列出一些常用的動作:

  • ACCEPT :允許數據包通過。

  • DROP :直接丟棄數據包,不給任何迴應信息。

  • REJECT :拒絕數據包通過,必要時會給數據發送端一個響應的信息,客户端剛請求就會收到拒絕的信息。

  • SNAT :源IP地址轉換。

  • MASQUERADE :是SNAT的一種特殊形式,適用於動態IP上。

  • DNAT :目標IP地址轉換。

  • REDIRECT :在本機做端口映射。

  • LOG :在 /var/log/messages 文件中記錄日誌信息,然後將數據包傳遞給下一條規則,也就是説除了記錄以外不對數據包做任何其他操作,仍然讓下一條規則去匹配。

下面我們通過幾個簡單的例子來闡明 iptables 命令的使用:

1. 允許本地迴環接口(即運行本機訪問本機)

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 ACCEPT

3. 禁止數據轉發

iptables -A FORWARD -j REJECT

4. 禁止IP段訪問

iptables -I INPUT -s 124.45.0.0/16 -j DROP   # 禁止IP段從123.45.0.1到123.45.255.254訪問

5. 查看已添加的 iptables 規則

iptables -L -n -v

總結

本文主要介紹了 Netfilter iptables 的原理,並且還介紹了 iptables 命令的簡單使用。由於 iptables 是一個複雜的系統,所以本文不能完整的介紹其所有功能,有興趣的可以繼續查閲其他相關的資料。

下一篇文章我們將會介紹 Netfilter iptables 的實現過程。

技術交流羣: