命令记不住

登陆

Iptables 防火墙状态机制

Iptables防火墙状态机制

1. 防火墙状态机制说明

状态机制是iptables中较为特殊的一部分,这也是iptables和比较老的ipchains的一个比较大的区别之一,运行状态机制(连接跟踪)的防火墙称作带有状态机制的防火墙,以下简称为状态防火墙。状态防火墙比非状态防火墙要安全,因为它允许我们编写更严密的规则。
在iptables上一共有四种状态,分别被称为NEW、ESTABLISHED、INVALID、RELATED,这四种状态对于TCP、UDP、ICMP三种协议均有效。下面,我们来分别阐述四种状态的特性。

  • NEW
    meaning that the packet has started a new connection, or otherwise associated with a connection which has not seen packets in both directions
    NEW说明这个包是我们看到的第一个包。意思就是,这是conntrack模块看到的某个连接的第一个包,它即将被匹配了。比如,我们看到一个SYN 包,是我们所留意的连接的第一个包,就要匹配它。
    ip1
  • ESTABLISHED
    meaning that the packet is associated with a connection which has seen packets in both directions
    ESTABLISHED已经注意到两个方向上的数据传输,而且会继续匹配这个连接的包。处于ESTABLISHED状态的连接是非常容易理解的。只要发送并接到应答,连接就是ESTABLISHED的了。一个连接要从NEW变为ESTABLISHED,只需要接到应答包即可,不管这个包是发往防火墙的,还是要由防火墙转发的。ICMP的错误和重定向等信息包也被看作是ESTABLISHED,只要它们是我们所发出的信息的应答。
    ip2
  • RELATED
    meaning that the packet is starting a new connection, but is associated with an existing connection, such as an FTP data transfer, or an ICMP error.
    RELATED是个比较麻烦的状态。当一个连接和某个已处于ESTABLISHED状态的连接有关系时,就被认为是RELATED的了。换句话说,一个连接要想是RELATED的,首先要有一个ESTABLISHED的连接。这个ESTABLISHED连接再产生一个主连接之外的连接,这个新的连接就是 RELATED的了,当然前提是conntrack模块要能理解RELATED。ftp是个很好的例子,FTP-data 连接就是和FTP-control有关联的,如果没有在iptables的策略中配置RELATED状态,FTP-data的连接是无法正确建立的,还有其他的例子,比如,通过IRC的DCC连接。有了这个状态,ICMP应答、FTP传输、DCC等才能穿过防火墙正常工作。注意,大部分还有一些UDP协议都依赖这个机制。这些协议是很复杂的,它们把连接信息放在数据包里,并且要求这些信息能被正确理解。
    ip3
  • INVALID
    meaning that the packet is associated with no known connection
    INVALID说明数据包不能被识别属于哪个连接或没有任何状态。有几个原因可以产生这种情况,比如,内存溢出,收到不知属于哪个连接的ICMP错误信息。一般地,我们DROP这个状态的任何东西,因为防火墙认为这是不安全的东西
    ip4

2.防火墙状态机制详述

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

cat /proc/net/nf_conntrack
tcp 6 117 SYN_SENT src=10.0.0.8 dst=10.0.0.7 sport=1031 dport=22 [UNREPLIED] src=10.0.0.7 dst=10.0.0.8 sport=23 dport=1031 use=1

# 模拟现实以上信息方法:在远程登录主机上配置以下策略
iptables -A OUT -p tcp --sport 22 -d 10.0.0.8 -j DROP

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

tcp 6 57 SYN_RECV src=10.0.0.8 dst=10.0.0.7 sport=1031 dport=22 src=10.0.0.7 dst=10.0.0.8 sport=22 dport=1031 use=1

# 模拟现实以上信息方法:在防火墙主机上配置以下策略
iptables -A INPUT -i eth0 -s 10.0.0.7 -m state --state ESTABLISHED -j DROP

现在我们已经收到了相应的SYN/ACK包,状态也变为SYN_RECV,这说明最初发出的SYN包已正确传输,并且SYN/ACK包也到达了防火墙。 这就意味着在连接的两方都有数据传输,因此可以认为两个方向都有相应的回应。
接下来,TCP三次握手的随后一个报文ACK包也到达了防火墙,防火墙上的状态表变成了:

tcp 6 431999 ESTABLISHED src=10.0.0.8 dst=10.0.0.7 sport=1031 dport=22 src=10.0.0.7 dst=10.0.0.8 sport=23 dport=1031 use=1
推荐阅读