Linux个人防火墙的设计与实现(转)[@more@]一、防火墙概述
网路防火墙技术是一种拿来强化网路之间访问控制,避免外部网路用户以非法手段通过外部网路步入内部网路,访问内部网路资源,保护内部网路操作环境的特殊网路互联设备。它对两个或多个网路之间传输的数据包根据一定的安全策略来施行检测,以决定网路之间的通讯是否被准许,并监视网路运行状态。?
按照防火墙所采用的技术不同,可以将它分为四种基本类型:包过滤型、网络地址转换—NAT、代理型和检测型。包过滤型产品是防火墙的中级产品,其技术根据是网路中的总包传输技术。包过滤技术的优点是简单实用,实现成本较低,在应用环境比较简单的情况下,才能以较小的代价在一定程度上保证系统的安全。网路地址转换是一种用于把IP地址转换成临时的、外部的、注册的IP地址标准。它容许具有私有IP地址的内部网路访问因特网。
代理型防火墙也可以被称为代理服务器,它的安全性要低于包过滤型产品,并早已开始向应用层发展。代理型防火墙的优点是安全性较高,可以针对应用层进行探测和扫描,对付基于应用层的侵入和病毒都非常有效。其缺点是对系统的整体性能有较大的影响,并且代理服务器必须针对顾客机可能形成的所有应用类型逐一进行设置,大大降低了系统管理的复杂性。
检测型防火墙是新一代的产品,才能对各层的数据进行主动的、实时的检测,在对那些数据加以剖析的基础上linux操作系统论文,检测型防火墙才能有效地判定出各层中的非法侵入。同时,这些测量型防火墙产品通常还带有分布式侦测器,这种侦测器安置在各类应用服务器和其他网路的节点之中,除了才能测量来自网路外部的功击,同时对来自内部的恶意破坏也有极强的防范作用。检测型防火墙在安全性上已赶超了包过滤型和代理服务器型防火墙,但其实现成本较高。基于对系统成本与安全技术成本的综合考虑,用户可以选择性地使用个别检测型技术。
二、基于Linux个人防火墙总体设计
本文研究的是防火墙系统的软硬件环境以及该防火墙的开发步骤和所要实现的功能,最后重点对该防火墙系统所须要的硬件和软件平台原理进行说明。虽然所有Linux系统都自带防火墙内核程序,但须要用户进行配置就能起到保护网路安全的目的。
1、防火墙系统总体设计
Linux系统下实现软件防火墙的设计与应用,实质上就是基于主机的网路安全解决方案。因而,我们完全可以选择合适的软硬件平台和相应的防火墙设计原理,自己开发出一套才能满足要求的防火墙系统。
归纳上去这儿要实现的防火墙须要满足两大要求:第一,必须才能对主机提供安全保护,即对主机与局域网以外的主机进行数据传输时施行安全保护;第二,必须才能提供良好的人机插口界面,具有容易操作、容易管理的优点。
考虑到现有硬件设备的限制,在保证满足实验要求的环境下尽可能地简化了实验环境。由于该防火墙系统是基于主机设计的,故只须要一个联网的主机即可进行实验。该系统是在Linux环境下用C语言实现包过滤型软件防火墙的设计与应用,采用Kylix开发工具进行界面设计和数据库联接。
基于Linux的个人防火墙系统主要具有以下功能:
(1)全程动态包过滤本防火墙要在Linux下实现全程动态包过滤功能,通过剖析数据包的地址、协议、端口对任何网路联接当前状态进行访问控制,因而提升系统的性能和安全性。
(2)提供日志审计本防火墙配备了日志记录系统和查询工具,用于记录系统管理、系统访问及针对安全策略的网路访问情况。
(3)防火墙数据库的备份本防火墙制做防火墙过滤数据库,而且管理员可以能动地对该数据库进行设置。
三、基于Linux的数据包捕获模块结构与原理剖析
本节就监控层数据包捕获模块的结构特点进行阐述,并详尽阐述其原理,且对实现数据包捕获功能的程序的一些重要函数进行说明。
1、数据包捕获模块结构
数据包捕获模块用于监视和验证网路流量情况,它可以截取或则阅读网路上OSI合同模型中各个合同层次上的数据包。
本文所设计的数据包捕获程序可以捕获通过原始套插口(Socket)的原始数据包(RawPacket),当一个数据包抵达网路插口时,数据包捕获程序就直接从缓存区读取捕获的数据包,以供数据剖析和处理时调用。数据捕获模块的结构如图1所示:
TCP/IP网路
↓
数据捕获
网卡设置
获取数据包
得到数据榆林信息
图1数据捕获程序结布光
2、数据包捕获模块原理剖析
(1)网卡设置原理
在一个实际的系统中,数据的收发是由网卡来完成的,网卡接收到传输来的数据学linux有前途吗,网卡内的程序接收数据帧的目的MAC地址,按照计算机上的网卡驱动程序设置的接收模式判定该不该接收,觉得不该接收就抛掉不管。而对于网卡来说通常有四种接收模式:广播模式组播模式、直接方法、混杂模式。数据包捕获程序首先使网路插口(网卡)处于混杂状态,因而可查获网路上的内容,但是通过相应的软件处理,可以实时剖析这种数据的内容,为数据包过滤作打算。
(2)基本函数说明
本文中在Linux主机上用C语言编撰数据包捕获程序,所编撰的程序中用到好多Linux中的预定义函数,在此节将对那些基本函数的功能和使用特性进行说明。
1)ioctl函数定义
ioctl()函数十分繁杂,它可以控制各类文件的属性。它用于控制特殊文件的底层设备参数,这种特殊文件一般是指终端、套接字和插口。ioctl函数原型为:
intioctl(inthandle,intcmd[,int*argdx,intargcx]);
2)socket函数定义
常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据包式Socket(SOCK_DGRAM)。流式是一种面向联接的Socket,针对面向联接的TCP服务应用;数据报式Socket是一种无联接的Socket,针对无联接的UDP服务应用。Socket函数原型为:
intsocket(intdomain,inttype,intprotocol);
3)recvfrom()函数定义
用recvfrom()函数来实现接收数据包,recvfrom()是具备“阻塞式I/O”特性的函数,就能在没有数据包抵达的情况下暂时挂起等待,直到接收到数据包后,再激活转到下一步处理。recvfrom()函数的原型为:
intrecvfrom(SOCKETs,charFAR*buf,intlen,intflags,structsockaddrFAR*from,int*fromlen);
本函数从已联接套插口上接收数据,并捕获数据发送源的地址。对于SOCK_STREAM类型的套插口,最多可以接收缓冲区大小个数据。假如套插口被设置为线内接收带外数据(选项为SO_OOBINLINE),且有带外数据未读入,则返回带外数据。应用程序可通过调用ioctlsocket()的SOCATMARK命令来确定是否有带外数据待读入。对于SOCK_STREAM类型套插口,忽视from和fromlen参数。
4)一些“字节次序”转换函数
由于网路和主机采用的储存字节时显存次序安排形式的差别,就存在“字节次序”的问题。在网路环境下储存时,低位字节储存在显存的起始位置,而低字节则储存在较高的位置。主机方式的储存次序正好相反,高位字节储存在显存的起始位置。这就须要以下相应的字节次序转换函数:
inet_ntoa():将32位的网路二补码数值转换为可读十补码方式的带点分割符的IP地址。
inet_addr():将带有分割符的IP地址转换为32位的unsignedlong的格式。
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(structifreq)结构中所含插口名称所指插口的标记。第一个参数是打开的原始套接字描述符“sock”,第二个参数是所要执行的恳求操作。第三个参数是插口恳求数据结构的地址表针,该结构中包含了所以进行恳求操作的插口名称值。
我们通过将混和标记(IFF_PROMISC)应用到插口恳求结构的标记位变量中来改变插口标记位。操作符“|=”将混和标记符与原有的插口标记进行“或”操作来设置新的插口标记。获得新的插口标记后linux内核防火墙源代码分析,将其设置到实际插口中。第二次的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,(structsockaddr*)&addr,&len)
这是从打开的网路插头Socket读取数据包的地方,但要注意,addr结构有一个强制类型转换,以适应recvfrom()函数的句型要求,recvfrom()函数在成功读取的情况下返回读取的字节数linux内核防火墙源代码分析,否则返回-1。
(4)判定榆林表针
该数据包捕获模块可以接收到的数据包都是原始数据包,它们的格式通常先是以太网数据帧的腹部,接着是ARP或则IP数据包的脑部。IP数据包后紧跟随TCP或UDP、ICMP的背部,最后才是真正要传输的数据。于是,在分拆IP数据包时,先提取以太网数据帧的腹部,再提取IP数据包的腹部,之后剖析TCP或UDP、ICMP数据包的脸部。最后,从数据包提取出须要的数据。
3、程序中用到的一些结构体解析
(1)sockadd_in结构体
在网路中第一个被创造的结构类型是sockaddr。这个数据结构是为许多类型的套插口存储地址信息。它的定义如下:
structsockaddr{
unsignedshortsa_family;/*这个是地址族,一般是AF-xxxx的方式*/
charsa_data[14];/*14字节的地址信息*/
};
(2)ethhdr结构体
以下是相应数据结构:
structethhdr
unsignedcharh_dest[ETH_ALEN];/*48位的目标地址的网卡化学地址*/
unsignedcharh_source[ETH_ALEN];/*48位的源地址的数学网卡地址*/
unsignedshorth_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是校准码,urgptr是紧急表针。
(5)udphdr结构体
这是Linux下ip合同中udp合同的一部份,以下是相应数据结构:
structudphdr
u_int16_tsource;/*源端口*/
u_int16_tdest;/*目的端口*/
u_int16_tlen;/*udp宽度*/
u_int16_tcheck;/*校准码*/
本文设计的是一个基于Linux主机的包过滤型个人防火墙,它实现的功能和现在市场上流行的防火墙有巨大差别。随着技术的不断发展,防火墙也处于不断的变化之中。防火墙技术经历了包过滤、应用代理网段再到状态监测三个阶段。其中状态检查是比较先进的防火墙技术,它革除了包过滤防火墙仅考查数据包的IP地址等几个参数,而不关心数据包联接状态变化的缺点,在防火墙的核心部份构建状态联接表,并将进出网路的数据当作一个个的会话,借助状态表跟踪每一个会话状态。状态监测技术在大力提升安全防范能力的同时也改进了流量处理速率。状态检测技术采用了一系列优化技术,使防火墙性能大幅度提高,能应用在各种网路环境中,尤其是在一些规则复杂的小型网路上。深度包测量技术将为防火墙的发展提高到一个新的阶段。该技术对数据榆林或有效荷载所封装的内容进行剖析,因而引导、过滤和记录基于IP的应用程序和Web服务通讯流量,其工作并不受合同种类和应用程序类型的限制。采用深度包检查技术,企业网路可以获得性能上的大幅度提高而无需选购高昂的服务器或是其他安全产品。