Netfilter組件也稱為內(nèi)核空間,是集成在內(nèi)核中的一部分,是Linux 防火墻架構的核心,是各種與防火墻相關模塊的實現(xiàn)基礎。它是Linux內(nèi)核的一個子系統(tǒng),自身實現(xiàn)的只是一個通用的框架,不依賴于具體的協(xié)議。它的作用是定義、保存相應的規(guī)則,以實現(xiàn)防火墻功能。而iptables組件是一種工具,也稱為用戶空間,用以插入、修改、刪除信息的過濾規(guī)則及其他配置。管理員可以通過iptables來設置適合當前應用環(huán)境的規(guī)則,而這些規(guī)則會保存在內(nèi)核空間中。
Netfilter通過提供一個鉤子(hook)函數(shù)通用接口來實現(xiàn)各個子模塊、各種協(xié)議對數(shù)據(jù)包的特殊處理。如果某個模塊需要對流經(jīng)網(wǎng)絡協(xié)議棧中的某些數(shù)據(jù)包進行處理時,它就需要向Netfilter系統(tǒng)注冊鉤子函數(shù),告訴Netfilter它所感興趣的數(shù)據(jù)包協(xié)議類型和處理的鉤子點。當這些期待的數(shù)據(jù)包通過Netfilter框架中注冊過的鉤子點時,相應的鉤子函數(shù)就會被調(diào)用,在鉤子函數(shù)中就可以實現(xiàn)對數(shù)據(jù)包處理過程:丟棄或者更改數(shù)據(jù)包內(nèi)容。
一般來說,每個網(wǎng)絡連接包括以下信息:源地址、目的地址、源端口和目的端口,協(xié)議類型、連接狀態(tài)(TCP協(xié)議)和超時時間等。防火墻通常把這些信息稱作狀態(tài),能夠檢測每個連接狀態(tài)的防火墻稱作狀態(tài)包過濾防火墻。它主要完成兩部分的工作,除了能夠完成簡單包過濾防火墻的工作外,它還在內(nèi)存中維護一個跟蹤連接狀態(tài)的表,從而比簡單包過濾防火墻具有更大的安全性。這些狀態(tài)可以一起使用,以便匹配數(shù)據(jù)包。這可以使得防火墻非常強壯和有效。以前,經(jīng)常打開1024以上的所有端口來放行應答的數(shù)據(jù)?,F(xiàn)在,有了狀態(tài)檢測機制,就不需再這樣了。因為可以只開放那些有應答數(shù)據(jù)的端口,其他的都可以關閉,這樣就安全多了。
狀態(tài)檢測技術是基于動態(tài)包過濾技術之上發(fā)展而來的新技術。這種防火墻加入了一種被稱為狀態(tài)檢測的模塊,它會在不影響網(wǎng)絡正常工作的情況下,采用抽取相關數(shù)據(jù)的方法對網(wǎng)絡通信的各個層進行監(jiān)測,并根據(jù)各種過濾規(guī)則作出安全決策。狀態(tài)檢測技術保留了包過濾技術對數(shù)據(jù)包的頭部、協(xié)議、地址、端口等信息進行分析的功能,并進一步發(fā)展為會話過濾功能。在每個連接建立時,防火墻會為這個連接構造一個會話狀態(tài),里面包含了這個連接數(shù)據(jù)包的所有信息,以后這個連接都基于這個狀態(tài)信息進行。這種檢測方法的優(yōu)點是能對每個數(shù)據(jù)包的內(nèi)容進行監(jiān)控,一旦建立了一個會話狀態(tài),則此后的數(shù)據(jù)傳輸都要以這個會話狀態(tài)作為依據(jù)。而且,會話狀態(tài)的保留是有時間限制的,在限制的范圍內(nèi)如果沒有再進行數(shù)據(jù)傳輸,這個會話狀態(tài)就會被丟棄。
狀態(tài)檢測防火墻將屬于同一連接的所有數(shù)據(jù)包作為一個整體數(shù)據(jù)流來看待,建立連接狀態(tài)表。并將規(guī)則表與連接狀態(tài)表結合判斷,來對流經(jīng)防火墻的數(shù)據(jù)包進行有效的過濾。狀態(tài)檢測技術可以對包的內(nèi)容進行分析,從而擺脫了傳統(tǒng)防火墻僅局限于過濾包頭信息的弱點,而且這種防火墻可以不必開放過多的端口,從而進一步杜絕了可能因開放過多端口而帶來的安全隱患。
狀態(tài)檢測機制不再把數(shù)據(jù)包之間看作是無關的,它不再對單個數(shù)據(jù)包進行處理,而是以連接會話為單位進行檢測。它在協(xié)議棧底層截去數(shù)據(jù)包,然后分析這些數(shù)據(jù)包。并且將當前數(shù)據(jù)包及其狀態(tài)信息和其前一時刻的數(shù)據(jù)包及其狀態(tài)信息進行比較,從而得到該數(shù)據(jù)包的控制信息,達到保護網(wǎng)絡安全的目的??傊?,它的思想就是將屬于同一連接的所有數(shù)據(jù)包作為一個整體的數(shù)據(jù)流來看待。狀態(tài)檢測機制不對數(shù)據(jù)包進行過濾處理,它只是跟蹤并記錄數(shù)據(jù)包的走向,數(shù)據(jù)報過濾、網(wǎng)絡地址轉(zhuǎn)換就是建立在狀態(tài)檢測基礎上的。由于狀態(tài)檢測機制是在內(nèi)核模式下進行的,所以速度很快。
Netfilter/iptables防火墻系統(tǒng)使用連接跟蹤技術來實現(xiàn)狀態(tài)檢測功能。連接跟蹤作為一個獨立運行的模塊,它是動態(tài)包過濾、地址轉(zhuǎn)換的基礎。連接跟蹤機制依靠設置在Netfilter防火墻框架中的鉤子函數(shù),來檢查每一個有效的連接的狀態(tài),然后根據(jù)這些信息決定數(shù)據(jù)包是否可以通過防火墻。
連接跟蹤機制的核心是在協(xié)議棧底層為數(shù)據(jù)包建立連接狀態(tài)信息,通過識別數(shù)據(jù)包的狀態(tài),避免了包過濾防火墻僅考查數(shù)據(jù)包的IP地址和端口等幾個參數(shù)而不關心數(shù)據(jù)包之間相互聯(lián)系的缺點。在防火墻的核心部分建立動態(tài)的連接狀態(tài)表,并將進出網(wǎng)絡的數(shù)據(jù)當成一個個的會話,利用狀態(tài)表跟蹤每一個會話狀態(tài)。連接跟蹤機制對每一個包的檢查不僅根據(jù)規(guī)則表更考慮了數(shù)據(jù)包是否符合會話所處的狀態(tài),這種方式可以帶來更高的效率、更有力的訪問控制和更強的安全能力。
當數(shù)據(jù)包到達時,防火墻的連接跟蹤機制根據(jù)連接狀態(tài)表中的信息來決定包的狀態(tài)。如果該IP包是屬于一個已經(jīng)建立的連接那么就直接越過協(xié)議棧中的規(guī)則檢測部分,交給上層協(xié)議處理。如果該IP包不屬于一個已經(jīng)建立的連接,那么轉(zhuǎn)入正常的規(guī)則檢測部分,然后根據(jù)規(guī)則檢測的結果決定對IP包的操作。同時,連接狀態(tài)表的使用大大降低了把數(shù)據(jù)包偽裝成一個正在使用的連接的一部分的可能。
Netfilter/iptables防火墻的狀態(tài)檢測機制還能對應用層的信息進行檢查,即對特定類型的數(shù)據(jù)包中的數(shù)據(jù)進行檢測。可以檢查ICMP報文所承載的數(shù)據(jù),可以檢查FTP、SMTP數(shù)據(jù)包中是否包含了不安全的命令,可以過濾HTTP協(xié)議的不安全的請求,甚至能實現(xiàn)簡單的URL或關鍵字過濾。
Netfilter的連接跟蹤模塊(nf_conntrack.ko)可以將進入?yún)f(xié)議棧的報文建立連接,進行連接跟蹤。因為使用狀態(tài)檢測,所以如果沒有數(shù)據(jù)率限制時,只需要檢測首包,也就是在連接跟蹤表中還未建立連接的報文。如果發(fā)現(xiàn)是狀態(tài)為已建立連接,不用匹配任何規(guī)則,直接放行。
在每一條數(shù)據(jù)包檢查路徑上,連接跟蹤、包過濾和地址轉(zhuǎn)換都注冊了相應的鉤子函數(shù),并創(chuàng)建與之相關的數(shù)據(jù)結構,完成其功能。以防火墻轉(zhuǎn)發(fā)數(shù)據(jù)包為例,鉤子執(zhí)行功能點檢查的順序如下:連接跟蹤、目的地址轉(zhuǎn)換、包過濾、源地址轉(zhuǎn)換、連接跟蹤。
連接跟蹤在路徑上出現(xiàn)了兩次,所起作用是:在第一個點上創(chuàng)建連接跟蹤的結構,即連接跟蹤表(庫),這個結構會在后面的目的地址轉(zhuǎn)換和包過濾中被使用;在第二個點上將連接跟蹤的結構加載到系統(tǒng)的連接表中。
連接跟蹤表實際是一個以哈希散列值排列的雙向鏈表數(shù)組,用來描述所有的連接狀態(tài),鏈表記錄元素即為連接記錄所包含的數(shù)據(jù)包五元組及其它必需的狀態(tài)信息等,用來唯一標識一個連接。連接跟蹤表是一塊內(nèi)存空間,采用了高效的插入、修改、移動、刪除等算法,故匹配速度比規(guī)則集更高效更快速。連接跟蹤表的容量不是無限大,默認值隨著硬件配置,特別是內(nèi)存大小而改變。實際上,百萬條記錄的連接跟蹤表也不會占用超過1GB的內(nèi)存。此外,默認的防火墻最大連接跟蹤數(shù)目是有限制的,與Linux系統(tǒng)的體系結構、內(nèi)存容量是有一定相關性的。當然,如果認為默認的最大連接跟蹤數(shù)不足,是可以通過修改連接跟蹤模塊的參數(shù)值調(diào)整的。
無論是流入、轉(zhuǎn)發(fā),還是防火墻本地進程產(chǎn)生的數(shù)據(jù)包,在到達網(wǎng)絡層之后,首先利用這個狀態(tài)檢測機制來查看連接跟蹤表是否具有該數(shù)據(jù)包的軌跡連接項,如果沒有數(shù)據(jù)包的軌跡項,就將為該數(shù)據(jù)包在連接跟蹤表中初始化一個軌跡項,在此時將檢驗該連接是否是某個期望的連接,如果是就將其狀態(tài)信息定義為相關連接,如果沒有相關性,就將其信息值定義為新建連接,數(shù)據(jù)包在連接跟蹤表中初始化對應的軌跡項后繼續(xù)根據(jù)優(yōu)先級調(diào)用防火墻代碼處理;如果在連接跟蹤表中找到了對應的軌跡項,我們將把這個軌跡項定義為舊值,再根據(jù)這個舊值以及輸入的數(shù)據(jù)包的包類型,連接方向來確定一個新值,并用這個新值來更新連接跟蹤表。
簡單說來,Netfilter在協(xié)議棧底層截取數(shù)據(jù)包進行分析,并且將當前數(shù)據(jù)包及其狀態(tài)信息和其前一時刻數(shù)據(jù)包及狀態(tài)信息進行比較,得到該數(shù)據(jù)包控制信息。Linux內(nèi)核的連接跟蹤模塊將數(shù)據(jù)包的連接分為四個狀態(tài):NEW、ESTABLISHED、RELATED和INVALID。通過對這四種狀態(tài)的匹配,實現(xiàn)狀態(tài)化防火墻的所有功能。需要指明的是,這四種狀態(tài)是與協(xié)議無關的,即對TCP、UDP、ICMP 三種協(xié)議均有效,切記不可與面向連接的TCP狀態(tài)轉(zhuǎn)化機制相混淆。對這四種狀態(tài)的描述如下:
NEW,表示分組將要或已經(jīng)開始建立一個新的連接,或者是這個數(shù)據(jù)包和一個還沒有在兩端都有數(shù)據(jù)發(fā)送的連接有關,它即將通過防火墻的安全規(guī)則進行匹配了。顯而易見,此狀態(tài)的數(shù)據(jù)包必然與Netfilter規(guī)則集匹配,并經(jīng)此處理過程后建立連接跟蹤表。
ESTABLISHED,意思是分組是完全有效的,而且屬于一個已建立的連接,這個連接的兩端都已經(jīng)有數(shù)據(jù)發(fā)送。此狀態(tài)表明狀態(tài)檢測機制已經(jīng)看到兩個方向上的數(shù)據(jù)傳輸并且將不斷匹配它。處于ESTABLISHED狀態(tài)的連接很容易理解,只要發(fā)送數(shù)據(jù)包并接到應答,連接就處于ESTABLISHED狀態(tài)。應答數(shù)據(jù)包到達或通過防火墻,此連接就從NEW狀態(tài)轉(zhuǎn)變到ESTABLISHED狀態(tài)了。即使該數(shù)據(jù)包是ICMP錯誤和重定向數(shù)據(jù)包,只要該數(shù)據(jù)包是請求包的回應包,該連接的狀態(tài)都將轉(zhuǎn)變?yōu)镋STABLISHED狀態(tài)。
RELATED,說明分組正在建立一個新的連接,這個連接是和一個已建立的連接相關的。也就是說,當一個連接和某個已處于ESTABLISHED狀態(tài)的連接有關系時,就被認為是RELATED狀態(tài)。RELATED是個比較麻煩的狀態(tài),這說明一個狀態(tài)要成為RELATED狀態(tài),則必須先有ESTABLISHED連接狀態(tài),這 個ESTABLISHED狀態(tài)再產(chǎn)生一個該連接以外的連接,這樣這個新的連接就處于RELATED狀態(tài),當然前提是連接跟蹤模塊要能理解RELATED狀態(tài)。以FTP為例,每個FTP 由數(shù)據(jù)連接和控制連接組成,數(shù)據(jù)連接就是和控制連接有關聯(lián)的。如果沒有RELATED狀態(tài),數(shù)據(jù)連接是無法正確建立的。有了這個狀態(tài),ICMP特定類型的響應、FTP傳輸?shù)炔拍艽┻^防火墻正常工作。一言以蔽之,這個RELATED狀態(tài)是某個處于ESTABLISHED狀態(tài)的數(shù)據(jù)包所期望的、也是被動產(chǎn)生的,不屬于現(xiàn)在任何連接的新連接。
INVALID,表示分組對應的連接是未知的,說明數(shù)據(jù)包不能被識別屬于哪個連接或沒有任何狀態(tài)。這就意味著這個包沒有己知的流或連接與之關聯(lián),也可能是它包含的數(shù)據(jù)或包頭有問題。狀態(tài)為INVALID的包就是狀態(tài)不明的包,也就是不屬于前面3種狀態(tài)的包,這類包一般會被視為惡意包而被丟棄。有多種原因產(chǎn)生該情況的數(shù)據(jù)包,比如連接跟蹤表溢出,系統(tǒng)內(nèi)存耗盡,或ICMP報錯消息對任何已知連接不作響應。通常的選擇是丟棄此狀態(tài)下的所有包。要特別指出的是,對于很多掃描攻擊工具構造的掃描或攻擊報文,Netfilter/iptables會將其標記為INVALID狀態(tài),如需要記錄或追蹤惡意數(shù)據(jù)包的來源,深入研究如何處理INVALID狀態(tài)的數(shù)據(jù)包就十分關鍵。
對于TCP 協(xié)議來說該連接的第一個數(shù)據(jù)包是SYN數(shù)據(jù)包。對于Ping 操作的ICMP 數(shù)據(jù)包的第一個包是回聲請求包。但對UDP 協(xié)議或其它數(shù)據(jù)包來說,當它們不是SYN數(shù)據(jù)包時,連接跟蹤機制也把它的第一個數(shù)據(jù)包當成NEW 狀態(tài)的數(shù)據(jù)包。
NEW,表示這個分組需要發(fā)起一個連接,或者說,分組對應的連接在兩個方向上都沒有進行過分組傳輸。NEW說明這個包是我們看到的第一個包。意思就是,這是連線跟蹤模塊看到的某個連接第一個包,它即將被匹配了。比如,我們看到一個SYN包,是我們所留意的連接的第一個包,就要匹配它。第一個包也可能不是SYN包,但它仍會被認為是NEW狀態(tài)。比如一個特意發(fā)出的探測包,可能只有RST位,但仍然是NEW。某些精心構造的網(wǎng)絡掃描或攻擊報文,與此類似。
當下層網(wǎng)絡接收到初始化連接同步(SYN)包,將被Netfilter規(guī)則庫檢查。該數(shù)據(jù)包在規(guī)則鏈中依次進行比較。如果該數(shù)據(jù)包應該被丟棄,發(fā)送一個復位(RST)包到遠程主機,否則連接接收。這次連接的信息將被保存在連接跟蹤信息表中,并表明該數(shù)據(jù)包所應有的狀態(tài)。這個連接跟蹤信息表位于內(nèi)核模式下,其后的網(wǎng)絡包就將與此連接跟蹤信息表中內(nèi)容進行比較,根據(jù)信息表中信息來決定該數(shù)據(jù)包的操作。因為數(shù)據(jù)包首先是與連接跟蹤信息表進行比較,只有SYN包才與規(guī)則庫進行比較,數(shù)據(jù)包與連接跟蹤信息表的比較都是在內(nèi)核模式下進行的,所以速度很快。
Netfilter/iptables的連接狀態(tài)跟蹤的全功能實現(xiàn),對基于TCP協(xié)議的應用而言相對容易;對基于TCP與UDP組合協(xié)議的應用(如SIP),特別是在NAT環(huán)境下,需借助應用級網(wǎng)關技術;對基于TCP(UDP)與ICMP組合協(xié)議的應用,如路由探測工具,則是充分利用了ICMP協(xié)議某些類型數(shù)據(jù)包的“雙IP包頭”特性。所謂雙IP包頭是指網(wǎng)絡設備生成特定類型的ICMP響應報文時,會將引發(fā)此響應的原數(shù)據(jù)包(不管是TCP、UDP還是ICMP包)原封不動地封裝在ICMP響應應答數(shù)據(jù)包中,最為ICMP報文的承載數(shù)據(jù)。在此以路由探測工具所產(chǎn)生的數(shù)據(jù)包為例,進行拓展分析,加深對NEW、ESTABLISHED、RELATED這三種狀態(tài)的理解。
Windows主 機 到Netfilter/iptables防火墻自身IP地址的路由探測包,從INPUT鏈流入的ICMP回聲請求數(shù)據(jù)包狀態(tài)為NEW,從OUTPUT鏈流出的ICMP 回聲應答數(shù)據(jù)包的狀態(tài)總是為ESTABLISHED。而穿過防火墻到遠端主機的路由探測包,從FORWARD鏈流入的ICMP回聲請求數(shù)據(jù)包狀態(tài)為NEW,目標遠程主機返回穿過FORWARD鏈的ICMP回聲應答數(shù)據(jù)包的狀態(tài)總是為ESTABLISHED,而探測路徑下游的路由器因路由探測數(shù)據(jù)包的TTL值為0,而生成的反饋給源Windows主機的ICMP 超時數(shù)據(jù)包的狀態(tài)為RELATED。
Linux主機到Netfilter/iptables防火墻自身IP地址的路由探測包,從INPUT鏈流入的UDP數(shù)據(jù)包狀態(tài)為NEW,從OUTPUT鏈流出的ICMP 目標不可達數(shù)據(jù)包的狀態(tài)總是為RELATED。而穿過防火墻到遠端主機的路由探測包,流入FORWARD鏈的UDP數(shù)據(jù)包的狀態(tài)總是為NEW,從目標遠端主機返回的ICMP 目標不可達數(shù)據(jù)包以及下游探測路徑中的路由器因路由探測數(shù)據(jù)包的TTL值為0,而生成的反饋給源端Linux主機的ICMP超時數(shù)據(jù)包的狀態(tài)總是為RELATED。
Linux到Netfilter/iptables防火墻自身的基于TCP協(xié)議的路由探測,如利用tcptraceroute工具生成的探測報文,進入INPUT鏈的TCP SYN數(shù)據(jù)包狀態(tài)為NEW,從OUTPUT鏈流出的TCP數(shù)據(jù)包的狀態(tài)為ESTABLISHED。而穿過防火墻到目標遠端主機的路由探測,經(jīng)FORWARD鏈轉(zhuǎn)發(fā)的TCP SYN數(shù)據(jù)包的狀態(tài)為NEW,下游探測路徑中的路由器因路由探測數(shù)據(jù)包的TTL值為0,而生成的反饋給源端Linux主機的ICMP 超時數(shù)據(jù)包的狀態(tài)總是為RELATED,而遠端主機返回的TCP數(shù)據(jù)包的狀態(tài)總是為ESTABLISHED。
Linux 內(nèi)核2.4/2.6中的防火墻Netfilter框架在應用層提供了iptables 這個工具,用戶通過它可以對內(nèi)核進行添加或查詢規(guī)則等操作。前文所述的四種狀態(tài)定義在命令接口的iptables 命令(基于Centos6.4,2.6.32內(nèi)核)的“-m state”或“-m conntrack”匹配中。當使用“-m state”時,iptables會自動加載xt_state.ko模塊;當使用“-m conntrack”時,iptables自動加載xt_conntrack.ko模塊。這兩個模塊位于/lib/modules/
編寫iptables匹配規(guī)則,要特別注意數(shù)據(jù)包流動的方向性,流入/流出規(guī)則成對匹配,轉(zhuǎn)發(fā)時要有對返回數(shù)據(jù)包的匹配規(guī)則,以保障數(shù)據(jù)包來回流動安全通暢。