• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • Linux2.4中netfilter框架實現

    發表于:2007-07-02來源:作者:點擊數: 標簽:
    Netfilter是 linux 2.4內核實現數據包過濾/數據包處理/NAT等的功能框架。該文討論了linux 2.4內核的netfilter功能框架,還對基于netfilter框架上的包過濾,NAT和數據包處理(packet mangling)進行了討論。閱讀本文需要了解2.2內核中ipchains的原理和使用方法

        Netfilter是linux2.4內核實現數據包過濾/數據包處理/NAT等的功能框架。該文討論了linux 2.4內核的netfilter功能框架,還對基于netfilter框架上的包過濾,NAT和數據包處理(packet mangling)進行了討論。閱讀本文需要了解2.2內核中ipchains的原理和使用方法作為預備知識,若你沒有這方面的知識,請閱讀IPCHAINS-HOWTO。

    第一部分:Netfilter基礎和概念

    一、什么是Netfilter

        Netfilter比以前任何一版Linux內核的防火墻子系統都要完善強大。Netfilter提供了一個抽象、通用化的框架,該框架定義的一個子功能的實現就是包過濾子系統。因此不要在2.4中期望討論諸如"如何在2.4中架設一個防火墻或者偽裝網關"這樣的話題,這些只是Netfilter功能的一部分。Netfilter框架包含以下三部分:

    1 為每種網絡協議(IPv4、IPv6等)定義一套鉤子函數(IPv4定義了5個鉤子函數),這些鉤子函數在數據報流過協議棧的幾個關鍵點被調用。在這幾個點中,協議棧將把數據報及鉤子函數標號作為參數調用netfilter框架。

    2 內核的任何模塊可以對每種協議的一個或多個鉤子進行注冊,實現掛接,這樣當某個數據包被傳遞給netfilter框架時,內核能檢測是否有任何模塊對該協議和鉤子函數進行了注冊。若注冊了,則調用該模塊的注冊時使用的回調函數,這樣這些模塊就有機會檢查(可能還會修改)該數據包、丟棄該數據包及指示netfilter將該數據包傳入用戶空間的隊列。

    3 那些排隊的數據包是被傳遞給用戶空間的異步地進行處理。一個用戶進程能檢查數據包,修改數據包,甚至可以重新將該數據包通過離開內核的同一個鉤子函數中注入到內核中。

        所有的包過濾/NAT等等都基于該框架。內核網絡代碼中不再有到處都是的、混亂的修改數據包的代碼了。當前netfilter框架在IPv4、IPv6及Decnet網絡棧中被實現。

    二、為什么需要Netfilter?

        其實這個問題也可以變為ipchains有什么缺點導致被拋棄?下面只是其中的幾個原因:

        因為基于2.2內核的ipchains沒有提供傳遞數據包到用戶空間的框架,所以任何需要對數據包進行處理的代碼都必須運行在內核空間,而內核編程卻非常復雜,而且只能用C語言實現,并且容易出現錯誤并對內核穩定性造成威脅。


        透明代理實現非常復雜,必須查看每個數據包來判斷是否有專門處理該地址的socket。網絡棧代碼中在11個文件中共出現了34個"#ifdef"條件編譯。


        創建一個不依賴于接口地址的數據報過濾規則是不可能實現的。我們必須利用本地接口地址來判斷數據報是本地發出、還是發給本地的或是轉發的。轉發鏈只有輸出接口的信息,因此管理員必需考慮數據報的源。


        偽裝和數據包過濾都在同一個模塊內實現,導致防火墻代碼過于復雜。


        IPchains代碼即不模塊化又不易于擴展(例如對mac地址的過濾)

    三、Netfilter的作者

        Netfilter框架的概念的提出及主要實現是由Rusty Russell完成的,他是ipchains的合作完成者及當前linux內核IP防火墻的維護者。還有Marc Boucher、James Morris、Harald Welte等都參與了Netfilter項目。

    四、Netfilter在IPv4中的結構

        一個數據包按照如下圖所示的過程通過Netfilter系統:


    --->[1]--->[ROUTE]--->[3]--->[4]--->
    | ^
    local| |
    | [ROUTE]
    v |
    [2] [5]
    | ^
    | |
    v |

    從圖中可以看到IPv4一共有5個鉤子函數,分別為:

    1 NF_IP_PRE_ROUTING
    2 NF_IP_LOCAL_IN
    3 NF_IP_FORWARD
    4 NF_IP_POST_ROUTING
    5 NF_IP_LOCAL_OUT

        數據報從左邊進入系統,進行IP校驗以后,數據報經過第一個鉤子函數NF_IP_PRE_ROUTING[1]進行處理;然后就進入路由代碼,其決定該數據包是需要轉發還是發給本機的;若該數據包是發被本機的,則該數據經過鉤子函數NF_IP_LOCAL_IN[2]處理以后然后傳遞給上層協議;若該數據包應該被轉發則它被NF_IP_FORWARD[3]處理;經過轉發的數據報經過最后一個鉤子函數NF_IP_POST_ROUTING[4]處理以后,再傳輸到網絡上。

        本地產生的數據經過鉤子函數NF_IP_LOCAL_OUT [5]處理可以后,進行路由選擇處理,然后經過NF_IP_POST_ROUTING[4]處理以后發送到網絡上。

    五、Netfilter基礎

        從上面關于IPv4的netfilter的例子討論,可以看到鉤子函數是如何被激活的。

        內核模塊可以對一個或多個這樣的鉤子函數進行注冊掛接,并且在數據報經過這些鉤子函數時被調用,從而模塊可以修改這些數據報,并向netfilter返回如下值:

    NF_ACCEPT 繼續正常傳輸數據報
    NF_DROP 丟棄該數據報,不再傳輸
    NF_STOLEN 模塊接管該數據報,不要繼續傳輸該數據報
    NF_QUEUE 對該數據報進行排隊(通常用于將數據報給用戶空間的進程進行處理)
    NF_REPEAT 再次調用該鉤子函數

    六、使用iptables進行數據報選擇

        一個基于Netfilter框架的、稱為iptables的數據報選擇系統在Linux2.4內核中被應用,其實它就是ipchains的后繼工具,但卻有更強的可擴展性。

        內核模塊可以注冊一個新的規則表(table),并要求數據報流經指定的規則表。這種數據報選擇用于實現數據報過濾(filter表),網絡地址轉換(Nat表)及數據報處理(mangle表)。

        Linux2.4內核提供的這三種數據報處理功能都基于netfilter的鉤子函數和IP表。它們是獨立的模塊,相互之間是獨立的。它們都完美的集成到由Netfileter提供的框架中。

    包過濾
        filter表格不會對數據報進行修改,而只對數據報進行過濾。iptables優于ipchains的一個方面就是它更為小巧和快速。它是通過鉤子函數NF_IP_LOCAL_IN, NF_IP_FORWARD及NF_IP_LOCAL_OUT接入netfilter框架的。因此對于任何一個數據報只有一個地方對其進行過濾。這相對ipchains來說是一個巨大的改進,因為在ipchains中一個被轉發的數據報會遍歷三條鏈。


    NAT
        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的一個特例)。


    數據報處理(Packet mangling)
        mangle表格在NF_IP_PRE_ROUTING和NF_IP_LOCAL_OUT鉤子中進行注冊。使用mangle表,可以實現對數據報的修改或給數據報附上一些帶外數據。當前mangle表支持修改TOS位及設置skb的nfmard字段。

    七、連接跟蹤

        連接跟蹤是NAT的基礎,但是已經作為一個單獨的模塊被實現。該功能用于對包過濾功能的一個擴展,使用連接跟蹤來實現“基于狀態”的防火墻。

    第二部分 使用iptables及netfilter進行數據包過濾

    一、概述

        下面的內容要求具有對TCP/IP,路由,防火墻及包過濾的基本概念的了解。

        在第一部分已經解釋過,filter表和三個鉤子進行了掛接,因此提供了三條鏈進行數據過濾。所有來自于網絡,并且發給本機的數據報會遍歷INPUT規則鏈。所有被轉發的數據報將僅僅遍歷FORWARD規則鏈。最后,本地發出的數據報將遍歷OUTPUT鏈。

    二、向規則鏈中插入規則

        Linux2.4提供了一個簡潔強大的工具"iptables"來插入/刪除/修改規則鏈中的規則。這里并不對iptalbes進行詳細的介紹,而只是討論它的主要的一些特性:

        該命令實現對所有的ip表進行處理,當前包括filter,nat及mangle三個表格,及以后擴展的表模塊。
        該命令支持插件來支持新的匹配參數和目標動作。因此對netfilter的任何擴展都非常的簡單。僅僅需要編寫一個完成實際目標動作處理的模塊和iptalbes插件(動態連接庫)來添加所需要的一切。它有兩個實現:iptables(IPV4)及ip6tables。兩者都基于相同的庫和基本上相同的代碼。

    基本的iptables命令
        一個iptables命令基本上包含如下五部分:

    希望工作在哪個表上
    希望使用該表的哪個鏈
    進行的操作(插入,添加,刪除,修改)
    對特定規則的目標動作
    匹配數據報條件
    基本的語法為:

    iptables -t table -Operation chain -j target match(es)
    例如希望添加一個規則,允許所有從任何地方到本地smtp端口的連接:

    iptables -t filter -A INPUT -j ACCEPT -p tcp --dport smtp

        當然,還有其他的對規則進行操作的命令如:清空鏈表,設置鏈缺省策略,添加一個用戶自定義的鏈....

    基本操作:

    -A 在鏈尾添加一條規則
    -I 插入規則
    -D 刪除規則
    -R 替代一條規則
    -L 列出規則

    基本目標動作,適用于所有的鏈

    ACCEPT 接收該數據報
    DROP 丟棄該數據報
    QUEUE 排隊該數據報到用戶空間
    RETURN 返回到前面調用的鏈
    foobar 用戶自定義鏈
    基本匹配條件,適用于所有的鏈

    -p 指定協議(tcp/icmp/udp/...)
    -s 源地址(ip address/masklen)
    -d 目的地址(ip address/masklen)
    -i 數據報輸入接口
    -o 數據報輸出接口
    出了基本的操作,匹配和目標還具有各種擴展。

    三、iptables的數據報過濾匹配條件擴展

        有各種各樣的數據包選擇匹配條件擴展用于數據包過濾。這里僅僅簡單的說明來讓你感受擴展匹配的強大之處。

        這些匹配擴展給了我們強大的數據報匹配手段:

    TCP匹配擴展能匹配源端口,目的端口,及tcp標記的任意組合,tcp選項等。
    UPD匹配擴展能匹配源端口和目的端口
    ICMP匹配擴展能匹配ICMP類型
    MAC匹配擴展能匹配接收到的數據的mac地址
    MARK匹配擴展能匹配nfmark
    OWNE匹配擴展(僅僅應用于本地產生的數據報)來匹配用戶ID,組ID,進程ID及會話ID
    LIMIT擴展匹配用來匹配特定時間段內的數據報限制。這個擴展匹配對于限制dos攻擊數據流非常有用。
    STATE匹配擴展用來匹配特定狀態下的數據報(由連接跟蹤子系統來決定狀態),可能的狀態包括:
    INVALID (不匹配于任何連接)
    ESTABLISHED (屬于某個已經建立的鏈接的數據報)
    NEW (建立連接的數據報)
    RELATED (和某個已經建立的連接有一定相關的數據報,例如一個ICMP錯誤消息或ftp數據連接)
    TOS匹配擴展用來匹配IP頭的TOS字段的值。

    四、iptables的數據報過濾目標動作擴展

    LOG 將匹配的數據報傳遞給syslog()進行記錄
    ULOG 將匹配的數據適用用戶空間的log進程進行記錄
    REJECT 不僅僅丟棄數據報,同時返回給發送者一個可配置的錯誤信息
    MIRROR 互換源和目的地址以后重新傳輸該數據報

    第三部分 利用iptables和netfilter進行NAT

        linux以前的內核僅僅支持有限的NAT功能,被稱為偽裝。Netfilter則支持任何一種NAT。一般來講NAT可以分為源NAT和目的NAT。

        源NAT在數據報經過NF_IP_POST_ROUTING時修改數據報的源地址。偽裝是一個特殊的SNAT。

        目的NAT在數據報經過NF_IP_LOCAL_OUT或NF_IP_PRE_ROUTING 時修改數據報目的地址。端口轉發和透明代理都是DNAT。

    一、iptables的NAT目標動作擴展

    SNAT
    變換數據包的源地址。

    例:

    iptables -t nat -A POSTROUTING -j SNAT --to-source 1.2.3.4


    MASQUERADE
        用于具有動態IP地址的撥號連接的SNAT,類似于SNAT,但是如果連接斷開,所有的連接跟蹤信息將被丟棄,而去使用重新連接以后的IP地址進行IP偽裝。

    例:

    iptables -t nat -A POSTROUTING -j MASQUERADE -o ppp0
    DNAT
        轉換數據報的目的地址,這是在PREROUTING鉤子鏈中處理的,也就是在數據報剛剛進入時。因此Linux隨后的處理得到的都是新的目的地址。

    例:

    iptables -t nat -A PREROUTING -j DNAT --to-destination 1.2.3.4:8080 -p tcp --dport 80 -i eth1


    REDIRECT
        重定向數據報為目的為本地,和DNAT將目的地址修改為接到數據報的接口地址情況完全一樣。

    例:

    iptables -t nat -A PREROUTING -j REDIRECT --to-port 3128 -i eth1 -p tcp --dport 80
     
    第四部分 利用iptables和netfilter進行數據報處理(Packet mangling)

    mangle表提供了修改數據報各個字段的值的方法。

    一、針對數據包處理的目標擴展

    MARK
        設置nfmark字段的值。我們可以修改nfmark字段的值。nfmark僅僅是一個用戶定義的數據報的標記(可以是無符號長整數范圍內的任何值)。該標記值用于基于策略的路由,通知ipqmpd (運行在用戶空間的隊列分撿器守護進程)將該數據報排隊給哪個哪個進程等信息。

    例: iptables -t mangle -A PREROUTING -j MARK --set-mark 0x0a -p tcp

    TOS
        設置數據報的IP頭的TOS字段值。若希望適用基于TOS的數據報調度及路由,這個功能是非常有用處的。

    例: iptables -t mangle -A PREROUTING -j TOS --set-tos 0x10 -p tcp --dport ssh

    第五部分 排隊數據報到用戶空間

        前面已經提到,任何時候在任何nefilter規則鏈中,數據報都可以被排隊轉發到用戶空間去。實際的排隊是由內核模塊來完成的(ip_queue.o)。

        數據報(包括數據報的原[meta]數據如nfmark和mac地址)通過netlink socket被發送給用戶空間進程.該進程能對數據報進行任何處理。處理結束以后,用戶進程可以將該數據報重新注入內核或者設置一個對數據報的目標動作(如丟棄等)。

        這是netfilter的一個關鍵技術,使用戶進程可以進行復雜的數據報操作。從而減輕了內核空間的復雜度。用戶空間的數據報操作進程能很容易的適用ntfilter提供的稱為libipq的庫來進行開發。

    參考文獻:

    LaForge@#s talk about Netfilter

    The netfilter framework in Linux 2.4

    Linux 2.4 Packet Filtering HOWTO

    Linux 2.4 NAT HOWTO

    netfilter hacking HOWTO

    (作者:ideal)

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>