简介
前面文章我们已经介绍了一些扩展模块,如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
。这些数据包将不会按照连接的状态(如 NEW
、ESTABLISHED
、RELATED
)来处理,而是根据其他规则(如果有的话)来决定是否允许通过。
需要注意的是,UNTRACKED
状态并不是所有的 iptables 版本或配置都支持,它主要与 Netfilter 框架中的某些特性相关。
实际应用举例
假设我这台主机提供了web服务,那么,我只允许其他主机访问我web服务,如http,但是我自己不允许主动发起连接去访问其他主机。那么我们该如何做呢?
我们可以直接设置iptables只允许INPUT 80端口,这样外面主机只能访问我的80端口,此时有一个问题,就是本机能否发直接发起连接访问其他主机呢?这取决于我们默认防火墙的策略是ACCEPT还是DROP。
对于一个web服务器,如果我们只想要允许外部访问自己,自己不允许主动发起连接,那么默认情况下INPUT和OUTPUT的默认动作都应该设置为DROP,拒绝所有流量。然后只允许外部访问自己的对应的服务端口这里是80,出方向只允许建立连接的返回流量通过。这样主机无法主动发起连接。
配置只允许访问本机80端口
![](https://img-blog.csdnimg.cn/direct/6357f8be590a40429abf6c417176e798.png)
![](https://img-blog.csdnimg.cn/direct/811b5f0cefd74ae693cbfdd40fa7b04b.png)
测试
![](https://img-blog.csdnimg.cn/direct/17c342587c9d4f89be9dbfccad58106e.png)
![](https://img-blog.csdnimg.cn/direct/8e6ae1899cf346ad94d03d962bbb094d.png)
![](https://img-blog.csdnimg.cn/direct/1f62786065914f3f8a045294402c86df.png)
限制本机发起的连接
此时140.250能否主动发起连接?答案是能,但是却无法成功建立连接,因为默认情况下OUTPUT动作是ACCEPT,允许主机流量出去,但是INPUT却只允许22和80端口入,所以发起的连接的返回数据包被INPUT链拒绝了。
配置限制主动发起连接
![](https://img-blog.csdnimg.cn/direct/083acda2ca28412393c7576f98391ffc.png)
![](https://img-blog.csdnimg.cn/direct/d35bde08ff29411e940c94e42018e56a.png)
将INPUT链默认规则修改为ACCEPT
![](https://img-blog.csdnimg.cn/direct/204d849d7cca48a6960333453a34708c.png)
测试
![](https://img-blog.csdnimg.cn/direct/17f7823707be4a1aa4e1ef398a42689e.png)
![](https://img-blog.csdnimg.cn/direct/016ad7308272419891b832f73f67bfb3.png)
![](https://img-blog.csdnimg.cn/direct/f7a37a5e6b3f44e4a14da2b542be2f6e.png)
总结
state扩展模块根据自己的需求和我们前面介绍的各种策略,源目IP地址网段、端口、和各种扩展模块进行组合应用从而形成自己特定的防火墙策略规则,如可以设置默认的白名单规则,即默认规则INPUT/OUTPUT都为DROP,那么只要上面允许的流量才会通过,也可以设置黑名单规则,即默认规则INPUT/OUTPUT都是ACCEPT,然后在上面规则中进行禁止。大家可以多做尝试验证,灵活搭配各种规则。