Linux iptables 与 Netfilter:原理、路径与运维要点

Linux iptables 与 Netfilter:原理、路径与运维要点

本文从 Linux 内核 Netfilter 框架 出发,说明 iptables (用户态配置工具)与 表(tables)、链(chains)、钩子(hooks)的关系;用流程图与表格 归纳报文路径、常用命令与匹配动作;并说明 iptables-save / iptables-restore 的导出格式与备份恢复、tcpdump 抓包点与 iptables 的先后 、规则数量对转发路径的影响 及持久化思路。具体钩子名、模块名随内核版本可能略有差异,排障请以当前内核文档与发行版说明为准。


目录

  1. [Netfilter 与 iptables 各自做什么](#Netfilter 与 iptables 各自做什么)
  2. 五个钩子与四张表
  3. 表与内置链对应关系
  4. [IPv4 包处理路径(示意)](#IPv4 包处理路径(示意))
  5. 命令格式与常用子命令
  6. 匹配条件与常见扩展模块
  7. 目标动作(-j)简表
  8. [配置示例:本机防火墙与 NAT](#配置示例:本机防火墙与 NAT)
  9. [iptables-save 与 iptables-restore](#iptables-save 与 iptables-restore)
  10. 查看、计数、日志与持久化
  11. [tcpdump 与 iptables:谁先谁后](#tcpdump 与 iptables:谁先谁后)
  12. 规则数量、复杂度与性能
  13. [nftables 与迁移提示](#nftables 与迁移提示)
  14. 延伸阅读
  15. 免责声明

Netfilter 与 iptables 各自做什么

概念 说明
Netfilter 工作在内核网络栈中的框架 :在若干固定钩子上注册回调,实现过滤、NAT、mangle、连接跟踪等。
iptables 用户态工具,通过 netlink 等机制把规则写入内核;日常说的「配防火墙」多数是在改 Netfilter 规则集。
nftables 新一代配置接口与规则引擎;发行版逐步默认 nft 后端,但 iptables-nft 兼容命令仍常见,概念(链、表、钩子)可对照理解。

内核
用户态
配置规则
iptables / ip6tables
Netfilter 钩子与规则
协议栈 / 路由 / 转发


五个钩子与四张表

钩子(hook):报文在网络栈中到达某阶段时,依次执行挂在该点上的规则(分表、分优先级)。

钩子 大致时机 常见用途(举例)
PREROUTING 路由判定之前 DNAT、raw、mangle、连接跟踪相关
INPUT 判定为本机接收后 过滤进入本机的流量
FORWARD 判定为需转发时 网关/路由器上过滤穿越本机的流量
OUTPUT 本机进程产生的报文离开前 过滤本机发出的流量
POSTROUTING 报文离开网络设备之前 SNAT、MASQUERADE、mangle

表(table) :同一钩子上,不同表按约定顺序处理(下列为常见教学顺序;实现细节以内核为准)。

优先级(概念上从高到低) 表名 主要用途
1 raw 连接跟踪前处理;可标记 NOTRACK 等
2 mangle 改 TTL、TOS、打 MARK 等
3 nat 地址转换:SNAT/DNAT/MASQUERADE
4 filter 允许/丢弃/拒绝(最常用)

表与内置链对应关系

并非每张表都挂接全部钩子。下面为 IPv4 / 经典 iptables 教学用归纳:

表 常见挂接的链
filter INPUT、FORWARD、OUTPUT
nat PREROUTING、INPUT、OUTPUT、POSTROUTING
mangle PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING
raw PREROUTING、OUTPUT

链(chain) :命名规则列表;内置链 与上表钩子对应,也可自建链并用 -j custom_chain 跳转,便于模块化。


IPv4 包处理路径(示意)

下列 ASCII 流程 与 Mermaid 一致,强调「先 PREROUTING → 路由分叉 → INPUT / FORWARD / OUTPUT」。

text 复制代码
                    ┌── PREROUTING(raw → mangle → nat)
                    ↓
              ┌─────────────┐
  入网        │   路由决策   │
              └─────────────┘
                    ↓
        ┌───────────┼───────────┐
        ↓           ↓           ↓
    本机接收      转发        (本机发出时从 OUTPUT 进入)
        ↓           ↓
     INPUT      FORWARD
        ↓           ↓
    本地协议栈   POSTROUTING(mangle → nat)
        ↑           ↓
     OUTPUT ───────┘(经 POSTROUTING 后出网卡)

本机
转发
本机发出
报文进入协议栈
PREROUTING

raw → mangle → nat
路由:本机 / 转发 / 本地发出
INPUT

mangle → filter
FORWARD

mangle → filter
OUTPUT

mangle → nat → filter
本机进程
POSTROUTING

mangle → nat
POSTROUTING

mangle → nat
出网卡

读图要点 :NAT 多在 PREROUTING(DNAT)与 POSTROUTING(SNAT) ;filter 默认只管 INPUT/FORWARD/OUTPUT,不在 PREROUTING 上挂 filter(教学模型下)。


命令格式与常用子命令

一般形式:

text 复制代码
iptables [-t 表名] 子命令 [链名] [匹配条件] [-j 目标 [目标选项]]

不加 -t 时默认 filter 表。

子命令 含义
-A 在链末尾追加规则
-I [链] [序号] 在指定位置插入(默认插到第一条)
-D 按规则内容或序号删除
-R 替换某条规则
-L 列出规则(大规则集时可能较慢)
-S 打印规则为 shell 可重放形式
-F 清空某链或全表链
-P 设置链的默认策略(如 DROP)
-N / -X 新建 / 删除自定义链
-Z 将计数器清零
-v / -n 详细 / 数字形式(不做 DNS 反查)

推荐习惯 :生产环境列规则时多用 iptables -S 或 iptables-save 做脚本化备份;需要包/字节计数时用 -L -v -n。


匹配条件与常见扩展模块

条件 含义 示例
-p 协议 -p tcp、udp、icmp
-s / -d 源 / 目的地址 -s 192.168.0.0/16
-i / -o 入 / 出接口 -i eth0
--sport / --dport 端口或范围 --dport 22、80:443
-m conntrack (或老 state) 连接状态 -m conntrack --ctstate ESTABLISHED,RELATED
-m multiport 多端口 -m multiport --dports 22,80,443
-m iprange IP 范围 --src-range 10.0.0.1-10.0.0.50
-m limit 限速 -m limit --limit 10/minute
-m comment 规则注释 --comment "allow ssh from vpn"

状态防火墙 常用写法:先放行 已建立连接 ,再开放少量端口,最后默认 DROP(见下节示例)。


目标动作(-j)简表

目标 行为简述
ACCEPT 放行(在当前链上结束本条规则处理,按路径继续)
DROP 丢弃(对端通常无显式反馈)
REJECT 拒绝并常伴随 ICMP 等错误返回(依协议与模块)
LOG 记日志后继续匹配下一条(注意日志风暴)
SNAT / MASQUERADE 改源地址(多在 POSTROUTING)
DNAT 改目的地址(多在 PREROUTING)
RETURN 从自定义链返回调用处

配置示例:本机防火墙与 NAT

1. 较严格的本机入站(示意)

bash 复制代码
# 默认先拒绝(SSH 会话请先确认有控制台或带外)
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
# 再按需开放业务端口

2. 内网通过网关访问外网(SNAT / MASQUERADE)

bash 复制代码
# 需 sysctl 打开 ip_forward,此处从略
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE

3. 端口转发(DNAT 示意)

bash 复制代码
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination 192.168.1.10:22

以上命令需在测试环境验证;远程服务器 上改 -P INPUT DROP 前务必保留 SSH 放行规则,避免被锁在外面。


iptables-save 与 iptables-restore

iptables-save 把当前内核中的 IPv4 规则 按固定文本格式 打印到标准输出;iptables-restore 从标准输入读入同一格式 ,一次性写回内核。二者成对使用,是备份、迁移、开机加载、脚本下发 的常用手段(ip6tables-save / ip6tables-restore 对应 IPv6)。

输出里有什么

典型片段包含:

  • *filter / *nat / *mangle / *raw:表头,表示后续规则属于哪张表。
  • :CHAIN POLICY [计数] :内置链的默认策略 (如 ACCEPT、DROP)及可选计数。
  • -A CHAIN ... :与 iptables -S 类似的追加规则 行,可被 iptables-restore 解析执行。
  • COMMIT:每个表结束时提交(格式要求的一部分)。

常用选项(以 man 页为准)

命令 选项 含义
iptables-save -t table 只导出指定表(如 nat);不写则常见实现为导出全部相关表。
-c 在输出中带上各链、各规则的包计数与字节计数 (与 iptables -L -v 一致方向,便于审计与对比)。
iptables-restore -t table 只恢复指定表,避免误改其他表。
-n / --noflush 不先清空 该表再导入(是否可用及语义以当前版本 man 为准;误用可能导致规则叠加而非「整表替换」)。
-c 与带 -c 的 save 文件配合,恢复计数器。

与 iptables -S 的对比

工具 特点
iptables-save 整表快照 :含表头、默认策略、多表一次导出;适合 iptables-restore 与落盘配置文件。
iptables -S 逐条规则 ,无 *filter 表壳;适合 grep、拼 shell、人工阅读单链。

典型用法示例

整库备份与恢复(替换式,慎用前先备份):

bash 复制代码
iptables-save > /root/iptables.backup.v4
# 确认文件内容无误后
iptables-restore < /root/iptables.backup.v4

只导出 / 只恢复 NAT 表:

bash 复制代码
iptables-save -t nat > /root/nat.only
iptables-restore -t nat < /root/nat.only

带计数备份(便于对比流量是否命中某条规则):

bash 复制代码
iptables-save -c > /root/iptables.with-counters.v4
# 恢复时若需写回计数:
iptables-restore -c < /root/iptables.with-counters.v4

脚本里快速统计规则条数 (不解析人类可读列,通常比大规则集下反复 iptables -L 更省事):

bash 复制代码
iptables-save | grep -c '^-A'

注意 :iptables-restore 从 stdin 读入的是「完整表描述」 ,错误文件可能导致策略与预期不符;生产环境建议先 save 再改 ,并保留串口/带外 或定时回滚 手段。发行版自带的 netfilter-persistent 等往往内部也是 save/restore 风格落盘,路径因发行版而异。


查看、计数、日志与持久化

需求 做法
看计数 iptables -L INPUT -n -v;或 iptables-save -c 落盘后对比
看行号便于删改 iptables -L INPUT --line-numbers
整表备份 / 下发 见上一节 iptables-save / iptables-restore
临时打日志 iptables -A INPUT -j LOG --log-prefix "ipt-in: "(慎用,量大影响性能)
开机持久化 Debian/Ubuntu :常将 iptables-save 输出 写入 /etc/iptables/rules.v4 并由 iptables-persistent 加载;RHEL 系 常见 /etc/sysconfig/iptables 或服务封装

仅统计规则条数:

bash 复制代码
iptables-save | grep -c '^-A'

tcpdump 与 iptables:谁先谁后

这与收包 / 发包方向 有关:教学上常记 入站 时 tcpdump 常在 PREROUTING 之前 就能看到帧;出站 时若包在 OUTPUT 被 DROP ,则 tcpdump 可能看不到(因未走到驱动发送路径上的抓包点)。
本机应用 Netfilter PREROUTING/INPUT tcpdump 抓包点 网卡/驱动 本机应用 Netfilter PREROUTING/INPUT tcpdump 抓包点 网卡/驱动 入站(简化) 帧进入 再进入协议栈与 iptables 若 ACCEPT 则交付本机

方向 常见结论(调试时)
入站 常能在 iptables DROP 之后仍于 tcpdump 看到包(抓包点更靠前)
出站 OUTPUT 上 DROP 可能导致 tcpdump 看不到该包
排障 入站问题:tcpdump + iptables 计数 ;出站问题:iptables LOG 、TRACE (慎用)与 tcpdump 对照

规则数量、复杂度与性能

Netfilter 对每条报文常做顺序匹配 直到命中 -j ;规则多、匹配复杂(如大量 string 匹配、滥用 LOG )会拉长软中断路径 上的时间,表现为延迟或 CPU 占用上升。Docker / Kubernetes 也会自动插入大量规则,属常见「条数很多」来源。

因素 建议
条数多 把命中率高 的规则放前面;大量 IP 用 ipset 合并
重复端口 用 multiport 减少规则条数
列表很慢 规则上千时 iptables-save 往往比 iptables -L 更适合脚本统计
评估 以 业务延迟、吞吐、CPU softirq 实测为准;下表仅为量级感,非保证
规则量级(经验谈) 可能现象(依流量与匹配复杂度而异)
< 几百 一般场景下影响常不明显
数百~一千多 可开始关注顺序与 LOG;容器环境常见
更多 建议审计规则来源、ipset 、评估 nftables 与架构(是否应旁路或卸载)

nftables 与迁移提示

项目 说明
动机 更统一的规则表示、内核侧实现演进;部分发行版默认 nft 后端
兼容 可使用 iptables-translate 做单条规则对照学习
建议 新项目可优先读发行版文档选择 nft 或 iptables-nft ;存量脚本仍以 iptables-save / iptables-restore 管理为主时注意发行版迁移公告

延伸阅读

同仓库内与网络栈、套接字状态相关的笔记可对照阅读,例如 hnjzsdx_doc/计算机网络/TCP与UDP数据路径_用户态网卡与对端应用.md 、hnjzsdx_doc/操作系统/Linux_ss命令详解与Netlink原理.md(连接与队列观察)。


免责声明

不同内核版本、发行版默认后端(legacy iptables / nft)与模块集合均有差异;NAT、转发 还涉及 ip_forward、rp_filter、策略路由 等全局设置。生产变更前请在测试环境验证,并保留恢复路径。


主题:Linux、Netfilter、iptables、NAT、防火墙、抓包、性能。

相关推荐
律宏阔5 小时前
WSL Docker 端口明明空闲,但就是绑不上端口
linux·windows
律宏阔5 小时前
WSL 突然断网,无法 ping 内网或外网
linux·windows
穷人小水滴5 小时前
用容器编译 VirtualBox 虚拟机软件 (ArchLinux, podman)
linux·容器·virtualbox
乱码三千6 小时前
如何优雅地直连无公网 IP 的远程 GPU 服务器
linux·人工智能·程序员
yunwei376 小时前
使用 eBPF 跟踪 Nginx 请求
linux·后端·性能优化
yunwei376 小时前
使用 eBPF 跟踪 MySQL 查询
linux·后端·性能优化
yunwei376 小时前
eBPF 示例教程:使用 XDP 捕获 TCP 信息
linux·后端·性能优化
judezh6 小时前
api 容器一直 unhealthy?我把一个 Agent 运行时的健康检查逐条拆了,查出四个问题
运维·docker
GeW6 小时前
制造业高端化,为什么必须重估Linux和数据库?
linux
百万蹄蹄向前冲6 小时前
双端同步!云服务器装最新Node.js v26.10全过程追踪
服务器·人工智能·node.js