把 iptables 学明白
摘要
本文总结了 Linux iptables 的核心概念与实战应用。尽管 ufw 等工具更简单,但 iptables 在 Docker、Kubernetes 等复杂场景及底层网络原理中不可或缺。文章详细讲解了表、链、规则及数据流向,提供了家庭网关搭建脚本。此外,还介绍了调试技巧(如查看计数、LOG)、常见错误(如漏放 ESTABLISHED)、规则持久化及 Docker 集成注意事项。
iptables 是 Linux 上最让人头大的工具之一。此文是我学了一年多之后的总结,不是 man page 翻译,是"为什么这样设计"和"实战怎么用"。
为什么学 iptables
ufw / firewalld 不是更简单吗?是,但:
ufw 在复杂场景下还是会让你直接写 iptables 规则
Docker 端口映射用的就是 iptables,不学就看不懂 docker 的网络行为
Kubernetes / 各种云上 VPC,本质都是 iptables / nftables
调试时
iptables -L -v看到的规则数比ufw status详细得多
所以,早晚要学,早学早解脱。
核心概念
表(Table)
iptables 里有 5 张表,最常用的两个:
filter:包过滤(默认表),决定包"过不过"
nat:网络地址转换(DNAT/SNAT/MASQUERADE)
其他:
mangle:改包头(TTL、TOS、MARK)
raw:连接跟踪豁免(高性能场景)
security:SELinux 联动
链(Chain)
每张表里有几条内置链:
PREROUTING:路由决策前(DNAT)
INPUT:发给本机的包
FORWARD:转发的包(路由决策后)
OUTPUT:本机发出的包
POSTROUTING:路由决策后(SNAT / MASQUERADE)
记忆口诀:PRE-/POST- 看路由决策的"前/后",INPUT/FORWARD/OUTPUT 看包的目的。
规则(Rule)和目标(Target)
规则:匹配条件 + 动作。
目标:
ACCEPT:放行DROP:丢弃,不响应REJECT:拒绝,回 RST/ICMP unreachableLOG:记日志,继续下一条SNAT/DNAT/MASQUERADE:NATRETURN:跳出当前链,回上一层
匹配条件(Match)
常见:
-p tcp --dport 22:TCP 目标端口 22-s 192.168.1.0/24:源 IP 段-i eth0:入接口-m state --state ESTABLISHED,RELATED:连接状态-m multiport --dports 80,443:多端口-m iprange --src-range 192.168.1.100-192.168.1.200:IP 范围
数据流图(最关键的)
关键点:
本机进程的包走 OUTPUT → POSTROUTING
转发的包走 FORWARD → POSTROUTING
发给本机的包走 INPUT
DNAT 在 PREROUTING,SNAT/MASQUERADE 在 POSTROUTING
实战:搭一个家庭网关
目标:
外网网卡 eth0(公网 IP)
内网网卡 eth1(192.168.1.1/24)
内网机器能通过网关访问外网(NAT)
外网能 SSH 进网关(22 端口)
内网能 SSH 进网关
外网能访问网关的 80 / 443(web 服务)
拒绝其他所有入站
调试:定位"为什么不通"
这是最重要的部分。规则不生效时怎么排查?
1. 看规则命中计数
2. 临时插 LOG 规则
注意:LOG 不会停止匹配,所以配合下面这样用:
3. 跟踪连接
4. nftables(iptables 的替代)
新一代 Linux 防火墙,语法更清晰,未来要切:
但目前还是 iptables 为主流,学完 iptables 再看 nft 不难。
常见错误
默认策略忘了改:默认 ACCEPT 改 DROP 时,第一条规则一定是放行自己的 SSH,不然被锁外。
ESTABLISHED 漏了:返回包被拦,看似建立了连接实际超时。
FORWARD 没允许:NAT 配了但转发没开,内网上不了外网。
INPUT 链有 eth0 的规则但忘了 ACCEPT lo:本地服务互相连不上。
规则没持久化:重启就丢。我每次写完都用
iptables-save > /etc/iptables.rules。
持久化
配合 docker 的坑
docker 启动时会自己改 iptables 规则(创建 DOCKER-USER 链、添加 NAT)。如果你手写的规则和 docker 的冲突:
docker 会改
FORWARD链docker 会加
iptables -t nat -A POSTROUTING重启 docker 服务会重置部分自定义规则
调试时用:
总结
iptables 的设计哲学是"如果某条规则命中,停止匹配;否则继续"。理解这一点,加上"5 张表 5 条链"的位置关系,基本就入门了。
剩下的就是多写多踩。我前 10 次配防火墙都至少有一个规则没写对,每次都学到东西。
参考
netfilter 官方文档 — 枯燥但权威
《Linux iptables 实战手册》— Oskar Andreasson,老书但讲得最清楚
Arch Wiki iptables — 实操级
