Netfilter/iptables状态防火墙探析

2015-03-18 12:24
网络安全和信息化 2015年8期
关键词:内核数据包路由

Netfilter组件也称为内核空间,是集成在内核中的一部分,是Linux 防火墙架构的核心,是各种与防火墙相关模块的实现基础。它是Linux内核的一个子系统,自身实现的只是一个通用的框架,不依赖于具体的协议。它的作用是定义、保存相应的规则,以实现防火墙功能。而iptables组件是一种工具,也称为用户空间,用以插入、修改、删除信息的过滤规则及其他配置。管理员可以通过iptables来设置适合当前应用环境的规则,而这些规则会保存在内核空间中。

Netfilter通过提供一个钩子(hook)函数通用接口来实现各个子模块、各种协议对数据包的特殊处理。如果某个模块需要对流经网络协议栈中的某些数据包进行处理时,它就需要向Netfilter系统注册钩子函数,告诉Netfilter它所感兴趣的数据包协议类型和处理的钩子点。当这些期待的数据包通过Netfilter框架中注册过的钩子点时,相应的钩子函数就会被调用,在钩子函数中就可以实现对数据包处理过程:丢弃或者更改数据包内容。

状态检测机制工作原理

一般来说,每个网络连接包括以下信息:源地址、目的地址、源端口和目的端口,协议类型、连接状态(TCP协议)和超时时间等。防火墙通常把这些信息称作状态,能够检测每个连接状态的防火墙称作状态包过滤防火墙。它主要完成两部分的工作,除了能够完成简单包过滤防火墙的工作外,它还在内存中维护一个跟踪连接状态的表,从而比简单包过滤防火墙具有更大的安全性。这些状态可以一起使用,以便匹配数据包。这可以使得防火墙非常强壮和有效。以前,经常打开1024以上的所有端口来放行应答的数据。现在,有了状态检测机制,就不需再这样了。因为可以只开放那些有应答数据的端口,其他的都可以关闭,这样就安全多了。

状态检测技术是基于动态包过滤技术之上发展而来的新技术。这种防火墙加入了一种被称为状态检测的模块,它会在不影响网络正常工作的情况下,采用抽取相关数据的方法对网络通信的各个层进行监测,并根据各种过滤规则作出安全决策。状态检测技术保留了包过滤技术对数据包的头部、协议、地址、端口等信息进行分析的功能,并进一步发展为会话过滤功能。在每个连接建立时,防火墙会为这个连接构造一个会话状态,里面包含了这个连接数据包的所有信息,以后这个连接都基于这个状态信息进行。这种检测方法的优点是能对每个数据包的内容进行监控,一旦建立了一个会话状态,则此后的数据传输都要以这个会话状态作为依据。而且,会话状态的保留是有时间限制的,在限制的范围内如果没有再进行数据传输,这个会话状态就会被丢弃。

状态检测防火墙将属于同一连接的所有数据包作为一个整体数据流来看待,建立连接状态表。并将规则表与连接状态表结合判断,来对流经防火墙的数据包进行有效的过滤。状态检测技术可以对包的内容进行分析,从而摆脱了传统防火墙仅局限于过滤包头信息的弱点,而且这种防火墙可以不必开放过多的端口,从而进一步杜绝了可能因开放过多端口而带来的安全隐患。

状态检测机制不再把数据包之间看作是无关的,它不再对单个数据包进行处理,而是以连接会话为单位进行检测。它在协议栈底层截去数据包,然后分析这些数据包。并且将当前数据包及其状态信息和其前一时刻的数据包及其状态信息进行比较,从而得到该数据包的控制信息,达到保护网络安全的目的。总之,它的思想就是将属于同一连接的所有数据包作为一个整体的数据流来看待。状态检测机制不对数据包进行过滤处理,它只是跟踪并记录数据包的走向,数据报过滤、网络地址转换就是建立在状态检测基础上的。由于状态检测机制是在内核模式下进行的,所以速度很快。

Netfilter/iptables防火墙系统使用连接跟踪技术来实现状态检测功能。连接跟踪作为一个独立运行的模块,它是动态包过滤、地址转换的基础。连接跟踪机制依靠设置在Netfilter防火墙框架中的钩子函数,来检查每一个有效的连接的状态,然后根据这些信息决定数据包是否可以通过防火墙。

连接跟踪机制的核心是在协议栈底层为数据包建立连接状态信息,通过识别数据包的状态,避免了包过滤防火墙仅考查数据包的IP地址和端口等几个参数而不关心数据包之间相互联系的缺点。在防火墙的核心部分建立动态的连接状态表,并将进出网络的数据当成一个个的会话,利用状态表跟踪每一个会话状态。连接跟踪机制对每一个包的检查不仅根据规则表更考虑了数据包是否符合会话所处的状态,这种方式可以带来更高的效率、更有力的访问控制和更强的安全能力。

当数据包到达时,防火墙的连接跟踪机制根据连接状态表中的信息来决定包的状态。如果该IP包是属于一个已经建立的连接那么就直接越过协议栈中的规则检测部分,交给上层协议处理。如果该IP包不属于一个已经建立的连接,那么转入正常的规则检测部分,然后根据规则检测的结果决定对IP包的操作。同时,连接状态表的使用大大降低了把数据包伪装成一个正在使用的连接的一部分的可能。

Netfilter/iptables防火墙的状态检测机制还能对应用层的信息进行检查,即对特定类型的数据包中的数据进行检测。可以检查ICMP报文所承载的数据,可以检查FTP、SMTP数据包中是否包含了不安全的命令,可以过滤HTTP协议的不安全的请求,甚至能实现简单的URL或关键字过滤。

连接跟踪的实现

Netfilter的连接跟踪模块(nf_conntrack.ko)可以将进入协议栈的报文建立连接,进行连接跟踪。因为使用状态检测,所以如果没有数据率限制时,只需要检测首包,也就是在连接跟踪表中还未建立连接的报文。如果发现是状态为已建立连接,不用匹配任何规则,直接放行。

在每一条数据包检查路径上,连接跟踪、包过滤和地址转换都注册了相应的钩子函数,并创建与之相关的数据结构,完成其功能。以防火墙转发数据包为例,钩子执行功能点检查的顺序如下:连接跟踪、目的地址转换、包过滤、源地址转换、连接跟踪。

连接跟踪在路径上出现了两次,所起作用是:在第一个点上创建连接跟踪的结构,即连接跟踪表(库),这个结构会在后面的目的地址转换和包过滤中被使用;在第二个点上将连接跟踪的结构加载到系统的连接表中。

连接跟踪表实际是一个以哈希散列值排列的双向链表数组,用来描述所有的连接状态,链表记录元素即为连接记录所包含的数据包五元组及其它必需的状态信息等,用来唯一标识一个连接。连接跟踪表是一块内存空间,采用了高效的插入、修改、移动、删除等算法,故匹配速度比规则集更高效更快速。连接跟踪表的容量不是无限大,默认值随着硬件配置,特别是内存大小而改变。实际上,百万条记录的连接跟踪表也不会占用超过1GB的内存。此外,默认的防火墙最大连接跟踪数目是有限制的,与Linux系统的体系结构、内存容量是有一定相关性的。当然,如果认为默认的最大连接跟踪数不足,是可以通过修改连接跟踪模块的参数值调整的。

连接跟踪的四种状态

无论是流入、转发,还是防火墙本地进程产生的数据包,在到达网络层之后,首先利用这个状态检测机制来查看连接跟踪表是否具有该数据包的轨迹连接项,如果没有数据包的轨迹项,就将为该数据包在连接跟踪表中初始化一个轨迹项,在此时将检验该连接是否是某个期望的连接,如果是就将其状态信息定义为相关连接,如果没有相关性,就将其信息值定义为新建连接,数据包在连接跟踪表中初始化对应的轨迹项后继续根据优先级调用防火墙代码处理;如果在连接跟踪表中找到了对应的轨迹项,我们将把这个轨迹项定义为旧值,再根据这个旧值以及输入的数据包的包类型,连接方向来确定一个新值,并用这个新值来更新连接跟踪表。

简单说来,Netfilter在协议栈底层截取数据包进行分析,并且将当前数据包及其状态信息和其前一时刻数据包及状态信息进行比较,得到该数据包控制信息。Linux内核的连接跟踪模块将数据包的连接分为四个状态:NEW、ESTABLISHED、RELATED和INVALID。通过对这四种状态的匹配,实现状态化防火墙的所有功能。需要指明的是,这四种状态是与协议无关的,即对TCP、UDP、ICMP 三种协议均有效,切记不可与面向连接的TCP状态转化机制相混淆。对这四种状态的描述如下:

NEW,表示分组将要或已经开始建立一个新的连接,或者是这个数据包和一个还没有在两端都有数据发送的连接有关,它即将通过防火墙的安全规则进行匹配了。显而易见,此状态的数据包必然与Netfilter规则集匹配,并经此处理过程后建立连接跟踪表。

ESTABLISHED,意思是分组是完全有效的,而且属于一个已建立的连接,这个连接的两端都已经有数据发送。此状态表明状态检测机制已经看到两个方向上的数据传输并且将不断匹配它。处于ESTABLISHED状态的连接很容易理解,只要发送数据包并接到应答,连接就处于ESTABLISHED状态。应答数据包到达或通过防火墙,此连接就从NEW状态转变到ESTABLISHED状态了。即使该数据包是ICMP错误和重定向数据包,只要该数据包是请求包的回应包,该连接的状态都将转变为ESTABLISHED状态。

RELATED,说明分组正在建立一个新的连接,这个连接是和一个已建立的连接相关的。也就是说,当一个连接和某个已处于ESTABLISHED状态的连接有关系时,就被认为是RELATED状态。RELATED是个比较麻烦的状态,这说明一个状态要成为RELATED状态,则必须先有ESTABLISHED连接状态,这 个ESTABLISHED状态再产生一个该连接以外的连接,这样这个新的连接就处于RELATED状态,当然前提是连接跟踪模块要能理解RELATED状态。以FTP为例,每个FTP 由数据连接和控制连接组成,数据连接就是和控制连接有关联的。如果没有RELATED状态,数据连接是无法正确建立的。有了这个状态,ICMP特定类型的响应、FTP传输等才能穿过防火墙正常工作。一言以蔽之,这个RELATED状态是某个处于ESTABLISHED状态的数据包所期望的、也是被动产生的,不属于现在任何连接的新连接。

INVALID,表示分组对应的连接是未知的,说明数据包不能被识别属于哪个连接或没有任何状态。这就意味着这个包没有己知的流或连接与之关联,也可能是它包含的数据或包头有问题。状态为INVALID的包就是状态不明的包,也就是不属于前面3种状态的包,这类包一般会被视为恶意包而被丢弃。有多种原因产生该情况的数据包,比如连接跟踪表溢出,系统内存耗尽,或ICMP报错消息对任何已知连接不作响应。通常的选择是丢弃此状态下的所有包。要特别指出的是,对于很多扫描攻击工具构造的扫描或攻击报文,Netfilter/iptables会将其标记为INVALID状态,如需要记录或追踪恶意数据包的来源,深入研究如何处理INVALID状态的数据包就十分关键。

TCP、UDP及ICMP状态跟踪分析

对于TCP 协议来说该连接的第一个数据包是SYN数据包。对于Ping 操作的ICMP 数据包的第一个包是回声请求包。但对UDP 协议或其它数据包来说,当它们不是SYN数据包时,连接跟踪机制也把它的第一个数据包当成NEW 状态的数据包。

NEW,表示这个分组需要发起一个连接,或者说,分组对应的连接在两个方向上都没有进行过分组传输。NEW说明这个包是我们看到的第一个包。意思就是,这是连线跟踪模块看到的某个连接第一个包,它即将被匹配了。比如,我们看到一个SYN包,是我们所留意的连接的第一个包,就要匹配它。第一个包也可能不是SYN包,但它仍会被认为是NEW状态。比如一个特意发出的探测包,可能只有RST位,但仍然是NEW。某些精心构造的网络扫描或攻击报文,与此类似。

当下层网络接收到初始化连接同步(SYN)包,将被Netfilter规则库检查。该数据包在规则链中依次进行比较。如果该数据包应该被丢弃,发送一个复位(RST)包到远程主机,否则连接接收。这次连接的信息将被保存在连接跟踪信息表中,并表明该数据包所应有的状态。这个连接跟踪信息表位于内核模式下,其后的网络包就将与此连接跟踪信息表中内容进行比较,根据信息表中信息来决定该数据包的操作。因为数据包首先是与连接跟踪信息表进行比较,只有SYN包才与规则库进行比较,数据包与连接跟踪信息表的比较都是在内核模式下进行的,所以速度很快。

Netfilter/iptables的连接状态跟踪的全功能实现,对基于TCP协议的应用而言相对容易;对基于TCP与UDP组合协议的应用(如SIP),特别是在NAT环境下,需借助应用级网关技术;对基于TCP(UDP)与ICMP组合协议的应用,如路由探测工具,则是充分利用了ICMP协议某些类型数据包的“双IP包头”特性。所谓双IP包头是指网络设备生成特定类型的ICMP响应报文时,会将引发此响应的原数据包(不管是TCP、UDP还是ICMP包)原封不动地封装在ICMP响应应答数据包中,最为ICMP报文的承载数据。在此以路由探测工具所产生的数据包为例,进行拓展分析,加深对NEW、ESTABLISHED、RELATED这三种状态的理解。

Windows主 机 到Netfilter/iptables防火墙自身IP地址的路由探测包,从INPUT链流入的ICMP回声请求数据包状态为NEW,从OUTPUT链流出的ICMP 回声应答数据包的状态总是为ESTABLISHED。而穿过防火墙到远端主机的路由探测包,从FORWARD链流入的ICMP回声请求数据包状态为NEW,目标远程主机返回穿过FORWARD链的ICMP回声应答数据包的状态总是为ESTABLISHED,而探测路径下游的路由器因路由探测数据包的TTL值为0,而生成的反馈给源Windows主机的ICMP 超时数据包的状态为RELATED。

Linux主机到Netfilter/iptables防火墙自身IP地址的路由探测包,从INPUT链流入的UDP数据包状态为NEW,从OUTPUT链流出的ICMP 目标不可达数据包的状态总是为RELATED。而穿过防火墙到远端主机的路由探测包,流入FORWARD链的UDP数据包的状态总是为NEW,从目标远端主机返回的ICMP 目标不可达数据包以及下游探测路径中的路由器因路由探测数据包的TTL值为0,而生成的反馈给源端Linux主机的ICMP超时数据包的状态总是为RELATED。

Linux到Netfilter/iptables防火墙自身的基于TCP协议的路由探测,如利用tcptraceroute工具生成的探测报文,进入INPUT链的TCP SYN数据包状态为NEW,从OUTPUT链流出的TCP数据包的状态为ESTABLISHED。而穿过防火墙到目标远端主机的路由探测,经FORWARD链转发的TCP SYN数据包的状态为NEW,下游探测路径中的路由器因路由探测数据包的TTL值为0,而生成的反馈给源端Linux主机的ICMP 超时数据包的状态总是为RELATED,而远端主机返回的TCP数据包的状态总是为ESTABLISHED。

iptables命令实现

Linux 内核2.4/2.6中的防火墙Netfilter框架在应用层提供了iptables 这个工具,用户通过它可以对内核进行添加或查询规则等操作。前文所述的四种状态定义在命令接口的iptables 命令(基于Centos6.4,2.6.32内核)的“-m state”或“-m conntrack”匹配中。当使用“-m state”时,iptables会自动加载xt_state.ko模块;当使用“-m conntrack”时,iptables自动加载xt_conntrack.ko模块。这两个模块位于/lib/modules//kernel/net/netfilter目 录 下。xt_conntrack.ko模块可视为xt_state.ko模块的加强版,使用方法几乎如出一辙,但功能更强大,语法使用也更灵活。

编写iptables匹配规则,要特别注意数据包流动的方向性,流入/流出规则成对匹配,转发时要有对返回数据包的匹配规则,以保障数据包来回流动安全通畅。

猜你喜欢
内核数据包路由
多内核操作系统综述①
二维隐蔽时间信道构建的研究*
强化『高新』内核 打造农业『硅谷』
活化非遗文化 承启设计内核
民用飞机飞行模拟机数据包试飞任务优化结合方法研究
铁路数据网路由汇聚引发的路由迭代问题研究
一种基于虚拟分扇的簇间多跳路由算法
Linux内核mmap保护机制研究
SmartSniff
探究路由与环路的问题