1.概述
在分析LINUX2.4.x網路安全的實現之前先簡單介紹一下它裡麵包含的幾個重要概念:netfilter、iptables、match、target、nf_sockopt_ops、網路安全功能點的實現。詳細解釋會在後面的分析中講到。
首先是netfilter,它定義了協議棧中的檢查點和在檢查點上引用的資料結構,以及在檢查點上對這些結構引用的過程。iptables定義了實現網路安全功能的規則的組織以及對規則的操作。一個規則中包含零個或多個match和一個target,規則群組織沿用了LINUX2.2.x中的chain,rule的概念,但是增加了table的概念,這三者的關係是:table是實現某項功能所有規則的總和,chain是在某個檢查點上所引用規則的集合,rule是一個單獨的規則。match在規則中用於匹配資料包中的各項參數,每個match匹配特定的參數,所以一個規則中可以有多個match,這包括系統已定義的match,也包括通過核心模組另外添加的match。target在規則中決定如何處理匹配到的資料包,因此在target中實現了具體的網路安全功能。nf_sockopt_ops是在系統調用get/setssockopt中引用的資料結構,實現使用者空間對規則的添加、刪除、修改、查詢等動作。以上的結構在使用之前必須先註冊到系統中才能被引用。
LINUX2.4.x網路安全實現了包過濾,地址轉換(包含了LINUX2.2.x中的地址偽裝和透明代理功能並有其他擴充功能),串連跟蹤(這是實現地址轉換的基礎,在它裡面實現了對串連狀態的記錄和監控,與狀態檢測類似),Mangle(這是LINUX2.4.x新增的一個功能,它對資料包進行檢查但不做禁止、丟棄或允許的判斷)。實現這些功能點需要分別註冊netfilter,iptables,match,target,nf_sockopt_ops的資料結構。如果實現其他新的功能,只需定義相應的結構並將它註冊到系統中,並且通過使用者空間的組態工具(這個組態工具也須支援新的結構)把它加入到規則中就可以了。這些結構在規則中自動被引用。
2.netfilter
netfilter定義了協議棧中的檢查點和檢查點上引用的資料結構以及對這些資料結構引用的過程。首先看看在檢查點上引用的資料結構,:
圖中ns_hook_ops就是在檢查點上引用的結構。每個協議棧預先定義的8個鏈表數組用於儲存這些結構,這些鏈表與協議棧中的檢查點一一對應。在實際的應用中,這8個鏈表並不一定都被使用,比如在IPV4中,只定義了5個檢查點,分別對應前5個鏈表。nf_hook_ops結構如下:
struct nf_hook_ops
{
struct list_head list;
nf_hookfn hook; /* 函數指標 */
int pf; /* 結構對應的協議棧號 */
int hooknum; /* 結構對應的檢查點號*/
int priority; /* 結構的優先值 */
};
nf_register_hook函數將ns_hook_ops結構註冊到這些鏈表上,鏈表的索引由結構中hooknum指定。同一鏈表上的結構按優先值由小到大排列。在檢查點上引用這些結構時,以它們在鏈表上的先後順序引用。
檢查點由宏NF_HOOK定義。在檢查點上,函數nf_hook_slow調用函數nf_iterate遍曆對應鏈表並調用鏈表上的結構ns_hook_ops中定義的函數。如果結構中的函數返回NF_ACCEPT,則繼續調用下一個結構中的函數;如果結構中的函數返回NF_DROP或NF_STOLEN或NF_QUEUE,則將這個值返回給nf_hook_slow;如果結構中的函數返回NF_REPEAT,則重複調用此結構上的函數;如果到了鏈表上的最後一個結構,則把這個結構中函數的傳回值返回給ns_hook_slow。在ns_hook_slow中判斷nf_iterate的傳回值,如果是NF_ACCEPT,則允許資料包通過,並將資料包傳遞給協議棧中的下一個函數;如果是NF_DROP,則釋放資料包,協議棧流程中斷;如果是NF_STOLEN,同樣中斷協議棧的流程,但是沒有釋放這個資料包;如果是NF_QUEUE,則將這個包發送到使用者空間處理,同時中斷協議棧的流程。
檢查點分布在協議棧的流程中,是IPV4中的檢查點:
圖中檢查點的名稱如下:
檢查點編號 檢查點名稱 檢查點所在檔案名稱
1 NF_IP_PRE_ROUTING ip_input.c
2 NF_IP_LOCAL_IN ip_input.c
3 NF_IP_FORWARD ip_forward.c
4 NF_IP_POST_ROUTING ip_output.c
5 NF_IP_LOCAL_OUT ip_output.c
表2.1 IPV4中檢查點的名稱
圖中,ROUTE(1)處對收到的包做路由尋找並判斷這個包是需要轉寄的包還是發往本機上層的包,ROUTE(2)處尋找發出包的路由。NF_IP_PRE_ROUTING處對所有傳入IP層的資料包進行檢查,在這之前,有關資料包的版本、長度、校正和等正確性檢查已經完成。NF_IP_LOCAL_IN對發往本機上層的資料包進行檢查。請注意這兩個檢查點與LINUX2.2.x中檢查點的區別,在LINUX2.2.x沒有區分發往本機上層包和需要轉寄的包,所以在做完地址解偽裝之後又調用了一次路由尋找函數,為解偽裝之後的包尋找路由。NF_IP_FORWARD處檢查需要轉寄的資料包。NF_IP_POST_ROUTING處對所有向鏈路層傳遞的資料包進行檢查,注意在此處資料包的路由已經確定。NF_IP_LOCAL_OUT對本機發出的包進行檢查,此處的路由還沒有確定,所以可以做目的地址轉換。實現某個網路安全功能可能需要在多個檢查點上註冊相應的結構,在後面的分析中我們可以看到具體的例子。