iptables的状态检测机制(TCP、UDP、ICMP状态详解)

iptables 的状态检测机制的状态检测机制
1.1.什么是状态检测什么是状态检测
什么是状态检测  每个网络连接包括以下信息:源地址、目的地址、源端口和目的端口,叫作套接字对(socket pairs);协议类型、连接状态(TCP 协议)和超时时间等。防火墙把这些信息叫作状态(stateful),能够检测每个连接状态的防火墙叫作状态包过滤防火墙。它除了能够完成简单包过滤防火墙的包过滤工作外,还在自己的内存中维护一个跟踪连接状态的表,比简单包过滤防火墙具有更大的安全性。  iptables 中的状态检测功能是由state 选项来实现的。对这个选项,在iptables 的手册页中有以下描述:
state
这个模块能够跟踪分组的连接状态(即状态检测)。
--state state
这里,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的状态检测机制将重组分组,并且以以下某种方式跟踪其状态:
分组是否匹配状态表中的一个已经实现(ESTABLISHED)的连接。
西门豹治邺翻译它是否是和状态表中某个UDP/TCP连接相关(RELATED)的一个ICMP分组。
这个分组是否要发起一个新(NEW)的连接。
如果分组和任何连接无关,就被认为是无效(INVALID)的。
FORWARD链
把分组的状态和过滤表中的规则进行匹配,如果分组与所有的规则都无法匹配,就使用默认的策略进行处理。
POSTROUTING链
如果有必要,就对分组进行源网络地址转换(SNAT),
注意:所有的分组都必须和过滤表的规则进行比较。如果你修改了规则,要拒绝所有的网络流量,那么即使分组的状态匹配状态表中的一个ESTABLISHED
条目,也将被拒绝。
下面,我们对UDP、TCP和ICMP三个协议分别进行分析。
连接
2.2.UDP连接
UDP(用户数据包协议)是一种无状态协议,以为这个协议没有序列号。不过,这并不意味着我们不能跟踪UDP连接。虽然没有序列号,但是我们还可以使用其它的一些信息跟踪UDP连接的状态。下面是状态表中关于UDP连接的条目: udp 17 19 src=192.168.1.2 dst=192.168.1.50 sport=1032 dport=53 [UNREPLIED] src=192.168.1.50 dst=192.168.1.2 sport=53 dport=1032 use=1 这个状态表项只有在iptables过滤规则允许建立新的连接时,才能建立。以下的规则可以产生这类状态表项,这两条规则只允许向外的UDP连接: iptables -A INPUT -p udp -m state --state ESTABLISHED -j ACCEPT iptables -A OUTPUT -P udp -m state --state NEW,ESTABLISHED -j ACCEPT 上面的状态表项包含如下信息:
连接的协议是UDP(IP协议号17)。
这个状态表项还有19秒中就超时。
发起连接方向上的源、目的地址和源、目的端口。
应答方向上的源、目的地址和源、目的端口。这个连接使用UNREPLIED标记,表示还没有收到应答。
UDP连接的超时时间在
/usr/src/linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c文件中设置,如果改变了这个值,需要重新编译Linux内核源代码才能生效。下面是UDP连接超时时间的相关的源代码:
#define UDP_TIMEOUT (30*HZ)
#define UDP_STREAM_TIMEOUT (180*HZ)
一个UDP请求等待应答的时间是30*HZ(这个值一般是30秒)。在上面的例
子中,等待的时间已经消耗了11秒,还剩余19秒,如果在这段时 间之内没有
收到应答分组,这个表项就会被删除。一旦收到了应答,这个值就被重置为30,UNREPLIED标志也被删除。这个表项编程如下形式:
udp 17 28 src=192.168.1.2 dst=192.168.1.50 sport=1032 dport=53
src=192.168.1.50 dst=192.168.1.2 sport=53 dport=1032 use=1
如果在这一对源、目的地址和源、目的端口上,发生了多个请求和应答,这个表项就作为一个数据流表项,它的超时时间是180秒。这种情况下,这个表项就变成如下形式:
udp 17 177 src=192.168.1.2 dst=192.168.1.50 sport=1032 dport=53
src=192.168.1.50 dst=192.168.1.2 sport=53 dport=1032 [ASSURED] use=1
这时我们看到这个表项使用ASSURED标志。一旦连接表项使用ASSURED标志,那么即使在网络负沉重的情况下,也不会被丢弃。如果状态表已经饱和,当新的连接到达时,使用UNREPLIED标志的表项会受被丢弃。
2.3.TCP连接
连接
一个TCP连接是通过三次握手的方式完成的。首先,客户程序发出一个同步请求(发出一个SYN分组);接着,服务器端回应一个SYN|ACK分组;最后返回一个ACK分组,连接完成。整个过程如下所示:
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.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.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.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, */
13年卷布机事件
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.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 2.4.ICMP
在iptables 看来,只有四种ICMP 分组,这些分组类型可以被归为NEW、ESTABLISHED 两类:
ECHO 请求(ping,8)和ECHO 应答(pong,0)。
时间戳请求(13)和应答(14)。
我国名画家张善子擅长画什么信息请求(15)和应答(16)。马克思唯物史观

本文发布于:2024-09-20 23:26:22,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/530090.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:连接   分组   状态   状态表   进行   表项   检测
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议