iptables的状态检测机制.docx

上传人:b****4 文档编号:4416743 上传时间:2022-12-01 格式:DOCX 页数:7 大小:19.95KB
下载 相关 举报
iptables的状态检测机制.docx_第1页
第1页 / 共7页
iptables的状态检测机制.docx_第2页
第2页 / 共7页
iptables的状态检测机制.docx_第3页
第3页 / 共7页
iptables的状态检测机制.docx_第4页
第4页 / 共7页
iptables的状态检测机制.docx_第5页
第5页 / 共7页
点击查看更多>>
下载资源
资源描述

iptables的状态检测机制.docx

《iptables的状态检测机制.docx》由会员分享,可在线阅读,更多相关《iptables的状态检测机制.docx(7页珍藏版)》请在冰豆网上搜索。

iptables的状态检测机制.docx

iptables的状态检测机制

iptables的状态检测机制

1.什么是状态检测

  每个网络连接包括以下信息:

源地址、目的地址、源端口和目的端口,叫作套接字对(socketpairs);协议类型、连接状态(TCP协议)和超时时间等。

防火墙把这些信息叫作状态(stateful),能够检测每个连接状态的防火墙叫作状态包过滤防火墙。

它除了能够完成简单包过滤防火墙的包过滤工作外,还在自己的内存中维护一个跟踪连接状态的表,比简单包过滤防火墙具有更大的安全性。

  iptables中的状态检测功能是由state选项来实现的。

对这个选项,在iptables的手册页中有以下描述:

  state

  这个模块能够跟踪分组的连接状态(即状态检测)。

  --statestate

  这里,state是一个用逗号分割的列表,表示要匹配的连接状态。

有效的状态选项包括:

INVAILD,表示分组对应的连接是未知的;ESTABLISHED,表示分组对应的连接已经进行了双向的分组传输,也就是说连接已经建立;NEW,表示这个分组需要发起一个连接,或者说,分组对应的连接在两个方向上都没有进行过分组传输;RELATED,表示分组要发起一个新的连接,但是这个连接和一个现有的连接有关,例如:

FTP的数据传输连接和控制连接之间就是RELATED关系。

  对于本地产生分组,在PREROUTING或者OUTPUT链中都可以对连接的状态进行跟踪。

在进行状态检测之前,需要重组分组的分片。

这就是为什么在iptables中不再使用ipchains的ip_always_defrag开关。

  UDP和TCP连接的状态表由/proc/net/ip_conntrack进行维护。

稍后我们再介绍它的内容。

  状态表能够保存的最大连接数保存在/proc/sys/net/ipv4/ip_conntrack_max中。

它取决于硬件的物理内存。

2.iptables的状态检测是如何工作的?

2.1.iptables概述

  在讨论iptables状态检测之前,我们先大体看一下整个netfilter框架。

如果要在两个网络接口之间转发一个分组,这个分组将以以下的顺序接收规则链的检查:

∙PREROUTING链

如果必要对这个分组进行目的网络地址转换(DNAT)和mangle处理。

同时,iptables的状态检测机制将重组分组,并且以以下某种方式跟踪其状态:

o分组是否匹配状态表中的一个已经实现(ESTABLISHED)的连接。

o它是否是和状态表中某个UDP/TCP连接相关(RELATED)的一个ICMP分组。

o这个分组是否要发起一个新(NEW)的连接。

o如果分组和任何连接无关,就被认为是无效(INVALID)的。

∙FORWARD链

把分组的状态和过滤表中的规则进行匹配,如果分组与所有的规则都无法匹配,就使用默认的策略进行处理。

∙POSTROUTING链

如果有必要,就对分组进行源网络地址转换(SNAT),

注意:

所有的分组都必须和过滤表的规则进行比较。

如果你修改了规则,要拒绝所有的网络流量,那么即使分组的状态匹配状态表中的一个ESTABLISHED条目,也将被拒绝。

  下面,我们对UDP、TCP和ICMP三个协议分别进行分析。

2.2.UDP连接

  UDP(用户数据包协议)是一种无状态协议,以为这个协议没有序列号。

不过,这并不意味着我们不能跟踪UDP连接。

虽然没有序列号,但是我们还可以使用其它的一些信息跟踪UDP连接的状态。

下面是状态表中关于UDP连接的条目:

udp1719src=192.168.1.2dst=192.168.1.50sport=1032dport=53[UNREPLIED]src=192.168.1.50dst=192.168.1.2sport=53dport=1032use=1

  这个状态表项只有在iptables过滤规则允许建立新的连接时,才能建立。

以下的规则可以产生这类状态表项,这两条规则只允许向外的UDP连接:

iptables-AINPUT-pudp-mstate--stateESTABLISHED-jACCEPT

iptables-AOUTPUT-Pudp-mstate--stateNEW,ESTABLISHED-jACCEPT

  上面的状态表项包含如下信息:

∙连接的协议是UDP(IP协议号17)。

∙这个状态表项还有19秒中就超时。

∙发起连接方向上的源、目的地址和源、目的端口。

∙应答方向上的源、目的地址和源、目的端口。

这个连接使用UNREPLIED标记,表示还没有收到应答。

  UDP连接的超时时间在/usr/src/linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c文件中设置,如果改变了这个值,需要重新编译Linux内核源代码才能生效。

下面是UDP连接超时时间的相关的源代码:

#defineUDP_TIMEOUT(30*HZ)

#defineUDP_STREAM_TIMEOUT(180*HZ)

  一个UDP请求等待应答的时间是30*HZ(这个值一般是30秒)。

在上面的例子中,等待的时间已经消耗了11秒,还剩余19秒,如果在这段时间之内没有收到应答分组,这个表项就会被删除。

一旦收到了应答,这个值就被重置为30,UNREPLIED标志也被删除。

这个表项编程如下形式:

udp1728src=192.168.1.2dst=192.168.1.50sport=1032dport=53src=192.168.1.50dst=192.168.1.2sport=53dport=1032use=1

  如果在这一对源、目的地址和源、目的端口上,发生了多个请求和应答,这个表项就作为一个数据流表项,它的超时时间是180秒。

这种情况下,这个表项就变成如下形式:

udp17177src=192.168.1.2dst=192.168.1.50sport=1032dport=53src=192.168.1.50dst=192.168.1.2sport=53dport=1032[ASSURED]use=1

  这时我们看到这个表项使用ASSURED标志。

一旦连接表项使用ASSURED标志,那么即使在网络负沉重的情况下,也不会被丢弃。

如果状态表已经饱和,当新的连接到达时,使用UNREPLIED标志的表项会受被丢弃。

2.3.TCP连接

  一个TCP连接是通过三次握手的方式完成的。

首先,客户程序发出一个同步请求(发出一个SYN分组);接着,服务器端回应一个SYN|ACK分组;最后返回一个ACK分组,连接完成。

整个过程如下所示:

ClientServer

 SYN--->

         <---SYN+ACK

 ACK--->

         <---ACK

 ACK--->

       .........

       .........

  SYN和ACK是由TCP分组头的标志决定的。

在每个TCP分组头还有32位的序列号和应答号用于跟踪会话。

  为了跟踪一个TCP连接的状态,你需要使用下面这样的规则:

iptables-AINPUT-ptcp-mstate--stateESTABLISHED-jACCEPT

iptables-AOUTPUT-ptcp-mstate--stateNEW,ESTABLISHED-jACCEPT

2.3.1.连接建立过程中状态表的变化

  下面,我们详细讨论在连接建立的每个阶段中,状态表发生的变化:

∙一旦一个初始SYN分组进入OUTPUT链,并且输出规则允许这个分组建立一个新的连接,状态表的相关表项将如下所示:

cp6119SYN_SENTsrc=140.208.5.62dst=207.46.230.218sport=1311dport=80[UNREPLIED]src=207.46.230.218dst=140.208.5.62sport=80dport=1311use=1

其中,TCP连接状态是SYN_SENT,连接被标记为UNREPLIED。

∙现在,我们等待SYN+ACK分组的响应。

一旦得到响应,这个TCP连接表项就变为:

tcp657SYN_RECVsrc=140.208.5.62dst=207.46.230.218sport=1311dport=80src=207.46.230.218dst=140.208.5.62sport=80dport=1311use=1

连接的状态变为SYN_RECV,UNREPLIED标志被清除。

∙现在我们需要等待完成握手的ACK分组。

ACK分组到达后,我们首先对其序列号进行一些检查,如果正确,就把这个连接的状态变为ESTABLISHED,并且使用ASSURED标记这个连接。

这时,这个连接的状态如下所示:

cp6431995ESTABLISHEDsrc=140.208.5.62dst=207.46.230.218sport=1311dport=80src=207.46.230.218dst=140.208.5.62sport=80dport=1311[ASSURED]use=1

2.3.2.透视状态表

  上面,我们涉及了很多CP连接的状态。

现在,我们分析一下TCP连接的状态检测。

实际上,状态表只知道NEW、ESTABLISHED、RELATED和INVALID。

  要注意:

状态检测的状态不等于TCP状态。

当一个SYN分组的响应SYN+ACK分组到达,Netfilter的状态检测模块就会认为连接已经建立。

但是,这时还没有完成三次握手,因此TCP连接还没有建立。

  另外,包过滤规则不能删除状态表中的表项,只有连接超时,对应的状态表项才会被删除。

ACK分组能够建立一个NEW状态表项。

向防火墙之后一台并不存在主机发送ACK分组,并不会返回RST分组,可以证明这个结论。

因此,你需要使用以下的规则明确新的TCP连接应该是SYN分组建立的:

iptables-AINPUT-ptcp!

--syn-mstate--stateNEW-jDROP

  这样可以阻止空会话的继续进行。

2.3.3.超时

  所谓状态表项的超时值是指每个表项存在的最大时间,这些超时值的大小在/usr/src/linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c文件中设置。

以下是相关的代码:

staticunsignedlongtcp_timeouts[]

={30MINS,/*TCP_CONNTRACK_NONE,*/

    5DAYS,/*TCP_CONNTRACK_ESTABLISHED,*/

    2MINS,/*TCP_CONNTRACK_SYN_SENT,*/

    60SECS,/*TCP_CONNTRACK_SYN_RECV,*/

    2MINS,/*TCP_CONNTRACK_FIN_WAIT,*/

    2MINS,/*TCP_CONNTRACK_TIME_WAIT,*/

    10SECS,/*TCP_CONNTRACK_CLOSE,*/

    60SECS,/*TCP_CONNTRACK_CLOSE_WAIT,*/

    30SECS,/*TCP_CONNTRACK_LAST_ACK,*/

    2MINS,/*TCP_CONNTRACK_LISTEN,*/

};

2.3.4.连接的中断

  关闭一个TCP连接可以有两种方式。

第一种类似于建立TCP连接的三次握手。

一旦一个TCP会话完成,要终止会话的一方首先发出一个FIN为1的分组。

接收方TCP确认这个FIN分组,并同志自己这边的应用程序不要在接收数据了。

这个过程可以如下所示:

  ClientServer

             .........

             .........

   FIN+ACK--->

              <---ACK

              <---FIN+ACK

    ACK--->

  在这个过程之中或者之后,状态表的连接状态变为TIME_WAIT。

在默认情况下,2分钟之后从状态表删除。

  除此之外,还有其它关闭中断的方式。

TCP会话的任何一方发出一个RST标志为1的分组,可以快速断开一个TCP连接。

而且,RST分组不需要应答。

在这种情况下,状态表项的状态变为CLOSE,10秒之后被删除。

和http连接经常通过这种方式中断,如果一个连接很长时间没有请求了,服务器端就会发出一个RST分组中断连接。

2.4.ICMP

  在iptables看来,只有四种ICMP分组,这些分组类型可以被归为NEW、ESTABLISHED两类:

∙ECHO请求(ping,8)和ECHO应答(pong,0)。

∙时间戳请求(13)和应答(14)。

∙信息请求(15)和应答(16)。

∙地址掩码请求(17)和应答(18)。

  这些ICMP分组类型中,请求分组属于NEW,应答分组属于ESTABLISHED。

而其它类型的ICMP分组不基于请求/应答方式,一律被归入RELATED。

  我们先看一个简单的例子:

iptables-AOUTPUT-picmp-mstate--stateNEW,ESTABLISHED,RELATED-jACCEPT

iptables-AINPUT-picmp-mstate--stateESTABLISHED,RELATED-jACCEPT

  这链条规则进行如下的过滤:

∙一个ICMPecho请求是一个NEW连接。

因此,允许ICMPecho请求通过OUTPUT链。

∙当对应的应答返回,此时连接的状态是ESTABLISED,因此允许通过INPUT链。

而INPUT链没有NEW状态,因此不允许echo请求通过INPUT链。

也就是说,这两条规则允许内部主机ping外部主机,而不允许外部主机ping内部主机。

∙一个重定向ICMP(5)分组不是基于请求/应答方式的,因此属于RELATED。

INPUT和OUTPUT链都允许RELATED状态的连接,因此重定向(5)分组可以通过INPUT和OUTPUT链。

3.FTP协议的状态检测

  上面,我们比较详细地介绍了iptables的态检测机制。

现在,我们以FTP状态检测为例介绍如何使用iptables进行连接状态检测。

  首先,你需要加载ip_conntrack_ftp模块。

使用如下规则就可以允许建立FTP控制连接(这里没有考虑IMCP问题):

iptables-AINPUT-ptcp--sport21-mstate--stateESTABLESED-jACCEPT

iptables-AOUTPUT-ptcp--dport21-mstate--stateNEW,ESTABLISED-jACCEPT

  除了控制连接之外,FTP协议还需要一个数据通道,不过,数据连接可以通过主动和被动两种模式建立,我们需要分别讨论。

3.1.主动模式

  在主动模式下,客户程序在控制通道上,使用PORT命令告诉FTP服务器自己这边的数据传输端口,然后FTP从20端口向这个端口发起一个连接。

连接建立后,服务器端和客户端就可以使用这个连接传输数据了,例如:

传诵的文件、ls等命令的结果等。

因此,在主动模式下FTP数据传输通道是反向建立的,它从FTP服务器端向客户端发起。

  在主动模式下,客户端使用的数据传输端口是不固定的,因此我们需要在规则中使用端口范围。

由于客户端使用的端口都是大于1024的,这并不会降低系统的安全性。

  在iptables中,有一个专门跟踪FTP状态的模块--ip_conntrack_ftp。

这个模块能够识别出PORT命令,并从中提取端口号。

这样,FTP数据传输连接就被归入RELATED状态,它和向外的FTP控制连接相关,因此我们不需要在INPUT链中使用NEW状态。

下面的规则可以实现我们的意图:

iptables-AINPUT-ptcp--sport20-mstate--stateESTABLISED,RELATED-jACCEPT

iptables-AOUTPUT-ptcp--dport20-mstate--stateESTABLISED-jACCEPT

3.2.被动模式

  和主动模式相反,在被动模式下,指定连接端口的PORT命令是服务器端发出的。

FTP服务器通过PORT命令告诉客户端自己使用的FTP数据传输端口,然后等待客户端建立数据传输连接。

在被动模式下,建立数据传输连接的方向和建立控制连接的方向是相同的。

因此,被动模式具有比主动模式更好的安全性。

  由于ip_conntrack_ftp模块能够从PORT命令提取端口,因此我们在OUTPUT链中也不必使用NEW状态,下面的规则可以实现对被动模式下的FTP状态检测:

iptables-AINPUT-ptcp--sport1024:

--dport1024:

-mstate--stateESTABLISHED-jACCEPT

iptables-AOUTPUT-ptcp--sport1024:

--dport1024:

-mstate--stateESTABLISHED,RELATED-jACCEPT

  综合以上的分析,我们可以得到FTP连接的状态检测规则,对于主动模式的FTP,需要下面的iptables规则:

iptables-AINPUT-ptcp--sport21-mstate--stateESTABLESED-jACCEPT

iptables-AOUTPUT-ptcp--dport21-mstate--stateNEW,ESTABLISED-jACCEPT

iptables-AINPUT-ptcp--sport20-mstate--stateESTABLISED,RELATED-jACCEPT

iptables-AOUTPUT-ptcp--dport20-mstate--stateESTABLISED-jACCEPT

  对于被动模式的FTP连接,需要使用如下iptables规则

iptables-AINPUT-ptcp--sport21-mstate--stateESTABLESED-jACCEPT

iptables-AOUTPUT-ptcp--dport21-mstate--stateNEW,ESTABLISED-jACCEPT

iptables-AINPUT-ptcp--sport1024:

--dport1024:

-mstate--stateESTABLISHED-jACCEPT

iptables-AOUTPUT-ptcp--sport1024:

--dport1024:

-mstate--stateESTABLISHED,RELATED-jACCEPT

  本文中提到的状态检测,在iptables中实际叫作连接跟踪(Connectiontracking),出于自己的习惯,我在本文中一律改为状态检测:

P

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1