iptables 不是防火墙本身。防火墙在内核里,叫 netfilter。iptables 只是往那些 hook 上挂规则的用户态工具。
先不要背参数。先跟一个包:它从网卡进来之后,会按固定顺序穿过五条链。走哪几条,取决于这包是给本机的、路过本机的,还是本机自己发出的。
五条链,不是三条
常见说法是「INPUT / OUTPUT / FORWARD 三条链」。那是 filter 表里默认能看到的三条。netfilter 的钩子有五个:
| 链 | 什么时候经过 | 典型用途 |
|---|---|---|
PREROUTING |
包刚进协议栈、还没做路由判决 | DNAT、连线追踪入口 |
INPUT |
路由认定:目的是本机 | 主机防火墙 |
FORWARD |
路由认定:目的是别处,本机只是路过 | 网关、容器转发 |
OUTPUT |
本机进程构造出来的包 | 本机访问外网的限制 |
POSTROUTING |
包马上要离开本机、路由已经定了 | SNAT / MASQUERADE |
三条路径记住就够用:
- 别人访问本机:网卡 →
PREROUTING→ 路由 →INPUT→ 进程 - 本机当路由器:网卡 →
PREROUTING→ 路由 →FORWARD→POSTROUTING→ 网卡 - 本机自己发出去:进程 →
OUTPUT→ 路由 →POSTROUTING→ 网卡
本机发出的包不进 PREROUTING。这就是为什么 kube-proxy 要把 ClusterIP 的 DNAT 同时挂在 PREROUTING 和 OUTPUT:包可能从别的 Pod 进来,也可能是本机进程自己访问 Service。
表挂在链上
链是路径,表是挂在路径上的规则集。同一个包会按固定顺序穿过多张表,不是「选一张表走一遍」。
| 表 | 常见链 | 干什么 |
|---|---|---|
raw |
PREROUTING、OUTPUT |
最早;常用来 NOTRACK,跳过 conntrack |
mangle |
五条都有 | 改 TOS / MARK,少改地址 |
nat |
PREROUTING、INPUT、OUTPUT、POSTROUTING |
改地址。DNAT 在路由前,SNAT 在路由后 |
filter |
INPUT、FORWARD、OUTPUT |
放行或丢掉。默认表 |
顺序可以记成:raw → mangle → nat → filter。查规则时 -t 选表,不写就是 filter。
匹配上了会发生什么
规则自上而下,先匹配先生效。-A 追加到末尾,-I 插到指定位置(默认最前)。
| 动作 | 含义 |
|---|---|
ACCEPT |
这一张表放过,包继续往下走 |
DROP |
丢掉,对端通常只看到超时 |
REJECT |
丢掉,并新造一个 ICMP unreachable 或 TCP RST 回去。不是把原包弹回去 |
LOG |
写日志,然后继续匹配后面的规则 |
SNAT / MASQUERADE / DNAT |
改地址,交给 conntrack 记下来,回程自动改回去 |
-P 是 --policy,给内置链设默认策略:规则都没中时怎么办。它不是 default 的缩写。用户自定义链没有 policy,用完必须 -j RETURN 或终结动作。
-X 删的是空的自定义链,不是「快速删规则」。清空规则是 -F。
一条能看懂的主机防火墙
# 只动 filter / nat,先清空再写
iptables -F
iptables -X
iptables -Z
iptables -t nat -F
# 默认:入站和转发丢掉,本机出站放行
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -s 192.168.0.0/16 -p tcp -m multiport --dports 22,80,443 \
-m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
iptables -A INPUT -j REJECT
读这段时按路径走一遍:SSH 新建连接走 INPUT 的 NEW;对端回包走 ESTABLISHED,不必再开 22。本机访问外网走 OUTPUT(默认 ACCEPT)和 POSTROUTING(这里没改地址)。这台机器如果不是路由器,FORWARD 的 DROP 不会挡住本机自己的流量。
常用匹配:-s / -d、-i / -o、-p、--sport / --dport、-m conntrack --ctstate、-m limit。-m state 是旧写法,现在用 conntrack。
和容器、Kubernetes 的交界
Docker / 多数 CNI 会在 FORWARD 放行,在 POSTROUTING 做 MASQUERADE。kube-proxy 的 iptables 模式在 PREROUTING 把 ClusterIP DNAT 成 Pod IP,回程靠这台机器上的 conntrack 把源地址改回 VIP。下一篇 K8s 网络 按包把这条路径画开。
nftables 是后继者,语义仍是同一套 hook。先把五条链走熟,再换工具不亏。