iptables的状态机制

状态机制

            状态机制是iptables中较为特殊的一部分,这也是iptables和比较老的ipchains的一个比较大的区别之一,运行状态机制(链接跟踪)的防火墙称做带有状态机制的防火墙,如下简称为状态防火墙。状态防火墙比非状态防火墙要安全,由于它容许咱们编写更严密的规则。安全

            在iptables上一共有四种状态,分别被称为NEW、ESTABLISHED、INVALID、RELATED,这四种状态对于TCP、UDP、ICMP三种协议均有效。下面,咱们来分别阐述四种状态的特性。服务器

  1. NEW:NEW说明这个包是咱们看到的第一个包。意思就是,这是conntrack模块看到的某个链接的第一个包,它即将被匹配了。好比,咱们看到一个SYN 包,是咱们所留意的链接的第一个包,就要匹配它。
  2. ESTABLISHED: ESTABLISHED已经注意到两个方向上的数据传输,并且会继续匹配这个链接的包。处于ESTABLISHED状态的链接是很是容易理解的。只要发送并接到应答,链接就是ESTABLISHED的了。一个链接要从NEW变为ESTABLISHED,只须要接到应答包便可,无论这个包是发往防火墙的,仍是要由防火墙转发的。ICMP的错误和重定向等信息包也被看做是ESTABLISHED,只要它们是咱们所发出的信息的应答。
  3. RELATED: RELATED是个比较麻烦的状态。当一个链接和某个已处于ESTABLISHED状态的链接有关系时,就被认为是RELATED的了。换句话说,一个链接要想是RELATED的,首先要有一个ESTABLISHED的链接。这个ESTABLISHED链接再产生一个主链接以外的链接,这个新的链接就是 RELATED的了,固然前提是conntrack模块要能理解RELATED。ftp是个很好的例子,FTP-data 链接就是和FTP-control有关联的,若是没有在iptables的策略中配置RELATED状态,FTP-data的链接是没法正确创建的,还有其余的例子,好比,经过IRC的DCC链接。有了这个状态,ICMP应答、FTP传输、DCC等才能穿过防火墙正常工做。注意,大部分还有一些UDP协议都依赖这个机制。这些协议是很复杂的,它们把链接信息放在数据包里,而且要求这些信息能被正确理解。
  4. INVALID:INVALID说明数据包不能被识别属于哪一个链接或没有任何状态。有几个缘由能够产生这种状况,好比,内存溢出,收到不知属于哪一个链接的ICMP错误信息。通常地,咱们DROP这个状态的任何东西,由于防火墙认为这是不安全的东西。

            每一个状态相对于不一样的第四层协议来说,稍微有些区别,对于TCP协议来讲,当防火墙收到第一个数据包,也就是SYN报文时,将该会话标记为NEW状态,在系统的/proc/net/目录下,能够查阅ip_conntrack,这是在内存空间里存放防火墙当前状态表的临时文件,对于NEW状态的记录以下:网络

tcp 6 117 SYN_SENT src=192.168.1.5 dst=192.168.1.35 sport=1031 dport=23 [UNREPLIED] src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 use=1

            从上面的记录能够看出,SYN_SENT状态被设置了,这说明链接已经发出一个SYN包,但应答还没发送过来,这可从[UNREPLIED]标志看出,当服务器端回应了SYN/ACK包后,状态表改写为:tcp

tcp 6 57 SYN_RECV src=192.168.1.5 dst=192.168.1.35 sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 use=1

            如今咱们已经收到了相应的SYN/ACK包,状态也变为SYN_RECV,这说明最初发出的SYN包已正确传输,而且SYN/ACK包也到达了防火墙。 这就意味着在链接的两方都有数据传输,所以能够认为两个方向都有相应的回应。测试

            接下来,TCP三次握手的随后一个报文ACK包也到达了防火墙,防火墙上的状态表变成了:spa

tcp 6 431999 ESTABLISHED src=192.168.1.5 dst=192.168.1.35 sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 use=1

            如今,咱们来看看UDP协议的状态描述方法,从协议自己的特性来看,UDP链接是无状态的,由于它没有任何的链接创建和关闭过程。以某个顺序收到的两个数据包是没法肯定它们的发出顺序的。但内核仍然能够对UDP链接设置状态。咱们来看看是如何跟踪UDP链接的,以及在核心目录 /proc/net/ip_conntrack的相关记录。code

            当第一个UDP的数据包到达防火墙后,防火墙在他的状态表中留下了这样的记录:orm

udp 17 20 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 [UNREPLIED] src=192.168.1.5 dst=192.168.1.2 sport=1025 dport=137 use=1

            UNREPLIED表明这是一个状态为NEW的数据包,当这条链接的回应数据包到达防火墙后,防火墙当即将修改这条状态记录:ip

udp 17 160 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 src=192.168.1.5 dst=192.168.1.2 sport=1025 dport=137 use=1

            在这条新的状态记录中,UNREPLIED被删除了,这表明如今防火墙已经创建了一条UDP协议的会话,但这里并无象TCP协议那样显示 ESTABLISHED标记,这是TCP的状态记录和UDP的状态记录稍微不一样的一个地方,固然,还有一个地方须要注意,在测试中,还须要有一些数据包通过,防火墙才会将状态记录改写成:内存

udp 17 179 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 src=192.168.1.5 dst=192.168.1.2 sport=1025 dport=137 [ASSURED] use=1

            ASSURED状态表示当前有数据在进行传输,表面当前链接的状态是ACTIVE的。若是,在这个状态下数据中止了传输,则这条记录会有一个计时器,也就是记录中的第三个字段,上面这条记录的第三个字段是179,表明当前的ASSURED状态还可以保持179秒,若是还有新的数据包通过,那么计时器会被从新设置成缺省的180秒,若是在180秒内都没有流量,那么这条状态记录就会从状态表中被删除。

 

 

            最后,咱们在来看看Linux kernel是如何标示ICMP协议的状态的,ICMP也是一种无状态协议,它只是用来控制而不是创建链接。

            ICMP包有不少类型,但只有四种类型有应答包,它们是回显请求和应答(Echo request and reply),时间戳请求和应答(Timestamp request and reply),信息请求和应答(Information request and reply),还有地址掩码请求和应答(Address mask request and reply),这些包有两种状态,NEW和ESTABLISHED 。时间戳请求和信息请求已经废除不用了,回显请求仍是经常使用的,好比ping命令就用的到,地址掩码请求不太经常使用,可是可能有时颇有用而且值得使用。看看下面的图,就能够大体了解ICMP链接的NEW和ESTABLISHED状态了。

            如图所示,主机向目标发送一个回显请求,防火墙就认为这个包处于NEW状态。目标回应一个回显应答,防火墙就认为包处于ESTABLISHED了。当回显请求被发送时,ip_conntrack里就有这样的记录了:

icmp 1 25 src=192.168.1.6 dst=192.168.1.10 type=8 code=0 id=33029 [UNREPLIED] src=192.168.1.10 dst=192.168.1.6 type=0 code=0 id=33029 use=1

            能够看到,ICMP的记录和TCP、UDP的有点区别,协议名称、超时时间和源、目地址都同样,不一样之处在于没有了端口,而新增了三个新的字段:type,code和id。字段type说明ICMP的类型。code说明ICMP的代码,这些代码在附录ICMP类型里有说明。id是 ICMP包的ID。每一个ICMP包被发送时都被分配一个ID,接受方把一样的ID 分配给应答包,这样发送方能认出是哪一个请求的应答。

            [UNREPLIED] 的含义和前面同样,说明数的传输只发生在一个方向上,也就是说未收到应答。再日后,是应答包的源、目地址,还有相应的三个新字段,要注意的是type和 code是随着应答包的不一样而变化的,id和请求包的同样。和前面同样,应答包被认为是ESTABLISHED的。然而,在应答包以后,这个ICMP 链接就再也不有数据传输了。因此,一旦应答包穿过防火墙,ICMP的链接跟踪记录就被销毁了。所以,要想在/proc/ip_conntrack文件中抓到 ICMP协议的状态记录实在不是一件容易的事。您能够用以下的命令来尝试获取这些记录:

#cat /proc/net/ip_conntrack | grep icmp

            若是没有输出,那么就不停的重复这个命令,直到发现icmp的记录为止。

            以上各类状况,请求被认为NEW,应答是ESTABLISHED。换句话说,就是当防火墙看到一个请求包时,就认为链接处于NEW状态,当有应答时,就是ESTABLISHED状态。

            state匹配:state匹配在防火墙配置过程当中很是重要的,若是没有state的配置,那么须要配置双向的规则才能知足通信的须要,但防火墙既然有状态检测功能,咱们为何很差好使用它呢?

            --state:state的状态有四种,指定要匹配包的的状态,当前有4种状态可用:INVALID,ESTABLISHED,NEW和RELATED。四种数据包的状态咱们在前面已经作了详细的描述本节咱们只进行state的用法描述,以下例所示:

#iptables –A FORWARD –p tcp –m state --state RELATED,ESTABLISHED –j ACCEPT

            本例代表凡是数据包状态为“RELATED”、“ESTABLISHED”的tcp包容许经过防火墙。在通常状况下,基于状态的策略都是配置在每一条 chain的最前面,由于当包被匹配到之后,就可以直接被处理了,这是一种比较高效的配置方法。

            关键字ESTABLISHED比较容易理解,即匹配状态为 “已经创建链接”的数据包,那么怎么理解“RELATED”呢,RELATED表示不属于已经创建的那条链接,但和那条链接有关,好比ftp,ftp在创建链接的过程当中会首先创建一条ftp-control链接用以传输指令等,真正传输数据的是一条叫作ftp-data的链接,而传输数据的链接是和传输控制信号的链接相关的,所以“RELATED”是用于相似这些特殊服务的。在正常状况下,对于每一种协议:TCP、UDP、ICMP均可以单独的配置状态策略,但一种比较简单高效的作法是:

#iptables –A INPUT –p all –m state --state RELATED,ESTABLISHED –j ACCEPT

            multiport:这个匹配选项为咱们解决了如何在一条策略种匹配那些端口不连续的服务,在通常状况下,一个公司或企业的安全策略是容许内部网络使用有限的Internet服务,如收发电子邮件、上网浏览网页、msn聊天等,看看下面的例子:

#iptables –A FORWARD –i eth0 –p tcp –m multiport --dports 25,80,110,443,1863 –j ACCEPT
#iptables –A FORWARD –i eth0 –p udp --dport 53 –j ACCEPT

            仅仅两条命令就解决了内部用户上网收发E_mail、浏览网页、使用msn聊天等需求,怎么样,就这么简单~

相关文章
相关标签/搜索