介绍
防火墙是一种重要的工具,可以配置来保护您的服务器和基础设施。在 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
表中。如果规则用于决定是否允许数据包继续传输到其目的地,它可能会被添加到 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
提供了哪些不同的表格。这些表格代表了通过关注领域组织的一组规则,用于评估数据包。
过滤表(Filter Table)
过滤表是iptables
中最常用的表之一。filter
表用于决定是否允许数据包继续到达其预期目的地,还是拒绝其请求。在防火墙术语中,这被称为对数据包进行“过滤”。该表提供了人们在讨论防火墙时所考虑的大部分功能。
NAT表(NAT Table)
nat
表用于实现网络地址转换规则。当数据包进入网络堆栈时,该表中的规则将决定是否以及如何修改数据包的源地址或目标地址,以影响数据包和任何响应流量的路由方式。这通常用于在直接访问不可能时将数据包路由到网络。
损坏表(Mangle Table)
mangle
表用于以各种方式更改数据包的IP头。例如,您可以调整数据包的TTL(生存时间)值,从而延长或缩短数据包可以维持的有效网络跳数。其他IP头也可以以类似的方式进行更改。
该表还可以在数据包上放置内部内核“标记”,以便在其他表和其他网络工具中进一步处理。该标记不会触及实际数据包,而是将标记添加到内核对数据包的表示中。
原始表(Raw Table)
iptables
防火墙是有状态的,这意味着数据包根据其与先前数据包的关系进行评估。建立在netfilter
框架之上的连接跟踪功能允许iptables
将数据包视为正在进行的连接或会话的一部分,而不是作为一系列不相关的数据包流。连接跟踪逻辑通常在数据包到达网络接口后不久应用。
raw
表具有非常明确定义的功能。它的唯一目的是提供一种标记数据包以选择退出连接跟踪的机制。
安全表(Security Table)
security
表用于在数据包上设置内部SELinux安全上下文标记,这将影响SELinux或其他能够解释SELinux安全上下文的系统处理数据包的方式。这些标记可以根据每个数据包或每个连接应用。
链与表之间的关系
如果三个表都有PREROUTING
链,它们的评估顺序是怎样的?
下表指示了在从左到右读取时每个iptables
表中可用的链。例如,我们可以知道raw
表具有PREROUTING
和OUTPUT
链。从上到下读取时,它还显示了触发相关netfilter
挂钩时每个链被调用的顺序。
应该注意几点。在下面的表示中,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
扩展进行显著扩展。规则可以根据协议类型、目标或源地址、目标或源端口、目标或源网络、输入或输出接口、标头或连接状态等条件进行匹配。这些条件可以组合以创建区分不同流量的复杂规则集。
目标
“目标”指的是当数据包满足规则的匹配条件时触发的动作。目标通常分为两类:
- 终止目标:终止目标执行一个动作,该动作终止链内的评估,并将控制返回给
netfilter
钩子。根据提供的返回值,钩子可能丢弃数据包,或允许数据包继续到处理的下一阶段。 - 非终止目标:非终止目标执行一个动作,并在链内继续评估。虽然每个链最终必须返回最终的终止决定,但可以在此之前执行任意数量的非终止目标。
每个规则中目标的可用性取决于上下文。例如,表和链类型可能决定了可用的目标。规则中激活的扩展和匹配子句也可以影响目标的可用性。
跳转到用户定义的链
还有一类特殊的非终止目标:跳转目标。跳转目标是导致评估转移到不同链以进行额外处理的动作。我们已经介绍了与调用它们的netfilter
钩子相关联的内置链。然而,iptables
还允许管理员创建自己的链以进行组织。
规则可以像放置到内置链中一样放置到用户定义的链中。不同之处在于只能通过从规则“跳转”到它们来到达用户定义的链(它们本身没有在netfilter
钩子中注册)。
用户定义的链充当调用它们的链的扩展。例如,在用户定义的链中,如果到达规则列表的末尾,或者通过匹配规则激活了RETURN
目标,评估将返回到调用链。评估也可以跳转到其他用户定义的链。
这种结构允许更好的组织,并提供了更健壮的分支所需的框架。
IPTables 和连接跟踪
当我们讨论raw
表和连接状态匹配条件时,我们介绍了建立在netfilter
框架之上的连接跟踪系统。连接跟踪允许iptables
在进行连接的上下文中对数据包做出决策。连接跟踪系统为iptables
提供了执行“有状态”操作所需的功能。
连接跟踪应用在数据包进入网络堆栈后的很短时间内。只有raw
表链和一些合理性检查是在将数据包与连接关联之前执行的逻辑。
系统会检查每个数据包是否与一组现有连接相关。如果需要,它将更新连接的状态,并在必要时将新连接添加到系统中。在raw
链中标记为NOTRACK
目标的数据包将绕过连接跟踪例程。
可用状态
连接跟踪系统跟踪的连接将处于以下状态之一:
NEW
:当到达一个不与现有连接关联但不是作为第一个数据包无效的数据包时,将向系统添加一个带有此标签的新连接。这适用于TCP等连接感知协议以及UDP等无连接协议。ESTABLISHED
:当连接在相反方向接收到有效响应时,将连接从NEW
更改为ESTABLISHED
。对于TCP连接,这意味着SYN/ACK
,对于UDP和ICMP流量,这意味着源和目标的原始数据包被交换的响应。RELATED
:不属于现有连接但与系统中已有连接相关联的数据包被标记为RELATED
。这可能意味着辅助连接,如FTP数据传输连接的情况,或者可能是其他协议尝试连接的ICMP响应。INVALID
:如果数据包不与现有连接相关,并且不适合打开新连接,或者无法识别,或者无法路由等其他原因,数据包可能会被标记为INVALID
。UNTRACKED
:如果在raw
表链中被标记为UNTRACKED
,则数据包可能会被标记为UNTRACKED
以绕过跟踪。SNAT
:当源地址已经通过NAT操作更改时,将设置为虚拟状态SNAT
。这是由连接跟踪系统使用的,以便它知道在回复数据包时要将源地址更改回来。DNAT
:当目标地址已经通过NAT操作更改时,将设置为虚拟状态DNAT
。这是由连接跟踪系统使用的,以便它知道在路由回复数据包时要将目标地址更改回来。
连接跟踪系统中跟踪的状态允许管理员制定针对连接生命周期中特定点的规则,从而提供了更全面和安全的规则所需的功能。
结论
netfilter
数据包过滤框架和 iptables
防火墙是大多数 Linux 服务器上防火墙解决方案的基础。netfilter
内核钩子与网络堆栈紧密结合,可以强大地控制系统处理数据包的过程。iptables
防火墙利用这些功能,提供了一种灵活、可扩展的方法来向内核传达策略要求。通过了解这些组件如何配合,您可以更好地利用它们来控制和保护服务器环境。
如果您想了解如何选择有效的 iptables
策略,请查看本指南。
以下指南可以帮助您开始实施 iptables
防火墙规则:
- 如何使用 Iptables 设置防火墙
- Iptables 基础知识:常见防火墙规则和命令
- 如何在 Ubuntu 22.04 上使用 UFW 设置防火墙
- 如何在 Rocky Linux 8 上使用 firewalld 设置防火墙
- 如何设置 Iptables 防火墙以保护服务器之间的流量