iptables(7)扩展模块state

简介

        前面文章我们已经介绍了一些扩展模块,如iprange、string、time、connlimit、limit,还有扩展匹配条件如--tcp-flags、icmp。这篇文章我们介绍state扩展模块

 state

         在 iptables 的上下文中,--state 选项并不是直接关联于一个扩展模块,而是与 iptables 的 state 匹配机制相关,特别是在处理 ICMP(Internet Control Message Protocol)或 TCP(Transmission Control Protocol)和 UDP(User Datagram Protocol)流量的时候。    

        state模块的报文可以分为5种状态,报文状态可以为NEW、ESTABLISHED、RELATED、INVALID、UNTRACKED。

NEW:连接中的第一个包,状态就是NEW,我们可以理解为新连接的第一个包的状态为NEW。
     The NEW state tells us that the packet is the first packet that we see. This means 
that the first packet that the conntrack module sees, within a specific connection, will 
be matched. For example, if we see a SYN packet and it is the first packet in a 
connection that we see, it will match. However, the packet may as well not be a SYN 
packet and still be considered NEW. This may lead to certain problems in some instances,
 but it may also be extremely helpful when we need to pick up lost connections from other 
firewalls, or when a connection has already timed out, but in reality is not closed. 
     NEW 状态告诉我们这个数据包是我们看到的第一个数据包。这意味着在特定的连接中,conntrack 模
块看到的第一个数据包将被匹配。例如,如果我们看到一个 SYN 数据包,并且它是我们在连接中看到的第一
个数据包,它就会被匹配。但是,数据包也可能不是 SYN 数据包而仍然被认为是 NEW。这在某些情况下可
能会导致某些问题,但在我们需要从其他防火墙恢复丢失的连接,或者连接已经超时但实际上并未关闭时,
这也可能非常有用。

ESTABLISHED:一个已建立的连接(已接收其开始和结束的数据包)表示连接已建立。
            The ESTABLISHED state has seen traffic in both directions and will then 
continuously match those packets. ESTABLISHED connections are fairly easy to understand. 
The only requirement to get into an ESTABLISHED state is that one host sends a packet, 
and that it later on gets a reply from the other host. The NEW state will upon receipt of 
the reply packet to or through the firewall change to the ESTABLISHED state. ICMP reply
 messages can also be considered as ESTABLISHED, if we created a packet that in turn 
generated the reply ICMP message. 
            ESTABLISHED 状态表示已经在两个方向上看到了流量,并且之后将持续匹配这些数据包。
ESTABLISHED 连接相对容易理解。进入 ESTABLISHED 状态的唯一要求是一台主机发送了一个数据包,并且
稍后从另一台主机收到了回复。当防火墙收到回复数据包时,NEW 状态将变为 ESTABLISHED 状态。如果我
们创建了一个数据包,而该数据包又生成了回复的 ICMP 消息,那么这些 ICMP 回复消息也可以被认为是 
ESTABLISHED 状态的。

RELATED:从字面上理解RELATED译为关系,与已建立的连接相关的数据包。
         比如FTP服务,FTP服务端会建立两个进程,一个命令进程,一个数据进程。
         命令进程负责服务端与客户端之间的命令传输。
         数据进程负责服务端与客户端之间的数据传输 。
         但是具体传输哪些数据,是由命令去控制的,所以,”数据进程中连接”的报文与”命令进程中连接
报文”是有”关系”的。那么,”数据进程中连接”报文可能就是RELATED状态,因为这些报文与”命令进程中连
接”报文有关系。
        (注意:如果想要对ftp进行连接追踪,需要单独加载对应的内核模块nf_conntrack_ftp、ip_nat_ftp,也可以自动加载)
        The RELATED state is one of the more tricky states. A connection is considered 
RELATED when it is related to another already ESTABLISHED connection. What this means, is 
that for a connection to be considered as RELATED, we must first have a connection that
 is considered ESTABLISHED. The ESTABLISHED connection will then spawn a connection 
outside of the main connection. The newly spawned connection will then be considered 
RELATED, if the conntrack module is able to understand that it is RELATED. Some good 
examples of connections that can be considered as RELATED are the FTP-data connections 
that are considered RELATED to the FTP control port, and the DCC connections issued 
through IRC. This could be used to allow ICMP error messages, FTP transfers and DCC's to
 work properly through the firewall. Do note that most TCP protocols and some UDP 
protocols that rely on this mechanism are quite complex and send connection information
within the payload of the TCP or UDP data segments, and hence require special helper 
modules to be correctly understood.
        RELATED 状态是比较复杂的状态之一。当一个连接与另一个已经 ESTABLISHED 的连接相关时,它
就被认为是 RELATED 的。这意味着,为了将一个连接视为 RELATED,我们首先必须有一个被认为是 
ESTABLISHED 的连接。这个 ESTABLISHED 的连接随后会在主连接之外产生一个新的连接。如果 conntrack 
模块能够理解这个新产生的连接是 RELATED 的,那么它就会被认为是 RELATED 的。一些被认为是 
RELATED 的连接的典型例子是 FTP 数据连接,它们与 FTP 控制端口相关,以及通过 IRC 发起的 DCC 连
接。这可以用于允许 ICMP 错误消息、FTP 传输和 DCC 通过防火墙正常工作。请注意,大多数 TCP 协议和
一些依赖这种机制的 UDP 协议都相当复杂,它们会在 TCP 或 UDP 数据段的负载中发送连接信息,因此需
要特殊的辅助模块来正确解析。

INVALID:如果一个包没有办法被识别,或者这个包没有任何状态,那么这个包的状态就是INVALID,我们可
以主动屏蔽状态为INVALID的报文。
        The INVALID state means that the packet can't be identified or that it does not 
have any state. This may be due to several reasons, such as the system running out of 
memory or ICMP error messages that do not respond to any known connections. Generally, it
 is a good idea to DROP everything in this state. 
        INVALID 状态意味着数据包无法被识别,或者它没有任何状态。这可能是由几个原因导致的,比如
系统内存不足,或者 ICMP 错误消息没有响应任何已知的连接。通常,在这种状态下建议丢弃所有内容。

UNTRACKED:报文的状态为untracked时,表示报文未被追踪,当报文的状态为Untracked时通常表示无法找
到相关的连接。UNTRACKED 状态并不是所有的 iptables 版本或配置都支持,它主要与 Netfilter 框架中
的某些特性相关。

下面简要说下iptables state模块的工作流程

主机1 (Client) ----------------------> iptables 防火墙 ----------------------> 主机2 (Web Server)  
  HTTP 请求 (NEW)                        检查状态 (NEW/ESTABLISHED/RELATED/INVALID/UNTRACKED)  
                                         如果匹配规则,允许通过  
                                                     |  
                                                     V  
                                                     |  
                                   HTTP 响应 (ESTABLISHED) <---------------------  
                                        检查状态 (ESTABLISHED/RELATED/UNTRACKED)

在这个图中,当主机1发起一个新的HTTP请求时,数据包的状态是 NEW。iptables 防火墙会检查这个数据包并根据其规则集来决定是否允许它通过。如果允许,数据包会到达主机2的Web服务器。

当Web服务器响应这个请求时,返回的数据包状态是 ESTABLISHED(因为这是对之前请求的一个响应,所以连接已经建立)。iptables 防火墙会再次检查这个数据包,并根据其规则集来决定是否允许它返回给主机1。

UNTRACKED 状态的数据包可能不会在常规的 HTTP 请求/响应过程中出现,但如果你使用了如 NAT(网络地址转换)之类的功能,某些数据包可能会被标记为 UNTRACKED。这些数据包将不会按照连接的状态(如 NEWESTABLISHEDRELATED)来处理,而是根据其他规则(如果有的话)来决定是否允许通过。

需要注意的是,UNTRACKED 状态并不是所有的 iptables 版本或配置都支持,它主要与 Netfilter 框架中的某些特性相关。

实际应用举例        

假设我这台主机提供了web服务,那么,我只允许其他主机访问我web服务,如http,但是我自己不允许主动发起连接去访问其他主机。那么我们该如何做呢?

我们可以直接设置iptables只允许INPUT 80端口,这样外面主机只能访问我的80端口,此时有一个问题,就是本机能否发直接发起连接访问其他主机呢?这取决于我们默认防火墙的策略是ACCEPT还是DROP。

对于一个web服务器,如果我们只想要允许外部访问自己,自己不允许主动发起连接,那么默认情况下INPUT和OUTPUT的默认动作都应该设置为DROP,拒绝所有流量。然后只允许外部访问自己的对应的服务端口这里是80,出方向只允许建立连接的返回流量通过。这样主机无法主动发起连接。

配置只允许访问本机80端口

先清空iptables规则,避免其他规则造成的影响,配置可以访问本机tcp的80端口,注意,INPUT链的默认规则为ACCEPT,所以我们直接设置该规则,后面默认还有ACCEPT,不能起到真正的阻塞作用,需要修改默认规则为DROP或者后面新增拒绝的规则。
注意,此时我新增了一条允许访问本机22端口,然后默认规则修改为DROP,否则,直接修改为DROP,本机将无法通过ssh连接。请大家配置策略的时候务必考虑清除自己配置策略的目的和影响,避免因为测试配置错误造成严重的故障。

测试

此时我通过140.250已经无法访问140.248这台主机了,因为前面iptables INPUT放行了80 和22端口,默认策略为DROP。
这里可以看到有数据包被匹配到
80端口是可以正常访问的

限制本机发起的连接

        此时140.250能否主动发起连接?答案是能,但是却无法成功建立连接,因为默认情况下OUTPUT动作是ACCEPT,允许主机流量出去,但是INPUT却只允许22和80端口入,所以发起的连接的返回数据包被INPUT链拒绝了。

      配置限制主动发起连接

OUTPUT新增一条规则,允许连接的established和related状态的数据包,及请求连接的返回数据包通过,然后将OUTPUT链默认规则改为DROP,此时本机将无法主动发出连接请求
此时无法ssh和无法ping外面的主机,是因为匹配到了OUTPUT链的默认规则

将INPUT链默认规则修改为ACCEPT

此时INPUT链默认规则是ACCEPT,前面也没有任何拒绝的规则,此时就以为着,该主机可以接收任何外部访问,但是由于OUTPUT默认动作是DROP,且state匹配状态为RELATED,ESTABLISHED,即无法主动发起任何连接。

测试

外部主机可以访问140.250
响应的数据包匹配上了该规则
但是140.250却无法主动发起任何连接,因为OUTPUT默认的动作是DROP,主动发起的数据包会被丢弃。

总结

state扩展模块根据自己的需求和我们前面介绍的各种策略,源目IP地址网段、端口、和各种扩展模块进行组合应用从而形成自己特定的防火墙策略规则,如可以设置默认的白名单规则,即默认规则INPUT/OUTPUT都为DROP,那么只要上面允许的流量才会通过,也可以设置黑名单规则,即默认规则INPUT/OUTPUT都是ACCEPT,然后在上面规则中进行禁止。大家可以多做尝试验证,灵活搭配各种规则。

  • 28
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Monster✺◟(∗❛ัᴗ❛ั∗)◞✺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值