天天看點

LINUX系統

安全基礎:簡單解析linux系統防火牆架構

【賽迪網-it技術報道】linux系統中的netfilter提供了一個抽象、通用化的架構,該架構定義的一個子功能的實作就是包過濾子系統,架構包含以下五部分:

1. 為每種網絡協定(ipv4、ipv6等)定義一套鈎子函數(ipv4定義了5個鈎子函數), 這些鈎子函數在資料報流過協定棧的幾個關鍵點被調用。在這幾個點中,協定棧将把資料報及鈎子函數标号作為參數調用netfilter架構。

2. 核心的任何子產品可以對每種協定的一個或多個鈎子進行注冊,實作挂接,這樣當某個資料包被傳遞給netfilter架構時,核心能檢測是否有任何子產品對該協定和鈎子函數進行了注冊。若注冊了,則調用該子產品的注冊時使用的回調函數,這樣這些子產品就有機會檢查(可能還會修改)該資料包、丢棄該資料包及訓示netfilter将該資料包傳入使用者空間的隊列。

3 .那些排隊的資料包是被傳遞給使用者空間的異步地進行處理。一個使用者程序能檢查資料包,修改資料包,甚至可以重新将該資料包通過離開核心的同一個鈎子函數中注入到核心中。

4. 任何在ip層要被抛棄的ip資料包在真正抛棄之前都要進行檢查。例如允許子產品檢查ip-spoofed包(被路由抛棄)。

5.ip層的五個hook點的位置如下所示:

(1)nf_ip_pre_routing:剛剛進入網絡層的資料包通過此點(剛剛進行完版本号,校驗 和等檢測),源位址轉換在此點進行;ip_input.c中ip_rcv調用;

(2)nf_ip_local_in:經路由查找後,送往本機的通過此檢查點,input包過濾在此點進行,ip_local_deliver中調用;

(3)nf_ip_forward:要轉發的包通過此檢測點,forword包過濾在此點進行;

(4)nf_ip_post_routing:所有馬上便要通過網絡裝置出去的包通過此檢測點,内置的目的位址轉換功能(包括位址僞裝)在此點進行;

(5)nf_ip_local_out:本機程序發出的包通過此檢測點,output包過濾在此點進行。

這些點是已經在核心中定義好的,核心子產品能夠注冊在這些hook點進行的處理,可使用nf_register_hook函數指定。在資料報經過這些鈎子函數時被調用,進而子產品可以修改這些資料報,并向netfilter傳回如下值:

一個基于netfilter架構的、稱為iptables的資料報選擇系統在linux2.4核心中被應用,其實它就是ipchains的後繼工具,但卻有更強的可擴充性。核心子產品可以注冊一個新的規則表(table),并要求資料報流經指定的規則表。這種資料報選擇用于實作資料報過濾(filter表),網絡位址轉換(nat表)及資料報處理(mangle表)。 linux2.4核心提供的這三種資料報處理功能都基于netfilter的鈎子函數和ip表。它們是獨立的子產品,互相之間是獨立的。它們都完美的內建到由netfileter提供的架構中。

<b>包過濾</b>

filter表格不會對資料報進行修改,而隻對資料報進行過濾。iptables優于ipchains的一個方面就是它更為小巧和快速。它是通過鈎子函數nf_ip_local_in、nf_ip_forward及nf_ip_local_out接入netfilter架構的。是以對于任何一個數 報隻有一個地方對其進行過濾。這相對ipchains來說是一個巨大的改進,因為在ipchains中一個被轉發的資料報會周遊三條鍊。

<b>nat</b>

nat表格監聽三個netfilter鈎子函數:nf_ip_pre_routing、nf_ip_post_routing及nf_ip_local_out。 nf_ip_pre_routing實作對需要轉發的資料報的源位址進行位址轉換而nf_ip_post_routing則對需要轉發的資料包的目的位址進行位址轉換。對于本地資料報的目的位址的轉換則由nf_ip_local_out來實作。nat表格不同于filter表格,因為隻有新連接配接的第一個資料報将周遊表格,而随後的資料報将根據第一個資料報的結果進行同樣的轉換處理。nat表格被用在源nat、目的nat,僞裝(其是源nat的一個特例)及透明代理(其是目的nat的一個特例)。

<b>資料報處理(packet mangling)</b>

mangle表格在nf_ip_pre_routing和nf_ip_local_out鈎子中進行注冊。使用 mangle表,可以實作對資料報的修改或給資料報附上一些帶外資料。目前mangle表支援修改tos位及設定skb的nfmard字段。

<b>源碼分析</b>

如果我們想加入自己的代碼,便要用nf_register_hook函數,其函數原型為:

我們的工作便是生成一個struct nf_hook_ops結構的執行個體,并用nf_register_hook将其hook上。其中list項我們總要初始化為{null,null};由于一般在ip層工作,pf總是pf_inet;hooknum就是我們選擇的hook點;一個hook點可能挂多個處理函數,誰先誰後,便要看優先級,即priority的指定了。netfilter_ipv4.h中用一個枚舉類型指定了内置的處理函數的優先級:

hook是提供的處理函數,也就是我們的主要工作,其原型為:

它的五個參數将由nfhook宏傳進去。nf_register_hook根據reg中注冊的協定簇類型和優先級在nf_hooks中找到相應的位置并插入到此表中。_hooks[nproto][nf_max_hooks]在netfilter初始化時(netfilter_init/netfilter.c,而它在sock_init時調用)已經初始為一個空表。

例如iptable在初始化時(init/iptable_filter.c)調用nf_register_hook注冊他的hook函數。

 

mangle在init/iptable_mangle.c中注冊它自己的hook函數。 

nat在init/ip_nat_standalone.c中注冊它自己的hook函數

繼續閱讀