【摘要】目前防火墻實現(xiàn)技術(shù)中關(guān)于數(shù)據(jù)包的處理方法,基本上都是采用BPF的包過濾算法,數(shù)據(jù)包的傳送采用復(fù)制的方式,增加了不必要的負荷。本文對FreeBSD操作系統(tǒng)下的netgraph機制進行了分析和描述,并針對內(nèi)容過濾防火墻,并和另外兩種常用的實現(xiàn)技術(shù)Squid,BPF進行了分析和比較。得出了基于netgraph機制的內(nèi)容過濾防火墻更優(yōu)越的結(jié)論。
【關(guān)鍵詞】netgraph;BPF;防火墻;Squid
1.引言
隨著因特網(wǎng)的廣泛使用,網(wǎng)絡(luò)安全成為一個很重要的問題。BPF具有靈活以及使用方便的優(yōu)點,也具有較快的運行速度,但是如果我們需要對內(nèi)容進行過濾的時候,傳統(tǒng)的BPF和應(yīng)用代理(例如squid)實現(xiàn)起來在速度和性能方面的卻并不是很好,而且也缺乏靈活性。為了增強多協(xié)議的支持以及提高處理的速度,提高系統(tǒng)的靈活性,我們基于netgraph機制進行了新的研究工作,并對三種實現(xiàn)技術(shù)的性能進行了比較。
2.netgraph機制
2.1 概述
netgraph機制是一個遵循Unix規(guī)范的一個內(nèi)核子系統(tǒng),它由許多模塊所組成,每個模塊完成一定的功能。直觀的來說,它是由nodes,edges組成。數(shù)據(jù)流沿著edge從一個node流向另外一個node。當(dāng)node收到數(shù)據(jù)包的時候,執(zhí)行一定的數(shù)據(jù)包處理操作,然后轉(zhuǎn)發(fā)數(shù)據(jù)包到另外一個node。在這個數(shù)據(jù)包處理操作中,可以是簡單的添加和刪除數(shù)據(jù)包頭,也可以添加更具體的處理操作(例如數(shù)據(jù)包的內(nèi)容合成,校驗等)。netgraph子系統(tǒng)設(shè)計思想采用了System V的流技術(shù),因此具有更快的速度、靈活性和更高的處理效率。
netgraph對每一個node和hook結(jié)構(gòu)采用引用計數(shù)。每一個到node或者hook的引用當(dāng)作一次計數(shù)。通過這種方式對內(nèi)存進行合理的管理和分配,避免內(nèi)存的浪費。因為netgraph運行在內(nèi)核中,所以需要考慮優(yōu)先級的問題,netgraph采取splnet來進行優(yōu)先級的分配和釋放。特別是在和用戶進程進行交互的時候,更需要特別考慮優(yōu)先級的問題。避免造成系統(tǒng)的死鎖或者阻塞。
2.2 netgraph在TCP/IP協(xié)議棧中位置
圖1 netgraph在TCP/IP協(xié)議棧中位置
簡單的說,在網(wǎng)卡驅(qū)動程序接收到來自網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)包以后,首先進行校驗和合法性檢查,如果是合法的數(shù)據(jù)包,則把數(shù)據(jù)包封裝到一個mbuf類型的數(shù)據(jù)結(jié)構(gòu)里。然后傳遞給ethernet網(wǎng)卡數(shù)據(jù)處理模塊函數(shù)ether_input的輸入隊列,ether_input從輸入隊列里讀入數(shù)據(jù)進行處理以后,然后傳遞給netgraph內(nèi)核子模塊的處理函數(shù)ng_input的輸入隊列,如果系統(tǒng)啟動netgraph子系統(tǒng),則數(shù)據(jù)包交給ng_input的輸入隊列,如果系統(tǒng)沒有啟動netgraph子系統(tǒng),則首先把數(shù)據(jù)copy一份給BPF進行處理,然后把數(shù)據(jù)轉(zhuǎn)發(fā)給上層協(xié)議處理單元進行處理。所以我們的netgraph子系統(tǒng)在上層協(xié)議處理單元處理數(shù)據(jù)以前就截獲了數(shù)據(jù)包,所以處理速度更快。
3.BPF與Squid分析
3.1 BPF技術(shù)介紹
BPF是berkeley packet filter的縮寫,BPF是一個核心態(tài)的組件,也是一個過濾器.BPF是一種比較理想的抓包方案。在核心態(tài)執(zhí)行,所以效率比較高,但是,只有少數(shù)OS支持(主要是一些BSD操作系統(tǒng).要使用這項功能前你必須修改kernel,以達成監(jiān)聽網(wǎng)絡(luò)的目的。像tcpdump和NFR這些程式都使用BPF。然而BSD的監(jiān)聽程式也都透過BPF來達成,如果有人拿到你系統(tǒng)的root權(quán)限的話,在系統(tǒng)上設(shè)定BPF功能反而幫助他們更容易的監(jiān)聽你的網(wǎng)路。如果沒有必要的話,不要設(shè)定kernel中BPF的功能。FreeBSD出廠的設(shè)定值是將這個功能關(guān)閉起來的。
如果內(nèi)核有多個BPF應(yīng)用程序,對每個數(shù)據(jù)包都要運行這幾個程序。問題在于很難從數(shù)據(jù)包過濾器程序推斷出應(yīng)用程序?qū)嶋H上對哪一種數(shù)據(jù)包感興趣,所以一般的解決方法就是始終運行過濾器。假設(shè)一個應(yīng)用程序注冊的BPF程序是獲取發(fā)往某個廣播地址的低速數(shù)據(jù)流。絕大多數(shù)以太網(wǎng)卡有一個64位入口的哈希表的硬件實現(xiàn)的廣播地址過濾器,用來忽略大多數(shù)不想要的廣播數(shù)據(jù)包,所以有可能以極低的開銷完成這一操作。但是由于有了BPF,內(nèi)核必須把接口設(shè)置為混雜模式,接收所有數(shù)據(jù)包,并對它們運行過濾器。不管怎樣,這樣確實可以工作,但考慮到對所要求的數(shù)據(jù)包進行的處理,就已經(jīng)變得過于麻煩了。
3.2 Squid技術(shù)分析
Squid是一個緩存internet數(shù)據(jù)的一個軟件,它接收用戶的下載申請,并自動處理所下載的數(shù)據(jù)。也就是說,當(dāng)一個用戶象要下載一個主頁時,它向Squid發(fā)出一個申請,要Squid替它下載,然后Squid連接所申請網(wǎng)站并請求該主頁,接著把該主頁傳給用戶同時保留一個備份,當(dāng)別的用戶申請同樣的頁面時,Squid把保存的備份立即傳給用戶,使用戶覺得速度相當(dāng)快。目前,Squid可以代理HTTP,F(xiàn)TP,GOPHER,SSL和WAIS協(xié)議,暫不能代理POP,NNTP等協(xié)議。
4.三種防火墻實現(xiàn)技術(shù)的比較
因為網(wǎng)關(guān)是一種攔截式的操作,BPF是一個旁路系統(tǒng),當(dāng)數(shù)據(jù)包傳送到了內(nèi)核以后,內(nèi)核從網(wǎng)卡截獲的數(shù)據(jù)包首先傳遞到ether_input隊列中,ether_input處理函數(shù)從ether_input輸入隊列中讀取數(shù)據(jù)包,然后轉(zhuǎn)發(fā)到BPF的輸入隊列中,接著判斷系統(tǒng)是否啟動netgraph內(nèi)核處理功能,如果啟動了這個功能,則把數(shù)據(jù)包轉(zhuǎn)發(fā)給netgraph進行處理,如果沒有啟動netgraph,則把數(shù)據(jù)包轉(zhuǎn)發(fā)給上層的協(xié)議處理輸入隊列(例如,IP,IPX輸入隊列等).從上邊的處理過程,我們可以看出,BPF是一個旁路式的系統(tǒng),把數(shù)據(jù)包COPY了一份交給它進行了處理,正常的數(shù)據(jù)包繼續(xù)向下邊傳輸進行處理,而netgraph是一個攔截式的處理,數(shù)據(jù)包交給了它以后,就不再向下邊傳輸,而直接對數(shù)據(jù)包進行了處理。
BPF對數(shù)據(jù)包的處理是利用一定的匹配策略和算法,對包頭符合一定規(guī)則的數(shù)據(jù)進行匹配,從而決定是丟棄數(shù)據(jù)包還是繼續(xù)處理。而我們的網(wǎng)關(guān)產(chǎn)品需要對內(nèi)容進行匹配和處理的操作,所以就是通過BPF進行處理,也需要對數(shù)據(jù)包進行合成的處理操作。所以現(xiàn)有的BPF匹配策略和算法對網(wǎng)關(guān)產(chǎn)品并沒有更多的可復(fù)用價值。
圖2 數(shù)據(jù)包的處理流程
與squid進行比較,squid的處理過程是在應(yīng)用層進行處理,而且squid是代理型的防火墻,它的優(yōu)點是在應(yīng)用層有豐富的庫函數(shù),有許多的庫函數(shù)可以供調(diào)用,而且開發(fā)起來速度非??欤瑢?shù)據(jù)的處理也非常的靈活,能夠?qū)τ脩魯?shù)據(jù)進行更多的處理操作,除了對url進行過濾以外還可以對內(nèi)容進行過濾,甚至可以利用語義識別的技術(shù)對特殊的關(guān)鍵字進行攔截的操作。缺點是:squid是利用realsocket的技術(shù)來進行數(shù)據(jù)包數(shù)據(jù)的處理的,這樣沒有辦法得到用戶的ethernet網(wǎng)頭的信息,如果需要對物理地址進行處理的時候,則沒有辦法得到ethernet網(wǎng)頭的信息,而且如果想讓squid作為網(wǎng)關(guān)產(chǎn)品,用戶必須在自己的個人計算機上邊設(shè)置代理服務(wù)器的地址和端口號,這樣就導(dǎo)致了管理和操作起來非常的不方便。而且處理能力也因為受代理服務(wù)器的限制而速度變慢。另外squid不能監(jiān)聽所有的端口,它只能監(jiān)聽固定的端口,這樣也缺乏靈活性。在性能方面,squid也是旁路系統(tǒng),同樣也有數(shù)據(jù)的copy操作,并不能節(jié)省系統(tǒng)的處理時間,反而增加了系統(tǒng)的負荷。Squid是一個顯式代理系統(tǒng),所有指向你的數(shù)據(jù)交給你處理,如果在squid沒有對這個端口進行接收,則數(shù)據(jù)直接丟棄。Squid實際上是一個重新定向的操作,用戶瀏覽的信息實際上是從squid服務(wù)器上邊取得的,而squid又從用戶需要訪問的服務(wù)器上邊把需要的數(shù)據(jù)給取回來。數(shù)據(jù)包的處理流程如圖1所示。
5.結(jié)論
Netgraph處理也比普通的socket性能優(yōu)越,netgraph是我挑包,只挑選適合我的數(shù)據(jù)包,不適合我的數(shù)據(jù)包直接丟棄,而socket則不同,它是包挑我,比如數(shù)據(jù)包是IP數(shù)據(jù)包,則直接把這個數(shù)據(jù)包轉(zhuǎn)發(fā)到了ip socket,socket必須無條件的接收。Netgraph中,socket是一個接口,需要什么數(shù)據(jù)包由內(nèi)核來做,內(nèi)核告訴netgraph,你去拿什么樣的包,而普通的socket則是告訴內(nèi)核,我需要什么樣的包,有這樣的包才交給我,滿足自己條件的數(shù)據(jù)包,自己才能看到。同時普通的socket對數(shù)據(jù)包的處理比netgraph多了2個步驟,一個是進行ip_input的處理,另外一個是多了tcp_input的處理。另外,在處理級別上邊,netgraph的處理級別比ip_input處理級別要高,netgraph的中斷處理級別也要比普通的socket的中斷處理級別也要高,通過以上的比較,我們可以看到netgraph處理的速度和效率明顯高于squid,而且處理的靈活性也要比squid高很多。
作者簡介:周安順(1975—),男,現(xiàn)供職于中國聯(lián)通洛陽市分公司,主要研究方向:計算機網(wǎng)絡(luò),網(wǎng)絡(luò)安全,項目管理等。