国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

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


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

1. 掛接點(diǎn)

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

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

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

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

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

NF_IP_PRE_ROUTING,在IP棧成功接收sk_buff包后處理,掛接點(diǎn)在在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包完成路由分類判斷是到達(dá)自身的包后進(jìn)行處理,掛接點(diǎn)在在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包完成路由分類判斷是需要進(jìn)行轉(zhuǎn)發(fā)的包進(jìn)行處理,掛接點(diǎn)在在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ā)出的包進(jìn)行處理,掛接點(diǎn)在在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包后處理,掛接點(diǎn)在在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. 掛接點(diǎn)操作

掛接點(diǎn)的操作由結(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:掛接點(diǎn)
priority:優(yōu)先級

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

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


3. 連接跟蹤

連接跟蹤的struct nf_hook_ops結(jié)構(gòu)在net/ipv4/netfilter/ip_conntrack_standalone.c中定義,
這是對用戶隱藏的,也就是用戶不能通過iptables規(guī)則對此操作點(diǎn)進(jìn)行配置,是有系統(tǒng)自動(dò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ù)包進(jìn)入(NF_IP_PRE_ROUTING)和自身數(shù)據(jù)發(fā)出(NF_IP_LOCAL_OUT)時(shí)進(jìn)行處理,其功能就是判斷該數(shù)據(jù)包是什么狀態(tài),填充該數(shù)據(jù)包struct sk_buff結(jié)構(gòu)中struct nf_ct_info *nfct項(xiàng)的值,維護(hù)連接狀態(tài)表,從而實(shí)現(xiàn)狀態(tài)檢測,具體處理過程分析可見另一篇文章:Linux下如何實(shí)現(xiàn)狀態(tài)檢測。

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

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

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

-------+---------------------------------+-------------------------------------
 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   | 全部五個(gè)都有
       |
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鏈掛鉤
       |
-------+---------------------------------+-------------------------------------

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

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

5. 總結(jié)

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

--

tech blog: http://yfydz.cublog.cn

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
netfilter: Linux 防火墻在內(nèi)核中的實(shí)現(xiàn)
LINUX2.4.x網(wǎng)絡(luò)安全框架
iptables ipt_do_table
Linux中Netfilter的原理介紹
netfilter中iptables表的實(shí)現(xiàn)
linux實(shí)現(xiàn)流量監(jiān)控的幾種方法
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服