跳转到主要内容

iptables 的表和链

写这玩意的时候头昏,建议看原文。

到底什么是 iptables?

你以为 iptables 就是基于 netfilter 的古老工具?

其实 iptables 有两个变体:

  • legacy 通常被称为 iptables-legacy 基于 netfilter;
  • nf_tables 通常被称为 iptables-nft 基于 nftable;

 

执行 iptables -V 如果得到的结果中有 (nf_tables) 那么这是基于nftable 的新式 iptables。
这是 iptables-legacy:

# iptables -V
iptables v1.4.21

这是 iptables-nft:

# iptables -V
iptables v1.8.4 (nf_tables)

 

执行 ls -al /usr/sbin/iptables 

这是 iptables-legacy:

# ls -al /usr/sbin/iptables
lrwxrwxrwx. 1 root root 13 1月  28 2021 /usr/sbin/iptables -> xtables-multi

这是 iptables-nft:

# ls -al /usr/sbin/iptables
lrwxrwxrwx 1 root root 17 11月 23 2022 /usr/sbin/iptables -> xtables-nft-multi


 

 

+--------------+     +--------------+     +--------------+
|   iptables   |     |   iptables   |     |     nft      |   USER
|    legacy    |     |     nft      |     |  (nftables)  |   SPACE
+--------------+     +--------------+     +--------------+
       |                          |         |
====== | ===== KERNEL API ======= | ======= | =====================
       |                          |         |
+--------------+               +--------------+
|   iptables   |               |   nftables   |              KERNEL
|      API     |               |     API      |              SPACE
+--------------+               +--------------+
             |                    |         |
             |                    |         |
          +--------------+        |         |     +--------------+
          |   xtables    |--------+         +-----|   nftables   |
          |    match     |                        |    match     |
          +--------------+                        +--------------+

所以 iptables 是一个前端,它负责帮你操作真正的后端 nftables(一种内核数据包分类框架)或 netfilter。
目前基本已被 Firewalld 或 ufw 替代(吗?)。

以下内容按照 CC BY-NC-SA 4.0  协议,主要参考、翻译自 https://www.digitalocean.com/community/tutorials/a-deep-dive-into-iptables-and-netfilter-architecture 有修改 ,作者 Justin Ellingwood

Netfilter Hooks

netfilter 提供了 5 个 hook 点。包经过协议栈时会触发内核模块注册在这里的处理函数 。触发哪个 hook 取决于包的方向(ingress/egress)、包的目的地址、包在上一个 hook 点是被丢弃还是拒绝等等。

nftables 重用了现有的 netfilter 子系统,例如现有的 hook 基础设施、连接跟踪系统、NAT、用户空间队列和日志子系统。
因此 nftables 中的 hook 也是相同的。

nftfilter 中有 5 个 hook:

  • NF_IP_PRE_ROUTING:收到的包进入协议栈后立即触发此 hook,在进行任何路由判断 (将包发往哪里)之前;
  • NF_IP_LOCAL_IN:接收到的包经过路由判断,如果目的是本机,将触发此 hook;
  • NF_IP_FORWARD:接收到的包经过路由判断,如果目的是其他机器,将触发此 hook;
  • NF_IP_LOCAL_OUT:本机产生的准备发送的包,在进入协议栈后立即触发此 hook;
  • NF_IP_POST_ROUTING:本机产生的准备发送的包或者转发的包,在经过路由判断之后, 将触发此 hook;

注册处理函数时必须提供优先级,以便 hook 触发时能按照优先级高低调用处理函数。
于是多个模块(或者同一内核模块的多个实例)可以在同一 hook 点注册,并且有确定的处理顺序。内核模块会依次被调用,每次返回一个结果给 netfilter 框架,提示该对这个包做什么操作。

--->[NF_IP_PRE_ROUTING]--->[ROUTE]--->[NF_IP_FORWARD]--->[NF_IP_POST_ROUTING]--->
                              |                        ^
                              |                        |
                              |                     [ROUTE]
                              v                        |
                       [NF_IP_LOCAL_IN]        [NF_IP_LOCAL_OUT]
                              |                        ^
                              |                        |
                              v                        |

iptables 表和链(Tables and Chains)

iptables 使用 table 来组织规则,这些 table 根据它们用于做出的决策类型对规则进行分类。
例如:如果规则处理网络地址转换,它将被放入 nat table;
如果是判断是否允许包继续到达其目的地,那可能会添加到 filter table;

在每个 table 内部,规则被进一步组织在单独 chain 中,虽然 table 是由它们所持有的规则的一般目的来定义的,但内置 chain 代表了触发它们的 netfilter hook。chain 决定了规则何时会被评估。

有 5 个预定义 table:

  • Filter: 是一个默认的规则表,用于报文的过滤。注册了三个链: INPUTFORWARDOUTPUT
  • NAT: 主要用于NAT转换,注册了四个链:PREROUTINGINPUTOUTPUTPOSTROUTING
  • Mangle: 用于以各种方式修改数据包的 IP 头,一共注册了五个链: PREROUTINGOUTPUTINPUTFORWARDPOSTROUTING
  • Raw: 可以不对报文进行链路跟踪,其优先级在 hook 中注册很高,注册了两个链: PREROUTINGOUTPUT
  • Security: 用于设置内部 SELinux 安全上下文标记,注册了三个链:INPUTOUTPUT 和 FORWARD

有 5 个预定义 china,且名字与 netfilter hook 名字一一对应:

  • PREROUTING:由 NF_IP_PRE_ROUTING hook 触发;
  • INPUT:由 NF_IP_LOCAL_IN hook 触发;
  • FORWARD:由 NF_IP_FORWARD hook 触发;
  • OUTPUT:由 NF_IP_LOCAL_OUT hook 触发;
  • POSTROUTING:由 NF_IP_POST_ROUTING hook 触发;

china 允许管理员控制在数据包传递路径中的何处评估规则。由于每个table 都有多个 chain,一个 table 可以在处理中的多个点施加影响。
因为某些类型的决策仅在网络堆栈中的某些点有意义,所以 table 内不会有一个 chain 注册到所有 kernel hook。

链表关系(Relationships Between Chains and Tables)

如果三个表有 PREROUTING 链,它们的计算顺序是什么?

下表指示从左到右阅读时每个表中可用的链。例如,我们可以看出该 raw 表同时具有 PREROUTING 和 OUTPUT 链。
当从上到下阅读时,它还会显示触发关联 netfilter hook 时调用每个链的顺序。

table↓/chain→ PREROUTING INPUT FORWARD OUTPUT POSTROUTING
(路由决策)        
RAW      
(启用连接跟踪)      
Mangle
NAT(DNAT)      
(路由决策)      
Filter    
Security    
NAT(SNAT)      

主要参考