4.4 防火墙系统功能的具体实现
4.4.1 封包采集模块
(1)发送数据封包
拦截到本机发送出去的数据包后,首先调用控管规则模块的发送数据包检查函数对NDIS_PACKET 网络封包进行解析,从网络封包结构解析出 NDIS_BUFFER 链表和网络封包的总字节数。根据从 NDIS_BUFFER 中得到的协议类型来判断是否是 TCP/IP 封包,若不是TCP/IP 类型封包,返回 XF_PASS 给调用者放行封包。若果是 TCP/IP 封包,则解析 IP 封包得到具体的协议类型。根据封包解析[32]
到的协议类型(TCP、UDP、ICMP)对数据封包进行不同的处理。如果解析到协议类型是 TCP 协议,得到 TCP 封包地址,调用 CheckTcp 解析封包并进一步对封包进行认证;解析到的协议类型为 UDP 协议,得到 UDP 封包地址,调用函数 CheckUdp 解析封包并对封包认证;若解析到的协议为 ICMP 协议,得到 ICMP 封包地址,调用 CheckIcmp 函数解析封包并进一步对封包进行认证。最后,得到认证结果返回给调用函数,发送数据封包过程结束。发送数据封包的具体流程如图 4.2 所示。
(2)接收数据封包
接收到外部发送来的数据封包,首先执行 MemoryAcl.c 模块的执行函数 CheckRecv,从该函数参数 HeaderBuffer 得到协议类型,然后判断是否为 TCP/IP 类型,如果不是 TCP/IP 封包,则会返回 XF_PASS 告诉调用者放行封包。如果是 TCP/IP 类型的封包,接下来的对数据包的处理的流程与接收数据包是一样的,在此不再详细介绍。数据包接收的流程如图 4.3 所示。
(3)TCP 封包解析和认证
TCP(Transmission Control Protocol)传输控制协议,是一种面向连接的、可靠的传输层协议,但传输效率低于 UDP 传输。如果封包类型为 TCP 协议,都必须对封包做下面的解析和认证。封包协议类型为 TCP,则会执行 CheckTcp 函数,解析 TCP 封包并将数据包信息保存到自定义结构 PACKET_BUFFER.TCP 是面向连接的网络协议,会根据 TCP 是否发出同步连线请求,做出不同的处理。发出同步连线请求,会根据不同的连线请求来选择调用函数CheckNnb 或函数 CheckApp 进行连接认证。若认证结果为放行并且是 ACK 应答包,则初始化连线封包记录并调用 PacketBuffer.c 模块的 AddDirection 增加连线记录。如果 TCP 并没有发出同步连线请求,调用 PacketBuffer.c 模块的 FindDirection 查找连线记录,如果连线记录是存在的,得到连线属性并保存到结构 PACKET_BUFFER 中。还需要继续判断是否结束连线请求(FIN),如果是,则要调用 PacketBuffer.c 模块的 DeleteDirection 函数删除连线记录。调用函数 GetFreePacket 得到一个空闲的封包缓冲区,并将封包保存到这个缓冲区,供 PSFW.EXE获取接着返回认证结果到调用函数,到此,整个过程结束了。TCP 封包的解析和认证流程如图 4.4 所示。
(4)UDP 封包解析和认证
UDP (英文全称 User Datagram Protocol)用户数据报协议,是一种无连接、不可靠的传输层协议,传输效率高。对 UDP 类型的数据封包进行解析和认证,首先也是执行 MemoryAcl.c模块的 CheckUdp 函数,解析 UDP 封包并保存在自定义的结构 PACKET_BUFFER 中。根据不同的资源连接请求,选择调用函数 CheckNnb 或 CheckApp 进行不同的连接认证。最后,调用 PacketBuffer.c 中的 GetFreePacket 函数得到一个空闲的封包缓冲区,并将封包保存到这个缓冲区,返回认证结果到调用函数,结束认证和解析。UDP 的解析和认证是不同于 TCP 协议类型的,因为它是面向非连接的,不要根据连接请求做出不同的处理,而 UDP 只需要对封包进行认证即可。UDP 封包认证解析的整个过程如图 4.5 所示。
(5)ICMP 封包解析和认证
ICMP是(Internet Control Message Protocol)Internet控制报文协议,主要用来检测网络是否通、主机是否可达,是网络用使用最为频繁的一个协议,主要使用网络命令ping进行网络探测[34][35].
对 ICMP 类型数据封包的解析和认证,首先调用 CheckIcmp 函数解析封包大小,协议类型等并保存到 PACKET_BUFFER 自定义结构中。根据函数 GetIcmpDirection 确定连线方向,对 ICMP 封包进行认证,最后调用 PacketBuffer.c 模块的 GetFreePacket 函数得到一个空闲的封包缓冲区,并将封包保存到这个缓冲区并返回认证结果到调用函数,结束 ICMP 认证。ICMP封包解析和认证流程如图 4.6 所示。
4.4.2 控管规则模块
(1)控管规则
文件结构及功能表根据存储内容的不同将控管规则文件进行划分,控管规则文件的整体结构如表4.5所示,整体结构包括:文件头、应用程序规则记录存储区、网站规则记录存储区、网上邻居规则记录存储区、ICMP 规则记录存储区,系统相关设置主要存储的文件头,记录存储区存储已经添加或新添加的控管规则。
(2)应用程序规则
定义为 XFILT.H 的_XACL 结构,记录结构表 4.7 如下:
控管规则模块主要是需要给保存控管规则申请内存空间,在 PSFW.EXE 可执行程序模块和 PSFW.DLL 动态链接库模块共享内存空间,还要对 NDIS 网络驱动拦截到的发送或接收数据封包进行解析,将解析的数据包信息与过滤规则进行比对,从而对数据包做出相应处理。
应用程序控管规则的功能列表如表 4.6 所示。现在主要来介绍一下应用程序规则比对是如何实现的。在 Memory.c 中应用规则比较函数 CheckApp 中介绍整个比较过程。首先,应用程序控管链表的头指针保存到 pAcl,若 pAcl 不为空,则需要比较应用程序规则与当前封包是否匹配,需要匹配的包括进程方向、协议类型、端口号等多个都是需要一一进行匹配的。如果应用程序规则与封包内容不匹配,则 pAcl = pAcl->next 继续进行比较,直到查找的匹配的规则或直到链表尾部,将管制动作保存到日志记录;若 pAcl 为空或者直到比较到链表结束也没有找到对应记录,比较过程直接结束。应用程序控管规则的流程图如图 4.7 和比较函数的具体实现代码如下所示。
站点控管规则的功能在控管规则功能列表4.6中已基本全部列出。在此对最主要的规则比较函数和比较的整个过程做详细介绍。站点规则比较函数CheckWeb应用于PSFW.DLL.开始调用站点规则,首先调用函数CheckSubWorkMode,根据网站过滤模式判断是否放行,根据是否需要继续判断来选择两条不同的执行方式。如果不需要继续判断,则直接返回上一级调用函数。继续判断,则网站控管规则链表的头指针保存到pWeb.接下来,继续判断pWeb是否为空,若不为空,则比较站点规则与当前封包是否匹配,需要匹配的是站点名称、管制动作、编号等方面。如若匹配,从控管规则中得到管制动作。如若站点规则与当前封包不匹配,则执行pWeb = pWeb->next,直到pWeb为空为止。pWeb为空,调用CheckQueryEx函数得到默认管制动作。最后将管制动作保存到记录并返回给调用者。站点规则比较函数的实现代码如下。
网上邻居规则比较函数CheckNnb,将网上邻居规则与当前封包匹配,并记录管制动作。
开始执行网上邻居规则比较函数CheckNnb之后,控管规则使用计数器加1,调用GetAccessWithoutAcl,不用管控规则进行判断是否需要继续,如果不需要继续则直接返回判断结果。需要继续,则调用函数CheckSubWorkMode根据网上邻居工作模式判断是否放行。
需要继续判断,则调用GetNameFromIp得到网上邻居的名字,进而得到网上邻居控管规则链表的头指针保存到pNb.若pNb为空,则调用CheckQueryEx得到默认管制动作,结束执行。如果pNb不为空,比较网上邻居规则与当前封包是否匹配,不匹配则需要pNb = pNb->next继续查找,指导指针指向的为空才会停止匹配操作。
(5)ICMP 控管规则
在XFILT.H中定义为_XACL_ICMP结构,记录结构表4.10如下所示:
本模块负责将ICMP过滤规则从过滤文件中读出,保存到过滤模块对象中。表4.6列出了控管规则主要功能,每一项控管规则都包括这几方面的功能。ICMP控管规则要完成的功能较多,添加、删除、修改、发送给过滤模块对象、比较规则等都是必不可少的功能。在这里重点介绍一下规则比较函数,设置的规则是否可以起到过滤危险信息的作用这个函数是非常重要的。
ICMP规则对比函数CheckIcmpAcl应用于PSFW.SYS.将ICMP控制规则链表的第一条记录的指针保存到pIcmp.需要判断pIcmp指针指向的链表是否为空,若不为空,则必须要再比较ICMP规则和当前封包,如果不匹配,则 pIcmp = pIcmp->next 继续查找直到pIcmp指针指向的链表为空,则要调用CheckQueryEx函数得到默认管制动作。如果ICMP规则与封包是匹配的,则管制动作保存记录并返回给调用者。结束ICMP规则比较函数。ICMP规则比较函数的流程图如下图4.8所示,并列出ICMP规则比较函数具体实现代码。
4.4.3 日志模块
日志是各类防火墙软件设计时不可缺少的主要功能模块,日志功能用来记录防火墙软件监听的所有发生的事件,记录访问时间、端口号、IP 地址、协议类型等。日志文件采用文本文件存放,使用户能够根据需要了解防火墙的工作状态和及时发现有问题的站点、应用程序等。
(1) 日志文件头结构
4.4.4 状态指示模块
状态指示模块主要实时显示防火墙的一些相关信息,如个人防火墙的开启时间、进出流量数、拒绝封包和放行封包数量、设置的控管规则以及工作模式等多个方面,都可以通过状态指示对应的对话框显示出来,从而可以很容易的观察到是否有大量数据包发送到本地,或本机频繁向外部发送数据包,起到安全保护本机的作用。
4.5 界面设计
根据 PSFW 个人防火墙的结构和各个模块的设计与实现,从而可以确定 PSFW 防火墙采用简单明了的对话框模式进行设计,每一个对话框对应一个核心功能模块,从主界面可以切换到不同核心功能对应的对话框。
防火墙的核心技术主要是包过滤技术,其中控管规则设置、封包采集等功能都是以封包过滤技术为基础。PSFW 防火墙系统能够实现防火墙的基本功能,包括网络数据包监视、日志查询、状态指示、管控中心的过滤规则设置,可以通过系统界面的设置来实现对于此防火墙的使用与管理,界面部分是由应用程序模块 PSFW.EXE 使用 VS2010 开发工具的 MFC 开发和实现。PSFW 的主界面设计如图 4.9 所示。
4.6 本章小结
PSFW 个人防火墙的设计架构分为总体结构和二级模块结构两个方面。在设计架构的基础上,对个人防火墙的详细设计和功能的具体实现进行分析。防火墙需要实现的主要功能包括封包采集、控管规则设置、日志记录、状态指示,首先,对发送和接收的数据包进行采集,然后根据采集到的这些数据封包及已经设置的相关控管规则,对数据包做相应的处理。各种数据包进出的日志会被记录下来以方便查询。采用 VS2010 作为开发工具,MFC 界面设计实现了个人防火墙的前端显示,便于设置规则以达到保护主机不受到外部侵袭的目的。