强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

iptables 完全指南 / 第 01 章:Netfilter 架构与 iptables 历史

第 01 章:Netfilter 架构与 iptables 历史

本章目标:理解 Linux 数据包过滤的内核基础,掌握 iptables 的定位,了解 nftables 的演进方向。


1.1 Netfilter 框架概述

Netfilter 是 Linux 内核中的一个包过滤框架,它在内核网络协议栈的多个位置插入了钩子点(Hook Points),允许模块化的代码对经过的数据包进行检查、修改或丢弃。

1.1.1 Netfilter 的设计哲学

Netfilter 的核心设计理念是可扩展性。它不直接提供防火墙功能,而是提供一套基础设施:

用户态工具(iptables / nft)
        │
        ▼
┌─────────────────────────────────────┐
│          Netfilter 框架              │
│  ┌──────────────────────────────┐   │
│  │  钩子点 (Hook Points)        │   │
│  │  ┌──────┐ ┌──────┐ ┌──────┐ │   │
│  │  │ PRER │ │FORWD│ │ POST │ │   │
│  │  │OUTING│ │      │ │ROUTNG│ │   │
│  │  └──────┘ └──────┘ └──────┘ │   │
│  │  ┌──────┐ ┌──────┐          │   │
│  │  │INPUT │ │OUTPUT│          │   │
│  │  └──────┘ └──────┘          │   │
│  └──────────────────────────────┘   │
│  ┌──────────────────────────────┐   │
│  │  表 (Tables)                 │   │
│  │  raw → mangle → nat → filter │   │
│  └──────────────────────────────┘   │
└─────────────────────────────────────┘
        │
        ▼
   网络协议栈继续处理

1.1.2 五个钩子点

Netfilter 定义了五个标准钩子点,数据包在内核协议栈中流经这些点时,会触发注册在该钩子上的处理函数:

钩子点触发时机典型用途
NF_INET_PRE_ROUTING数据包进入路由决策之前DNAT、连接跟踪入口
NF_INET_LOCAL_IN数据包目的是本机INPUT 链过滤
NF_INET_FORWARD数据包需要转发FORWARD 链过滤
NF_INET_LOCAL_OUT本机产生的数据包OUTPUT 链过滤
NF_INET_POST_ROUTING数据包离开路由决策之后SNAT、MASQUERADE

1.1.3 数据包流向图

                        ┌─────────────────────────────────────────────┐
                        │                本机进程                      │
                        │          ┌──────────────┐                   │
                        │          │  应用程序     │                   │
                        │          └──────┬───────┘                   │
                        │                 │ OUTPUT                    │
                        │                 ▼                           │
                        │          ┌──────────────┐                   │
                        │          │  路由决策     │                   │
                        │          └──────┬───────┘                   │
                        │                 │                           │
                        │                 ▼                           │
 ┌────────┐     ┌───────┴──────┐   ┌──────────────┐   ┌──────────┐ │
 │ 网络   │────→│PRE_ROUTING   │──→│  路由决策     │──→│POST_ROUTING│─→│ 网络
 │ 接口   │     └──────────────┘   └──────┬───────┘   └──────────┘ │ │ 接口
 └────────┘                               │                         │
                                          ▼                         │
                                   ┌──────────────┐                 │
                                   │   INPUT       │                 │
                                   └──────┬───────┘                 │
                                          │                         │
                                          ▼                         │
                                   ┌──────────────┐                 │
                                   │  本机进程     │                 │
                                   └──────────────┘                 │
                                                                    │
                        ┌───────────────────────────────────────────┘
                        │
                        │  FORWARD(转发)
                        ▼
                 ┌──────────────┐
                 │  路由决策     │──→ POST_ROUTING → 网络接口
                 └──────────────┘

关键理解:数据包的"命运"在路由决策那一刻确定——是发给本机(INPUT),还是转发给其他主机(FORWARD),还是由本机发出(OUTPUT)。


1.2 iptables 的历史演进

1.2.1 从 ipchains 到 iptables

时间事件说明
1995 年ipfwadmLinux 2.0 时代的防火墙工具
1999 年ipchainsLinux 2.2,引入链的概念,但不支持有状态过滤
2000 年iptablesLinux 2.4,引入表的概念、有状态过滤、NAT
2001 年Netfilter 子系统正式并入内核主线
2008 年conntrack 改进连接跟踪性能大幅优化
2014 年nftablesLinux 3.13,新一代包过滤框架进入内核
2018 年iptables 标记为 “legacy”nftables 成为推荐方案
2020 年+并存期大多数发行版同时支持两者

1.2.2 iptables 的版本和变体

变体说明使用场景
iptables经典版本,操作 IPv4传统服务器
ip6tables操作 IPv6IPv6 防火墙
arptables操作 ARP 协议ARP 过滤
ebtables操作以太网帧桥接网络过滤
iptables-nftnftables 后端 + iptables 语法过渡期兼容

注意:在较新的发行版(如 Debian 10+、Ubuntu 20.04+、RHEL 8+)中,iptables 命令实际上是 iptables-nft,底层使用 nftables 内核 API。


1.3 iptables vs nftables 对比

1.3.1 架构差异

iptables 架构:
┌─────────────────────────────────────────┐
│  iptables  │ ip6tables │ arptables │ ebtables │  ← 用户态工具
├─────────────────────────────────────────┤
│  ip_tables │ ip6_tables │ arp_tables │ bridge │  ← 内核模块
├─────────────────────────────────────────┤
│              Netfilter 钩子               │
└─────────────────────────────────────────┘

nftables 架构:
┌─────────────────────────────────────────┐
│              nft 命令行工具               │  ← 统一用户态工具
├─────────────────────────────────────────┤
│           nf_tables 内核模块              │  ← 统一内核模块
├─────────────────────────────────────────┤
│              Netfilter 钩子               │
└─────────────────────────────────────────┘

1.3.2 功能对比

特性iptablesnftables
内核模块数量多个(ip_tables、iptable_filter 等)单一(nf_tables)
规则匹配线性扫描支持集合(set)和字典
原子操作不支持(需逐条操作)支持(整表替换)
自定义链有限支持原生支持
IPv4/IPv6需要两套工具统一处理
性能规则多时性能下降明显集合查找 O(1)
语法命令行参数类编程语言语法
调试有限内置追踪功能
生态成熟度非常成熟快速成熟中

1.3.3 语法对比示例

iptables 语法

# 允许 SSH 访问
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 允许已建立的连接
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# 默认拒绝
iptables -P INPUT DROP

等价的 nftables 语法

# 创建表和链
nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }

# 允许已建立的连接
nft add rule inet filter input ct state established,related accept

# 允许 SSH 访问
nft add rule inet filter input tcp dport 22 accept

1.4 适用场景分析

1.4.1 iptables 适用场景

场景说明推荐度
传统服务器运维现有规则体系成熟,文档丰富⭐⭐⭐⭐⭐
Docker/Kubernetes 环境容器平台深度依赖 iptables⭐⭐⭐⭐⭐
嵌入式设备内核较老,可能不支持 nftables⭐⭐⭐⭐
教学与学习概念清晰,资料多⭐⭐⭐⭐⭐
简单防火墙需求规则少、逻辑简单⭐⭐⭐⭐

1.4.2 nftables 适用场景

场景说明推荐度
新项目部署从零开始,无历史包袱⭐⭐⭐⭐⭐
大规模规则集集合查找性能优势明显⭐⭐⭐⭐⭐
多协议环境IPv4/IPv6 统一管理⭐⭐⭐⭐⭐
复杂策略需要编程式逻辑⭐⭐⭐⭐
高频规则变更原子操作,避免规则闪烁⭐⭐⭐⭐⭐

1.4.3 企业场景:如何选择?

                    ┌──────────────────┐
                    │  是否有现有 iptables │
                    │  规则需要维护?      │
                    └────────┬─────────┘
                       是 │        │ 否
                          ▼        ▼
                  ┌──────────┐  ┌──────────────┐
                  │ 保持      │  │ 内核版本 ≥3.13?│
                  │ iptables  │  └──────┬───────┘
                  └──────────┘     是 │      │ 否
                                     ▼      ▼
                              ┌────────┐  ┌──────────┐
                              │ 使用    │  │ 使用      │
                              │nftables│  │ iptables  │
                              └────────┘  └──────────┘

实际建议:如果你的环境中有 Docker,短期内不要急于迁移到 nftables,因为 Docker 的网络驱动(如 docker0br-xxx 桥接)高度依赖 iptables 的 natfilter 表。


1.5 Netfilter 内核模块体系

1.5.1 核心模块

模块功能
nf_tablesnftables 核心框架
nf_tables_inetnftables IPv4/IPv6 混合支持
ip_tablesiptables IPv4 核心
iptable_filterfilter 表实现
iptable_natnat 表实现
iptable_manglemangle 表实现
iptable_rawraw 表实现
nf_conntrack连接跟踪核心
nf_conntrack_ftpFTP 协议连接跟踪辅助

1.5.2 查看已加载模块

# 查看所有 Netfilter 相关模块
lsmod | grep -E "^(nf_|ipt_|xt_|ip6t_)"

# 典型输出示例:
# nf_conntrack          147456  4 xt_conntrack,nf_nat,nf_conntrack_netlink,xt_CHECKSUM
# nf_defrag_ipv6         16384  1 nf_conntrack
# nf_nat                 40960  2 nf_nat_masquerade_ipv4,nf_nat_ipv4
# ip_tables              28672  3 iptable_filter,iptable_mangle,iptable_raw
# xt_conntrack            16384  2
# xt_tcpudp              16384  8

1.5.3 加载必要的内核模块

# 手动加载连接跟踪模块
modprobe nf_conntrack
modprobe nf_conntrack_ipv4

# 加载 NAT 相关模块
modprobe nf_nat
modprobe nf_nat_masquerade_ipv4

# 开机自动加载
echo "nf_conntrack" >> /etc/modules-load.d/conntrack.conf
echo "nf_nat" >> /etc/modules-load.d/nat.conf

1.6 动手实验:观察 Netfilter 钩子

实验 1:用 tcpdump 观察数据包流向

# 终端 1:监听所有接口的 ICMP 包
sudo tcpdump -i any icmp -n

# 终端 2:ping 一个外部地址
ping -c 1 8.8.8.8

实验 2:查看当前内核的 Netfilter 配置

# 查看内核是否支持 Netfilter
grep CONFIG_NETFILTER /boot/config-$(uname -r) | head -20

# 查看当前运行的 conntrack 参数
sysctl -a | grep net.netfilter.nf_conntrack

实验 3:用 iptables -L 查看初始状态

# 查看所有链(初始状态应该是空的)
sudo iptables -L -n -v

# 典型输出:
# Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
#  pkts bytes target     prot opt in     out     source               destination
#
# Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
#  pkts bytes target     prot opt in     out     source               destination
#
# Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
#  pkts bytes target     prot opt in     out     source               destination

解读:默认策略是 ACCEPT,没有任何规则,所有数据包都被接受——这是一个完全开放的防火墙状态,生产环境必须加固。


1.7 注意事项

⚠️ 远程操作防火墙的风险:如果你通过 SSH 远程管理服务器,在添加 DROP 策略前,务必先添加允许 SSH 的规则,否则会立即断开连接。

# ❌ 危险操作:直接设置默认 DROP(远程会话将断开)
iptables -P INPUT DROP

# ✅ 正确做法:先添加允许规则
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -P INPUT DROP

⚠️ 内核版本兼容性:某些高级功能(如 hashlimitconnlimit)需要较新的内核版本和对应的 xt_* 模块。在生产环境使用前,先在测试环境验证模块是否可用。

⚠️ 容器环境注意:Docker、Podman 等容器运行时会自动插入大量 iptables 规则,手动修改 iptables 可能导致容器网络异常。


1.8 扩展阅读

资源链接说明
Netfilter 官方文档https://www.netfilter.org/documentation/权威参考
nftables Wikihttps://wiki.nftables.org/nftables 官方指南
Linux 内核源码 - Netfilterhttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/netfilter内核实现
《Linux 防火墙》(第4版)Michael Rash 著经典教材
Red Hat - 使用 iptableshttps://docs.redhat.com/RHEL 官方文档

本章小结

要点说明
Netfilter内核包过滤框架,提供 5 个钩子点
iptablesNetfilter 的用户态管理工具,2000 年诞生
nftablesiptables 的继任者,2014 年进入内核
共存当前两者并存,iptables 仍广泛使用
核心模块ip_tables、iptable_filter、nf_conntrack

下一章第 02 章:核心概念——四表五链,将深入讲解 iptables 的表、链、规则等核心概念。