APP下载

基于Linux平台防止IP欺骗的SYN攻击防火墙的设计与实现

2014-06-19夏跃伟牛文倩刘金广

现代电子技术 2014年9期
关键词:防火墙

夏跃伟 牛文倩 刘金广

摘 要: 目前,SYN FLOOD攻击占70%~80%。IP欺骗是常用的方式,如何防止IP欺骗的SYN攻击成为研究热点。设计是以redhat 5.0 为平台,结合RED算法设计并实现一个抗SYN攻击的包过滤防火墙,该防火墙在轻度和中度攻击的情况下判断一个数据包的丢弃概率,当被丢弃则保存该数据包到哈希表中,主机等待客户机重传TCP连接请求,检测是否是真实性的IP地址,经过分析研究和实验的验证具有较好的吞吐量,同时正常数据包的通过率很高。当遭受的是重度攻击时,则直接采用的是RED中的随机丢弃数据包。

关键词: 防火墙; SYN攻击; RED算法; 哈希表

中图分类号: TN915.08?34 文献标识码: A 文章编号: 1004?373X(2014)09?0083?03

0 引 言

随着网络的发展,网络攻击的手段越来越多,其中以IP欺骗形式的SYN攻击所占的比例较大,众多的专家学者都致力于研究如何有效控制SYN攻击[1]。也提出了较多的方法,例如状态检测算法,该算法主要是利用TCP连接过程中的几个状态[2],判断是否是攻击性数据包,但是该算法存在一些缺陷,对每个数据包都要检测其状态,而且要保存较多的数据包信息,这对系统的吞吐量和内存都有较大的影响。因此,本实验防火墙致力于提高正常包的通过率,以及系统吞吐量。对于轻度和中度攻击时的系统性能有很大的提高。

1 系统相关知识

1.1 防火墙

防火墙是防止网络攻击的主要手段之一,目前的防火墙得到很大的发展,它防止外部网络对内部网络的攻击,一个防火墙的参考模型如图1所示。

图1 防火墙模型

1.2 RED算法

RED算法[3]利用当前队列的平均长度计算数据包的丢弃概率,如图2所示,具体由三个原则确定:

(1) 当平均队列长度[Lav]小于给定的数据包队列长度最小门限值minth时,数据包丢弃概率[P=0;]

(2) 当平均队列长度[Lav]大于给定的数据包队列长度最大门限值maxth时,数据包的丢弃概率[P=1;]

(3) 当平均队列长度在minth和maxth之间,数据包的丢弃概率在0~1之间。而且[P=max*][(Q-Min)(maxth-minth)。]

图2 数据包丢弃概率[P]和两个门限值的关系图

2 总体设计

因为IP欺骗形式的SYN攻击,是采用的伪造IP地址和端口,主机发送ACK数据包,攻击机器是不会做出回应的[4]。所以判断正常包就可以让客户机其超时重传,从而检测是否是真实IP。防火墙的设计主要是针对SYN请求数据包,利用RED算法计算当前的TCP连接请求数据包到来时的TCP缓冲区的平均队列长度[Q,]如果平均队列长度[Q]小于给定的最小队列门限值minth,则说明当前没有SYN攻击或者只有少数的SYN数据包,这种情况下不会影响本机性能,可以直接接收数据包。如果平均队列长度大于最大门限值maxth,说明当前遭受到较强的SYN攻击,则随机的丢弃数据包。如果平均队列长度在最小门限minth和最大门限值maxth之间,则计算当前数据包的随机丢弃概率[P,]如果[P]小于给定的阈值[Pm,]则接收数据包,如果[P]大于给定的阈值,则先到哈希表中查找是否存在相同数据包信息的元素(哈希表存放的是被丢弃的数据包的相关信息),如果找到则接收数据包到本机,如果没有找到则保存数据包相关信息到哈希表中,同时丢弃该数据包。总体设计如图3所示。

3 防火墙关键技术实现

3.1 包检测模块

采用RED算法实现对数据包的处理,判断进入到主机的TCP连接请求数据包的丢弃概率,首先要定义RED算法中用到的参数:

struct red_parms{

/* Parameters */

u32 limit; /*队列长度上限*/

u32 qth_min; /*算法需要的两个门限值*/

u32 qth_max;

u32 Rmask;

u32 Scell_max; /*最大空闲时间*/

unsigned char flags;

char Wlog; /*log(W)*/

char Plog; /*random number bits*/

char Scell_log;

u8 Stab[256];

unsigned long qave; /*平均队列长度*/

int qcount; /*上次丢弃分组后收到的分组个数*/

u32 qR; /*Cached random number*/

psched_time_t qidlestart; /*队列空间开始时间*/

struct tc_red_xstats st;

};

图3 SYN防火墙总体设计

队列的平均长度是判断丢弃概率的关键因素,利用函数red_cmp_thresh实现RED算法的队列长度判断,对于不同的返回值,计算丢弃概率。

static inline int red_cmp_thresh(struct red_parms *p, unsigned long qavg)

{

if (qavg < p?>qth_min)

return RED_BELOW_MIN_THRESH;

else if (qavg >= p->qth_max)

return RED_ABOVE_MAX_TRESH;

else

return RED_BETWEEN_TRESH;

}

针对不同的队列长度,计算出当前数据包的丢弃概率:

static inline int red_action(struct red_parms *p, unsigned long qavg)

{

switch (red_cmp_thresh(p, qavg)) {

case RED_BELOW_MIN_THRESH:

p->qcount = -1;

return RED_DONT_MARK;

case RED_BETWEEN_TRESH:

if (++p->qcount) {

if (red_mark_probability(p, qavg)) {

p->qcount = 0;

p->qR = red_random(p);

}

} else

p->qR = red_random(p);

}

3.2 哈希表

一个TCP连接请求数据包的丢弃概率经过上面的函数计算以后,根据和预定的概率值进行比较,如果概率小于给定的阈值,则接收数据包通过主机,如果概率大于给定阈值,则到哈希表中进行查找,哈希表中存在相同的数据包信息则接收数据包进入主机,如果不存在则删除数据包,同时保存数据包的相关信息到哈希表中。

定义哈希结构PACK_hash,为了方便系统的快速查找,在这里将其定义为大小为4 096的哈希数组。

进行哈希函数的查找和插入的哈希函数,可以利用数据包的源地址表示,将源地址的前16位和后16位相加,得到的结果除留余数,具体的函数可以是:

hash_key(struct iphdr src)

{

u16 hashavl,hashky;

hashavl=(u16)(src->saddr>>16+src->saddr&&0x0000ffff);

hashky=hashkvl%32;

//采用32取余数,能够较好地防止哈希冲突

}

3.3 数据包信息结构和定时器

在后面的处理过程中,只用到了数据包的源地址和目的地址,所以可以定义数据包的信息结构:

struct PACK_info

{

struct list_head pack_list; //哈希冲突时,存储为一个链表

struct iphdr src,drc; //表示数据包的源地址

struct timer_list time;

//定时器,防止哈希表一直被填满,到达时间就删除这个节点

u16 spt,dpt ; //数据包的源端口和目的端口

}

内核中提供了对定时器处理函数[5]如下:

void init_timer(struct timer_list *timer)

//初始化定时器队列结构

vod add_timer(struct timer_list *timer) //启动定时器

int del_timer(struct timer_list *timer)

//启动定时器前将它删除,因为在超时后系统会自动

将它删除

3.4 数据包匹配

数据包在哈希表中查找相应的节点,匹配数据包的源地址和目的地址是否相同。

基于数据包的源IP 地址进行匹配:

static int check_spkt(struct PACK_info *skb)

{

if (! skb )

return NF_ACCEPT;

if ((skb->src->saddr >= htonl(fw_deny.sipf)) && (skb->src->saddr <= htonl(fw_deny.sipt)))

return NF_DROP;

return NF_ACCEPT;

}

基于数据包的目的IP地址进行匹配:

static int check_dpk(struct sk_buff *skb)

{

if (! skb )

return NF_ACCEPT;

if ((skb->drc->daddr >= htonl(fw_deny.sipf)) && (skb->

drc->daddr <= htonl(fw_deny.dipt)) )

return NF_DROP;

return NF_ACCEPT;

}

4 结 论

本防火墙的设计采用的拥塞控制算法RED算法,同时利用了哈希表相关知识。构建了一个简单实用的小型防止IP地址欺骗的SYN攻击的防火墙,经过试验测试,该防火墙在轻度和重度攻击时,有较好的防御能力,正常包的通过率保持在98%左右,系统性能较好,吞吐量较大。

参考文献

[1] 周剑岚,冯珊.运用hook技术实现的软件防火墙[J].华中科技大学学报:自然科学版,2004,32(3):83?85.

[2] 毛德操,胡希明.Linux内核源代码情景分析[M].杭州:浙江大学出版社,2001.

[3] 陈军,陈志刚.主动队列管理RED算法的改进与实验仿真研究[J].计算机工程,2006,9(6):44?47.

[4] POTTER B. Open source firewall alternatives [J]. Network Security, 2006, 18(6): 16?17.

[5] 丁晓波,桑楠,张宁.Linux 2.6内核的内核对象机制分析[J].计算机应用,2005,25(1):76?84.

[6] 何映,覃以威,李丹.基于Windows内核态个人防火墙的设计与实现[J].现代电子技术,2012,35(6):49?52.

{

if (qavg < p?>qth_min)

return RED_BELOW_MIN_THRESH;

else if (qavg >= p->qth_max)

return RED_ABOVE_MAX_TRESH;

else

return RED_BETWEEN_TRESH;

}

针对不同的队列长度,计算出当前数据包的丢弃概率:

static inline int red_action(struct red_parms *p, unsigned long qavg)

{

switch (red_cmp_thresh(p, qavg)) {

case RED_BELOW_MIN_THRESH:

p->qcount = -1;

return RED_DONT_MARK;

case RED_BETWEEN_TRESH:

if (++p->qcount) {

if (red_mark_probability(p, qavg)) {

p->qcount = 0;

p->qR = red_random(p);

}

} else

p->qR = red_random(p);

}

3.2 哈希表

一个TCP连接请求数据包的丢弃概率经过上面的函数计算以后,根据和预定的概率值进行比较,如果概率小于给定的阈值,则接收数据包通过主机,如果概率大于给定阈值,则到哈希表中进行查找,哈希表中存在相同的数据包信息则接收数据包进入主机,如果不存在则删除数据包,同时保存数据包的相关信息到哈希表中。

定义哈希结构PACK_hash,为了方便系统的快速查找,在这里将其定义为大小为4 096的哈希数组。

进行哈希函数的查找和插入的哈希函数,可以利用数据包的源地址表示,将源地址的前16位和后16位相加,得到的结果除留余数,具体的函数可以是:

hash_key(struct iphdr src)

{

u16 hashavl,hashky;

hashavl=(u16)(src->saddr>>16+src->saddr&&0x0000ffff);

hashky=hashkvl%32;

//采用32取余数,能够较好地防止哈希冲突

}

3.3 数据包信息结构和定时器

在后面的处理过程中,只用到了数据包的源地址和目的地址,所以可以定义数据包的信息结构:

struct PACK_info

{

struct list_head pack_list; //哈希冲突时,存储为一个链表

struct iphdr src,drc; //表示数据包的源地址

struct timer_list time;

//定时器,防止哈希表一直被填满,到达时间就删除这个节点

u16 spt,dpt ; //数据包的源端口和目的端口

}

内核中提供了对定时器处理函数[5]如下:

void init_timer(struct timer_list *timer)

//初始化定时器队列结构

vod add_timer(struct timer_list *timer) //启动定时器

int del_timer(struct timer_list *timer)

//启动定时器前将它删除,因为在超时后系统会自动

将它删除

3.4 数据包匹配

数据包在哈希表中查找相应的节点,匹配数据包的源地址和目的地址是否相同。

基于数据包的源IP 地址进行匹配:

static int check_spkt(struct PACK_info *skb)

{

if (! skb )

return NF_ACCEPT;

if ((skb->src->saddr >= htonl(fw_deny.sipf)) && (skb->src->saddr <= htonl(fw_deny.sipt)))

return NF_DROP;

return NF_ACCEPT;

}

基于数据包的目的IP地址进行匹配:

static int check_dpk(struct sk_buff *skb)

{

if (! skb )

return NF_ACCEPT;

if ((skb->drc->daddr >= htonl(fw_deny.sipf)) && (skb->

drc->daddr <= htonl(fw_deny.dipt)) )

return NF_DROP;

return NF_ACCEPT;

}

4 结 论

本防火墙的设计采用的拥塞控制算法RED算法,同时利用了哈希表相关知识。构建了一个简单实用的小型防止IP地址欺骗的SYN攻击的防火墙,经过试验测试,该防火墙在轻度和重度攻击时,有较好的防御能力,正常包的通过率保持在98%左右,系统性能较好,吞吐量较大。

参考文献

[1] 周剑岚,冯珊.运用hook技术实现的软件防火墙[J].华中科技大学学报:自然科学版,2004,32(3):83?85.

[2] 毛德操,胡希明.Linux内核源代码情景分析[M].杭州:浙江大学出版社,2001.

[3] 陈军,陈志刚.主动队列管理RED算法的改进与实验仿真研究[J].计算机工程,2006,9(6):44?47.

[4] POTTER B. Open source firewall alternatives [J]. Network Security, 2006, 18(6): 16?17.

[5] 丁晓波,桑楠,张宁.Linux 2.6内核的内核对象机制分析[J].计算机应用,2005,25(1):76?84.

[6] 何映,覃以威,李丹.基于Windows内核态个人防火墙的设计与实现[J].现代电子技术,2012,35(6):49?52.

{

if (qavg < p?>qth_min)

return RED_BELOW_MIN_THRESH;

else if (qavg >= p->qth_max)

return RED_ABOVE_MAX_TRESH;

else

return RED_BETWEEN_TRESH;

}

针对不同的队列长度,计算出当前数据包的丢弃概率:

static inline int red_action(struct red_parms *p, unsigned long qavg)

{

switch (red_cmp_thresh(p, qavg)) {

case RED_BELOW_MIN_THRESH:

p->qcount = -1;

return RED_DONT_MARK;

case RED_BETWEEN_TRESH:

if (++p->qcount) {

if (red_mark_probability(p, qavg)) {

p->qcount = 0;

p->qR = red_random(p);

}

} else

p->qR = red_random(p);

}

3.2 哈希表

一个TCP连接请求数据包的丢弃概率经过上面的函数计算以后,根据和预定的概率值进行比较,如果概率小于给定的阈值,则接收数据包通过主机,如果概率大于给定阈值,则到哈希表中进行查找,哈希表中存在相同的数据包信息则接收数据包进入主机,如果不存在则删除数据包,同时保存数据包的相关信息到哈希表中。

定义哈希结构PACK_hash,为了方便系统的快速查找,在这里将其定义为大小为4 096的哈希数组。

进行哈希函数的查找和插入的哈希函数,可以利用数据包的源地址表示,将源地址的前16位和后16位相加,得到的结果除留余数,具体的函数可以是:

hash_key(struct iphdr src)

{

u16 hashavl,hashky;

hashavl=(u16)(src->saddr>>16+src->saddr&&0x0000ffff);

hashky=hashkvl%32;

//采用32取余数,能够较好地防止哈希冲突

}

3.3 数据包信息结构和定时器

在后面的处理过程中,只用到了数据包的源地址和目的地址,所以可以定义数据包的信息结构:

struct PACK_info

{

struct list_head pack_list; //哈希冲突时,存储为一个链表

struct iphdr src,drc; //表示数据包的源地址

struct timer_list time;

//定时器,防止哈希表一直被填满,到达时间就删除这个节点

u16 spt,dpt ; //数据包的源端口和目的端口

}

内核中提供了对定时器处理函数[5]如下:

void init_timer(struct timer_list *timer)

//初始化定时器队列结构

vod add_timer(struct timer_list *timer) //启动定时器

int del_timer(struct timer_list *timer)

//启动定时器前将它删除,因为在超时后系统会自动

将它删除

3.4 数据包匹配

数据包在哈希表中查找相应的节点,匹配数据包的源地址和目的地址是否相同。

基于数据包的源IP 地址进行匹配:

static int check_spkt(struct PACK_info *skb)

{

if (! skb )

return NF_ACCEPT;

if ((skb->src->saddr >= htonl(fw_deny.sipf)) && (skb->src->saddr <= htonl(fw_deny.sipt)))

return NF_DROP;

return NF_ACCEPT;

}

基于数据包的目的IP地址进行匹配:

static int check_dpk(struct sk_buff *skb)

{

if (! skb )

return NF_ACCEPT;

if ((skb->drc->daddr >= htonl(fw_deny.sipf)) && (skb->

drc->daddr <= htonl(fw_deny.dipt)) )

return NF_DROP;

return NF_ACCEPT;

}

4 结 论

本防火墙的设计采用的拥塞控制算法RED算法,同时利用了哈希表相关知识。构建了一个简单实用的小型防止IP地址欺骗的SYN攻击的防火墙,经过试验测试,该防火墙在轻度和重度攻击时,有较好的防御能力,正常包的通过率保持在98%左右,系统性能较好,吞吐量较大。

参考文献

[1] 周剑岚,冯珊.运用hook技术实现的软件防火墙[J].华中科技大学学报:自然科学版,2004,32(3):83?85.

[2] 毛德操,胡希明.Linux内核源代码情景分析[M].杭州:浙江大学出版社,2001.

[3] 陈军,陈志刚.主动队列管理RED算法的改进与实验仿真研究[J].计算机工程,2006,9(6):44?47.

[4] POTTER B. Open source firewall alternatives [J]. Network Security, 2006, 18(6): 16?17.

[5] 丁晓波,桑楠,张宁.Linux 2.6内核的内核对象机制分析[J].计算机应用,2005,25(1):76?84.

[6] 何映,覃以威,李丹.基于Windows内核态个人防火墙的设计与实现[J].现代电子技术,2012,35(6):49?52.

猜你喜欢

防火墙
筑牢防火墙 系紧安全带
“一封家书”寄深情 筑牢疫情“防火墙”
全民总动员,筑牢防火墙
构建防控金融风险“防火墙”
防火墙技术在网络安全应用中的现状
计算机网络安全中防火墙技术的应用思考
智慧防火墙
海南新农合有了“防火墙”
在舌尖上筑牢抵御“僵尸肉”的防火墙
下一代防火墙要做的十件事