一、防火墙概述
网络防火墙技术是一种用来加强网络之间访问控制,防止外部网络用户以非法手段通过外部网络进入内部网络,访问内部网络资源,保护内部网络操作环境的特殊网络互联设备。它对两个或多个网络之间传输的数据包按照一定的安全策略来实施检查,以决定网络之间的通信是否被允许,并监视网络运行状态。?
根据防火墙所采用的技术不同,可以将它分为四种基本类型:包过滤型、网络地址转换—NAT、代理型和监测型。包过滤型产品是防火墙的初级产品,其技术依据是网络中的分包传输技术。包过滤技术的优点是简单实用,实现成本较低,在应用环境比较简单的情况下,能够以较小的代价在一定程度上保证系统的安全。网络地址转换是一种用于把IP地址转换成临时的、外部的、注册的IP地址标准。它允许具有私有IP地址的内部网络访问因特网。
代理型防火墙也可以被称为代理服务器,它的安全性要高于包过滤型产品,并已经开始向应用层发展。代理型防火墙的优点是安全性较高,可以针对应用层进行侦测和扫描,对付基于应用层的侵入和病毒都十分有效。其缺点是对系统的整体性能有较大的影响,而且代理服务器必须针对客户机可能产生的所有应用类型逐一进行设置,大大增加了系统管理的复杂性。
监测型防火墙是新一代的产品,能够对各层的数据进行主动的、实时的监测,在对这些数据加以分析的基础上,监测型防火墙能够有效地判断出各层中的非法侵入。同时,这种检测型防火墙产品一般还带有分布式探测器,这些探测器安置在各种应用服务器和其他网络的节点之中,不仅能够检测来自网络外部的攻击,同时对来自内部的恶意破坏也有极强的防范作用。监测型防火墙在安全性上已超越了包过滤型和代理服务器型防火墙,但其实现成本较高。基于对系统成本与安全技术成本的综合考虑,用户可以选择性地使用某些监测型技术。二、基于Linux个人防火墙总体设计
本文研究的是防火墙系统的软硬件环境以及该防火墙的开发步骤和所要实现的功能,最后重点对该防火墙系统所需要的硬件和软件平台原理进行说明。尽管所有Linux系统都自带防火墙内核程序,但需要用户进行配置才能起到保护网络安全的目的。
1、防火墙系统总体设计
Linux系统下实现软件防火墙的设计与应用,实质上就是基于主机的网络安全解决方案。因此,我们完全可以选择合适的软硬件平台和相应的防火墙设计原理,自己开发出一套能够满足要求的防火墙系统。
归纳起来这里要实现的防火墙需要满足两大要求:第一,必须能够对主机提供安全保护,即对主机与局域网以外的主机进行数据传输时实施安全保护;第二,必须能够提供良好的人机接口界面,具有容易操作、容易管理的优点。
考虑到现有硬件设备的限制,在保证满足实验要求的环境下尽可能地简化了实验环境。因为该防火墙系统是基于主机设计的,故只需要一个联网的主机即可进行实验。该系统是在Linux环境下用C语言实现包过滤型软件防火墙的设计与应用,采用Kylix开发工具进行界面设计和数据库连接。
基于Linux的个人防火墙系统主要具有以下功能:
(1)全程动态包过滤 本防火墙要在Linux下实现全程动态包过滤功能,通过分析数据包的地址、协议、端口对任何网络连接当前状态进行访问控制,从而提高系统的性能和安全性。
(2)提供日志审计 本防火墙配备了日志记录系统和查询工具,用于记录系统管理、系统访问及针对安全策略的网络访问情况。
(3)防火墙数据库的备份 本防火墙制作防火墙过滤数据库,并且管理员可以能动地对该数据库进行设置。三、基于Linux的数据包捕获模块结构与原理分析
本节就监控层数据包捕获模块的结构特性进行探讨,并详细论述其原理,且对实现数据包捕获功能的程序的一些重要函数进行说明。
1、数据包捕获模块结构
数据包捕获模块用于监视和验证网络流量情况,它可以截取或者阅读网络上OSI协议模型中各个协议层次上的数据包。
本文所设计的数据包捕获程序可以捕获通过原始套接口(Socket)的原始数据包(Raw Packet),当一个数据包到达网络接口时,数据包捕获程序就直接从缓存区读取捕获的数据包,以供数据分析和处理时调用。数据捕获模块的结构如图1所示:
TCP/IP网络
↓
数据捕获
网卡设置
获取数据包
得到数据包头信息
图1 数据捕获程序结构图
2、数据包捕获模块原理分析
(1)网卡设置原理
在一个实际的系统中,数据的收发是由网卡来完成的,网卡接收到传输来的数据,网卡内的程序接收数据帧的目的MAC地址,根据计算机上的网卡驱动程序设置的接收模式判断该不该接收,认为不该接收就丢掉不管。而对于网卡来说一般有四种接收模式:广播模式组播模式、直接方式、混杂模式。数据包捕获程序首先使网络接口(网卡)处于混杂状态,从而可截获网络上的内容,并且通过相应的软件处理,可以实时分析这些数据的内容,为数据包过滤作准备。
(2)基本函数说明
本文中在Linux主机上用C语言编写数据包捕获程序,所编写的程序中用到很多Linux中的预定义函数,在此节将对这些基本函数的功能和使用特点进行说明。
1)ioctl函数定义
ioctl()函数非常庞杂,它可以控制各种文件的属性。它用于控制特殊文件的底层设备参数,这些特殊文件通常是指终端、套接字和接口。ioctl函数原型为:
int ioctl(int handle,int cmd[,int *argdx,int argcx]);
2)socket函数定义
常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据包式Socket (SOCK_DGRAM)。流式是一种面向连接的Socket,针对面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,针对无连接的UDP服务应用。Socket函数原型为:
int socket(int domain, int type,int protocol);
3)recvfrom()函数定义
用recvfrom()函数来实现接收数据包,recvfrom()是具备“阻塞式I/O”特性的函数,能够在没有数据包到达的情况下暂时挂起等待,直至接收到数据包后,再激活转入下一步处理。recvfrom()函数的原型为:
int recvfrom(SOCKET s,char FAR *buf,int len,int flags,struct sockaddr FAR *from,int *fromlen);
本函数从已连接套接口上接收数据,并捕获数据发送源的地址。对于SOCK_STREAM类型的套接口,最多可以接收缓冲区大小个数据。如果套接口被设置为线内接收带外数据(选项为 SO_OOBINLINE),且有带外数据未读入,则返回带外数据。应用程序可通过调用ioctlsocket()的SOCATMARK命令来确定是否有带外数据待读入。对于SOCK_STREAM类型套接口,忽略from和fromlen参数。
4)一些“字节顺序”转换函数
因为网络和主机采用的存储字节时内存顺序安排方式的差异,就存在“字节顺序”的问题。在网络环境下存储时,高位字节存放在内存的起始位置,而低字节则存放在较高的位置。主机形式的存放顺序恰好相反,低位字节存放在内存的起始位置。这就需要以下相应的字节顺序转换函数:
inet_ntoa():将32位的网络二进制数值转换为可读十进制形式的带点分割符的IP地址。
inet_addr():将带有分割符的IP地址转换为32位的unsigned long的格式。
ntohs():将网络字节顺序转换为32位的主机字节顺序。
ntohl():将网络字节顺序转换成16位的主机字节顺序。
htonl():将32位u_long的值由主机字节顺序转换为网络字节顺序。
htons():将16位u_long的值由主机字节顺序转换为网络字节顺序。
本文设计的数据捕获程序需要使用SOCK_PACKET设备,SOCK_PACKET只在基于Linux的操作系统中有效定义。为此,美国洛仑兹伯克利国家实验室编写了专用于数据包截获的API函数库“Libpcap”。该函数的设计目标是统一不同系统上所提供的用于数据包截获的不同类型接口,并使得类似的高层应用程序的编写和移植变得简单有效,不再需要对每一个应用都使用不同的依赖于具体系统的数据包截获模块。