# Linux下状态检测防火墙的设计与实现
## 0x00 简介
本实验为2021年华中科技大学网络空间安全学院《网络安全课程设计》的实验,要求实现一个带NAT功能的状态检测防火墙(NAT我没有实现)。这份课设本来就有参考之前的学长学姐的代码,虽然我写的很垃但还是贡献出来,送给想划水的同学,希望能帮到你,也希望你写好之后也能上传分享给以后的学弟学妹 :)
## 0x01 实验目的和要求
**实验目的**
- 结合理论课程学习,深入理解计算机网络安全的基本 原理与协议,巩固计算机网络安全基本理论知识
- 熟练掌握计算机网络编程方法,拓展学生的应用能力
- 加强对网络协议栈的理解
- 提高分析、设计软件系统以及编写文档的能力
- 培养团队合作能力。
**实验要求**
- 正确理解题意
- 具有良好的编程规范和适当的注释
- 有详细的文档,文档中应包括设计题目涉及的基础知识、 设计思路、程序流程图、程序清单、开发中遇到的问题及解决方法、设计中待解决的问题及改进方向
**任务要求:**
1. 系统运行
- 系统启动以后插入模块,防火墙以内核模块方式运行
- 应用程序读取配置,向内核写入规则,报文到达,按照规则进行处理
2. 界面
- 采用图形或者命令行方式进行规则配置,界面友好
3. 功能要求
- 能对TCP、UDP、ICMP协议的报文进行状态分析和过滤
- 每一条过滤规则至少包含:报文的源IP(带掩码的网络地址)、目的IP(带掩码的网络地址)、源端口、目的端口、 协议、动作(禁止/允许),是否记录日志
- 过滤规则可以进行添加、删除、保存,配置的规则能立即生效
- 过滤日志可以查看
- 具有NAT功能,转换地址分按接口地址转换和指定地址转 换(能实现源或者目的地址转换的任一种即可)
- 能查看所有连接状态信息
4. 测试
- 测试系统是否符合设计要求
- 系统运行稳定
- 性能分析
## 0x02 实验原理
### 状态检测技术
状态检测技术是防火墙近几年才应用的新技术。传统的包过滤防火墙只是通过检测IP包头的相关信息来决定数据流的通过还是拒绝,而状态检测技术采用的是一种基于连接的状态检测机制,将属于同一连接的所有包作为一个整体的数据流看待,构成连接状态表,通过规则表与状态表的共同配合,对表中的各个连接状态因素加以识别。这些状态信息可由状态检测表存储,状态检测表包括所有通过防火墙的连接,并维护所有连接。每条连接的信息包括源地址、目的地址、协议类型、协议相关信息(如TCP/UDP协议的端口、ICMP协议的ID号)、连接状态(如TCP连接状态)和超时时间(若进行NAT转换,还需记录转换前后地址端口信息)等。这里动态连接状态表中的记录可以是以前的通信信息,也可以是其他相关应用程序的信息,因此,与传统包过滤防火墙的静态过滤规则表相比,它具有更好的灵活性和安全性。
对于TCP连接,一次连接以3次握手开始,以4次挥手或Reset报文结束。由于TCP协议是询问-应答类型的可靠数据传输协议,故TCP连接存在状态,对于同一连接的报文,只需对其握手报文进行规则匹配即可,若允许通过,则同一TCP连接的所有报文均可通过,无需遍历规则表。
![TCP连接处理流程](images/clip_image002.jpg)
对于非TCP连接,防火墙为其建立虚拟连接。
UDP:一方发出UDP包后,如DNS请求,防火墙会将从目的地址和端口返回的、到达源地址源端口的包作为状态相关的包而允许通过。
ICMP:信息查询报文,如ping(echo)包,其状态相关包就是来自目的地址的echo reply包,而没有与echo包对应的echo reply包则认为是状态非法的。
### Linux Netfilter架构
Netfilter 是 Linux 内核中进行数据包过滤,连接跟踪(Connect Track),网络地址转换(NAT)等功能的主要实现框架;该框架在网络协议栈处理数据包的关键流程中定义了一系列钩子点(Hook 点),并在这些钩子点中注册一系列函数对数据包进行处理。这些注册在钩子点的函数即为设置在网络协议栈内的数据包通行策略,也就意味着,这些函数可以决定内核是接受还是丢弃某个数据包,换句话说,这些函数的处理结果决定了这些网络数据包的“命运”。
Netfilter框架在网络协议各层的各个hook点如下图所示。
![Netfilter框架hook点](images/clip_image002-16414060761671.jpg)
### Linux字符设备驱动
字符设备:是指只能一个字节一个字节进行读写操作的设备,不能随机读取设备中的某一数据、读取数据要按照先后数据。字符设备是面向流的设备,常见的字符设备有鼠标、键盘、串口、控制台和LED等。
字符设备可以通过文件节点来访问,比如/dev/tty1和/dev/lp0等。这些设备文件和普通文件之间的唯一差别在于对普通文件的访问可以前后移动访问位置,而大多数字符设备是一个只能顺序访问的数据通道。然而,也存在具有数据区特性的字符设备,访问它们时可前后移动访问位置。例如framebuffer就是这样的一个设备,app可以用mmap或lseek访问抓取的整个图像。
如图,在Linux内核代码中:
- 使用struct cdev结构体来抽象一个字符设备;
- 通过一个dev_t类型的设备号(分为主(major)、次设备号(minor))一确定字符设备唯一性;
- 通过struct file_operations类型的操作方法集来定义字符设备提供个VFS的接口函数。
![Linux字符设备驱动](images/clip_image002.png)
## 0x03 实验环境和采用的工具
操作系统:Ubuntu14.04
内核版本:Linux 4.4.0-142-generic
编译环境:gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.4)
## 0x04 系统设计
### 系统静态结构设计
- 内核模块设计
内核模块由访问控制处理逻辑和字符设备驱动构成。访问控制处理逻辑负责对报文进行过滤分析,实现状态监测;字符设备驱动负责内核态与用户态的交互。
访问控制处理逻辑维护了规则表、日志表、HASH表与连接链、NAT表。其中,规则表负责记录规则信息,包括七元组(五元组+IP掩码)、动作、以及是否记录日志等;日志表负责记录规则与连接信息;HASH表与连接链共同维护连接信息,包括连接双方的网络信息、剩余超时时间等;NAT表负责维护NAT地址转换。
hook_in和hook_out两个Hook函数维护了连接链和HASH表。通过查询规则表的访问控制规则决定是否允许报文通过,同时更新连接链和Hash表的状态信息,并且对匹配的规则记录日志。
字符设备驱动部分通过对字符设备的操作实现内核模块与用户模块的信息传递。其中,.read操作负责根据操作码,将内核模块所维护的连接信息、日志信息以及NAT信息发送给字符设备供用户模块读取;.write操作负责从字符设备读取操作码,实现规则载入以及调用.read实现信息输出。
- 用户模块设计
用户模块由C++实现,完成了规则的维护(包括存储、读取、新增、删除、以及载入到内核)、连接信息的获取、日志获取。
用户模块项目结构如下所示,将内核模块的5个重要数据结构抽象成类。
内核模块的规则信息在用户模块抽象成Rule类。主要实现新规则的构造、规则信息的格式转换,以及规则展示�
小英子架构
- 粉丝: 1030
- 资源: 4157
最新资源
- 图像的卷积、关联和算术运算Matlab代码.rar
- 图像的线性拉伸Matlab代码.rar
- 图像量化Matlab代码.rar
- 图像平铺Matlab代码.rar
- 图像配准可视化Matlab代码.rar
- 图像阈值(或)颜色到二进制图像转换的手动代码Matlab代码.rar
- 图像筛选Matlab代码.rar
- 图像去斑过滤和分析工具箱Matlab代码.rar
- 围绕图像内的任何点执行图像旋转。.rar
- 围绕任意点旋转图像Matlab代码.rar
- 为 Chan-Vese 方法生成边界Matlab代码.rar
- 向稀疏 sinogram 添加新投影,提高断层重建的质量Matlab代码.rar
- 线性扩散过滤、边缘增强线性和非线性各向异性过滤Matlab代码.rar
- 一个有用的程序,用于在图像中选择平滑区域Matlab代码.rar
- 一个基于各向异性扩散的乘法噪声去除混合模型Matlab代码.rar
- 为磁铁矿涂层碳钢拍摄的 EDAX 图像Matlab代码.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈