一句话理解 iptables
iptables 是 Linux 内核 netfilter 的用户态客户端。内核真正干活的叫 netfilter,iptables 只是写规则、改规则、查规则的命令行工具。
iptables 规则的组织方式:
- 表(table):按用途分组,常见两张表:
filter:默认表,存放防火墙规则(接受/丢弃/拒绝)nat:网络地址转换、端口转发
- 链(chain):表里的检查点,决定规则何时生效:
INPUT:进入本机的数据包OUTPUT:本机发出的数据包FORWARD:本机转发的数据包(多网卡/网关场景)PREROUTING:路由前(DNAT 经常用)POSTROUTING:路由后(SNAT/MASQUERADE 经常用)
- 规则(rule):链里的一条匹配 + 动作,从上到下依次匹配,命中即执行;都没命中走链的默认策略。
基本命令
查帮助:
iptables -h > ~/iptables_help # 把帮助信息存到文本,方便搜索
查看规则:
# 查看 filter 表(默认)
iptables -L -n
# 查看 nat 表
iptables -L -n -t nat
三参数含义:-L 列出规则;-n 不做 DNS 反查,直接显示 IP;-t 表名 指定表。
五个实战场景
场景 1:禁止本机 ping 某个地址
需求:本机不允许 ping 百度。先 ping 一下确认能通:
ping -c 4 www.baidu.com
然后插一条 OUTPUT 链规则:
iptables -I OUTPUT -p icmp -d www.baidu.com -j DROP
参数含义:
-I OUTPUT:插入到 OUTPUT 链最前面(-A是追加末尾,-I是插入开头)-p icmp:匹配协议-d:匹配目的地址(域名会先解析成 IP)-j DROP:动作为悄悄丢弃
再次 ping:
ping -c 4 www.baidu.com
# ping: sendmsg: Operation not permitted
场景 2:导出 / 编辑 / 导入规则
复杂规则不要直接命令行改——一个 typo 就可能锁死自己。最佳实践:先导出现有规则到文件,编辑文本,再重新导入。
导出:
iptables-save > /home/ubuntu/iptables_rules
编辑:iptables_rules 是普通文本,每行一条规则。常见操作是在某条链下面加 -A 行:
*filter
:INPUT ACCEPT
:FORWARD ACCEPT
:OUTPUT ACCEPT
-A OUTPUT -p icmp -d 114.114.114.114 -j DROP # 新增:禁止 ping 114 DNS
COMMIT
导入:
iptables-restore < /home/ubuntu/iptables_rules
iptables -L -n # 校验规则是否生效
iptables -F。清自定义链用 -X,重置计数器用 -Z。场景 3:黑/白名单(按源 IP 限制)
需求:让本机作为网关时,特定 PC(按 IP 识别)不能访问某些网站,其他设备不受限。
思路:建一条名为 BLACKLIST 的自定义链,里面放要屏蔽的目的地址;然后让"特定 PC 的出流量"跳进这条链。
# 清环境
iptables -F
iptables -X
# 建一条自定义链
iptables -N BLACKLIST
# 源 IP 是 10.135.166.86(本机)时跳进 BLACKLIST
iptables -A OUTPUT -s 10.135.166.86 -j BLACKLIST
# BLACKLIST 里加具体屏蔽的目标
iptables -A BLACKLIST -d 114.114.114.114 -j DROP
iptables -A BLACKLIST -d 220.181.111.188 -j DROP
扩展示例(限制另一台 PC 通过本机转发):再加一条 -A OUTPUT -s <另一台 IP> -j BLACKLIST。要新增屏蔽目标,只需往 BLACKLIST 链追加。
场景 4:端口映射 / 转发
需求:把访问 8080 的请求转到 80 端口。本地实例:
# 本地 8080 → 80
iptables -t nat -A OUTPUT -p tcp -d 127.0.0.1 --dport 8080 -j DNAT --to 127.0.0.1:80
外网 8080 → 本机 80(走 PREROUTING,更常见):
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-ports 80
两个动作区别:
DNAT:目标地址改写。可以转到另一台机器的另一个端口。REDIRECT:把包转到本机的另一个端口(本质是 DNAT 的本地特化)。
场景 5:把自己锁在外面了怎么办
加了规则后 SSH 连不上(最常见的翻车):
- 云厂商控制台:登录 VNC / serial console,执行
iptables -F。 - 物理机:用本地显示器或 IPMI。
- 容器/VM:宿主机上
docker exec或虚拟化层 shell。
防患于未然的两条规矩:
- 改规则前先
iptables-save备份,保留 5–10 分钟再iptables-restore兜底。 - 在 cron 里挂一条 10 分钟后自动恢复的"安全网"规则:
at now + 10 minutes << 'EOF'
iptables-restore < /root/iptables.bak
EOF
与 nftables 的关系
CentOS 7 / Debian 10 之前的发行版默认是 iptables;从 CentOS 8 / Debian 10 / Ubuntu 20.04 起,新装系统默认是 nftables,iptables 在很多发行版里已经是 iptables-nft 的兼容层。
判断当前用的是哪一套:
iptables --version
# iptables v1.8.7 (nf_tables) ← 说明走 nftables 后端
# iptables v1.8.7 (legacy) ← 说明还走旧 xtables
迁移建议:
- 新项目直接写 nftables 规则(语法更清晰、支持集合与字典、性能更好)。
- 老项目先保留 iptables 兼容层,迁移时用
nft list-ruleset导出后逐条转写。
使用准则
- 永远先
iptables-save备份,再改。 - 复杂规则用脚本 / 配置管理(Ansible、systemd unit)部署,不要手敲。
- 任何
-F/-I INPUT -j DROP前先想清楚一条"逃生路径"。 - 新机器直接用 nftables,iptables 当兼容层理解即可。