一、防火牆概述
網絡防火牆技術是一種用來加強網絡之間訪問控制,防止外部網絡用戶以非法手段通過外部網絡進入內部網絡,訪問內部網絡資源,保護內部網絡操作環境的特殊網絡互聯設備。它對兩個或多個網絡之間傳輸的數據包按照一定的安全策略來實施檢查,以決定網絡之間的通信是否被允許,並監視網絡運行狀態。
根據防火牆所采用的技術不同,可以將它分為四種基本類型:包過濾型、網絡地址轉換—NAT、代理型和監測型。包過濾型產品是防火牆的初級產品,其技術依據是網絡中的分包傳輸技術。包過濾技術的優點是簡單實用,實現成本較低,在應用環境比較簡單的情況下,能夠以較小的代價在一定程度上保證系統的安全。網絡地址轉換是一種用於把IP地址轉換成臨時的、外部的、注冊的IP地址標准。它允許具有私有IP地址的內部網絡訪問因特網。
代理型防火牆也可以被稱為代理服務器,它的安全性要高於包過濾型產品,並已經開始向應用層發展。代理型防火牆的優點是安全性較高,可以針對應用層進行偵測和掃描,對付基於應用層的侵入和病毒都十分有效。其缺點是對系統的整體性能有較大的影響,而且代理服務器必須針對客戶機可能產生的所有應用類型逐一進行設置,大大增加了系統管理的復雜性。
監測型防火牆是新一代的產品,能夠對各層的數據進行主動的、實時的監測,在對這些數據加以分析的基礎上,監測型防火牆能夠有效地判斷出各層中的非法侵入。同時,這種檢測型防火牆產品一般還帶有分布式探測器,這些探測器安置在各種應用服務器和其他網絡的節點之中,不僅能夠檢測來自網絡外部的攻擊,同時對來自內部的惡意破壞也有極強的防范作用。監測型防火牆在安全性上已超越了包過濾型和代理服務器型防火牆,但其實現成本較高。基於對系統成本與安全技術成本的綜合考慮,用戶可以選擇性地使用某些監測型技術。
二、基於Linux個人防火牆總體設計
本文研究的是防火牆系統的軟硬件環境以及該防火牆的開發步驟和所要實現的功能,最後重點對該防火牆系統所需要的硬件和軟件平台原理進行說明。盡管所有Linux系統都自帶防火牆內核程序,但需要用戶進行配置才能起到保護網絡安全的目的。
1、防火牆系統總體設計
Linux系統下實現軟件防火牆的設計與應用,實質上就是基於主機的網絡安全解決方案。因此,我們完全可以選擇合適的軟硬件平台和相應的防火牆設計原理,自己開發出一套能夠滿足要求的防火牆系統。
歸納起來這裡要實現的防火牆需要滿足兩大要求:第一,必須能夠對主機提供安全保護,即對主機與局域網以外的主機進行數據傳輸時實施安全保護;第二,必須能夠提供良好的人機接口界面,具有容易操作、容易管理的優點。
考慮到現有硬件設備的限制,在保證滿足實驗要求的環境下盡可能地簡化了實驗環境。因為該防火牆系統是基於主機設計的,故只需要一個聯網的主機即可進行實驗。該系統是在Linux環境下用C語言實現包過濾型軟件防火牆的設計與應用,采用Kylix開發工具進行界面設計和數據庫連接。
基於Linux的個人防火牆系統主要具有以下功能:
(1)全程動態包過濾 本防火牆要在Linux下實現全程動態包過濾功能,通過分析數據包的地址、協議、端口對任何網絡連接當前狀態進行訪問控制,從而提高系統的性能和安全性。
(2)提供日志審計 本防火牆配備了日志記錄系統和查詢工具,用於記錄系統管理、系統訪問及針對安全策略的網絡訪問情況。
(3)防火牆數據庫的備份 本防火牆制作防火牆過濾數據庫,並且管理員可以能動地對該數據庫進行設置。
三、基於Linux的數據包捕獲模塊結構與原理分析
本節就監控層數據包捕獲模塊的結構特性進行探討,並詳細論述其原理,且對實現數據包捕獲功能的程序的一些重要函數進行說明。
1、數據包捕獲模塊結構
數據包捕獲模塊用於監視和驗證網絡流量情況,它可以截取或者閱讀網絡上OSI協議模型中各個協議層次上的數據包。
本文所設計的數據包捕獲程序可以捕獲通過原始套接口(Socket)的原始數據包(Raw Packet),當一個數據包到達網絡接口時,數據包捕獲程序就直接從緩存區讀取捕獲的數據包,以供數據分析和處理時調用。數據捕獲模塊的結構如圖1所示:
TCP/IP網絡
↓
數據捕獲
網卡設置
獲取數據包
得到數據包頭信息
圖1 數據捕獲程序結構圖
2、數據包捕獲模塊原理分析
(1)網卡設置原理
在一個實際的系統中,數據的收發是由網卡來完成的,網卡接收到傳輸來的數據,網卡內的程序接收數據幀的目的MAC地址,根據計算機上的網卡驅動程序設置的接收模式判斷該不該接收,認為不該接收就丟掉不管。而對於網卡來說一般有四種接收模式:廣播模式組播模式、直接方式、混雜模式。數據包捕獲程序首先使網絡接口(網卡)處於混雜狀態,從而可截獲網絡上的內容,並且通過相應的軟件處理,可以實時分析這些數據的內容,為數據包過濾作准備。
(2)基本函數說明
本文中在Linux主機上用C語言編寫數據包捕獲程序,所編寫的程序中用到很多Linux中的預定義函數,在此節將對這些基本函數的功能和使用特點進行說明。
1)ioctl函數定義
ioctl()函數非常龐雜,它可以控制各種文件的屬性。它用於控制特殊文件的底層設備參數,這些特殊文件通常是指終端、套接字和接口。ioctl函數原型為:
int ioctl(int handle,int cmd[,int *argdx,int argcx]);
2)socket函數定義
常用的Socket類型有兩種:流式Socket(SOCK_STREAM)和數據包式Socket (SOCK_DGRAM)。流式是一種面向連接的Socket,針對面向連接的TCP服務應用;數據報式Socket是一種無連接的Socket,針對無連接的UDP服務應用。Socket函數原型為:
int socket(int domain, int type,int protocol);
3)recvfrom()函數定義
用recvfrom()函數來實現接收數據包,recvfrom()是具備“阻塞式I/O”特性的函數,能夠在沒有數據包到達的情況下暫時掛起等待,直至接收到數據包後,再激活轉入下一步處理。recvfrom()函數的原型為:
int recvfrom(SOCKET s,char FAR *buf,int len,int flags,strUCt sockaddr FAR *from,int *fromlen);
本函數從已連接套接口上接收數據,並捕獲數據發送源的地址。對於SOCK_STREAM類型的套接口,最多可以接收緩沖區大小個數據。如果套接口被設置為線內接收帶外數據(選項為 SO_OOBINLINE),且有帶外數據未讀入,則返回帶外數據。應用程序可通過調用ioctlsocket()的SOCATMARK命令來確定是否有帶外數據待讀入。對於SOCK_STREAM類型套接口,忽略from和fromlen參數。
4)一些“字節順序”轉換函數
因為網絡和主機采用的存儲字節時內存順序安排方式的差異,就存在“字節順序”的問題。在網絡環境下存儲時,高位字節存放在內存的起始位置,而低字節則存放在較高的位置。主機形式的存放順序恰好相反,低位字節存放在內存的起始位置。這就需要以下相應的字節順序轉換函數:
inet_ntoa():將32位的網絡二進制數值轉換為可讀十進制形式的帶點分割符的IP地址。
inet_addr():將帶有分割符的IP地址轉換為32位的unsigned long的格式。
ntohs():將網絡字節順序轉換為32位的主機字節順序。
ntohl():將網絡字節順序轉換成16位的主機字節順序。
htonl():將32位u_long的值由主機字節順序轉換為網絡字節順序。
htons():將16位u_long的值由主機字節順序轉換為網絡字節順序。
本文設計的數據捕獲程序需要使用SOCK_PACKET設備,SOCK_PACKET只在基於Linux的操作系統中有效定義。為此,美國洛侖茲伯克利國家實驗室編寫了專用於數據包截獲的API函數庫“Libpcap”。該函數的設計目標是統一不同系統上所提供的用於數據包截獲的不同類型接口,並使得類似的高層應用程序的編寫和移植變得簡單有效,不再需要對每一個應用都使用不同的依賴於具體系統的數據包截獲模塊。
四、基於Linux的數據包捕獲模塊設計實現
1、 數據包捕獲模塊設計流程圖
在數據包捕獲程序中,通過設置網卡工作於混雜狀態,對網絡鏈路進行監聽並收集數據包,從而獲得數據包頭信息。其流程圖如圖2所示:
啟動SOCKET函數
設置網卡為混雜模式
從緩沖區接收數據
數據包格式檢查並顯示
數據處理模塊
圖2 數據包捕獲模塊流程圖
2、數據包捕獲模塊實現
該數據包捕獲程序用C語言來編寫,程序中用到很多Linux網絡編程中的函數。
(1)設置網絡接口為混雜模式
網絡接口的混雜模式使得一個網絡接口設備從只能讀取目標地址為6字節MAC地址的數據包,變為可讀取網絡廣播媒體中的所有數據包。該部分通過兩次ioctl函數調用實現:
ioctl(sock, SIOCGIFFLAGS, &ifr)
ifr.ifr_flags = IFF_PROMISC
ioctl(sock, SIOCGIFFLAGS, &ifr)
第一次的ioctl函數調用,用來截獲ifr(struct ifreq)結構中所含接口名稱所指接口的標記。第一個參數是打開的原始套接字描述符“sock”,第二個參數是所要執行的請求操作。第三個參數是接口請求數據結構的地址指針,該結構中包含了所以進行請求操作的接口名稱值。
我們通過將混合標記(IFF_PROMISC)應用到接口請求結構的標記位變量中來改變接口標記位。操作符“=”將混合標記符與原有的接口標記進行 “或”操作來設置新的接口標記。獲得新的接口標記後,將其設置到實際接口中。第二次的ioctl調用,將接口設備設置為混合模式。正如第一個ioctl調用是獲得網絡接口的標記,這次調用是設置ifr結構中修改過的新標記寫到物理接口上。
(2)打開Socket設備
用socket函數來打開Socket設備。
sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
domain域使用AF_PACKET,能夠既接收鏈路層也接收網絡層的數據包。
(3)接收數據
使用recvfrom()函數來實現接收數據包:
recvfrom(sock,(char *)buf,sizeof(buf), 0, (struct sockaddr *)&addr,&len)
這是從打開的網絡插座Socket讀取數據包的地方,但要注意,addr結構有一個強制類型轉換,以適應recvfrom()函數的語法要求,recvfrom()函數在成功讀取的情況下返回讀取的字節數,否則返回-1。
(4)判斷包頭指針
該數據包捕獲模塊可以接收到的數據包都是原始數據包,它們的格式一般先是以太網數據幀的頭部,接著是ARP或者IP數據包的頭部。IP數據包後緊跟著 TCP或UDP、ICMP的頭部,最後才是真正要傳輸的數據。於是,在拆分IP數據包時,先提取以太網數據幀的頭部,再提取IP數據包的頭部,然後分析 TCP或UDP、ICMP數據包的頭部。最後,從數據包提取出需要的數據。
3、程序中用到的一些結構體解析
(1)sockadd_in結構體
在網絡中第一個被創造的結構類型是sockaddr。這個數據結構是為許多類型的套接口儲存地址信息。它的定義如下:
struct sockaddr{
unsigned shortsa_family; /*這個是地址族,通常是AF-xxxx的形式*/
charsa_data[14]; /*14字節的地址信息*/
};
(2)ethhdr結構體
以下是相應數據結構:
struct ethhdr
{
unsigned char h_dest[ETH_ALEN];/*48位的目標地址的網卡物理地址*/
unsigned char h_source[ETH_ALEN];/*48位的源地址的物理網卡地址*/
unsigned short h_proto;/*16位的以太網協議*/
}
(3)iphdr結構體
這是Linux 的ip協議報頭,針對版本的不同它可以有不同的定義,我們國內一般用BIG的定義,其中version 是ip的版本,protocol是ip的協議分類,saddr是32位的源ip地址,daddr是32位的目標ip地址。
(4)tcphdr結構體
這是Linux 下tcp協議的一部分,與ip協議相同取BIG,其中source是源端口,dest 是目的端口,seq是s序,ack_seq是a序號,其余的是tcp的連接標志其中包括6個標志:syn表示連接請求,urg 表示緊急信息,fin表示連接結束,ack表示連接應答,psh表示推棧標志,rst表示中斷連接。window是表示接受數據窗口大小,check是校驗碼,urg ptr是緊急指針。
(5)udphdr結構體
這是Linux下ip協議中udp協議的一部分,以下是相應數據結構:
struct udphdr
{
u_int16_t source;/* 源端口*/
u_int16_t dest;/* 目的端口*/
u_int16_t len;/* udp 長度*/
u_int16_t check;/*校驗碼*/
}
本文設計的是一個基於Linux主機的包過濾型個人防火牆,它實現的功能和現今市場上流行的防火牆有巨大差距。隨著技術的不斷發展,防火牆也處於不斷的變化之中。防火牆技術經歷了包過濾、應用代理網關再到狀態檢測三個階段。其中狀態檢測是比較先進的防火牆技術,它摒棄了包過濾防火牆僅考查數據包的 IP 地址等幾個參數,而不關心數據包連接狀態變化的缺點,在防火牆的核心部分建立狀態連接表,並將進出網絡的數據當成一個個的會話,利用狀態表跟蹤每一個會話狀態。狀態檢測技術在大力提高安全防范能力的同時也改進了流量處理速度。狀態監測技術采用了一系列優化技術,使防火牆性能大幅度提升,能應用在各類網絡環境中,尤其是在一些規則復雜的大型網絡上。深度包檢測技術將為防火牆的發展提升到一個新的階段。該技術對數據包頭或有效載荷所封裝的內容進行分析,從而引導、過濾和記錄基於IP的應用程序和Web服務通信流量,其工作並不受協議種類和應用程序類型的限制。采用深度包檢測技術,企業網絡可以獲得性能上的大幅度提升而無需購買昂貴的服務器或是其他安全產品。