Linux中国 Linux中国门户站!
设为主页 设为主页
收藏本站 收藏本站
 
当前位置 :首页 ->Linux技术 ->系统管理 ->正文

iptables的状态检测机制

来源:Linux-cn.com 作者:Webmaster 时间:2007-05-05 点击: [收藏] [投稿]

    Client Server

     SYN --->
             <--- SYN+ACK
     ACK --->
             <--- ACK
     ACK --->
           .........
           .........
  SYN和ACK是由TCP分组头的标志决定的。在每个TCP分组头还有32位的序列号和应答号用于跟踪会话。

  为了跟踪一个TCP连接的状态,你需要使用下面这样的规则:
    iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT
2.3.1.连接建立过程中状态表的变化

  下面,我们详细讨论在连接建立的每个阶段中,状态表发生的变化:
  • 一旦一个初始SYN分组进入OUTPUT链,并且输出规则允许这个分组建立一个新的连接,状态表的相关表项将如下所示:

      cp 6 119 SYN_SENT src=140.208.5.62 dst=207.46.230.218 sport=1311 dport=80 [UNREPLIED] src=207.46.230.218 dst=140.208.5.62 sport=80 dport=1311 use=1

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

  • 现在,我们等待SYN+ACK分组的响应。一旦得到响应,这个TCP连接表项就变为:

      tcp 6 57 SYN_RECV src=140.208.5.62 dst=207.46.230.218 sport=1311 dport=80 src=207.46.230.218 dst=140.208.5.62 sport=80 dport=1311 use=1

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

  • 现在我们需要等待完成握手的ACK分组。ACK分组到达后,我们首先对其序列号进行一些检查,如果正确,就把这个连接的状态变为ESTABLISHED,并且使用ASSURED标记这个连接。这时,这个连接的状态如下所示:

      cp 6 431995 ESTABLISHED src=140.208.5.62 dst=207.46.230.218 sport=1311 dport=80 src=207.46.230.218 dst=140.208.5.62 sport=80 dport=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 -A INPUT -p tcp !--syn -m state --state NEW -j DROP
  这样可以阻止空会话的继续进行。

2.3.3.超时

  所谓状态表项的超时值是指每个表项存在的最大时间,这些超时值的大小在/usr/src/linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c文件中设置。以下是相关的代码:
    static unsigned long tcp_timeouts[]
    = { 30 MINS, /* TCP_CONNTRACK_NONE, */
        5 DAYS, /* TCP_CONNTRACK_ESTABLISHED, */
        2 MINS, /* TCP_CONNTRACK_SYN_SENT, */
        60 SECS, /* TCP_CONNTRACK_SYN_RECV, */
        2 MINS, /* TCP_CONNTRACK_FIN_WAIT, */
        2 MINS, /* TCP_CONNTRACK_TIME_WAIT, */
        10 SECS, /* TCP_CONNTRACK_CLOSE, */
        60 SECS, /* TCP_CONNTRACK_CLOSE_WAIT, */
        30 SECS, /* TCP_CONNTRACK_LAST_ACK, */
        2 MINS, /* TCP_CONNTRACK_LISTEN, */
    };
2.3.4.连接的中断

  关闭一个TCP连接可以有两种方式。第一种类似于建立TCP连接的三次握手。一旦一个TCP会话完成,要终止会话的一方首先发出一个FIN为1的分组。接收方TCP确认这个FIN分组,并同志自己这边的应用程序不要在接收数据了。这个过程可以如下所示:
      Client Server
                 .........
                 .........
       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两类:


 如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<



上一篇:Squid优化完全手册(1)   下一篇:网站综合实例

文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论
更多相关文章
Power by linux-cn.com 粤ICP备05006655号