logo资料库

基于Linux的包过滤防火墙设计与实现.docx

第1页 / 共17页
第2页 / 共17页
第3页 / 共17页
第4页 / 共17页
第5页 / 共17页
第6页 / 共17页
第7页 / 共17页
第8页 / 共17页
资料共17页,剩余部分请下载后查看
摘要 随着互联网的飞速发展,网络安全问题也变得越来越突出。包过滤防火墙技 术作为保护网路安全的的一种技术,其应用十分广泛。所谓包过滤就是对流经网 络防火墙的所有数据包进行逐个的检查,并依据设置好的防火墙过滤策略来决定 每个数据包是通过还是不通过。 在此提出了一种基于 linux 系统 netfiter 内核模块的包过滤防火墙的策略 设计与实现方法,其功能设计实现是仿照 linux 系统中的 iptables 和 netfiter 实现的。借助于 netfilter 的数据包过滤功能框架,本文对 linux 包过滤防火墙 的访问控制策略进行了研究、设计以及代码实现。其中最常用的过滤策略包括: IP 过滤,端口过滤以及协议过滤,在 netfiter 内核模块中,系统定义了五个钩 子函数,在开发防火墙时,可以在相应的钩子点注册自己的处理函数,然后设置 一些规则,当网络数据包到达内核协议栈时,会进入到程序里设定的处理函数, 将每一个数据包的 ip 地址,端口,协议等信息与规则进行匹配,若匹配成功,则 按照规则设置的策略对数据包进行处理。 关键字:网络安全 防火墙 包过滤技术 Linux netfilter 设计目的 随着互联网的迅速发展,各种网络应用软件层出不穷,一些网络新业务也开 始兴起,比如电子商务、数字货币、互联网络银行等,人们的生活和学习对网络 的依赖越来越多,但问题也接踵而来,比如,网站遭到攻击,网上的个人重要信 息被窃取,病毒泛滥等等,所以网络安全问题越来越受到人们的重视。目前,网 络互连一般都基于 TCP/IP 协议,TCP/IP 协议在制订之初,并没有把安全考虑在内, 所以协议中存在很多的安全问题。为解决这一问题,人们想出了两种办法,一种 是重新制定出一个更安全的网际互连协议,比如现在正在研究的 IPv6,另一种方 法就是采用网络安全技术,比如密码技术,防火墙技术等等。其中,防火墙作为 最早出现的网络安全产品和使用量最大的安全产品,受到了广大用户和研发机构 的青睐,在内网和外网之间设置防火墙已被我们广泛的应用于实践,它也被证明 是一种行之有效的方法。因此,研究防火墙的包过滤技术,无论从理论上还是实 际应用上都具有十分重要的意义。 防火墙简介 所谓防火墙指的是一个由软件和硬件设备组合而成、在内部网和外部网之间、 专用网与公共网之间的界面上构造的保护屏障.是一种获取安全性方法的形象说
法,它是一种计算机硬件和软件的结合,使 Internet 与 Intranet 之间建立起一 个安全网关(Security Gateway),从而保护内部网免受非法用户的侵入,防火 墙主要由服务访问规则、验证工具、包过滤和应用网关 4 个部分组成,防火墙就 是一个位于计算机和它所连接的网络之间的软件或硬件。该计算机流入流出的所 有网络通信和数据包均要经过此防火墙。 在网络中,所谓“防火墙”,是指一种将内部网和公众访问网(如 Internet) 分开的方法,它实际上是一种隔离技术。防火墙是在两个网络通讯时执行的一种 访问控制尺度,它能允许你“同意”的人和数据进入你的网络,同时将你“不同 意”的人和数据拒之门外,最大限度地阻止网络中的黑客来访问你的网络。换句 话说,如果不通过防火墙,公司内部的人就无法访问 Internet,Internet 上的 人也无法和公司内部的人进行通信。 用一句简短的话来描述便是:防火墙是一种位于内部网络与外部网络之间的 网络安全系统。 防火墙的种类 防火墙从诞生到现在,已经历了四个发展阶段:基于路由器的防火墙、用户 化的防火墙工具套、建立在通用操作系统上的防火墙、具有安全操作系统的防火 墙。目前常见的防火墙属于具有安全操作系统的防火墙,例如 NETEYE、 NETSCREEN、TALENTIT 等。 从结构上来分,防火墙有两种:即代理主机结构和路由器+过滤器结构,后 一种结构如下所示:内部网络过滤器(Filter)路由器(Router)Internet 从原理上来分,防火墙则可以分成 4 种类型:特殊设计的硬件防火墙、数据 包过滤型、电路层网关和应用级网关。安全性能高的防火墙系统都是组合运用多 种类型防火墙,构筑多道防火墙“防御工事”。 Linux 防火墙分析 Netfilter 框架 在 Linux 操作系统上,有一个成功的网络数据过滤框架——netfiter,于是基 于这一框架,仿照 Linux 系统的 iptables 所设计的一个简单的包过滤防火墙。 基于 Linux 系统 Netfilter 框架构造防火墙, Netfilter 是 Linux 核心中一个抽 象、通用架构,用于扩展各种服务的结构化底层服务。Netfilter 组件也称为内核 空间(kernel space),是内核的一部分,由一些数据包过滤表组成,这些表包含内
核用来控制数据包过滤处理的规则集。Netfilter 是 Linux 实现的防火墙框架, Netfliter 框架提供了一系列的“表”(tables),每个表由若干“链”(chains)组成,其实 质是处理数据包时,提供的一系列的检查点,又称为钩子函数。而每条链可以由 一条或数条“规则”(rules)组成,对每一个流经的数据包,Netfilter 根据其流动方向, 会利用相应的钩子函数按照规则进行检查。Netfilter 在 IPV4 中定义了 5 个检查点, 其位置如图 1 所示。方框为检查点,箭头表示数据包的流向。如下图所示: NF_ INET _PRE_ROUTING ROUTE NF_INET_FORWARD NF_IP_POST_ROUTING 网络数据包 网络数据包 NF_INET_LOCAL_IN ROUTE NF_INET_LOCAL_OUT 本地网络数据 数据包进入系统,在第一个检查点 NF_INET_PRE_ROUTING 进行处理,然后进入 路由选择,判断数据包是需要转发还是发给本机的。若该数据包是发往本机的,则 该数据包经过检查点 NF_INET_LOCAL_IN 处理后传递给上层协议;若该数据包应该被 转发则它被 NF_INET_FORWARD 处理, 经过转发的数据包经过最后一个检查点 NF_INET_POST_ROUTING 处理后,再传输到网络上。本地产生的数据包经过检查点 NF_INET_LOCAL_OUT 处理后再进行路由选择处理,然后经过 NF_INET_POST_ROUTING 处理后发送到网络上。上述的五个检查点具体含义如下: NF_INET_PRE_ROUTING,在报文作路由以前执行 NF_INET_FORWARD,在报文转向另一个 NIC 以前执行 NF_INET_POST_ROUTING,在报文流出以前执行 NF_INET_LOCAL_IN,在流入本地的报文作路由以后执行 NF_INET_LOCAL_OUT,在本地报文做流出路由前执行 数据包处理过程中,会检查相应的钩子函数在链表中是否有钩子函数注册,如 果注册了该钩子函数则监听数据包,调用该钩子函数,并根据钩子函数返回的结果 决定下一步的动作。钩子函数的返回结果值有 5 个值,分别如下:
NF_DROP:通知内核丢弃该数据包 NF_ACCEPT:通知内核接受该数据包,继续其旅途 NF_STOLEN:通知内核忘掉该数据包,有本模块接管 NF_QUEUE:通知内核将该数据包传递到用户空间 NF_REPEAT:通知内核再次调用该hook函数(需要防止死循环) 防火墙采用 Netfilter 的 5 个钩子实现,选取 Netfilter 5 个钩子中的 3 个作为实 现防火墙网络数据截取的基础: NF_INET_LOCAL_IN , NF_INET_LOCAL_OUT , NF_INET_FORWARD,分别对应于防火墙的 INPUT、OUTPUT 和 FORWARD 链。当在 上述的 3 个钩子上截取了网络数据的时候,可以查找网络数据上的内容在不同的链 上进行规则的查找。如果找到匹配的规则,则进行规则制定动作的处理。 用户空间与内核空间的通信 防火墙要能与用户交互,必须有一种适合用户空间和内核空间交互的方式。在 Linux 中内核空间和用户空间进行交互的方法有 sysctl()方法、ioctl()方法,PROC 方 法、文件读写的方法以及网络的方法等等。早期的 iptables 框架采用了网络框架中 的 setsocket()/getsockopt()的方法来实现用户空间和内核空间的通信,现在 iptables 采用了 netlink()方法。 该防火墙采用 netlink 框架的方法实现用户空间和内核空间的通信。netlink 框 架用于实现用户命令行的交互,即用户的命令行交互使用 netlink 来实现,将用户的 命令设置发送到内核。示意图如下
用户空间 内核空间 创建 netlink_socket 绑定到本进程 填充数据 调用 send_to 发送信息 调用 recv_from 接收信息 关闭 socket 定义接收回调函数 创建 socket 套接字,并注 册回调函数 回调函数接收 广播或单播 释放 socket netlink 是一种特殊的 socket,它是 Linux 所特有的,是一种在内核与用 户应用间进行双向数据传输的非常好的方式,用户态应用使用标准的 socket API 就可以使用 netlink 提供的强大功能,内核态需要使用专门的内核 API 来 使用 netlink, netlink 提供了一种异步通讯方式,与其他 socket API 一样, 它提供了一个 socket 队列来缓冲或者平滑瞬时的消息高峰。发送 netlink 消息 的系统调用在把消息加入到接收者的消息对列后,会触发接收者的接收处理函数。 接收者在接收处理函数上下文中,可以决定立即处理消息还是把消息放在队列中, 在以后其它上下文去处理它(因为我们希望接收处理函数执行的尽可能快)。系统 调用与 netlink 不同,它需要一个同步的处理,因此,当我们使用一个系统调用 来从用户态传递消息到内核时,如果处理这个消息的时间很长的话,内核调度的 粒度就会受到影响。 总体框架及工作过程 防火墙的总体架构分为两部分:内核空间部分的主要处理模块和用户空间部 分的交互控制用户接口。内核模块主要有网络数据的过滤,防火墙过滤规则的增 删。 用户空间部分主要处理用户输入命令格式的解析,用户空间与内核空间的 通信。 内核模块中的钩子函数是防火墙网络数据的主要处理部分,按照用户定义的
过滤规则,对通过 Netfilter 架构上的 INPUT、OUTPUT、FORWARD 这 3 个监视点 的网络数据进行过滤,目前实现 DROP 和 ACCEPT 两种处理方式。网络数据进入 网络协议栈之后, Netfilter 架构有 5 个钩子函数,用户调用插入的回调函数, 当用户设置了回调函数之后,就会进入用户的处理过程。该防火墙选择了上述 3 个,对进入本地、从本机发出、从本机转发的数据进行处理。 内核中与用户的通信采用了 Netfilter 的框架进行处理。内核建立了一个 私有的 netlink 通信类型,与用户的通信通过此类型的套接字进行处理。此模 块中用于处理用户对过滤规则的增加等操作。当模块接收到用户空间发来的数据 后,根据其操作方式对过滤规则链表中的规则进行增加等操作。 用户空间主要用于与防火墙进行交互,通过 netlink 网络协议与防火墙进行 规则的设置等操作,用户空间主要分为命令行解析和与内核通信。命令行主要将 用户输入的过滤规则转换成易于传送的数据格式。通信部分主要负责给内核发送 规则数据。 内核模块在启动时进行初始化工作,建立好 netlink 通信后监听用户交互数 据以及网络数据的到来。用户的 netlink 部分和内核部分的 netlink 部分进行交 互,对防火墙的过滤规则进行处理。钩子函数则会对网络数据进行处理。 用户命令格式 用户输入命令格式如下: 操作 链名称 源 ip 源端口 目的 ip 目的端口 协议类型 动作名称 用户输入的命令行参数和含义: 命令字段 Command chain Sip Sport Dip Dport Proto Act 参数含义 规则操作类型 链名称 源 IP 源端口 目的 IP 目的端口 协议 对包的处理动作 防火墙所支持的链: 防火墙支持进入、发出、转发 3 个链: 含义 链名称 IUPUT OUTPUT FORWARD 发往本机的网络数据 从本机发出的网络数据 通过本机转发的网络数据 类型 Int Int Unsigned long Unsigned short Unsigned long Unsigned short Int Int 类型 Int Int Int 防火墙所支持的命令: 命令名称 含义 值 命令选项
APPEND FLUSH 向某个链尾插入规则 删除所有规则 0 4 -A -F 防火墙所支持的协议: 防火墙支持根据网络数据的协议进行过滤,支持 TCP、UDP 两种协议类型: 协议名称 TCP UDP 含义 TCP 协议 UDP 协议 值 IPPROTO_TCP IPPROTO_UDP 防火墙所支持的动作: 防火墙的支持通过和丢弃两种动作,其中 ACCEPT 表示让网络数据正常通过, 不对数据进行处理,DROP 表示丢弃网络数据: 动作名称 DROP ACCEPT 含义 丢弃网络数据 让网络数据通过,不进行处理 值 0 1 部分模块代码 SK_BUFF 结构体 网络数据存放在 skb 中,它是一个 struct sk_buff 结构,sk_buff 是一个 复杂的双向链表,在这个结构中有 next 和 prev 指针,分别指向链表的下一个节 点和前一个节点。。并且为了某些需求需要很快定位到链表头部,所以还有一个 指向链表头部的指针 list。 sk_buff_head 结构是: struct sk_buff_head { }; /* These two members must be first. */ struct sk_buff *next; struct sk_buff *prev; __u32 qlen; //代表元素节点数目 spinlock_t lock; //加锁,防止对表的并发访问 IP 头 通过 struct sk_buff 结构可以的 nh 枚举类型的 iph 成员变量,可以获得
IP 的头部结构,通过 IP 的头部结构可以获得网络数据的源 IP 地址,目的 IP 地 址和协议类型。 struct iphdr 结构的原型如下: struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4, version:4; #elif defined (__BIG_ENDIAN_BITFIELD) __u8 version:4, ihl:4; #else #error "Please fix " #endif __u8 tos; __be16 -tot_len; __be16 -id; __be16 -frag_off; __u8 ttl; __u8 protocol; __be16 -check; __be32 -saddr; __be32 -daddr; }; 各字段含义: iphdr->version 版本(4 位),目前的协议版本号是 4,因此 IP 有时也称作 IPv4。 iphdr->ihl 首部长度(4 位):首部长度指的是 IP 层头部占 32 bit 字的数目 (也就是 IP 层头部包含多少个 4 字节 -- 32 位),包括任何选项。 iphdr->tos 服务类型字段(8 位) iphdr->tot_len 总长度字段(16 位)是指整个 IP 数据报的长度,以字节为单 位。利用首部长度字段和总长度字段,就可以知道 IP 数据报中数据内容的起始 位置和长度。 iphdr->id 标识字段(16 位)唯一地标识主机发送的每一份数据报。通常每 发送一份报文它的值就会加 1。 iphdr->frag_off (16 位) frag_off 域的低 13 位 -- 分段偏移(Fragment offset)域指明了该分段在当前数据报中的什么位置上。 iphdr->ttl TTL(time-to-live) -- 8 位,生存时间字段设置了数据报可以 经过的最多路由器数。它指定了数据报的生存时间。 iphdr->protocol 协议字段(8 位): 根据它可以识别是哪个协议向 IP 传送 数据。 iphdr->check 首部检验和字段(16 位)是根据 IP 首部计算的检验和码。
分享到:
收藏