netfilter是一種內核中用于擴展各種網絡服務的結構化底層框架。netfilter的設計思想是生成一個模塊結構使之能夠比較容易的擴展。新的特性加入到內核中并不需要從新啟動內核。這樣,可以通過簡單的構造一個內核模塊來實現網絡新特性的擴展。給底層的網絡特性擴展帶來了極大的便利,使更多從事網絡底層研發的開發人員能夠集中精力實現新的網絡特性。
Netfilter有4大特性:
1. 每一個協議定義"hooks"(鉤子),IPv4定義了5個鉤子,他們遍布協議棧中包傳輸的整個過程。在每一個點上,協議將使用包和鉤子號來調用netfilter框架。
2. 部分內核可注冊后可以為每一個協議監聽不同的鉤子。因此,當包通過netfilter框架時,它檢查看是否有模塊為協議和鉤子注冊;如果有,他們每一個都有機會按順序檢驗(也可能是更改)包,拋棄包,允許包通過,或者請求netfilter為用戶空間排隊包。
3. 排隊了的包可以被收集送往用戶空間;這些包是被異步的處理的。
4.有非常良好的代碼和文檔。這一點對于一個擁有良好擴展性的開放式框架具有極其深遠的意義。離開了這一特性,netfilter結構將大為遜色甚至是難以操作的。
Netfilter整體結構如下圖所示,netfilter僅僅只是協議棧中多個點上一系列鉤子。IPv4的整個流程圖如下
:包橫穿netfilter系統示意圖:
------ →[1]------ →[ROUTE]------ →[3]------ →[4]------ →
| ^
| |
| [ROUTE]
v |
[2] [5]
| ^
| |
v |
[1]:NF_IP_PRE_ROUTING:剛剛進入網絡層的數據包通過此點(剛剛進行完版本號,校驗和等檢測), 源地址轉換在此點進行;
[2]:NF_IP_LOCAL_IN:經路由查找后,送往本機的通過此檢查點,INPUT包過濾在此點進行;
[3]:NF_IP_FORWARD:要轉發的包通過此檢測點,FORWORD包過濾在此點進行;
[4]:NF_IP_POST_ROUTING:所有馬上便要通過網絡設備出去的包通過此檢測點,內置的目的地址轉換功能(包括地址偽裝)在此點進行;
[5]:NF_IP_LOCAL_OUT:本機進程發出的包通過此檢測點,OUTPUT包過濾在此點進行。
內核模塊可以被注冊以監聽這些鉤子中的任意一個。接著當netfilter鉤子被來自域網絡代碼的核心調用,每一個在那一處注冊了的模塊就可以自由的操作處理包。接下來模塊可以告知netfilter做下列五件事中的一件:
1.NF_ACCEPT:繼續傳遞,保持和原來傳輸的一致;
2.NF_DROP:丟棄包;不再繼續傳遞;
3.NF_STOLEN:接管包;不再繼續傳遞;
4.NF_QUERE:隊列化包(通常是為用戶空間處理做準備);
5. NF_REPEAT:再次調用這一個鉤子。
我們看include/linux/netfilter.h里面定義了
/* Largest hook number + 1 */
#define NF_MAX_HOOKS 8
也就是說Netfilter最多可以支持8個hook.為了擴展方便,Netfilter也提供了很方便的nf_register_hook函數用來加入我們自己的代碼。int nf_register_hook(struct nf_hook_ops *reg)
下面是nf_hook_ops的結構
struct nf_hook_ops
{
struct list_head list;
/* User fills in from here down. */
nf_hookfn *hook;
int pf;
int hooknum;
/* Hooks are ordered in ascending priority. */
int priority;
};
(作者:sw0rd)