基于Linux平台防止IP欺骗的SYN攻击防火墙的设计与实现
2014-06-19夏跃伟牛文倩刘金广
夏跃伟 牛文倩 刘金广
摘 要: 目前,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.