小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

netfilter整體架構(gòu)解析初步

 mrjbydd 2010-09-19


本文檔的Copyleft歸yfydz所有,使用GPL發(fā)布,可以自由拷貝,轉(zhuǎn)載,轉(zhuǎn)載時請保持文檔的完整性,嚴禁用于任何商業(yè)用途。
msn: yfydz_no1@hotmail.com
來源:http://yfydz.

1. 掛接點

netfilter是Linux2.4/2.6內(nèi)核中自帶的防火墻架構(gòu),定義了5個掛接點:

NF_IP_PRE_ROUTING-------->NF_IP_FORWARD--------->NF_IP_POST_ROUTING
                     |                    ^
                     |                    |
                     V                    |
                 NF_IP_LOCAL_IN       NF_IP_LOCAL_OUT

netfilter定義了一個二維的鏈表頭數(shù)組struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS]來表示所有協(xié)議族的各個掛接點,NPROTO值為32,可表示linux所支持所有32個協(xié)議族(include/linux/socket.h文件中定義),也就是使用socket(2)函數(shù)的第一個參數(shù)的值,如互聯(lián)網(wǎng)的TCP/IP協(xié)議族PF_INET(2)。每個協(xié)議族有NF_MAX_HOOKS(8)個掛接點,但實際只用了如上所述的5個,數(shù)組中每個元素表示一個協(xié)議族在一個掛接點的處理鏈表頭,。

以下分析使用2.4.26內(nèi)核中的netfilter代碼。

在IPv4(PF_INET協(xié)議族)下,各掛接點定義在:

NF_IP_PRE_ROUTING,在IP棧成功接收sk_buff包后處理,掛接點在在net/ipv4/ip_input.c的函數(shù)
int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
中定義:
        return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
                       ip_rcv_finish);

NF_IP_LOCAL_IN,在對接收的sk_buff包完成路由分類判斷是到達自身的包后進行處理,掛接點在在net/ipv4/ip_input.c的函數(shù)int ip_local_deliver(struct sk_buff *skb)中定義:

        return NF_HOOK(PF_INET, NF_IP_LOCAL_IN, skb, skb->dev, NULL,
                       ip_local_deliver_finish);

NF_IP_FORWARD,在對接收的sk_buff包完成路由分類判斷是需要進行轉(zhuǎn)發(fā)的包進行處理,掛接點在在net/ipv4/ip_input.c的函數(shù)int ip_forward(struct sk_buff *skb)中定義:

        return NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, dev2,
                       ip_forward_finish);

NF_IP_LOCAL_OUT,在對自身發(fā)出的包進行處理,掛接點在在net/ipv4/ip_output.c的函數(shù)
int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
                          u32 saddr, u32 daddr, struct ip_options *opt)
中定義:

        return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
                       output_maybe_reroute);


NF_IP_POST_ROUTING,在IP棧成功接收sk_buff包后處理,掛接點在在net/ipv4/ip_output.c的函數(shù)
__inline__ int ip_finish_output(struct sk_buff *skb)中定義:

        return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
                       ip_finish_output2);

2. 掛接點操作

掛接點的操作由結(jié)構(gòu)struct nf_hook_ops定義:
include/linux/netfilter.h

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;
};

數(shù)組中的元素說明如下:
struct list_head list: 鏈表頭,用于將此結(jié)構(gòu)接入操作鏈表
nf_hookfn *hook:用戶定義的掛接處理函數(shù)
int pf:協(xié)議族
hooknum:掛接點
priority:優(yōu)先級

每個struct nf_hook_ops結(jié)構(gòu)需要掛接到nf_hooks數(shù)組中的某個鏈表中才起作用,每個協(xié)議族的各種處理形成一個處理鏈表,鏈表上可以掛接多個節(jié)點,每個節(jié)點是一個數(shù)據(jù)處理結(jié)構(gòu)(struct nf_hook_ops),用來描述對數(shù)據(jù)包進行如何處理,這些節(jié)點根據(jù)優(yōu)先級順序進行排序處理,優(yōu)先級是有符號的32位數(shù),值越小優(yōu)先級越高,如果優(yōu)先級相同,則按掛接的順序依次處理,netfilter預定義了以下優(yōu)先級:

        NF_IP_PRI_FIRST = INT_MIN,
        NF_IP_PRI_CONNTRACK = -200,
        NF_IP_PRI_MANGLE = -150,
        NF_IP_PRI_NAT_DST = -100,
        NF_IP_PRI_FILTER = 0,
        NF_IP_PRI_NAT_SRC = 100,
        NF_IP_PRI_LAST = INT_MAX,

由此可見,netfilter的處理順序是先連接跟蹤、然后是mangle處理,再目的NAT(PREROUTING),然后是過濾(FILTER),然后是源NAT(POSTROUTING),這就是為什么mangle鏈的規(guī)則會先執(zhí)行。

在各個處理點處理數(shù)據(jù)包時,如果發(fā)現(xiàn)需要丟棄數(shù)據(jù)包,那么數(shù)據(jù)包就被立即釋放而不再進入后面的處理點;如果該處理點的最終結(jié)論是接受,那該數(shù)據(jù)包還會繼續(xù)進入下一處理點進行匹配檢查,所以對于最終通過防火墻的數(shù)據(jù)包,是經(jīng)過了所有處理點的匹配的。


3. 連接跟蹤

連接跟蹤的struct nf_hook_ops結(jié)構(gòu)在net/ipv4/netfilter/ip_conntrack_standalone.c中定義,
這是對用戶隱藏的,也就是用戶不能通過iptables規(guī)則對此操作點進行配置,是有系統(tǒng)自動完成的。

定義如下:
static struct nf_hook_ops ip_conntrack_in_ops
= { { NULL, NULL }, ip_conntrack_in, PF_INET, NF_IP_PRE_ROUTING,
        NF_IP_PRI_CONNTRACK };
static struct nf_hook_ops ip_conntrack_local_out_ops
= { { NULL, NULL }, ip_conntrack_local, PF_INET, NF_IP_LOCAL_OUT,
        NF_IP_PRI_CONNTRACK };

分別掛接在外部數(shù)據(jù)包進入(NF_IP_PRE_ROUTING)和自身數(shù)據(jù)發(fā)出(NF_IP_LOCAL_OUT)時進行處理,其功能就是判斷該數(shù)據(jù)包是什么狀態(tài),填充該數(shù)據(jù)包struct sk_buff結(jié)構(gòu)中struct nf_ct_info *nfct項的值,維護連接狀態(tài)表,從而實現(xiàn)狀態(tài)檢測,具體處理過程分析可見另一篇文章:Linux下如何實現(xiàn)狀態(tài)檢測。

4. 規(guī)則表(table)

為了定義每個處理點上要執(zhí)行哪些規(guī)則,netfilter定義了表(table)的概念,每個表由一個struct ipt_table來描述,如缺省的filter/nat/mangle表,每個表可單獨分成幾個規(guī)則鏈,分別在幾個掛接點起作用,如filter表是在只在NF_IP_LOCAL_IN/NF_IP_LOCAL_OUT/NF_IP_FORWARD上起作用,然后通過函數(shù)ipt_do_table()來實現(xiàn)對某個表中某個hooknum的規(guī)則集進行匹配處理。而由結(jié)構(gòu)struct nf_hook_ops所定義的各個處理點的處理函數(shù)都是直接或間接的調(diào)用了ipt_do_table()函數(shù)來實現(xiàn)對規(guī)則集的調(diào)用。

下面是系統(tǒng)缺省的三個表的定義情況:

-------+---------------------------------+-------------------------------------
 table |  table definition               | file name
-------+---------------------------------+-------------------------------------
filter | struct ipt_table packet_filter  | net/ipv4/netfilter/iptable_filter.c
       | 
hook   | NF_IP_LOCAL_IN、NF_IP_LOCAL_OUT、NF_IP_FORWARD
       |
ops    | struct nf_hook_ops ipt_ops[]
       | net/ipv4/netfilter/iptable_filter.c
       |
       |NF_IP_LOCAL_IN: ipt_hook()
       |    調(diào)用ipt_do_table()函數(shù)與filter表的INPUT鏈掛鉤
       |
       |NF_IP_LOCAL_FORWARD: ipt_hook()
       |    調(diào)用ipt_do_table()函數(shù)與filter表的FORWARD鏈掛鉤
       |
       |NF_IP_LOCAL_OUT: ipt_local_out_hook()
       |    調(diào)用ipt_do_table()函數(shù)與filter表的OUTPUT鏈掛鉤
       |
-------+---------------------------------+-------------------------------------
nat    | struct ipt_table nat_table      | net/ipv4/netfilter/ip_nat_rule.c
       |                                 
hook   | NF_IP_PRE_ROUTING_IN、NF_IP_LOCAL_OUT、NF_IP_POST_ROUTING
       |
ops    | net/ipv4/netfilter/ip_nat_standalone.c
       |
       |NF_IP_PRE_ROUTING: 
       |    struct nf_hook_ops ip_nat_in_ops, ip_nat_fn()
       |      調(diào)用ip_nat_rule_find()函數(shù)
       |        調(diào)用ipt_do_table()函數(shù)與nat表的PREROUTING鏈掛鉤
       |
       |NF_IP_POST_ROUTING: 
       |    struct nf_hook_ops ip_nat_out_ops,ip_nat_out()
       |      調(diào)用ip_nat_fn()
       |        調(diào)用ip_nat_rule_find()函數(shù)
       |          調(diào)用ipt_do_table()函數(shù)與nat表的POSTROUTING鏈掛鉤
       |
-------+---------------------------------+-------------------------------------
mangle | struct ipt_table packet_mangler | net/ipv4/netfilter/iptable_mangle.c
       |                                 |
hook   | 全部五個都有
       |
ops    | struct nf_hook_ops ipt_ops[]
       | net/ipv4/netfilter/iptable_mangle.c
       |
       |NF_IP_PRE_ROUTING: ip_route_hook()
       |    調(diào)用ipt_do_table()函數(shù)與mangle表的PREROUTING鏈掛鉤
       |
       |NF_IP_LOCAL_IN: ip_route_hook()
       |    調(diào)用ipt_do_table()函數(shù)與mangle表的INPUT鏈掛鉤
       |
       |NF_IP_FORWARD: ipt_hook()
       |    調(diào)用ipt_do_table()函數(shù)與mangle表的FORWARD鏈掛鉤
       |
       |NF_IP_LOCAL_OUT: ipt_local_hook()
       |    調(diào)用ipt_do_table()函數(shù)與mangle表的OUTPUT鏈掛鉤
       |
       |NF_IP_POST_ROUTING: ip_route_hook()
       |    調(diào)用ipt_do_table()函數(shù)與mangle表的POSTROUTING鏈掛鉤
       |
-------+---------------------------------+-------------------------------------

每個數(shù)據(jù)處理表(table)中就是定義各自的規(guī)則集,是用動態(tài)長度的數(shù)組的形式保存,每個數(shù)組節(jié)點是一個規(guī)則,規(guī)則用struct ipt_entry結(jié)構(gòu)進行描述,每條規(guī)則除了基本項外,其他附加匹配條件項還形成一個動態(tài)長度的匹配數(shù)組,struct ipt_entry中保存數(shù)組頭的地址,每個匹配用結(jié)構(gòu)struct ipt_match描述。規(guī)則的動作如果是擴展動作的話,用struct ipt_target描述。

用戶可以自己定義自己的新的表,可以以缺省表為藍本,然后定義新的struct nf_hook_ops操作節(jié)點,在該操作節(jié)點中調(diào)用ipt_do_table()函數(shù)將該ops和新表聯(lián)系起來,這樣就可以用iptables定義新的規(guī)則集。如果不定義新表,用戶也可以在ops處理函數(shù)中對包直接進行判斷處理,適合需要對包進行固定方式處理的場合。

5. 總結(jié)

netfilter架構(gòu)以nf_hooks數(shù)組為基點,掛接在內(nèi)核的協(xié)議處理的幾個基本點上,通過鏈表方式鏈接struct nf_hook_ops處理結(jié)構(gòu),這些處理結(jié)構(gòu)可以是在內(nèi)核內(nèi)部自動固定處理,如狀態(tài)檢測;也可以通過和struct ipt_table聯(lián)系,通過iptables來動態(tài)配置處理規(guī)則,實現(xiàn)了一個擴展性很高的防火墻處理架構(gòu),不過實現(xiàn)細節(jié)部分仍然很復雜,各種細節(jié)功能將在后續(xù)文章里分析。

--

tech blog: http://yfydz.

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多