iptables 是一个功能强大的工具,用于管理 Linux 系统中的网络流量。它允许管理员通过设置规则来决定哪些数据包可以进入、离开或通过系统,从而增强网络安全。iptables 主要用于 IPv4(IPv6 使用 ip6tables),通过定义规则来过滤、修改或转发网络数据包。

尽管 iptables 被认为是传统工具,nftables 作为其现代替代品提供了更多功能,但 iptables 因其成熟性和广泛支持仍被广泛使用。

iptables发展历史

2.1. 前身:ipfwadm 和 ipchains

iptables 出现之前,Linux 系统也存在其他的防火墙解决方案。其中,在 Linux 内核 2.0.x 版本中广泛使用的是 ipfwadm,而在 Linux 内核 2.2.x 版本中则被 ipchains 所取代 。这些早期的工具与 iptables 不同,它们直接修改内核的网络代码来实现数据包的控制 。这种直接操作的方式使得这些工具的灵活性和可扩展性受到一定的限制,并且在管理复杂的防火墙策略时可能会显得不够高效。  

值得一提的是,ipfwadmipchains 的设计思想借鉴了 BSD 系统中的 ipfw 防火墙 。这表明在操作系统的发展过程中,网络安全理念和技术的相互借鉴和演进是一个常见的现象。早期 Linux 防火墙工具的发展为后续更加完善的 iptables 的出现奠定了基础。  

由于早期的 Linux 内核缺乏一个通用的数据包控制框架,ipfwadmipchains 需要直接修改网络代码来操纵数据包 。这种实现方式的不足之处在于,它使得防火墙的功能与内核的特定版本紧密耦合,升级内核时可能需要对防火墙配置进行相应的调整。此外,直接修改内核代码也增加了潜在的风险。  

2.2. Netfilter 和 iptables 的诞生

为了克服早期防火墙工具的局限性,Rusty Russell 于 1998 年启动了 Netfilter 项目 。Netfilter 是 Linux 内核中的一个框架,它提供了一种更为结构化的方法来处理网络数据包 。这个框架通过在内核网络堆栈的关键点设置钩子(hooks),允许注册的模块在数据包流经这些点时执行特定的操作,例如过滤、修改或转发 。iptables 就是构建在 Netfilter 框架之上的用户空间工具,它通过配置 Netfilter 模块中的规则来控制网络流量 。  

Netfilter 项目于 1999 年 8 月 26 日被合并到 Linux 内核 2.3.15 版本中 ,并在 2001 年随 Linux 内核 2.4.0 稳定版正式发布 。iptables 的出现标志着 Linux 防火墙技术进入了一个新的时代,它以其灵活性、可扩展性和强大的功能迅速取代了之前的 ipchains 。  

Netfilter 框架的一个重要设计理念是将数据包操作分离成多个独立的部分,例如包过滤和网络地址转换(NAT)。这与 ipchainsipfwadm 将这些功能混合在一起的做法不同。Netfilter 的连接跟踪和 NAT 子系统也比早期工具中的相应功能更加通用和强大 。  

2.3. 关键里程碑和发展

1999 年,随着 Netfilter 项目的不断发展,Rusty Russell 成立了 Netfilter 核心团队 。最初的成员包括 Marc Boucher 等 。核心团队负责 Netfilter 和 iptables 的开发和维护工作。随着时间的推移,Netfilter 项目涌现出许多重要的贡献者,其中一些关键人物包括 Harald Welte 和 Patrick McHardy,他们先后领导了核心团队 。他们对 Netfilter 项目的持续发展和壮大起到了至关重要的作用。  

即使在 nftables 出现之后,iptables 仍然在不断进行维护和更新。例如,根据最新的信息 ,iptables 的稳定版本 1.8.11 于 2024 年 11 月 8 日发布。此外,从 Netfilter 项目的官方网站 可以看到,iptables 的各个版本仍在持续发布,这表明该工具仍在被广泛使用和积极维护。这可能是因为 iptables 在许多现有的 Linux 系统中仍然是默认的防火墙管理工具,并且许多系统管理员已经熟悉其使用方法。  

2.4. nftables 的出现

尽管 iptables 非常强大,但随着网络技术的发展和安全需求的日益复杂,其固有的某些限制也逐渐显现出来。为了解决这些问题,Netfilter 项目于 2014 年发布了 nftables,并将其合并到 Linux 内核 3.13 版本中 。nftables 被设计为 iptables 的后继者,旨在提供更灵活、更具扩展性和更高性能的包分类功能 。  

nftables 的出现并非意味着 iptables 会立即消失。事实上,iptables 在许多系统中仍然被广泛使用。然而,nftables 代表了 Linux 防火墙技术的未来发展方向,它在语法、性能和功能上都带来了显著的改进。

基本概念

理解 iptables 如何工作的关键是这张。图中在上面的小写字母代表,在下面的大写字母代表从任何网络端口进来的每一个 IP 数据包都要从上到下的穿过这张图。一种常见的错误认知是认为 iptables 对从内部端口进入的数据包和从面向互联网端口进入的数据包采取不同的处理方式,相反,iptables 对从任何端口进入的数据包都会采取相同的处理方式。可以定义规则使 iptables 采取不同的方式对待从不同端口进入的数据包。当然一些数据包是用于本地进程的,因此在图中表现为从顶端进入,到 <Local Process> 停止,而另一些数据包是由本地进程生成的,因此在图中表现为从 <Local Process> 发出,一直向下穿过该流程图。一份关于该流程图如何工作的详细解释请参考这里

在大多数使用情况下都不会用到 rawmanglesecurity 表。下图简要描述了网络数据包通过 iptables 的过程:

                               XXXXXXXXXXXXXXXXXX
                             XXX     Network    XXX
                               XXXXXXXXXXXXXXXXXX
                                       +
                                       |
                                       v
 +-------------+              +------------------+
 |table: filter| <---+        | table: nat       |
 |chain: INPUT |     |        | chain: PREROUTING|
 +-----+-------+     |        +--------+---------+
       |             |                 |
       v             |                 v
 [local process]     |           ****************          +--------------+
       |             +---------+ Routing decision +------> |table: filter |
       v                         ****************          |chain: FORWARD|
****************                                           +------+-------+
Routing decision                                                  |
****************                                                  |
       |                                                          |
       v                        ****************                  |
+-------------+       +------>  Routing decision  <---------------+
|table: nat   |       |         ****************
|chain: OUTPUT|       |               +
+-----+-------+       |               |
      |               |               v
      v               |      +-------------------+
+--------------+      |      | table: nat        |
|table: filter | +----+      | chain: POSTROUTING|
|chain: OUTPUT |             +--------+----------+
+--------------+                      |
                                      v
                               XXXXXXXXXXXXXXXXXX
                             XXX    Network     XXX
                               XXXXXXXXXXXXXXXXXX

1. 表(Tables)

iptables 使用不同的表来组织规则,每张表有特定的用途:

  1. filter:这是最常用的表,主要用于实现无状态的包过滤 。它根据数据包的源地址、目标地址、端口号、协议类型等信息来决定是否允许(ACCEPT)或拒绝(DROP 或 REJECT)数据包通过。

  2. nat:用于网络地址转换(Network Address Translation),包括 SNAT(源地址转换)、DNAT(目标地址转换)和 MASQUERADE。这在例如多个内网主机共享一个公网 IP 地址的场景中非常有用。

  3. mangle:用于修改数据包的头部信息 ,例如修改数据包的生存时间(TTL)或服务类型(TOS)字段。这个表通常用于实现服务质量(Quality of Service, QoS)等更高级的网络功能。

  4. raw:用于绕过连接跟踪的特殊处理。

  5. security:用于强制访问控制(Mandatory Access Control),如 SELinux。

大部分情况仅需要使用 filternat。其他表用于更复杂的情况——包括多路由和路由判定。

需要注意的是,如果在执行 iptables 命令时没有使用 -t 选项指定表名,则默认操作的是 filter 表 。  

表名

用途

常见的预定义链

filter

无状态包过滤(允许/拒绝数据包)

INPUT, FORWARD, OUTPUT

nat

网络地址转换(修改源/目标 IP 地址和端口)

PREROUTING, POSTROUTING, OUTPUT

mangle

修改数据包头部信息

PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING

2. 链(Chains)

每张表包含若干链,链是规则的序列,决定数据包的处理方式。iptables预定义的链包括:

  1. INPUT:这个链处理目标地址是本机的数据包 。它控制着哪些外部流量可以访问运行在本机上的服务。

  2. OUTPUT: 这个链处理从本机发出的数据包 。它控制着本机上的程序可以访问哪些外部网络资源。  

  3. FORWARD:当系统作为路由器时,所有需要通过本机转发的数据包都会经过这个链 。它控制着哪些流量可以从一个网络接口转发到另一个网络接口。

  4. PREROUTING:数据包进入系统后,在进行路由决策之前会首先进入这个链 。通常用于执行目标 NAT(DNAT),即将发往本机特定端口的数据包转发到内网的某个主机。

  5. POSTROUTING: 在进行路由决策之后,数据包在即将离开网络接口之前会进入这个链 。通常用于执行源 NAT(SNAT)或地址伪装(MASQUERADE),使得内网主机可以通过一个共享的公网 IP 地址访问互联网。

每个预定义的链都有一个默认策略(Policy),例如 ACCEPT(允许)或 DROP(丢弃)。当一个数据包流经某个链的所有规则后仍然没有匹配任何规则时,就会执行该链的默认策略 。设置一个安全的默认策略(通常是 DROP)对于保护系统至关重要。

3. 规则(Rules):

每条规则由以下部分组成:

  • 匹配(Matches):数据包必须满足的条件,例如源 IP 地址、目标端口或协议。

  • 目标(Targets):匹配数据包后执行的操作,例如:

    • ACCEPT:允许数据包通过。

    • DROP:丢弃数据包,不通知发送方。

    • REJECT:丢弃数据包并返回错误响应。

    • LOG:记录数据包信息到日志文件。

    • SNAT/DNAT:修改数据包的源或目标地址。

  • 规则按顺序评估,第一个匹配的规则决定数据包的处理方式。

4. 默认策略(Default Policy)

每个链有一个默认策略(通常为 ACCEPT 或 DROP),当数据包不匹配任何规则时应用。

使用规则

1. 规则的结构

一条 iptables 规则由匹配条件(matches)和动作(target 或 verdict)组成 。匹配条件用于定义哪些数据包会受到这条规则的影响,而动作则定义了当数据包满足匹配条件时应该执行的操作。  

当一个数据包进入一个链时,iptables 会按照链中规则的顺序逐条检查该数据包是否满足当前规则的匹配条件 。如果一个规则的匹配条件不满足,则该数据包会继续与链中的下一条规则进行匹配 。

如果一个数据包满足了某条规则的所有匹配条件,那么 iptables 就会执行该规则指定的动作 。这个动作可能是允许数据包继续流向下一个规则,也可能是停止数据包的进一步处理。

2. 常用的匹配模块和选项

为了提供更灵活的匹配能力,iptables 允许使用各种匹配模块(match modules) 。这些模块可以扩展 iptables 的匹配功能,例如根据 TCP、UDP 协议的特定字段或连接状态进行匹配。常用的匹配模块包括:  

  • -m tcp:用于匹配 TCP 协议的数据包。可以使用 --sport 指定源端口,--dport 指定目标端口,--tcp-flags 指定 TCP 标志位等选项。

  • -m udp:用于匹配 UDP 协议的数据包。可以使用 --sport 指定源端口,--dport 指定目标端口。

  • -m state:用于根据连接状态匹配数据包。常用的状态包括 NEW(新的连接)、ESTABLISHED(已建立的连接)、RELATED(与已有连接相关的连接)等。

  • -m iprange:用于匹配指定 IP 地址范围的数据包。

  • -m mac:用于匹配指定源 MAC 地址的数据包。

除了使用匹配模块,还可以直接使用一些基本的匹配选项,例如:

  • -s <源 IP 地址或网络>:匹配来自指定源 IP 地址或网络的数据包。

  • -d <目标 IP 地址或网络>:匹配发往指定目标 IP 地址或网络的数据包。

  • -p <协议>:匹配指定协议类型的数据包,例如 tcpudpicmp 等。

  • -i <输入接口>:匹配通过指定网络接口进入的数据包。

  • -o <输出接口>:匹配通过指定网络接口发出的数据包。

3. 内建目标(Built-in Targets)和判决(Verdicts)

当一个数据包匹配到一条规则时,会执行该规则指定的动作,这个动作被称为目标(target)。iptables 提供了一些内建的目标和判决(verdicts) :  

  • ACCEPT 允许数据包通过,停止在该链中的进一步处理。

  • DROP 静默地丢弃数据包,不给发送方任何通知,停止在该链中的进一步处理。

  • REJECT 丢弃数据包,并向发送方发送一个拒绝报文(例如,对于 TCP 连接,发送 RST 包;对于 UDP 或 ICMP,发送 ICMP port unreachable 或 ICMP host unreachable 消息),停止在该链中的进一步处理。

  • LOG 将数据包的相关信息记录到系统日志中,然后继续在该链中执行下一条规则 。可以使用 --log-prefix 选项指定日志消息的前缀,方便在日志中识别 iptables 的日志 。还可以使用 --log-level 选项指定日志的级别 。  

  • JUMP <链名> 将数据包的处理流程跳转到指定的链(可以是预定义链或用户自定义链) 。跳转后,会从目标链的第一条规则开始执行。  

  • GOTO <链名>JUMP 类似,也是将数据包的处理流程跳转到指定的链 。但不同的是,GOTO 跳转后不会返回到原来的链。  

目标/判决

描述

典型应用场景

ACCEPT

允许数据包通过,停止在该链中的进一步处理。

允许特定的入站或出站连接。

DROP

静默地丢弃数据包,不给发送方任何通知,停止在该链中的进一步处理。

阻止不需要或恶意的流量,不希望告知发送方被阻止。

REJECT

丢弃数据包,并向发送方发送一个拒绝报文,停止在该链中的进一步处理。

明确拒绝连接,并告知发送方连接被拒绝。

LOG

将数据包的相关信息记录到系统日志中,然后继续在该链中执行下一条规则。

审计防火墙活动,监控可疑流量,故障排除。

JUMP <链名>

将数据包的处理流程跳转到指定的链(可以是预定义链或用户自定义链)。

创建更复杂的规则流程,将相关的规则组织到一起。

GOTO <链名>

将数据包的处理流程跳转到指定的链(可以是预定义链或用户自定义链),不返回。

用于特定的控制流场景,例如在某个条件满足时完全切换到另一组规则进行处理。

常见的 iptables 命令和用法

1. 列出规则

使用 iptables -L 命令可以列出当前 iptables 中的所有规则 。常用的选项包括:  

  • -n:以数字格式显示 IP 地址和端口号,而不是尝试解析主机名和服务名。这可以加快命令的执行速度。

  • -v:显示详细输出,包括每个规则匹配的数据包和字节计数。

  • --line-numbers:显示链中每个规则的行号,这在删除或修改特定规则时非常有用。

  • -t <table>:指定要列出规则的表,例如 iptables -L -t nat 列出 nat 表中的规则。如果省略 -t 选项,则默认列出 filter 表中的规则 。  

  • -S:以可以被 iptables 命令直接使用的格式显示规则。

  • -F <链名>:仅列出指定链中的规则,例如 iptables -L INPUT 列出 filter 表中 INPUT 链的规则。

2. 添加新规则

  • iptables -A <链名> <匹配条件> -j <目标>:将一条新规则追加到指定链的末尾。例如,iptables -A INPUT -p tcp --dport 22 -j ACCEPT 表示允许来自任何地址的 TCP 流量访问本机的 22 端口。

  • iptables -I <链名> [<规则序号>] <匹配条件> -j <目标>:将一条新规则插入到指定链的指定位置。如果省略规则序号,则默认插入到链的第一个位置。例如,iptables -I INPUT 1 -s 192.168.1.100 -j DROP 表示将阻止来自 IP 地址 192.168.1.100 的所有入站流量,并将其放在 INPUT 链的第一条规则。

3. 删除规则

  • iptables -D <链名> <规则序号>:根据规则的行号删除指定链中的规则。需要先使用 iptables -L --line-numbers 命令查看规则的行号。例如,要删除 INPUT 链中行号为 3 的规则,可以使用 iptables -D INPUT 3

  • iptables -D <链名> <匹配条件> -j <目标>:根据规则的匹配条件和目标删除规则。需要指定与要删除的规则完全相同的匹配条件和目标。例如,要删除之前添加的允许 TCP 流量访问 22 端口的规则,可以使用 iptables -D INPUT -p tcp --dport 22 -j ACCEPT

4. 修改规则

iptables -R <链名> <规则序号> <匹配条件> -j <目标>:替换指定链中指定行号的规则。例如,要将 INPUT 链中行号为 1 的规则替换为允许来自 IP 地址 192.168.1.100 的 TCP 流量访问本机的 80 端口,可以使用 iptables -R INPUT 1 -s 192.168.1.100 -p tcp --dport 80 -j ACCEPT

5. 设置默认策略

iptables -P <链名> <策略>:设置指定预定义链的默认策略。常用的策略有 ACCEPTDROP。例如,iptables -P INPUT DROP 表示将 INPUT 链的默认策略设置为丢弃所有未匹配到任何规则的入站流量。这是一个重要的安全措施。

6. 管理用户自定义链

  • iptables -N <链名>:创建一个新的用户自定义链 。例如,iptables -N CUSTOM_CHAIN 创建一个名为 CUSTOM_CHAIN 的新链。  

  • iptables -X <链名>:删除一个空的用户自定义链 。只有当该链中没有任何规则,并且没有被其他链引用时才能被删除。例如,iptables -X CUSTOM_CHAIN 删除名为 CUSTOM_CHAIN 的链。  

  • iptables -E <旧链名> <新链名>:重命名一个用户自定义链。

7. 清空规则

iptables -F [<链名>]:清空指定链中的所有规则。如果省略链名,则清空所有表中的所有链的所有规则 。例如,iptables -F INPUT 清空 filter 表中 INPUT 链的所有规则,而 iptables -F 则清空所有规则。  

8. 保存和恢复规则集

iptables 中配置的规则在系统重启后会丢失。为了使规则持久化,需要将当前的规则集保存到文件中,并在系统启动时恢复。

  • 保存规则: 可以使用 iptables-save 命令将当前的规则集保存到文件中。例如,sudo iptables-save > /etc/iptables/rules.v4 将 IPv4 的规则保存到 /etc/iptables/rules.v4 文件中。对于 IPv6,可以使用 ip6tables-save > /etc/iptables/rules.v6

  • 恢复规则: 可以使用 iptables-restore 命令从文件中加载规则集。例如,sudo iptables-restore < /etc/iptables/rules.v4/etc/iptables/rules.v4 文件中恢复 IPv4 的规则。对于 IPv6,可以使用 ip6tables-restore < /etc/iptables/rules.v6

不同的 Linux 发行版可能有不同的机制来自动保存和恢复 iptables 规则。通常会提供相应的服务或脚本来管理这些操作。

实际应用案例和示例

1. 允许入站 SSH 连接

要允许来自任何 IP 地址的 TCP 流量访问本机的 22 端口(SSH 服务),可以使用以下命令:

sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

这条命令将一条规则追加到 filter 表的 INPUT 链中。-p tcp 指定了协议为 TCP,--dport 22 指定了目标端口为 22,-j ACCEPT 指定了动作为允许连接。

2. 允许 Web 流量

要允许入站的 HTTP(80 端口)和 HTTPS(443 端口)流量,可以使用以下命令:

sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

这两条命令分别允许 TCP 协议访问本机的 80 端口和 443 端口,这是 Web 服务器常用的端口。

3. 阻止特定 IP 地址或网段的流量

要阻止来自特定 IP 地址(例如 192.168.1.100)的所有流量,可以使用以下命令:

sudo iptables -A INPUT -s 192.168.1.100 -j DROP

这条命令将丢弃所有源 IP 地址为 192.168.1.100 的入站流量。同样,可以使用 -d 选项阻止发往特定目标 IP 地址或网段的流量。需要注意的是,在不同的链中阻止流量可能会有不同的效果。在 INPUT 链中阻止会阻止进入本机的数据包,而在 FORWARD 链中阻止会阻止通过本机转发的数据包。

4. 为内部服务进行端口转发

假设内网有一台 IP 地址为 192.168.1.10 的 Web 服务器,希望通过公网 IP 的 8080 端口访问该服务器。可以在作为网关的 Linux 主机上使用以下命令进行端口转发:

sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.10:80
sudo iptables -t nat -A POSTROUTING -j MASQUERADE

第一条命令在 nat 表的 PREROUTING 链中添加一条规则,将所有发往本机 8080 端口的 TCP 流量转发到 192.168.1.10 的 80 端口。第二条命令在 nat 表的 POSTROUTING 链中启用地址伪装,确保内网主机可以通过网关的公网 IP 地址响应外部请求。

5. 实现基本的网络地址转换(NAT)

如果一个 Linux 系统作为局域网的网关,并且只有一个公网 IP 地址,可以使用 iptables 实现 NAT,使得局域网内的所有主机都可以通过该公网 IP 地址访问互联网:

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

这条命令在 nat 表的 POSTROUTING 链中添加一条规则,对所有通过 eth0 接口(假设这是连接到公网的接口)发出的流量进行地址伪装。这样,局域网内的所有主机发出的数据包的源 IP 地址都会被替换为网关的公网 IP 地址。

向 nftables 的过渡

1. nftables 简介

nftables 是 Netfilter 项目的下一代包过滤框架,旨在取代 iptables 。它自 Linux 内核 3.13 版本(2014 年发布)开始可用 。  

2. 主要区别和优势

iptables 相比,nftables 具有一些显著的优势 :  

  • 统一的语法: nftables 使用一个统一的命令行工具 nft 和一套统一的语法来管理不同协议(IPv4、IPv6、ARP、以太网桥接)的规则,而 iptables 则需要使用不同的工具(iptablesip6tablesarptablesebtables)。

  • 更高的性能: nftables 在处理大型规则集时通常比 iptables 更有效率。

  • 更灵活的规则管理: nftables 允许创建用户自定义的表,并且可以为每个表配置不同的钩子和优先级,提供了更灵活的规则组织方式。

  • 更好的扩展性: nftables 的设计更加模块化,更容易进行功能扩展。

3. 共存和兼容性

iptablesnftables 可以同时安装在同一个系统中 ,并且通常会提供一些兼容性层,使得一些基于 iptables 的脚本和工具仍然可以工作。然而,为了避免潜在的冲突和混淆,通常建议选择其中一种防火墙管理工具进行配置。对于新的系统,推荐使用 nftables,因为它代表了 Linux 防火墙技术的未来发展方向。  

功能特性

iptables

nftables

命令行工具

iptables, ip6tables, arptables, ebtables

nft

内核版本要求

2.4+

3.13+

语法

表特定的命令和选项

统一的语法

灵活性

相对较低

更高

性能

大型规则集下可能效率较低

通常更高效

对象

有限的预定义表和链

用户自定义表,可配置钩子

结论

iptables 作为 Linux 系统中一款经典且功能强大的防火墙管理工具,在网络安全领域发挥着至关重要的作用。它通过配置内核中的 Netfilter 框架,实现了对网络流量的细粒度控制。理解 iptables 的基本概念、核心功能和常用命令,对于系统管理员来说是必备的技能。

尽管 iptables 已经存在了很长时间,并且在许多系统中仍然被广泛使用 ,但其后继者 nftables 的出现代表了 Linux 防火墙技术的未来发展趋势。nftables 以其更灵活的架构、更高效的性能和更统一的语法,为系统管理员提供了更强大的网络安全管理能力。然而,由于 iptables 在现有系统中仍然占据着重要的地位,并且拥有大量的用户基础,因此掌握 iptables 的相关知识在未来一段时间内仍然具有重要的意义。