开放了不该开的端口、被扫到 SSH 爆破、想让内网机器通过公网 IP 访问——这些都靠防火墙解决。iptables 是 Linux 最经典的防火墙工具,虽然新系统逐步转向 nftables,但 iptables 语法在无数教程、脚本和服务器里依然无处不在。这篇文章把 iptables 的"四表五链"讲明白,并给出最常用的实战规则。
一、iptables 是什么?先理解四表五链
iptables 的本质是:内核里挂着一串规则,数据包经过时按规则一个个匹配,匹配到就执行动作(放行、拒绝、丢弃、转发)。
五个链(数据包经过的检查点):
| 链 | 作用 |
|---|---|
| INPUT | 进入本机的数据包 |
| OUTPUT | 本机发出的数据包 |
| FORWARD | 经过本机转发的数据包 |
| PREROUTING | 路由决策前(做 DNAT 目标地址转换) |
| POSTROUTING | 路由决策后(做 SNAT 源地址转换) |
四张表(规则的分类):
| 表 | 用途 | 常用场景 |
|---|---|---|
| filter | 过滤(默认表) | 放行/拒绝端口、IP |
| nat | 地址转换 | 端口转发、共享上网 |
| mangle | 修改数据包 | 改 TTL、标记 |
| raw | 跳过状态追踪 | 高性能场景 |
日常使用 90% 在 filter 表,端口转发用 nat 表。
二、基础命令:查看、添加、删除规则
查看规则:
iptables -L -n -v # 列出规则(-n 不解析域名,-v 显示计数)
iptables -t nat -L -n -v # 查看 nat 表规则
添加放行规则(最常用):
iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 放行 SSH
iptables -A INPUT -p tcp --dport 80 -j ACCEPT # 放行 HTTP
iptables -A INPUT -p tcp --dport 443 -j ACCEPT # 放行 HTTPS
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 放行已建立连接
默认策略:拒绝所有入站,只放行需要的(生产环境推荐):
iptables -P INPUT DROP # 默认丢弃入站
iptables -P FORWARD DROP # 默认丢弃转发
iptables -P OUTPUT ACCEPT # 出站放行
删除规则:
iptables -D INPUT -p tcp --dport 80 -j ACCEPT # 按规则删除
iptables -F # 清空所有规则(小心断网)
iptables -X # 删除自定义链
三、按 IP 控制访问
只允许指定 IP 访问某端口(比如只允许自己的 IP 访问 22 端口):
iptables -A INPUT -p tcp -s 1.2.3.4 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
封禁恶意 IP:
iptables -A INPUT -s 5.6.7.8 -j DROP
封禁整个网段:
iptables -A INPUT -s 123.45.0.0/16 -j DROP
防止 SSH 暴力破解(限速):
iptables -A INPUT -p tcp --dport 22 -m recent --name ssh_brute --set
iptables -A INPUT -p tcp --dport 22 -m recent --name ssh_brute --update --seconds 60 --hitcount 5 -j DROP
60 秒内连接超过 5 次就丢弃,配合 fail2ban 效果更好。
四、NAT 端口转发实战(重点)
场景 1:把公网 8080 端口转发到内网机器的 80 端口
# 目标地址转换:发往本机 8080 的流量,转到内网 192.168.1.100:80
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80
iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -j ACCEPT # 放行转发
场景 2:内网共享上网(SNAT 源地址转换)
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
所有内网机器经这台服务器上网时,源 IP 都会换成公网 IP。
场景 3:本机端口重定向(把 80 转到 8080)
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
五、规则持久化(关键!不保存重启就没了)
iptables 规则默认只存内存,重启后全部丢失。必须保存。
CentOS 6 / 老系统:
service iptables save
CentOS 7+ / 通用方法:
iptables-save > /etc/iptables.rules
开机自动恢复,写进 /etc/rc.local:
echo 'iptables-restore < /etc/iptables.rules' >> /etc/rc.local
chmod +x /etc/rc.local
Ubuntu 用 iptables-persistent:
apt install -y iptables-persistent
netfilter-persistent save # 保存规则
netfilter-persistent reload # 恢复规则
六、iptables 与 firewalld/ufw 的关系
新系统默认的 firewalld、ufw 只是 iptables 的"前端界面",最终规则还是会落到内核 netfilter。可以这么理解:
| 工具 | 本质 | 适用系统 |
|---|---|---|
| iptables | 直接操作规则 | 所有 Linux |
| firewalld | iptables 的图形化封装 | CentOS 7+ |
| ufw | iptables 的简化封装 | Ubuntu |
用哪个都行,但看懂 iptables 语法,遇到任何前端工具都能排查到底层。
七、常见问题排查
1. 配置后连不上 SSH 了
默认策略改成 DROP 前,先放行 22 端口,并且不要在 SSH 会话里清空规则(iptables -F)。万一断了,通过 VNC/控制台重连后执行 iptables -F 恢复。
2. 端口转发了没生效
检查两件事:FORWARD 链是否放行了(默认 DROP 会挡转发),以及是否开启了内核转发:
sysctl net.ipv4.ip_forward=1
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
sysctl -p
3. 规则很多很乱
用 iptables -L -n --line-numbers 查看带行号的规则,删除单条:
iptables -D INPUT 3 # 删除 INPUT 链第 3 条
4. 想临时放行又怕断网
不要直接改默认策略,先追加放行规则,确认无误后再改策略。
总结
iptables 核心就三件事:filter 表管放行/拒绝(INPUT/OUTPUT/FORWARD),nat 表管地址转换(PREROUTING 做 DNAT、POSTROUTING 做 SNAT),规则记得持久化(iptables-save)。生产环境推荐"默认 DROP + 白名单放行"策略,端口转发记住 DNAT + FORWARD + ip_forward 三件套。掌握这些,防火墙不再是玄学。




