禹定臣 夏跃伟 刘金广
(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.