Iptables与Netfilter深度解析:Linux防火墙核心架构探秘
防火墙:保护服务器和基础设施的关键工具
防火墙是一种重要的工具,可以配置来保护服务器和基础设施。在Linux生态系统中,iptables是一种广泛使用的防火墙工具,它与内核的Netfilter数据包过滤框架协同工作。创建可靠的防火墙策略可能具有挑战性,因为它涉及到复杂的语法和许多相互关联的部分。
在本指南中,我们将深入探讨iptables的架构,旨在帮助用户更轻松地构建自己的防火墙策略。我们将讨论iptables如何与Netfilter交互,以及各个组件如何协同工作,提供完善的过滤系统。
IPTables和Netfilter:核心概念解析
多年来,Linux中最常用的防火墙软件是iptables。尽管在一些发行版中,它已被名为nftables的新工具所取代,但iptables的语法仍然常用作基准。iptables防火墙通过与Linux内核网络堆栈中的数据包过滤钩子进行交互来工作。这些内核钩子被称为Netfilter框架。
所有通过网络层的数据包(无论是进入还是离开)都会触发这些钩子,使得程序能够在关键点与流量进行交互。与iptables相关的内核模块会向这些钩子注册,以确保流量符合防火墙规则所规定的条件。
Netfilter钩子:数据包处理的关键点
Netfilter提供了五个钩子,供程序进行注册。当数据包在网络堆栈中传输时,它们将触发已向这些钩子注册的内核模块。数据包触发哪个钩子取决于它是传入还是传出、数据包的目的地,以及数据包在之前的某个点上是否被丢弃或拒绝。
以下钩子代表了网络堆栈中明确定义的处理点:
- NF_IP_PRE_ROUTING: 这个钩子会在任何传入流量进入网络堆栈后立即触发。它在进行任何关于数据包路由的决策之前处理。
- NF_IP_LOCAL_IN: 如果传入数据包的目标是本地系统,则在路由后触发此钩子。
- NF_IP_FORWARD: 如果传入数据包需要转发到另一个主机,则在路由后触发此钩子。
- NF_IP_LOCAL_OUT: 任何本地创建的出站流量在进入网络堆栈时都会触发此钩子。
- NF_IP_POST_ROUTING: 任何出站或转发流量在路由完成后,即将发送到网络之前,都会触发此钩子。
需要在这些钩子中注册的内核模块还必须提供一个优先级数字,以帮助确定在触发钩子时它们的调用顺序。这为多个模块(或同一模块的多个实例)与每个钩子连接提供了确定性的顺序。每个模块将依次被调用,并在处理后向Netfilter框架返回一个决策,指示应该如何处理该数据包。
IPTables 表和链:规则的组织结构
iptables防火墙使用“表”来组织其规则。这些表根据规则的决策类型对规则进行分类。例如,如果一条规则处理网络地址转换(NAT),它将被放入nat
表。如果该规则用于决定是否允许数据包继续发送到目标地址,它可能会被添加到filter
表。
在每个iptables表内部,规则进一步按照独立的“链”进行组织。虽然表是由它们所包含规则的总体目标来定义的,但内置的链代表了触发它们的Netfilter钩子。链决定了何时对规则进行评估。
内置链的名称与它们关联的Netfilter钩子的名称相同:
- PREROUTING: 由NF_IP_PRE_ROUTING钩子触发。
- INPUT: 由NF_IP_LOCAL_IN钩子触发。
- FORWARD: 由NF_IP_FORWARD钩子触发。
- OUTPUT: 由NF_IP_LOCAL_OUT钩子触发。
- POSTROUTING: 由NF_IP_POST_ROUTING钩子触发。
链允许管理员控制规则在数据包传输路径中的评估位置。由于每个表都有多个链,一个表的影响可以在多个处理点上施加。因为某些类型的决策只在网络堆栈的某些点上才有意义,所以并非每个表都在每个内核钩子上注册有链。
Netfilter内核钩子只有五个,因此每个钩子都注册了来自多个表的链。例如,有三个表具有PREROUTING链。当这些链在关联的NF_IP_PRE_ROUTING钩子上注册时,它们指定了一个优先级,该优先级决定了每个表的PREROUTING链的调用顺序。在进入下一个PREROUTING链之前,会按顺序评估具有最高优先级的PREROUTING链中的每个规则。我们将稍后查看每个链的具体顺序。
IPTables可用表类型详解
让我们暂时退后一步,看一下iptables提供的不同表。这些表代表了按关注领域组织的规则集,用于评估数据包。
Filter表:数据包过滤的核心
filter
表是iptables中最常用的表之一。它用于决定是否允许数据包继续传送到其目标地址,或者拒绝其请求。在防火墙术语中,这被称为“过滤”数据包。这个表提供了人们在讨论防火墙时所考虑的大部分功能。
NAT表:网络地址转换的实现
nat
表用于实施网络地址转换规则。当数据包进入网络堆栈时,该表中的规则将确定如何修改数据包的源地址或目标地址,以影响数据包及任何响应流量的路由方式。这通常用于在直接访问不可行时将数据包路由到网络。
Mangle表:IP头部修改与标记
mangle
表用于以不同的方式改变数据包的IP头部。例如,您可以调整数据包的TTL(生存时间)值,延长或缩短数据包可以承受的有效网络跳数。其他IP头部也可以通过类似的方式进行更改。
这个表还可以在数据包上放置一个内部内核“标记”,以便在其他表和其他网络工具中进行进一步处理。这个标记不会影响实际的数据包,而是将标记添加到内核对数据包的表示中。
Raw表:连接跟踪的例外处理
iptables防火墙是有状态的,这意味着数据包的评估与其与先前数据包的关系有关。建立在Netfilter框架之上的连接跟踪功能使iptables能够将数据包视为正在进行的连接或会话的一部分,而不是一系列离散且无关的数据包流。连接跟踪逻辑通常在数据包到达网络接口后很快应用。
raw
表具有非常狭窄的功能。其唯一目的是提供一个机制来标记数据包,以便退出连接跟踪。
Security表:SELinux安全上下文集成
security
表用于在数据包上设置内部SELinux安全上下文标记,这将影响SELinux或其他能解释SELinux安全上下文的系统处理这些数据包的方式。这些标记可以基于每个数据包或每个连接应用。
链和表之间的关系
PREROUTING链的评估顺序是什么?
在Iptables中,有多个表都包含PREROUTING链。那么,这些PREROUTING链的评估顺序是怎样的呢?
下表展示了Iptables中各表所包含的链(从左到右),以及在Netfilter钩子触发时,各链的调用顺序(从上到下)。例如,我们可以看到raw
表包含PREROUTING和OUTPUT链。
需要注意的是,在下面的示意图中,为了更清晰地展示NAT操作的顺序,nat
表被细分为DNAT(改变数据包目标地址)和SNAT(改变数据包源地址)。此外,我们还加入了路由决策点和连接跟踪启用点,以便更全面地理解数据包的处理流程。
表/链 | PREROUTING | INPUT | FORWARD | OUTPUT | POSTROUTING |
---|---|---|---|---|---|
(路由决策) | ✓ | ||||
raw | ✓ | ✓ | |||
(连接跟踪已启用) | ✓ | ✓ | |||
mangle | ✓ | ✓ | ✓ | ✓ | ✓ |
nat (DNAT) | ✓ | ✓ | |||
(路由决策) | ✓ | ✓ | |||
filter | ✓ | ✓ | ✓ | ||
security | ✓ | ✓ | ✓ | ||
nat (SNAT) | ✓ | ✓ |
当一个数据包触发Netfilter钩子时,相关的链将按照上表中从上到下的顺序进行处理。数据包触发的钩子(列)取决于它是入站包还是出站包、所做的路由决策以及数据包是否通过了过滤条件。
在处理过程中,特定事件会导致表链被跳过。例如,在连接中,只有第一个数据包会进行NAT规则评估。对于第一个数据包做出的任何NAT决策将应用于连接中的所有后续数据包,无需额外评估。对于NAT连接的响应,系统将自动应用相反的NAT规则以正确路由。
链式遍历顺序示例
假设服务器知道如何路由数据包,并且防火墙规则允许其传输,在不同的情况下,数据包将经过以下路径:
- 发往本地系统的入站数据包: PREROUTING -> INPUT
- 发往其他主机的入站数据包: PREROUTING -> FORWARD -> POSTROUTING
- 本地生成的数据包: OUTPUT -> POSTROUTING
如果我们将上述信息与前面表格中的排序结合起来,我们可以看到,一个发送到本地系统的入站数据包首先会在raw
、mangle
和nat
表的PREROUTING链上进行评估。然后,它将在mangle
、filter
、security
和nat
表的INPUT链上进行遍历,最后被传递到本地套接字。
IPTables规则
Iptables规则被放置在特定表的特定链中。每当调用某个链时,系统将按顺序检查数据包是否符合链中的每条规则。每条规则都包含一个匹配部分和一个动作部分。
匹配
一个规则的匹配部分指明了数据包必须满足的条件,以便执行相关的动作(或“目标”)。
匹配系统非常灵活,可以通过附加的Iptables扩展大幅增强。可以根据协议类型、目标或源地址、目标或源端口、目标或源网络、输入或输出接口、头部或连接状态等条件来构建规则进行匹配。这些条件可以组合在一起,创建复杂的规则集以区分不同的流量。
目标
“目标”是指当数据包符合规则匹配条件时触发的动作。目标一般分为两大类:
- 终止目标: 终止目标执行一个动作,该动作会终止当前链中的评估,并将控制权返回给Netfilter钩子。根据返回值的不同,钩子可能会丢弃数据包,或者允许数据包继续进行下一阶段的处理。
- 非终止目标: 非终止目标执行一个动作后,会继续在当前链中进行评估。尽管每个链最终都必须返回一个最终的终止决策,但在那之前可以执行任意数量的非终止目标。
每个规则中目标的可用性将取决于上下文。例如,表和链类型可能会决定可用的目标。规则中激活的扩展和匹配子句也可以影响目标的可用性。
跳转到用户定义的链
还有一类特殊的非终止目标:跳转目标。跳转目标是导致评估移动到另一个链进行额外处理的操作。我们已经讨论了与调用它们的Netfilter钩子相关联的内置链。然而,Iptables还允许管理员为了组织目的创建自己的链。
规则可以以与内置链相同的方式放置在用户定义的链中。不同的是,用户定义的链只能通过从规则中“跳转”到它们来访问(它们本身不通过Netfilter钩子进行注册)。
用户定义的链作为调用它们的链的扩展。例如,在用户定义的链中,如果到达规则列表的末尾或者匹配规则激活了一个返回目标,评估将返回到调用链。评估也可以跳转到其他用户定义的链。
这种结构可以增加组织性,为更强大的分支提供所需的框架。
IPTables和连接跟踪
连接追踪:Iptables实现有状态操作的核心
在探讨raw
表和连接状态匹配准则时,我们深入了解了基于Netfilter框架实现的连接追踪系统。连接追踪(Connection Tracking,通常简称Conntrack)是Iptables能够对持续连接中的数据包进行决策的关键。它为Iptables提供了执行“有状态”操作所需的功能,极大地增强了防火墙的智能性。
数据包进入网络堆栈后不久,连接追踪机制便会介入。在将数据包与现有连接关联之前,系统仅对raw
表链进行逻辑处理,并执行一些基本的健全性检查。
系统会根据一组现有连接来检查每个传入的数据包。如果需要,它将更新连接在存储中的状态;如果数据包属于一个新连接,则会在系统中添加该新连接。值得注意的是,被标记为NOTRACK
目标的数据包将绕过连接追踪例程,直接进行后续处理。
连接追踪系统追踪的连接状态详解
连接追踪系统所追踪的连接可以处于以下几种状态之一:
- NEW(新建):当一个数据包到达,它不属于任何现有连接,但也不是一个无效的初始数据包时,系统会为该数据包创建一个新的连接,并将其标记为
NEW
状态。这适用于像TCP这样面向连接的协议,也适用于像UDP这样无连接的协议。 - ESTABLISHED(已建立):当一个
NEW
状态的连接收到来自相反方向的有效响应时,其状态会变为ESTABLISHED
。对于TCP连接,这意味着收到了SYN/ACK
包;对于UDP和ICMP流量,这意味着收到了源和目标地址与原始数据包互换的响应包。 - RELATED(相关):不属于现有连接,但与系统中已存在的某个连接相关联的数据包会被标记为
RELATED
。这可能是一个辅助连接,例如FTP数据传输连接,或者是由其他协议发起的连接尝试所产生的ICMP响应。 - INVALID(无效):如果数据包不与现有连接关联,也不适合开启新连接,或者无法识别,或者不可路由等原因,它可能会被标记为
INVALID
。 - UNTRACKED(未追踪):如果数据包在
raw
表链中被指定为绕过追踪,则会被标记为UNTRACKED
状态。 - SNAT(源地址转换):这是一个虚拟状态,当源地址通过NAT操作被修改时设置。连接追踪系统利用此状态,以便在回复数据包时能够将源地址改回原始地址。
- DNAT(目的地址转换):这是一个虚拟状态,当目的地址通过NAT操作被修改时设置。连接追踪系统利用此状态,以便在路由回复数据包时能够将目的地址改回原始地址。
连接追踪系统中跟踪的这些状态允许管理员制定针对连接生命周期中特定点的规则,从而提供更全面和安全的规则功能。
结论:Netfilter与Iptables的协同力量
Netfilter数据包过滤框架和Iptables防火墙是Linux服务器上大多数防火墙解决方案的基础。Netfilter内核钩子与网络堆栈紧密结合,可以对数据包进行强大的控制,以便在系统处理数据包时进行操作。Iptables防火墙利用这些功能,为内核提供了一种灵活、可扩展的策略传达方法。通过深入了解这些组件如何协同工作,您可以更好地利用它们来控制和保护服务器环境。
如果您想了解更多关于如何选择有效的Iptables策略的信息,请查阅以下指南。
以下指南可以帮助您开始实施您的Iptables防火墙规则:
- 如何使用Iptables设置防火墙
- Iptables基础:常见防火墙规则和命令
- 如何在Ubuntu 22.04上使用UFW设置防火墙
- 如何在Rocky Linux 8上使用firewalld设置防火墙
- 如何设置Iptables防火墙以保护服务器间的流量