禹定臣 夏躍偉 劉金廣
(1.黃淮學院信息工程學院,河南駐馬店 463000;2.漯河職業技術學院計算機工程系,漯河 462000 3.黃淮學院信息工程學院,河南駐馬店 463000)
隨著網絡技術的不斷發展,給人們帶來便利的同時,也給人們的網絡安全帶來了巨大的隱患,如何做到有效的控制網絡的安全性成為當今研究的主要課題。防火墻技術就此產生,它是防止網絡攻擊的重要手段,目前的防火墻技術已經發展到一定的水平,商業產品也有很多,防火墻的主要作用就是防止外部網絡對內部網絡進行攻擊,一個標準的網絡防火墻的模型可以如圖1。

圖1 防火墻模型
防火墻的設計的一個重要規則就是要使內部網絡能夠輕松的訪問到外部網絡,外部網絡不能夠隨意的訪問到內部網絡。因此,防火墻的設計可以采用兩種默認規則:一個是完全的默認所有數據包能夠通過,只要預定的一些數據包不能通過。另外一種默認規則就是完全阻止所有的數據包,只有預定的數據包能夠通過。本課題采用的默認禁止的策略。根據數據包的來源,禁止或者允許該數據包的通過與否。防火墻設計的規則需要知道數據包的源IP地址、目的IP地址,數據包的源端口和目的端口等信息。
1.在網絡攻擊中,一種常見的攻擊方式就是ICMP攻擊,這個攻擊是采用的向主機發送大量的ICMP數據包,致使主機耗費大量的時間去處理該數據包。在本課題中,為了應對這種攻擊,減少主機處理ICMP數據包的處理時間和數量,在單位時間內,限制ICMP數據包的個數,而且為了防止異常的ICMP數據包,限定該包的大小,如果大于規定的數值則認為是異常包,直接丟棄。在linux的netfilter的NF_IP_PRE_ROUTIN開始處理。具體的處理代碼如下:
icmp_fire(void)
{
int count=0;//進入主機的ICMP包計數
Int m=10;//單位時間最大允許ICMP包數量
if(ip->version==0)// 判斷是否是 ICMP 包
{
If(ip->long>64)//判斷icmp包的大小是否在64字節以內
DROP; //丟棄包
}
}
struct timer_list timer;//定義內核定時器
void timer_function(int para);//作為內核定時器的處理函數,此處para為形參而實際值由timer.data傳遞過來。
{
printk("<0>Timer Expired and para is %d ??! ",para);//輸出data參
}
int timer_init() //模塊初始化函數
{
init_timer(&timer);//初始化定時器鏈表
timer.data = 5;//參數為5,用于timer.function
timer.expires = jiffies + (20 * HZ);//設置定時時間為20秒
timer.function = timer_function;//設置操作函數
add_timer(&timer);//啟動定時器
//注意以上幾個函數的參數均為指針類型的,所以用&取地址
return 0;
}
void timer_exit()
{
del_timer( &timer );
}
2.SYN flood攻擊
網絡攻擊中的另外一種常見的攻擊方式就是SYN攻擊,它的攻擊原理就是不斷的向主機發送大量的SYN請求,可是又不回應主機的應答信息,主機會不停地重新發送應答信息,浪費主機的時間和空間資源。在netfilter的NF_IP_FORWARD這個鉤子點,是所有數據包通過防火墻的點,可以在該點設計防止SYN攻擊。同時要考慮到防火墻的開放性和完整性。為了方便,需要用到linux內核中的狀態檢測機制,在TCP通信過程中,有三次握手,則定為三種狀態。通過定義三個宏來標識這三個狀態:
TCP_SYN 0
TCP_ACCEPT 1
TCP_ACK 2
TCP_STATE_NUM 3
在設計過程中,通過定義一個哈希表ip_infor_hash來儲存處理的數據包,該哈希表的每一個節點都是一個雙向鏈表。當數據包到達NF_IP_FORWARD鉤子點的時候,分析該數據包的內在信息,IP地址、源端口、目的端口等,以及該數據包的狀態信息。如果這個地址的數據包已經存在于哈希表中,則認為它現有的狀態時不正確的,直接丟棄該數據包。如果哈希表中沒有改地址的數據包,則對這個數據包進行檢查,如果檢查數據包是錯誤的,則將這個數據包信息放到哈希表中,否則直接讓這個數據包通過這個鉤子點。
struct pack_info
{
struct list_head ip_list; //定義為一個鏈表結構
struct inaddr src,dst;//表示數據包的源地址和目的地址
u_int16_t proto;//數據包的傳輸協議類型
u_int16_t spts,dpts ; //數據包的源端口和目的端口
u_int8_t addr_flag ; //這是判斷地址信息的真假狀態標志。為0就表示地址是假,為1則表示為真
u_int8_t pack_state;//數據包擁有的狀態標志
u_int32_t sequence ;//TCP數據包中序列號
u_int32_t ackno ;//TCP數據包的確認序列號
struct ntimer_list timeout ; //定時器,到達定時則刪除這條記錄
}
static unsigned int ipt_forward(unsigned int hook,struct sk_uff **pskb,const struct
net_device in, const struct net_device out,int(okfn)(struct sk_uff*))
{
int judge,new_flag,verdict;process_defend_dos(pskb,&new_flag ,&verdict);if(new_flag)
{
judge=ipt_do_table(pskb,HOOK,in,out,&packet_filter,NULL);
Insert_hash_info(pskb);
Return judge;
}
return verdict;
}
上面的邏輯中,對DOS攻擊的邏輯處理都在process_defend_dos函數中實現。這個函數的三個參數類型分別為struct sk_buff, 首先在協議棧中有關數據的傳輸是通過變量值進行的,這個變量值就是structsk_buff,其次關于第2個參數是用來判斷的,判斷會話連接中的第1個數據包是否是此數據包,最后關于第3個參數是用來存放判斷結果的。關于該數據對會話連接有兩個方面,第一個就是如果這個數據包不是在會話連接的第一次,則把判斷的結果直接放到參數中去,同時返回該判斷結果,第二就是如果這個是會話中連接的第一個數據包,就把該數據包的信息放到哈希表中,然后也返回該數據包的判斷結果,Netfilter中一個重要的處理函數是ipt_do_table,該函數的主要功能就是對規則進行匹配操作,如果得到了匹配的規則后,就會按照要求分別進行對應的處理,這期間也會return一個對數據包的判斷結果。
在DOS攻擊中,常見的攻擊有ICMP攻擊、SYN攻擊,本課題在防火墻設計工程中,分析了這兩種攻擊的原理,分析了linux的Netfilter機制,然后構建了一個抵抗這兩種攻擊的防火墻,通過實驗的驗證,本設計的防御能力對于輕度和中度的攻擊行為能有較好的能力。
[1]周小勇.軟件防火墻設計[J].華中科技大學學報(自然科學版), 2008;32(3):83-85.
[2]毛德操,胡希明.Linux內核源代碼情景分析[M].杭州:浙江大學出版社,2001.
[3]付志剛.Linux內核防火墻分析 ,計算機工程[J],2009;11(3):56-60.
[4]Potter.B.open source firewall alternatives[J].Network security,2006;18(6):16-17.
[5]唐振云,李曉霞.Linux網絡內核的機制分析[J].計算機應用, 2010;25(1):76-84.