随着以Internet为代表的全球信息化浪潮的来临,信息网络技术的应用正日益广泛,应用层次正在深入,应用领域也从传统的、小型业务系统逐渐向大型、关键业务系统扩展,其中以党政系统、大中院校网络系统、银行系统、商业系统、管理部门、政府或军事领域等为典型。伴随网络的普及,公共通信网络传输中的数据安全问题日益成为关注的焦点。一方面,网络化的信息系统提供了资源的共享性、用户使用的方便性,通过分布式处理提高了系统效率和可靠性,并且还具备可扩充性。另一方面,也正是由于具有这些特点增加了网络信息系统的不安全性。开放性的网络,导致网络所面临的破坏和攻击可能是多方面的,例如:可能来自物理传输线路的攻击,也可以对网络通信协议和实现实施攻击,可以是对软件实施攻击,也可以对硬件实施攻击。国际性的网络,意味着网络的攻击不仅仅来自本地网络的用户,也可以来自linternet上的任何一台机器,也就是说,网络安全所面临的是一个国际化的挑战。开放的、国际化的Internet 的发展给政府机构、企事业单位的工作带来了革命性的变革和开放,使得他们能够利用Internet 提高办事效率、市场反应能力和竞争力。通过Internet,他们可以从异地取回重要数据,同时也面临Internet 开放所带来的数据安全的挑战与危险。如何保护企业的机密信息不受黑客和工业间谍的入侵,己成为政府机构、企事业单位信息化建设健康发展所要考虑的重要因素之一。广泛分布的企业内部网络由公共网络互联起来,这种互联方式面临多种安全威胁,极易受到外界的攻击,导致对网络的非法访问和信息泄露。防火墙是安全防范的最有效也是最基本的手段之一,虽然国外己有许多成熟的防火墙及其他相关安全产品,并且这些产品试图打入中国市场,但是对于安全产品来说,我们更希望能够自己掌握安全技术,使用自己的安全产品,所以对网络安全的研究非常重要,具有深远的意义。
目前Internet 的安全性保障不容乐观,计算机紧急事件响应队(CERT)近年收到的计算机安全事故报告的数量一直呈上升趋势,1999年该中心收到了约10, 000 份计算机安全事故报告,2000年达到了21, 756份,而2001 年更上升到了52, 658 份。2000年2 月上旬,Yahoo, eBay, CNN.com, Amazon,Buy. com和ETrade等著名商业网站连续遭到黑客攻击,造成了数以十亿美元的损失,向世人再一次敲响了网络并不安全的警钟。如果用户能根据自己的实际需要,将防火墙设计的一般理论和方法与自己系统的具体实际相结合,设计一些小而精、精而强的防火墙程序,则往往可以发挥出比花大价钱买来的通用型防火墙更好的作用。操作系统作为防火墙运行的基础平台,对防火墙起到一个至关重要的作用。Windows操作系统由于其源代码不公开,所以对操作系统加固安全性只能是打上微软公司最新的补丁,当发现新Bug 时等微软公司出新的补丁。对NT 防火墙的一致意见也正是在NT系统的bug 上,而NT 系统最大的bug 就是‘NT 安全性远远不能运行一个正规的防火墙。而Linux 操作系统良好的网络性能和开放源码的特点,使得在其上布置防火墙有了一个可靠的基石,也使得越来越多的用户选择了Linux 作为其防火墙的操作平台。Linux2. 4 内核版操作系统本身所带有的netfilter 是一个优秀防火墙架构,其功能和性能可与多数的商业防火墙产品媲美。在国内,大多数防火墙借鉴了netfilter 的结构。为适应日益增长的对网络安全产品的需求,向企事业单位提供网络安全解决方案参考,也为研究最新的网络安全技术,选择了在Linux 下作防火墙研究,并设计了一款防火墙。
1.3 项目的研究工作
在对Linux 2. 4 内核防火墙netfilter 的原理深入研究后,分析了在netfilter 架构下防火墙的设计、实现和开发过程。以kylix3. 0为开发环境,作者基于netfilter 架构开发了一款包过滤和应用代理的混合型防火墙,并对其做了测试。该防火墙系统是由包过滤管理模块、路由记录模块、应用代理模块(syn proxy)、扫描防御模块和日志记录模块构成。其中包过滤是基于netfilter 中的iptables 来实现的,网络地址转换也在包过滤管理模块中实现;路由记录模块通过修改Linux 内核中TCP/IP程序和重新编译内核使内核支持路由记录功能来实现的;在应用代理模块中实现了HTTP代理和一个通用代理服务,HTTP代理程序基于SQUID 实现,而通用代理由一个代理进程来实现;扫描防御模块中主要是通过一个网络扫描防御Demo 进程来监控是否有扫描发生;日志记录模块主要是选择记录日志的位置,有本机和邮件通知两种选择方式。针对常见的IP 地址欺骗、IP 源路由欺骗、ICMP 重定向欺骗、IP 劫持等常见网络攻击给予了分析并在过滤管理模块中加以解决实现,其中IP 劫持实现是用一个钩子函数注入协议栈中来实现的。文中还分析了加固操作系统而关闭一些危险和不使用的服务,使防火墙架设在一个相对安全的基础上,同时也将系统编译升级为最新的稳定内核。
2.1 防火墙的一般原理
随着网络规模的扩大和开放性的增强,网络上的很多敏感信息和保密数据将受到很多主动和被动的人为攻击。一种解决办法是为需要保护的网络上的每个工作站和服务器都装备上强大的安全特征(例如入侵检测),但这几乎是一种不切合实际的方法,因为对具有几百个甚至上千个节点的网络,它们可能运行着不同的操作系统,当发现了安全缺陷时,每个可能被影响的节点都必须加以改进以修复这个缺陷。另一种选择就是防火墙(Firewall),防火墙是用来在安全私有网络(可信任网络)和外部不可信任网络之间安全连接的一个设备或一组设备,作为私有网络和外部网络之间连接的单点存在。防火墙是设置在可信任的内部网络和不可信任的外部网络之间的一道屏障,它可以实施比较广泛的安全策略来控制信息流,防止不可预料的潜在的入侵破坏,其在网络环境中的位置如图2-1所示。
图2-1 具有DMZ外网和内部局域网的防火墙系统
防火墙具有以下性质:
(1) 从里向外和从外向里的流量都必须通过防火墙,这是通过物理上阻塞所有不经过防火墙的局域网访问来实现的;
(2) 只有被认可的通信量,即通过本地安全策略进行检查后,才能通过防火墙;
(3) 防火墙本身不可穿透,这就隐含使用了一个装有安全操作系统的可信任系统。
2.2 防火墙的功能
从逻辑上说,防火墙是一个分离器,是一个限制器,是一个分析器,建立防火墙可以达到以下目的:
(1) 管理进、出网络的访问防火墙允许网络管理员定义一个中心“扼制点”来防止非法用户进入内部网络,禁止存在安全脆弱性的服务进出网络,并抗击来自各种路线的攻击。防火墙能够简化安全管理,因为网络安全性是在防火墙系统上得到实施,而不是分布在内部网络的各个主机上的;
(2) 保护网络中脆弱的服务防火墙通过过滤存在安全缺陷的网络服务来降低内部网遭受攻击的威胁,因为只有经过选择的网络服务才能通过防火墙;
(3) 检测和报警在防火墙上可以很方便的监视网络的安全性,并产生报警。网络管理员通过防火墙日志可以审查常规记录并及时响应报警,以便知道防火墙或内部网络是否正受到攻击;
(4) 集中安全性如果一个内部网络的所有或大部分需要改动的安全程序都能集中放在防火墙系统中,而不是分散到每个主机中,这样防火墙的保护范围就相对集中,安全成本也相对便宜了;
(5) 日志与统计工nternet防火墙是审计和记录工nternet使用量的一个最佳地点。防火墙可以对正常网络使用情况做出统计,通过对统计结果的分析,可以使网络资源得到更好的利用。
2.3 防火墙的分类
2.3.1 IP级防火墙
又称为包过滤(packet filter)防火墙。在为IP报文进行转发之前根据报文的源地址、目的地址和端口号来过滤报文。IP 级防火墙具有很高的网络性能和很好的透明性、方便性。但它只能根据IP地址和端口号等特征来进行报文过滤,无法针对特定用户和特定服务等请求,粒度不够细致。IP 级防火墙可以作为一个独立的软硬件设备出现,也可以作为其他网络设备(如路由器)或系统中的一个功能模块来实现。
2.3.2 应用级防火墙
又称为代理防火墙,是运行在充当防火墙上的一些特定的应用程序或者服务器程序来实现的。充当防火墙的主机是指有一个网络接口连接互联网络而另一个接口连接内部网络的双宿主机。它封堵了外部网络的直接连接,一般针对特定的应用,由用户端的代理客户和防火墙端的代理服务器两部分组成。代理客户通常是对应用客户的改造,使其与防火墙而不是真正的应用服务器交互;而代理服务器代用户向应用服务器提交请求,并将结果返回给用户。应用级防火墙的优点是在用户和服务器之间不会有直接的工P 报文交换,所有的数据交换均由防火墙进行中继,而且防火墙能够提供鉴别、日志与审计功能,增强了安全性。
2.4 防火墙体系结构
防火墙的体系结构一般有以下几种:双重宿主主机体系结构、屏蔽主机体系结构和屏蔽子网体系结构:
1.双重宿主主机体系结构
双宿主主机结构是围绕着至少具有两个网络接口的双宿主主机(又称堡垒主机而构筑的。内外的网络均可与双宿主主机实施通信,但内外网络之间不可直接通信,内外网络之间的IP 数据流被双宿主主机完全切断。双宿主主机可以通过代理或让用户直接注册到其上来提供很高程度的网络控制。受保护网除了看到堡垒主机外,不能看到其他任何系统。同时堡垒主机不转发TCP/TP 诵信报亨,网络中的所有服务都必须由此主机的相应代理程序来支持。
2.屏蔽主机体系结构
屏蔽主机体系结构中提供安全保护的主机仅仅与内部网相连,另外有一台单独的过滤路由器连接内外网,这台路由器的意义就在于强迫所有到达路由器的数据包被发送到被屏蔽主机。这种体系结构中过滤路由器是否正确配置是这种防火墙安全与否的关键,过滤路由器的路由表应当受到严格的保护,否则如果遭到破坏,则数据包就不会被路由到堡垒主机上。
3.屏蔽子网体系结构
屏蔽子网体系结构增加一个把内部网与互联网隔离的周边网络(也称为非军事区DMZ),从而进一步实现屏蔽主机的安全性,通过使用周边网络隔离堡垒主机能够削弱外部网络对堡垒主机的攻击。
2.5 防火墙产品和技术发展方向
2.5.1 防火墙产品的发展
防火墙产品的发展可分为以下四个阶段:
1.第一代防火墙:基于路由器的防火墙
由于多数路由器中本身就包含有分组过滤功能,故网络访问控制可通过路由控制来实现,从而使具有分组过滤功能的路由器成为第一代防火墙产品。
其特点是:
(1) 利用路由器本身对分组的解析,以访问控制表方式实现对分组的过滤;
(2) 过滤判定的依据是IP地址、端口号和其他网络特征;
(3) 只有分组过滤功能,防火墙与路由器是一体的,对安全要求低的网络采用路由器附带防火墙功能的方法,对安全性要求高的网络则可单独利用一台路由器作为防火墙。
基于路由器的防火墙是网络安全的一种应急措施,其本身存在很多不足:
(1) 本身具有安全漏洞,外部网络要探寻内部网络十分容易;
(2) 分组过滤规则的设置和配置存在安全隐患。路由器中过滤规则的设置和配置十分复杂,它涉及到规则的逻辑一致性、作用端口的有效性和规则的正确性,一般的网络系统管理员难于胜任,加之一旦出现新的协议,管理员就得加上更多的规则去限制,这往往会带来很多错误;
(3) 攻击者可“假冒”地址,黑客可以在网络上伪造假的路由信息欺骗防火墙;
(4) 由于路由器的主要功能是为网络访问提供动态的、灵活的路由,而火墙则要对访问行为实施静态的、固定的控制,这是一对难以调和的矛盾防火墙的规则设置会大大降低路由器的性能。
2.第二代防火墙:用户化的防火墙
(1) 将过滤功能从路由器中独立出来,并加上审计和告警功能;
(2) 针对用户需求,提供模块化的软件包;
(3) 软件可通过网络发送,用户可自己动手构造防火墙;
(4) 与第一代防火墙相比,安全性提高而价格降低了。
由于是纯软件产品,第二代防火墙产品无论在实现还是在维护上都对系管理员提出了相当复杂的要求,因此也带来很多问题:
(1) 配置和维护过程复杂、费时;
(2) 对用户的技术要求高;
(3) 纯软件实现、安全性和处理速度均有局限;
(4) 实践表明,使用中出现差错的情况很多。
3.第三代防火墙:建立在通用操作系统上的防火墙
基于软件的防火墙在销售、使用和维护上的问题迫使防火墙开发商推出了建立在通用操作系统上的商用防火墙产品,近年来在市场上广泛使用的就是这一代产品,其特点是:
(1) 是批量上市的专用防火墙产品;
(2) 包括分组过滤或借用了路由器的分组过滤功能;
(3) 装有专用的代理系统,监控所有协议的数据和指令;
(4) 保护用户编程空间和用户可配置内核参数的设置;
(5) 安全性和速度大为提高。
第三代防火墙有以纯软件实现的,也有以硬件方式实现的。但随着安全需求的变化和使用时间的推延,表现出了不少问题,其中基于Windows NT开发的防火墙产品中表现得十分明显。
作为基础的操作系统,其内核往往不为防火墙管理者所知,由于源码的保密,其安全性无从保证。
大多数防火墙厂商并非通用操作系统的厂商,通用操作系统厂商不会对操作系统的安全性负责。
4.第四代防火墙:具有安全操作系统的防火墙
该是目前防火墙产品的毛要发展趋势。具有安全操作系统的防火墙本身就是一个操作系统,因而在安全性上较第三代防火墙有质的提高。获得安全操作系统的办法有两种:一种是通过许可证方式获得操作系统的源码;另一种是通过固化操作系统内核来提高可靠性。其特点是:
(1) 防火墙厂商具有操作系统的源代码,并可实现安全内核;
(2) 对安全内核实现加固处理:即去掉不必要的系统特性,加上内核特性,强化安全保护;
(3) 对每个服务器、子系统都作了安全处理,一旦黑客攻破了一个服务器,它将会被隔离在此服务器内,不会对网络的其他部分构成威胁;
(4) 在功能上包括了分组过滤、应用网关、电路级网关,且具有加密与鉴别功能;
(5) 透明性好,易于使用。
2.5.2 防火墙技术发展方向
防火墙从技术发展趋势来看,提高性能和采用模块化设计是防火墙技术发展的主要方向。处理能力的提高主要集中在两方面:硬件结构的优化和软件算法的更新。而硬件结构优化是走向软硬件一体化,充分发挥硬件最高效能,又提高了系统自身安全性。
功能设计模块化提高防火墙的适应能力、处理能力和提高防火墙性能的线速处理能力,达到对整个会话过程中的所有传输内容进行检查。审计报告也会向智能化方向发展,在报告的基础上对整个网络安全状况进行全盘的把握,并进行总结改进,依据充分的日志记录,为用户提供详细而又灵活的使用情况分析报告,为网络管理人员提供一个全局的视角。而入侵检测是防火墙产品回避不了的问题,因此未来防火墙的发展趋于协同互动的分布式防火墙。
在早期,由于Unix系统庞大,硬件的昂贵使商业市场和个人无法接受。现在IMBPC兼容机系列386,486,PENTIUM已具备了告诉大容量的特点,这就为Unix在pc上的发展铺平了道路,1991年Linux B.TORVALDS网络上组织人员为PC机写了第一个免费的Unix内核(KERNEL),发展至今天已经成为一个能在PC上可靠稳定工作的UNIX/X-WIN操作系统,这个系统被命名为LINUX系统,由于这些发展,个人拥有工作站已不再是梦想。每个学生,计算机爱好者都可以把自己的PC变成类似SUN Station或 BSD Unix系统的工作站。
Linux是一个在386/486/pentiun PC机上运行的Unix系统,Linux系统具有最新的Unix的全部功能,包括真正的多任务,虚拟存储,共享函数库,即时负载,优越的存储管理和 TCP/IP,UUDP网络工具。Linux具有免费获取系统软件,硬件费用低廉的特点,今年来发展迅猛。Linux的应用软件已达上千种类,从dos环境模拟的图片,印象信号的处理,从游戏到中文软件,无所不包,个大软件公司已纷纷开始推出Linux版本的商业软件,最近对Linux所做的基准测试表明,pentium/100的速度可以跟SUN/20媲美,94年底在华盛顿万国毁誉中心召开了Linux世界年会,各大软件公司都派出了阵容强大的代表团,展出了丰富的Linxu产品,Linux开始进入商业应用时代。
Linxu和windows对于代码透明度这一哲学问题上是完全不同的,Linux符合GNU通用公用许可证,用户可以拷贝,复制,并分发源代码。
Linux平台为用户提供了构建防火墙的框架,用户在此框架上构建符合需要的防火墙。为了使防火墙更加安全、效率更高、更充分利用内核已有功能,需要深入分析内核源代码,提炼出重要数据结构和数据处理流程。
3.3.1 netfilter介绍
网络数据按照来源和去向,可以分为三类:流入的、流经的和流出的,其中流入和流经的数据需要经过路由才能区分,而流经和流出的数据则需要经过投递。netfilte是Linux2.4提供的防火墙内核级框架。IPv4协议栈为了实现对netfilter架构的支持,在IP packet在IPv4协议栈上的游历路线之中,仔细选择了五个参考点。在这五个参考点上,各引入了一行对NF_ HOOK()宏函数的一个相应的调用。netfilter根据网络数据的流向,在以下几个参考点(钩子点)插入处理过程:
(1) NF IP PRE ROUTING,数据包进入路由之前;
(2) NF IP FORWARD,数据包转发到另一个网卡;
(3) NF IP POST ROUTING,最后一个钩子点,数据包流出重新进入网络之前;
(4) NF IP LOCAL IN,流入本地的数据包;
(5) NF IP LOCAL OUT,流出本地的数据包(本地路由之前)。
3.3.2 netfilter框架
一个数据包通过netfilter框架时,它将经过见图3-1所示流程。数据包从左边进入系统,校检IP,由NF_ IP PRE_ ROUTING钩子函数进行处理。然后路由判断,看数据包是转发还是进入本机。如是转发,则进入NF IP PORWARD钩子处理,否则进入NF IP LOCAL IN钩子处理,并在处理后传给上层协议。本地产生的数据包先经过NF_ IP_ LOCAL_ OUT钩子处理,再进行路由判断,决定是否发至外网。所有外发包都要经过NF_ IP_ POS几ROUTING处理,然后再发至外网。
内核模块可以对一个或多个这样的钩子函数进行注册挂接,并在数据包经过这些钩子函数是被调用。这样模块就可以修改数据包,并向netfilter返回如下值:
(1) NF ACCEPT:继续正常的报文处理;
(2) NF DROP:将报文丢弃;
(3) NF STOLEN:由钩子函数处理了该报文,不要再继续传送;
(4) NF一UEUE:将报文入队,通常交由用户程序处理;
(5) NF REPEAT:再次调用该钩子函数。
图3-1 netfilter框架数据包流程
3.3.3 netfilter分析
(1) 链表结构:struct list_head{
struct list head *next,*prev;
};
(2)链表二维数组:
struct list head of hooks[NPROTO][NF MAX HOOKS];其中,一维为协议族号,二维为上述五个HOOK号。此链表数组用以链接nf_hookes_ops结构体。
Struct_nf_hook_ops{
struct list_head list;//链表
nf_hookfn *hook;//指向用户定义的在该钩子点对应的处理函数
int pf;//协议族号
int hooknum;//核心指定的那五个钩子点之一
int priority;//优先级,在of hooks链表中各处理函数按优先级排序};//有关钩子函数的结构
(3) sk_buff结构体
它是Linux内核处理网络数据包所用的缓冲区。数据包从网卡接收到后,被放到此缓冲区中并传到协议堆栈。此结构体较长,内部结构省略。
(4) netfilter原理
数据包都要经过NF_HOOK宏处理}。 NF HOOK宏是这样的:使用netfilter的用户首先需要将自己的处理函数在nf_hook链表数组上注册,即把相应nf_hook ops结构插入到nf_hooks链表中。
然后NF HOOK根据nf_hooks链表二维数组的pf、hook值找到相应链表,如果链表为空则调用okfn指针所指函数处理skb指针所指数据包,否则调用nf_hook_slow()函数处理此数据包。nf_hook_slow()函数又调用nf_iterate()函数遍历此链表。nf_iterate()遍历过程中,根据链表各元素((nf_hook_ops结构体)所含处理函数指针对skb所指数据包进行处理,并返回处理结果。nf_hook_slow()函数根据处理结果,选择对数据包接收还是丢弃。
netfilter上的钩子函数都将去执行一个重要函数—ipt_do_table()函数。此函数的几个输入参数解释如下:
(1) struct sk_buff **pskb:传入的待处理网络报;
(2) unsigned int hook:处理此网络报的钩子点;
(3) struct ipt_ table *table:用户定义的规则表。
Ipt_do_table()函数就是根据传入的规则表来处理网络数据包。此函数前半部分主要是从传入的待处理网络协议包中取出相应的字段,并将其整理成和新定义的数据结构。首先取出如下数据:IP头、对应协议地址、数据长度、输入输出设备、分片偏移量、规则表的入口指针、相应钩子点ipt_entry入口指针及下溢指针。然后调用函数ip_packet_match()。根据待处理的网络协议包的IP头、输入输出设备、分片偏移量与规则所定义的IP头信息进行匹配。匹配规则完成后,返回有标准目标和非标准目标。非标准目标的处理通过函数指针t->u.kernel.target->target()调用相应处理函数进行。
3.3.4 netfilter的连线跟踪机制
1.连线跟踪框架
连线跟踪 (Connection Tracking,也称为状态检测)作为一个独立运行模块,
它是动态包过滤、地址转换的基础W1。它被设置在Netfilte:框架中四个钩子点:
(1) NF_IP_PRE_ROUTING;
(2) NF_IP_POST_ROUTING;
(3) NF_IP_LOCA_IN;
(4) NF_IP_LOCAL_OUT。
2.连线跟踪工作原理
检查每一个有效连接的状态,并根据这些信息决定网络数据包是否能够通过防火墙。它在协议栈底层截取数据包进行分析,并且将当前数据包及其状态信息和其前一时刻数据包及状态信息进行比较,得到该数据包控制信息。以TCP三次握手连接为例,第一个SYN包到达后,由防火墙规则库检查此SYN包,SYN包在规则库中依次与规则匹配。如都不匹配,将此SYN包弃掉。如匹配则接收,并将这次连接的状态信息保存在一个连接跟踪信息表中。连接跟踪信息表位于内核中。SYN包之后的SYN/ACK, ACK包则不必用规则库匹配,而是跟连线跟踪信息表的内容比较,然后决定包丢弃还是接收。利用连线跟踪可以提高防火墙性能,因为每个数据包首先跟连线跟踪信息表进行比较,而不是跟规则库一一比较。
连线跟踪模块截获、分析并处理所有试图通过防火墙的数据包,保证网络安全和数据完整。连接跟踪信息表是动态的,它会根据网络状态不断更新自己。模块可以识别不同应用的服务类型,还可以通过以前的连接分析出状态信息。模块把相关状态和状态之间的关联信息,存储到动态连接表并随时更新。通过这些数据,连线跟踪模块可以检测到后继的连接。连线跟踪技术对应用程序透明,不需要针对每个服务设置单独代理,使其具有更高的安全性、更好的可扩展性。
3.状态机制
连线跟踪模块将数据包连接分为四个状态:NEW, ESTABLISHED, RELATED和INVALID。通过对这四种状态匹配,可以实现状态防火墙。这四种状态对TCP,UDP, ICMP三种协议均有效。下面具体介绍这四种状态。
NEW: NEW说明这是conntrack模块看到的某一个连接的第一个包,它即将被匹配。比如,如果看到一个SYN包并且它是某连接的第一个包,它将被匹配。然而,数据包也可能不是一个SYN包但其状态却被当作NEW。某些情况下,这可能导致某些问题。但是,当需要从其它防火墙找到丢失的连接或者当一个连接己经超时但实际却未关闭时,状态为NEW的非SYN包也可能会带来很大帮助。
ESTABLISHED:此状态已经看到两个方向的数据传输并且将不断匹配它。处于ESTABLISHED状态的连接很容易理解。只要发送并接到应答,连接就处于ESTABLISHED状态。应答数据包一到达或一通过防火墙,此连接就从NEW状态转为ESTABLISHED状态。响应外发数据包而产生的ICMP报错及重定向消息也可以被看作ESTABLISHED状态。
RELATED: RELATED是一个较难理解的状态。当一个连接和某个已处于ESTABLISHED状态的连接有关系时,就被认为是RELATED的。换句话说,一个连接要想是RELATED的,首先要有个ESTABLISHED连接,由这个ESTABLISHED连接再产生一个主连接之外的连接(RELATED连接)。 FTP是个很好的例子,每个FTP由数据连接和控制连接组成,数据连接就是和控制连接有关联的。如果没有RELATED状态,数据连接是无法正确建立的。有了这个状态,ICMP响应、FTP传输等才能穿过防火墙正常工作。注意:依赖于此状态的大部分TCP和一些UDP协议是十分复杂的,并且在TCP, UDP数据段的有效载荷中发送连接信息,因此需要特殊的helper模块才能被正确理解。
INVALID: INVALID状态表示此数据包不能被识别或它没有任何状态。这可能由于几种原因,诸如系统内存耗尽或ICMP报错信息对任何已知连接不作响应。通常的选择是丢弃此状态下的所有包。
4.连线跟踪内核实现
从内核角度,连接跟踪在查找哪些协议、规则匹配一个数据包之前,它首先要把此数据包转化为一个元组( tuple ),元组代表了数据包有用的部分。这个元组又分为可操纵部分和不可操纵部分,分别称为“源(src)”和“目的(dst ) "。方向相同的数据包流中的每一个数据包所对应的元组是相同的。
比如,一个TCP包之元组包含了可操纵部分:源IP地址和源端口,还包含了不可操纵部分目的IP地址和目的端口。不过,这两个部分并不要求是同样类型的。比如,一个ICMP包之元组的可操纵部分:源IP和ICMP编号,它的不可操纵部分:目的IP和ICMP类型和代码号。可见,这两部分元组组成是不同的。
每个元组都有一个逆(inverse ),逆是数据包流中应答包之元组。比如,有一个ICMP数据包(ping发出):icmp编号为12345,从192.168.1.1到1.2.3.4。那么,它的逆为一个ping响应包:icmp编号为12345,从1.2.3.4到192.168.1.10。
用ip_conntrack_tuple结构体表示的元组得到了广泛的使用。实际上,数据包流入所经过的hook点(它对操作类型有所影响)和涉及到的设备形成了有关数据包的完整信息。大部分元组都包含在ip_conntrac_tuple_hash结构体中,此结构体有一个双向链表入口地址和一个指向元组所属的连接的指针。连接用ip_conntrack结构体表示:它有两个ip_ conntrack_tuple_ hash(一个表示源数据包方向,另一个表示响应包方向)。
总之,连线跟踪模块的任务是对于一个己经存在的建立好的连接,指定哪些数据包属于这个连接。这个模块要做的工作如下:
(1) 告诉netfilte:此模块对哪些数据包感兴趣;
(2) 在netfilter中注册一个函数。一旦数据包匹配上述规则,就调用此函数;
(3) 可以调用ip_conntrack_expect_related()函数通知netfilte以要求相关连接要求的连接的第一个数据包到达时,如果有其他工作要做,模块可以注册一个回调函数在那时调用。
3.3.5 netfilter防火墙流程结构
Linux内核对TCP流程的处理主要在tcp_ipv4.c文件中的函数实现。具体的,当处理TCP SYN包时,系统进入tcp_v4_conn_request函数。其中调用cookie_v4_init_sequence生成一个ISN(Initial Sequence Number)。Linux内核把它作为SYN Cookie流程中的cookie。Netfilte:防火墙由规则表构成,而规则表又由规则链(相对于netfiler中的五个钩子点,netfilter防火墙有五个内置规则链:PREROUTING, INPUT, OUTPUT,FORWARD以及POSTROUTING)构成。数据包依次到达每个规则链,然后按链中的规则进行匹配,根据匹配结果执行相应策略(接收、丢弃等)。按照这种划分方法,netfilte:
图3-2 防火墙的流程结构图
3.4.1 iptables与netfilter的关系
从上节netfilter内核分析中,可以看到netfilte框架在数据包接收、转发、发送过程中,都要经过NF_ HOOK宏处理。NF_HOOK又调用相应钩子函数执行一个通用函数—ipt_do table()。此函数从设置好的规则链中取出规则,对数据包进行匹配、目标处理等操作,最后返回处理结果。设置规则是通过iptables进行的。
iptables是Linux系统为用户提供的基于netfilte的一个用以配置防火墙的工具。此工具提供了一个命名规则集。数据包经过每个钩子点时,都应遍历规则集中的相应规则链。用户可以直接操作iptables、iptables又通过socket系统调用访问内核netfilter。 iptables规则表注册后,用户可以用getsockopt()系统调用得到它的内容,也可以调用setsockopt()修改它。iptables做为netfilter的用户配置工具,它为用户配置防火墙提供了强大的功能和方便的途径。
概括地说,iptables与netfilter的关系是:netfilter提供了内核中对网络数据包处理的手段,iptables则是内核netfilter在用户空间上的实现。netfilter提供了一个框架,而框架内容则由用户用iptables来填充。
3.4.2 iptables关键数据结构
1.netfilter与iptables体系每个规则都由三部分组成:
(1) 一个struct ipt entry结构体;
(2) 0个或多个struct ipt entry match结构体,此结构体数据长度不定((0或多字节);
(3) 一个struct ipt entry target结构体,此结构体数据长度不定((0或多字节)由于规则由可变长结构体组成,它的长度也是未定的。这一特性为规则扩展提供了巨大的灵活性。以后将看到,特别在每个匹配(match)或目标(target )都能装载任意多个数据时,这一优点将得到体现。
insigned char elems[0];
2.ipt_entry_match与ipt_entry_target结构体
这两个结构体非常类似,它们都包含了一个总长度域(相应为match_size和target_size)和一个共用体(包含了匹配名或目标名和一个指针,前者对应用户空间,后者对应内核空间)。
内核是靠hook点来找相应规则的,找到后它就按此规则处理数据包。首先,如果匹配ipt_entry结构体中的ipt_ip域,那么依次检查每一个ipt_entry_match结构体(调用相应匹配函数)。如果匹配函数返回0,在此规则上的检查停止。如果检查一直到终点,计数加一,并检查ipt entry target结构体:如果是标准目标,设置返回规则。如果是非标准目标,调用目标函数处理之,然后继续下一个规则。从上述数据处理流程可以看出每个规则的三个组成部分之间的关系。
规则是用链表组织起来的,形成规则链。规则链的入口地址、规则的偏移地址等信息由ipt_table结构体管理,真正记录这些信息的是ipt_table中private指针所指的ipt_table_info结构体:
struct ipt_table_info
{
unsigned int size ; // 表大小
unsigned int number; //表中的规则数
unsigned int initial_entrids; //初始的规则数,用于模块计数
/*相对于规则入口 (对应于具体HOOK)的偏移量*/
unsigned int hook_entry[NF_IP_UNMHOOKS];
/*于hook_entry相对应的规则表上偏移量*/
unsigned int underflow[NF_IP_NUMHOOKS];
char entries[0]___cacheline_aligned; //规则表入口
}
综上所述,iptables规则组织是分层次的。第一级是规则表,每个防火墙可以有多个规则表;第二级是hook,每个规则表都有一个hook集合,每个hook都有一个规则链:第三级为规则,每个规则包含三个部分:ip规则信息、匹配规则信息、目标信息。
iptables工作机制:用户事先设置好规则,然后将规则挂到规则链中去。netfilter会根据设置好的规则链取出规则逐一处理相应数据包。此机制通过Linux系统提供的iptables命令实现的。
3.4.3 iptables命令
1.iptables命令的基本语法为:
iptables [-t table] command [match] [target]
下面介绍一下该命令各选项含义:
这是可选项。用以指定所操作的表。系统已设了三个内置表:filter, nat和mangle } filter作为缺省表。
filte:表用于数据包过滤,但不对包修改,只是判断接收还是丢弃。它在NF_IP_ LOCAL_ IN, NF_ IP_ FORWARD和NF_IP_ LOCAL_OUT三处注册了钩子函数。这样它就提供了与上述钩子对应的三条链进行数据过滤:进入内网的数据包,遍历INPUT规则链;转发的数据包将遍历FORWORD规则链;最后,本地发出的数据包将遍历OUTPUT规则链。通过这三条链可以检测所有数据包。
nat表用于要转发的数据包,它以Connection Tracking模块为基础,仅对每个连接的第一个数据包进行匹配和处理,然后交Connection Tracking模块将处理结果应用到该连接之后的所有数据包。nat在NF_IP_PRE_ROUTING , NF_ IP_ POST_ROUTING注册了钩子函数,如果需要,还可以在NF_ IP_ LOCAL_ IN和NF IP_LOCAL_OUT两处注册钩子,提供对本地数据包(出/入)的地址转换。nat仅对数据包头的地址信息进行修改,而不修改数据包内容,按所修改的部分,nat可分为源NAT ( SNAT)和目的NAT ( DNAT)两类,前者修改第一个数据包的源地址部分,而后者则修改第一个数据包的目的地址部分。SNAT可用来实现IP伪装,而DNAT yJ是透明代理的实现基础。
mangle表属于可以进行报文内容修改的IP Tables,可供修改的数据包内容包括MARK , TOS , TTL等,mangle表的操作函数嵌入在Netfilter的NF IP_PRE_ROUTING 和 NF_IP_LOCAL OUT两钩子点。
除上述三个内置表,用户可以通过挂接模块,调用Netfilte:的接口函数创建新的iptables。
2.command选项
必选项,它是iptables命令的最重要部分。它告诉iptables命令要做什么,例如,插入规则、将规则添加到链的末尾或删除规则。以下是最常用的一些命令:
(1) -A或--append:该命令将一条规则附加到链的末尾;
(2) -D或--delete:通过用一D指定要匹配的规则或者指定规则在链中的位置编号,该命令从链中删除该规则;
(3) _P或--policy:该命令设置链的缺省目标,即策略。所有与链中任何规则都不匹配的信息包都将被强制使用此链的策略;
(4) -N或--new-chain:用命令中所指定的名称创建一个新链;
(5) -F或--flush:如果指定链名,该命令删除链中的所有规则,如果未指定链名,该命令删除所有链中的所有规则;
(6) -L或--list:列出指定链中的所有规则。
3.match选项
可选项。iptables命令的match部分指定数据包与规则匹配所应具有的特征(如源和目的地址、协议等)。匹配分为两大类:通用匹配和特定于协议的匹配。这里,将研究可用于采用任何协议的信息包的通用匹配。下面是一些重要的且常用的通用匹配:
(1) _p或一protocol:协议匹配。用于检查某些特定协议:TCP, UDP, ICMP及它们的组合。ALL是缺省匹配。可以使用!符号,表示‘非’;
(2) -s或一source:源地址匹配。用于根据数据包的源IP地址来与它们匹配。
该匹配还允许对某一范围内的IP地址进行匹配,可以用!符号。缺省为与所有IP地址匹配;
(3) -d或一destination:目的地址匹配。用于根据数据包的目的IP地址来与它们匹配。该匹配还允许对某一范围内IP地址进行配,可以使用!符号。
4.target选项
target(目标)是由规则指定的操作,对与那些规则匹配的数据包执行这些操作。除了允许用户定义的目标之外,还有许多可选的目标项。
(1) ACCEPT:当数据包与规则完全匹配时,接受数据包,并停止遍历链;
(2) DROP:当数据包与规则完全匹配时,会阻塞该信息包,且不对它做进一步处理;
(3) REJECT:该目标的工作方式与DROP目标相同,但和DROP不同的是:
REJECT不会在服务器和客户机上留下死套接字。另外,REJECT将错误消息发回给数据包的发送方。
RETURN:停止遍历与该规则匹配的数据包,并返回到前面调用的链。
其它:用于建立高级规则的目标,如LOG , REDIRECT , MARK ,MIRROR和MASQUERADE等。
Linux内核是整体式结构,这使得用户在内核增加新功能很不方便。为此,Linux提供了一种全新的机制—“可安装”模块(module。有了这个机制,可以根据需要,在不必对内核重新编译连接的条件下,将可安装模块动态地插入运行中的内核,成为内核的一个有机组成部分;或从内核移走己经安装的模块(s10正是这种机制,使得内核的内存映像保持最少,但却具有很大的灵活性和可扩充性。Linux中很多设备驱动程序或文件系统都用模块来实现,系统灵活性大大提高。
加载和卸载模块有两种方式:
(1) root用户通过insmod 和 rmmod命令显式地将模块载入内核或从内核卸载;
(2) 内核也可在需要时,请求守护进程(kerneld)加载和卸载模块。
模块机制的优点是极大改善了Linux的灵活性,缺点是定义模块需要额外的代码,增加了系统开销。用户进程通过模块对核心访问是间接的,这会降低访问效率。
模块加载入 Linux内核后,就成了内核代码的一部分。内核中有一个
module_ list链表,它是作为全局变量出现的,其定义原型为extern struct module*module_ list。每当一个模块要加载入内核,这个模块就会被加到module_ list链表中。每当内核要使用某加载的模块时,它就查找这个链表,找到此模块后,再使用其提供的功能。
每个模块可以输出变量和函数,供其它模块或核心代码调用。模块在需要时,可通过符号表(symbol table)使用核心资源,内核将资源登记在符一号表中。当模块加载时,内核利用符号表来解决模块的资源引用问题。Linux支持模块堆栈(module stacking)机制,即一个模块可请求其它模块为之提供服务。模块加载入内核时,系统修改内核中的符号表将新加载模块提供的资源和符号加到内核符号表中。通过这种通信机制,新模块可以访问老模块提供的资源。此机制为模块可重用性提供了保证。
本章深入分析了Linux内核的防火墙框架,包括三方面内容:netfilter, iptables和模块机制。netfilter是Linux2.4提供的防火墙内核级框架。它通过预设的五个钩子点捕获网络数据包,再根据规则链对这些数据包进行判定(拒绝、接收或其它)。iptables是netfilter在用户空间上的实现,是netfilter的用户配置工具。用户用iptables命令设置自己需要的防火墙规则,然后iptables通过系统调用将规则置入规则链中,netfilter根据规则链对数据包判定。通过模块机制,可动态地将用户模块插入到运行中的netfilter,而不必对内核重新编译链接。本章是下一章的理论基础。
利用上一章分析结果,本章将研究基于Linux抵御拒绝服务(Denial of Services,DoS)攻击防火墙。
4.1.1 系统模块设计
本防火墙系统的模块可划分三层:最底层为Linux的netfilter内核,然后是基本模块层(实现防火墙所必备的功能),最上层为抵御DoS攻击的模块层(见图4-1)。
图4-1 防火墙系统模块
4.1.2 系统环境配置
1.系统拓扑图
图4-2 系统拓扑图
2.常量定义:
EXTERNAL INTERFACE="eth0" //防火墙与Internet连接网卡
INTERNAL INTERFACE="ethl" //防火墙与内部连接网卡
DMZ INTERFACE="eth2'' //防火墙与DMZ区连接网卡
LOOPBACK INTERNET="LO" //系统回环接口
LOOPBACK="127.0.0.0/8" //保留的回环地址范围
FIREWALLADDR="202.101.123.1" //防火墙IP地址,合法IP地址
ANYWHERE="any/0" //任何地址
INTERNALADDR=" 172.16.0.0/16" //内部网络地址
DMZADDR=" 192.168.9.0/24" //DMZ区网络地址,内部地址
WWWADDR=" 192.168.9.1/24" //WWW服务器地址,内部地址
CLASS D="224.0.0.0/4" //D类多播地址
CLASS E="240.0.0.0/5" //E类保留地址
4.1.3 系统默认策略
在Linux防火墙中,每个数据包都要经过检查,即与已建立的防火墙规则逐条匹配,并执行匹配规则策略,或执行默认策略。
前面已经叙述有两个基本策略可供选择:一个是默认允许一切:另一个是默认禁止一切。在本系统中采用的是默认禁止一切的防火墙默认策略,它使得流经iptables防火墙的数据包除非特别允许否则都将被丢弃。
4.2 系统基本模块
本节在netfilter框架基础上,利用iptable脚本语一言实现系统基本模块。
4.2.1 包过滤模块实现
通过对数据包头的过滤,控制数据包进出内部网络,从而实现对内部网络的管理。对内部局域网,包过滤是一种简单有效的手段。由于此模块是建立在netfilter内核框架上的,而netfilte:又提供对连线跟踪的支持(见上章),因此此模块支持状态检测(在Linux中称状态检测为连线跟踪)功能。
第一步,设置默认策略:
iptables -P INPUT DROP
iptables -P OUTPUT REJECT
iptables -P FORWARD REJECT
上面三条命令意思为:经过INPUT(输入)、OUTPUT(输出)、FORWARD(转发)三条链的所有数据包在默认情况下都被丢弃或拒绝。
第二步,允许所有从内部网络发出的数据包进入Internet;激活状态包检查允许任何相关的返回流量回到防火墙,
iptables -A OUTPUT -i eth0 -s$FIREWALLADDR –d $ ANYWHERE –j ACCEPT
iptables -A INTPUT-m state -state ESTABLISHED,RELATED –j ACCEPT
第三步,实现内部网络接口和网络外部接口之间的数据转发,激活状态包检查:
iptables -A FORWARD -i ethl一eth0 –s $ FIREWALLADDR -d $ ANYWHERE –j ACCEPT
iptables -A FORWARD -m state -state ESTABLISHED,RELATED -j ACCEPT
NAT模块实现:
如果内部网络的主机使用Internet合法地址,包过滤模块是可以正常运行的。但如用保留的公共IP地址(如172.16.0.0/16,则必须采用网络地址转换技术实现网络内部主机和Internet的连接。
1.通过NAT屏蔽内部网络
目标:通过NAT屏蔽内部网络,并允许内部网络访问Internet。但不允许Internet向内部网络发送网络连接请求。
第一步,设置默认策略:
iptables -P INPUT DROP
iptables -P OUTPUT REJECT
iptables -P FORWARD REJECT
第二步,允许所有从内部网络发出的数据包进入Internet;激活状态包检查允许任何相关的返回流量回到防火墙:
iptables -A OUTPUT -i eth0 -s $FIREWALLADDR -d $ANYWHERE -j ACCEPT
iptables -A INTPUT -m state -state ESTABLISHED,RELATED –j ACCEPT
第三步,通过NAT实现内网屏蔽,激活状态包检查规则:
iptables -t nat -A POSTROUTING –o eth0 -s $INTERNALADDR -d$ ANY WHERE –j SNAT-to-source $FIREWALLADDR –j ACCEPT
Iptables –t nat -A POSTROUTING -m state -state ESTABLISHED , RELATED -j ACCEPT
第四步,实现内部网络接口和网络外部接口之间的数据转发,激活状态包检查:
iptables -A FORWARD -i ethl -o eth0 -s $INTERNALADDR -d $ANYWIIERE -j ACCEPT
iptables -A FORWARD -i ethl -o eth2 -s $INTFRNAI_ADDR -d $ANYWHERE -j ACCEPT
iptables -A FORWARD -m state -state ESTABLISHED , RELATED -j ACCEPT
2.通过NAT来屏蔽服务器
目标:当外网主机访问防火墙80端口时,防火墙进行网络地址转换并自动将请求信息转发到内部WWW服务器。实现对内部WWW服务器的屏蔽。将上面第四步做如下修改,其他不变。
第四步,设置iptables防火墙,使之接收来自任何主机的HTTP请求,并将它们转发至WWW服务器,激活状态包检查:
iptables -t nat -A PRETOUTING -p tcp -s $ANYWHERE -d $FIREWALLADDR -dport http -j DNAT -to-dest $ WWWADDR -j ACCEPT iptables -t nat -A PRETOUTING -m state -state ESTABLISHED,RELATED –j ACCEPT
3.DMZ模块实现:
当前防火墙广泛应用DMZ区设置。在拓扑图中,WWW服务器和代理服务器
组成一个单独网段,形成一个DMZ区。
目标:将WWW服务器和代理服务器放置在DMZ区:
(1) 当外网主机访问防火墙80端口时,防火墙进行网络地址转换并自动将请;
求转发到内部WWW服务器,实现对内部WWW服务器的屏蔽。
(2) 当内网主机访问外部WWW服务时,防火墙将HTTP请求转发到代理服务器,代理服务器在TCP3128端口上监听,这个重定向对用户应该是透明的。
第一步,设置默认策略(同前)。
第二步,允许所有来自防火墙的数据包进入Internet:激活状态包检查允许任何相关的返回流量回到防火墙:
iptables -A OUTPUT -i eth0 -s$FIREWALLADDR -d$ANYWHERE -j ACCEPT
iptables -A INTPUT -m state -state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state -state ESTABLISHED,RELATED -j ACCEPT
第三步,通过NAT实现内网屏蔽,激活状态包检查规则:
iptables -t nat -A POSTROUTING -o eth0 -s $INTERNALADDR -d$ ANYWHERE –j SNAT-to-source $FIREWALLADDR -j ACCEPT
iptables -t nat -A POSTROUTING -m state -state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A FORWARD -i ethl -o eth0 -s $INTERNALADDR –d $ANYWHERE -j ACCEPT
第四步,设置iptables防火墙,使之接收来自内网主机的HTTP清求,并将它们转发至DMZ区的SQUID代理服务器(此代理服务器用来控制网络访问和优化网络连接):
iptables -t nat -A PRETOUTING -p tcp -s $ANYWHERE一$ANYWHERE -dport http -j DNAT -to-dest $SQUIDADDR: 3128一ACCEPT
iptables一nat -A PRETOUTING -m state -state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i ethl -o eth0 -s $INTERNALADDR -d $SQUIDADDR -port 3128 -j ACCEPT
第五步,设置iptables防火墙,允许外网主机访问DMZ区WWW服务器,激活状态包检查:
iptables -t nat -A PRETOUTING -p tcp -i eth0 -o eth2 -s $ANYWHERE –d $FIREWALLADDR -dport http一DNAT -to-dent $WWWADDR -j ACCEPT
iptables -t nat -A POSTROUTING -p tcp一i eth2 -o eth0 -s $ WWWADDR –d $ANYWHERE -j DNAT-to-source $FIREWALLADDR -j ACCEPT
iptables -A FORWARD一i eth0 -o eth2 -s $INTERNALADDR -d $WWWADDR -dport 80 -j ACCEPT
第六步,设置iptables防火墙,允许内网主机访问DMZ区WWW服务器:
iptables -A FORWARD -i ethl -o eth2 -s $INTERNALADDR -d $WWWADDR -dport 80 -j ACCEPT
4.2.2 系统基本模块综合实现
将以上各实例合并起来,就成为一个具有动态过滤、状态检测、NAT和DMZ等功能的防火墙。它是本系统抵御DoS攻击模块的基础。
4.3 抵御DoS攻击模块
本节将用netfilter方法实现抵御几种常见DoS攻击模块。
4.3.1 DoS攻击
DoS攻击是网络攻击最常见的一种。它故意攻击网络协议的缺陷或直接通过某种手段耗尽被攻击对象的资源,目的是让目标计算机或网络无法捉供正常的服务或资源访问,使目标系统服务停止响应甚至朋溃,而在此攻击中并不入侵目标服务器或目标网络设备。这些服务资源包括网络宽带、系统堆栈、开放的进程。或者允许的连接。这种攻击会导致资源耗尽,无论计算机的处理速度多快、内存容量多大、网络带宽的速度多快都无法避免这种攻击带来的后果。任何资源都有一个极限,所以总能找到一个方法使请求的值大于该极限值,导致所提供的服务资源耗尽。
DoS攻击有许多种类,主要有Land攻击、死亡之ping、泪滴、Smurf攻击及SYN洪水等。
4.3.2 抵御SYN洪水攻击模块
据统计,在所有黑客攻击事件中,syn洪水攻击是最常见又最容易被利用的一种DoS攻击手法。
1.攻击原理
要理解SYN洪水攻击,首先要理解TCP连接的三次握手过程(Three-wayhandshake)。在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。见图4-3
图4-3 TCP连接二次握手示意图
第一次握手:建立连接时,客户端发送SYN包((SYN=i)到服务器,并进入SYN SEND状态,等待服务器确认;
第二次握手:服务器收到SYN包,必须确认客户的SYN (ACK=i+1 ),同}Jj’自己也发送一个SYN包((SYN j)}即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN十ACK包,向服务器发送确认包ACK(ACK=j+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手,客户端与服务器开始传送数据。
在上述过程中,还有一些重要的概念:
半连接:收到SYN包而还未收到ACK包时的连接状态称为半连接,即尚未完全完成三次握手的TCP连接。
半连接队列:在三次握手协议中,服务器维护一个半连接队列,该队列为每个客户端的SYN包(SYN=i )开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于SYN_ RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。
Backlog参数:表示半连接队列的最大容纳数目。
SYN-ACK重传次数:服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超过系统规定的最大重传次数,系统将该连接信息、从半连接队列中删除。注意,每次重传等待的时间不一定相同。
半连接存活时间:是指半连接队列的条目存活的最长时间,也即服务从收到SYN包到确认这个报文无效的最长时间,该时间值是所有重传请求包的最长等待时间总和。有时也称半连接存活时间为Timeout时间、SYN_RECV存活时间。
上面三个参数对系统的TCP连接状况有很大影响。
SYN洪水攻击属于DoS攻击的一种,它利用TCP协议缺陷,通过发送大量的半连接请求,耗费CPU和内存资源。SYN攻击除了能影响主机外,还可以危害路由器、防火墙等网络系统,事实上SYN攻击并不管目标是什么系统,只要这些系统打开TCP服务就可以实施。从图4-3可看到,服务器接收到连接请求(SYN=i )将此信息加入未连接队列,并发送请求包给客户( SYN=j,ACK=i+1 ),此时进入SYN_RECV状态。当服务器未收到客户端的确认包时,重发请求包,一直到超时,才将此条目从未连接队列删除。配合IP欺骗,SYN攻击能达到很好的效果,通常,客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送SYN包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN 请求
被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。过程如下:
攻击主机C(地址伪装后为C')-----大量SYN包---->彼攻击主机
C'<-------SYN/ACK包----被攻击主机
由于C’地址不可达,被攻击主机等待SYN包超时。攻击主机通过发人量SYN包填满未连接队列,导致正常SYN包被拒绝服务。另外,SYN洪水攻击还可以通过发大量ACK包进行DoS攻击。
2.传统算法
抵御SYN洪水攻击较常用的方法为网关防火墙法、中继防火墙法和SYNcookies。为便于叙述,将系统拓扑图简化为图4-4。图中,按网络在防火墙内侧还是外侧将其分为内网、外网(内网是受防火墙保护的)。其次,设置防火墙的SYN重传计时器。超时值必须足够小,避免backlog队列被填满;同时又要足够大保证用户的正常通讯。
(1) 网关防火墙法
网关防火墙抵御攻击的基本思想是:对于内网服务器所发的SYN/ACK包,防火墙立即发送ACK包响应。当内网服务器接到ACK包后,从backlog队列中移出此半连接,连接转为开连接,TCP连接建成。由于服务器处理开连接的能力比处理半连接大得多,这种方法能有效减轻对内网服务器的SYN攻击,能有效地让backlog队列处于未满状态,同时在重传一个未完成的连接之前可以等待更长时间。
以下为算法完整描述:
第一步,防火墙截获外网客户端发向内网服务器SYN数据包,允许其通过,抵达内网服务器。同时在连接跟踪表中记录此事件.
第二步,防火墙截获服务器发向客户端的SYN/ACK响应包,用连接跟踪表中记录的相应SYN包匹配它.
第三步,防火墙让截获的SYN/ACK继续进行(发向客户端)。同时,向内网服务器发送ACK包。这样,对服务器来说,TCP连接三次握手己经完成。系统在backlog队列中删掉此半连接.
第四步,看此TCP连接是否有效,相应产生两种解决方法。如果客户端的连接尝试是有效的,那么防火墙将接到来自客户端的ACK包,然后防火墙将它转发到服务器。服务器会忽略这个冗余的ACK包,这在TCP协议中是允许的.
如果客户端的IP地址并不存在,那么防火墙将收不到来自客户端的ACK包,重转计时器将超时。这时,防火墙重传此连接.
(2) 中继防火墙法
中继防火墙抵御攻击的思想是:防火墙在向内网服务器发SYN包之前,首先完成与外网的三次握手连接,从而消除SYN洪水攻击的成立条件。
以下为算法完整描述:
第一步,防火墙截获外网客户端发向内网服务器SYN数据包.
第二步,防火墙并不直接向内网发SYN数据包,而是代替内网服务器向外网发SYNIACK数据包.
第三步,只有接到外网的ACK包,防火墙向内网发SYN包.
第四步,服务器应答SYN/ACK包.
第五步,防火墙应答ACK包.
(3) 分析
首先分析算法的性能,可以看出:为了提高效率,上述算法使用了状态检测等机制(可通过本系统的基本模块层得以实现)
其检测逻辑见图4-5
图4-5 检测逻辑
从图4-5可看出,对于非SYN包(CSYN/ACK及ACK包),如果在连线跟踪信息表未查找到相应项,则还要匹配规则库,而匹配规则库需比较诸多项(如IP地址、端口号等),花费较大,这会降低防火墙的流量。另外,在中继防火墙算法中,由于使用了SYN包代理,增加了防火墙的负荷,也会降低防火墙的流量。
其次,当攻击主机发ACK包,而不是SYN包,算法将出现安全漏洞。一般地,TCP连接从SYN包开始,一旦 SYN包匹配规则库,此连接将被加到连接跟踪表中,并且系统给其60s延时。之后,当接到ACK包时,此连接延时突然加大到3600s。如果,TCP连接从ACK包开始,同时此连接未在连接跟踪表中注册,ACK包会匹配规则库。如匹配成功,此连接将被加到连接跟踪表中,同时其延时被设置为3600s。即使系统无响应,此连接也不会终止。如果攻击者发大量的ACK包,就会使半连接队列填满,导致无法建立其它TCP连接。此类攻击来自于内网。因为,来自于外网的ACK包攻击,服务器会很快发RST包终止此连接(SOs>。而对于内网的外发包,其限制规则的严格性要小的多。一旦攻击者在某时间段内从内网发大量ACK包,并且速度高于防火墙处理速度,很容易造成系统瘫痪。
(4) SYN cookies
Linux支持SYN cookies,它通过修改TCP协议的序列号生成方法来加强抵御SYN洪水攻击能力。在TCP协议中,当收到客户端的SYN请求时,服务器需要回复SYN-SACK包给客户端,客户端也要发送确认包给服务器。通常,服务器的初始序列号由服务器按照一定的规律计算得到或采用随机数,但在SYN cookies中,服务器的初始序列号是通过对客户端IP地址、客户端端口、服务器IP地址和服务器端口以及其他一些安全数值等要素进行hash运算,加密得到的,称之为cookie。当服务器遭受SYN攻击使得backlog队列满时,服务器并不拒绝新的SYN请求,而是回复cookie(回复包的SYN序列号)给客户端,如果收到客户端的ACK包,服务器将客户端的ACK序列号减去1得到。cookie比较值,并将上述要素进行一次hash运算,看看是否等于此cookie。如果相等,直接完成三次握手(注意:此时并不用查看此连接是否属于backlog队列)。
此算法的优点是:半连接队列满时,SYN cookies仍可以处理新SYN请求。缺点是:某些TCP选项必须禁用,如大窗口等。计算cookies有花销。
综合上述三种算法的优点,克服其缺点,下面给出一个改进算法。
3.改进算法
目标:
本节给出的改进算法应该具有以下特点:
(1) 克服非SYN包需与规则库匹配的缺点,提高防火墙的流量;
(2) 能抵御ACK类的攻击;
(3) 半连接队列填满时,仍能处理新SYN请求;
(4) 数据包处理是透明的。
算法思想:
(1) 为避免不必要的规则库匹配,应该在接到建立连接所必需的包后,才将此连接的开始SYN包加入到连接跟踪表。
(2) 充分利用TCP数据包的包头信息,特别是其控制位,它反映了连接的状态。
(3) 为保证TCP选项的完整性,半连接队列未满时,不用 SYN cookiesa
措施
增设一个预连接表。SYN包匹配规则库后,先放入预连接表。非SYN包不用匹配规则库,而只需查找预连接表。
通过ACK位,区分数据包传输方向(进或出)。过滤SYN位,区分是否SYN包。
加设一个判断步骤,判断半连接队列是否填满。如果满,不用用SYN cookies。
算法描述
(1) 如果防火墙接到SYN包,判断半连接队列是否已满,已满则启用SYNcookies 。否则,与规则库匹配,不匹配则登记此包后弃掉它。如匹配则查找预连接表,是否有此包的关键字。有,则登记后弃包:否则,将此包关键字加到预连接表并转发此包;
(2) 如果防火墙接到SYN/ACK包,它根据预连接表中注册的SYN关键字匹配SYN/ACK包的关键字。如不匹配,登记后弃包;如匹配,查找连接跟踪表,看是否己经在连接跟踪表中注册。没有注册,则把此包的关键字拷贝到连接跟踪表中并转发此包;如果已注册,登记后弃包;
(3) 如果防火墙接到ACK包,它根据连接跟踪表匹配ACK包关键字。如匹配,此包被转发,连接被建立。同时,其在预连接表中相应的关键字将被删掉。如不匹配,登记后弃包。
逻辑流程图见图4-6:
图4-6 算法逻辑流程图
算法分析:
下面分析一下改进算法是如何抵御SYN洪水攻击的:
(1) 防火墙过滤SYN包以抵御SYN洪水攻击过程:
防火墙截获外网客户端发向内网服务器SYN数据包,允许其通过,抵达内网服务器。同时在预连接表中记录此包关键字;
如果在连接建立之前,防火墙截获了另一个从客户端到服务器的SYN包,它将阻塞此包,因为此包关键字已在预连接表中注册。
(2) 防火墙过滤SYN/ACK包以抵御SYN洪水攻击过程;
防火墙截获服务器对客户端的SYN/ACK应答包同时按此包关键字查找预连接表是否有相应SYN包;
如关键字未找到,登记并弃包;
如找到了关键字,拷贝此关键字并与连接跟踪表匹配;
如匹配成功,说明已有此包,登记并弃包;
如匹配不成功,说明无此包,此包关键字被加入到连接跟踪表中并转发此包。
(3) 防火墙过滤ACK包以抵御ACK洪水攻击过程:
防火墙截获客户端对服务器的ACK应答包。如此连接是有效的,那么防火墙将能在连接跟踪表中找到相应项并转发此包;
如防火墙在连接跟踪表中找不到相应项,说明此ACK包不属于一个建好的连接。登记并弃包。
结论:
(1) 改进算法可以根据半连接队列是否已满,选择是否采用SYN cookies。这样,既能保证在连接队列未满状态下,TCP协议的完整性及工作高效性;又可以在连接队列满状态下,仍进行TCP连接(但这时TCP协议某些选项被禁用);
(2) 改进算法根据包类型( SYN, SYN/ACK和ACK三类)分别采用不同处理方法。提高了安全性;
(3) 规则库的匹配工作只对SYN包进行,而对ACK包仅需查找连接跟踪表。从而大大减少了匹配运算,使得防火墙流量得以大大提高;
(4) 算法再改进
问题:
上述改进算法提高了防火墙流量,减少了安全漏洞,但仍可在其它力一面做进一步改进。主要表现在:未充分挖掘半连接队列中各连接项的信息;半连接队列填满后,只能使用SYN cookies做TCP连接,对半连接队列无能为力。这种被动方式在受到攻击时,尤其不利。因此,对这种被动方式作出改进就很有必要了。
算法思想:
充分挖掘半连接队列中连接项信息,采用主动方式检测SYN攻击,一旦发现可能是SYN攻击包,则发RST对其重置,将此连接删掉。此方式虽有风险(S YN攻击包可能误判),但在半连接队列填满时使用,利是大于弊的。
检测SYN攻击方法:
采用占用时间权值计算法,检测半连接队列中SYN攻击包。首先,建立一个权值计算表,记录时间权值计算所需要素:IP地址、存取次数、首次存取时问、最后一次存取时间、平均使用时间及传输数据大小。这些数据从每次收到SYN包时开始记取,因此是动态更新的。利用这些数据计算不同IP地址的SYN包的权值。
式中N为常数,C为存取次数。
判定准则:设定一个阂值MAXW,比较W与MAXW,如超出,则可能是SYN攻击包。
算法描述
判断半连接队列是否满。如未满不做处理,如满,则执行下一步;
遍历半连接队列,计算每个SYN包的W值;
如果W>MAXW则发RST重置,删掉此包。
(5) 实现
模块底层
此模块建立在本系统的基本模块层之上,所以基本模块以及Linux平台所提供的功能可以直接使用:包过滤、地址转化、连线跟踪、规则库以及SYN cookies等。Linux提供了一个系统参数CONFIG SYN COOKIES来决定SYN cookies功能的开关。
4.3.3 抵御泪滴攻击模块
1.攻击原理
泪滴(teardrop)攻击利用在TCP/IP堆栈中IP分片中的包的协议头所包含的信息来实现自己的攻击。IP分片含有其原包的信息,某些操作系统在收到含有重叠偏移的伪造分段时将崩溃。teardrop便是一个经典的利用这个漏洞的攻击程序。
2.处理分片重组时的算法漏洞
在某些系统中,在处理分片组装[3]时存在漏洞,发送异常的分片包会使系统运行异常。假定发生如下情况:发送两个..IP分片包(Frag 1, Frag2 ),其中第二个IP包完全与第一个在位置上重合(见图4-7 )。图中len, offset及end分别表示长度、起点位置及终点位置,offset2<end1。
图4-7 IP分片位置示意图
分片组装算法是:将offset2向后调到end 1 ( offset2=end 1 ),然后更改len2的值:lent=end2-offset2(即end2-endl)。如果两分片没有重合,end2将大于end1,二者之差将大于零。但如出现图4-7这种情况,运算后len2将变成了一个小于零的值。当用memcpy ( xx, xx, len2)函数进行内存拷贝时,由于len2<0,导致系统出错。teardrop攻击正是通过精心构造这类分片,攻击主机的。
3.改进算法
增加判断条件,首先计算len2的值,如果出现分片长度小于零或此分片与上一个分片完全重叠的情况,则把这个分片丢掉。
4.3.4 抵御Smurf攻击模块
1.攻击原理
可以通过广播地址或其他方法发送广播包到同一网络中的其它所有主机。当某主机使用广播地址发送一个ICMP echo请求包时,其它主机会回应一个ICMPecho应答包,这样此台主机会收到许多应答包。Smurf攻击(directed broadcast)就是使用ICMP这个原理来进行的。攻击时还需要一个假冒的IP源地址,此源地址即要受到攻击的主机地址,目的地址为广播地址。当攻击者以广播地址发送ICMP请求包时,其它主机会发送大量的响应信息给被攻击主机(因为它的地址被攻击者假冒了)。从而造成被攻击主机无法正常工作。
2.解决方案
首先使用网关,按网络在防火墙内侧还是外侧将其分为内网、外网。来自外网的目的地址为广播地址的ICMP请求包,给予拒绝。对内网主机可以向外网发ICMP包,但需要对此ICMP包的源地址进行转换,使外网无法知道内网真实IP地址。对安全有威胁的ICMP包:目的地址为重定向、掩码清求等,将被丢弃。
本章研究了基于Linux抵御常见DoS攻击的防火墙。首先用iptables方法实现了防火墙底层的基本模块。然后分析了抵御SYN洪水攻击的传统算法,并给出了改进算法。改进算法提高了防火墙流量,增强了抵御SYN洪水攻击的能力。分析了泪滴及Smurf攻击原理,对存在的安全薄弱点提出解决方案。最后用netfilter方法实现了防火墙上层的抵御SYN洪水、泪滴及Smurf攻击模块。经测试,构建的防火墙满足功能要求,可以有效抵御常见DoS攻击。
论文首先对防火墙知识做了一个总体上的认识。然后深入分析Linux Ij火墙内核,对netfilter的数据流程及其怎样实现防火墙框架机制进行剖析。在上述分析基础上,研究了基于Linux抵御常见DoS攻击的防火墙:用iptables方法实现了防火墙底层的基本模块。分析了抵御SYN洪水攻击的传统算法,给出了改进算法。分析了泪滴及Smurf攻击原理,对存在的安全薄弱点提出解决方案。用:ietfilter方法实现了防火墙上层的抵御SYN洪水、泪滴及Smurf攻击模块。经测试,构建的防火墙可以实现动态包过滤、NAT ( SNAT, DNAT)和DMZ功能。可以有效抵御常见DoS攻击。最后,介绍了防火墙新技术。
通过以上工作,本文从广度、深度两个方面认识防火墙体系,增强了防火墙的理论知识、积累了防火墙开发设计经验,为以后从事相关研究打下了坚实)l础。达到了本文目的。
下一步工作和展望:
由于时间原因,还有一些工作做的不够充分:
(1) 仅实现了防火墙的基本功能,对于具体环境下的防火墙,尚需根据情况添加具体规则以实现具体功能。
(2) 网络攻击方法不仅限于DoS攻击,还有许多其它攻击,如IP地址欺骗、缓冲溢出等等。这些攻击有些仅用Linux防火墙还无法抵御,还需要其它技术。因此,如何将Linux防火墙技术与其它新技术结合起来,是今后工作的重点。
这里有几点想法:
(1) 将Linux防火墙做到网络应用层;
(2) Linux分布式防火墙;
(3) Linux防火墙智能化。
最后结论:
由于计算机网络互联的重要性,网络安全是我国计算机网络建设中应当引起重视的问题。在计算机安全性和计算机所能提供功能之间的平衡性是很重要的。在很多情况下,最安全的计算机往往功能是简单的,能提供多种服务的则是最不安全的。本文作者为Linux2. 4 内核下基于netfilter 设计开发防火墙作了有意的尝试,设计了一个包过滤和应用代理的混合型防火墙,重点解决了在Linux 环境下在netfilter 中设计防火墙的问题,并在此基础上增加了主动及被动的安全措施以实现网络安全的功能。
Linux 操作系统中的包过滤防火墙具有一般包过滤防火墙的优点:简单,速度快,功能强,能按照系统设定的安全策略对防火墙进行过滤,但是它也具有了很多传统包过滤防火墙缺点:1.很多网络服务的端口号是不固定的,对这服务不可能进行很好的过滤;2一些应用协议使用的信息打包在IP 数据包中,所以不能方便地被包过滤级防火墙访问和使用,所以对应用服务的过滤很难;3.审计功能差,过滤规则的设计存在矛盾关系,过滤规则简单,安全性差,过滤规则复杂,管理困难。4.无法抵御欺骗攻击。对于端口扫描,我采用了对网络连接进行正态分布统计计算,对网络连入数在单位时间内进行智能更新,采用误判率1%为标准来决定扫描攻击,在一定程度上解决了扫描攻击问题。而对于欺骗攻击,则采用记录并分析所有通过防火墙的IP 数据包从源节点到目的节点所经过的路由信息,即过滤数据包时也检查该数据包所经过的路由,丢弃那些经过了不安全路由的数据包:特别是对IP劫持攻击采用服务器方收到重置RST信号时也向对方发送一个RST重置信号,来有效的防御欺骗攻击。为克服包过滤防火墙的缺点,就再设置了一个HTTP和通用应用代理服务器,从而采用混合防火墙来保证内部网络安全。
由于时间和条件限制,本论文所设计的防火墙还有很多地方需要改进和完善,主要表现在以下几个方面:
(1) 在包过滤管理模块中还缺乏过滤规则检查,有可能造成规则冲突的情况,这还需要防火墙管理员很高的专业知识;
(2) 对网络扫描防御还存在问题,当专业黑客扫描目标端口时可能只扫描攻击目标几个端口,所以防火墙对这中扫描攻击没有作用,还需要找出更加完善的办法来进行防范;
(3) 对常用网络应用协议都应该配置代理,本防火墙只实现了HTTP和一个通用代理;
(4) 还缺乏日志分析,本防火墙还只是靠专业人员对日志作分析。这些不足都需要进一步工作来完成。