iptables 是 Linux 内核防火墙 netfilter 的用户空间管理工具,它负责定义数据包在流经内核网络栈时的过滤和处理规则。它的核心概念是 表(table) 和 链(chain):表决定了规则的功能类型,而链决定了规则作用的时机。
1. 四表:按功能分类规则
iptables 内置了五个表(常用的是前四个),每个表专用于一类网络处理任务:
- filter 表(默认表):用于包过滤,决定是否允许数据包通过。绝大部分防火墙规则都在此表中定义。它包含 INPUT、FORWARD、OUTPUT 三条链。
- nat 表:用于网络地址转换(如端口映射、SNAT、DNAT),仅作用于新建连接的第一个数据包。包含 PREROUTING、OUTPUT、POSTROUTING 链。
- mangle 表:用于修改数据包的 IP 头部(如 TTL、TOS 字段),做特殊的流量标记,较少使用。包含全部五条链。
- raw 表:用于跳过连接跟踪(NOTRACK),主要在高并发场景下优化性能。包含 PREROUTING、OUTPUT 链。
- security 表(较少手动使用):配合 SELinux 等强制访问控制,用于标记数据包的安全上下文。
日常防火墙配置中,最常用的是 filter 表(控制访问)和 nat 表(做端口转发/共享上网)。
2. 五链:按数据包流经位置划分
链代表数据包在内核协议栈中的五个“挂载点”,即规则能发挥作用的位置:
- PREROUTING:数据包刚进入网络接口,尚未进行路由判断。适用于目的地址转换(DNAT)。
- INPUT:经过路由判断后,数据包的目的 IP 是本机。对本机进程提供服务的过滤都放在此链。
- FORWARD:数据包经过路由判断,发现目的 IP 不是本机,需要通过本机转发。用于控制经过本机的转发流量。
- OUTPUT:本机进程产生的数据包,在发出之前。可对本机对外访问进行过滤或转换。
- POSTROUTING:数据包即将离开网络接口,所有路由决策已完成。适用于源地址转换(SNAT 或 MASQUERADE)。
理解数据包走过的路径,是正确放置规则的前提。对于一台普通桌面或服务器:
- 保护本机服务的规则 → filter 表 INPUT 链;
- 允许本机对外访问 → filter 表 OUTPUT 链(一般默认放行);
- 做 NAT 共享上网 → nat 表 POSTROUTING 链(加 MASQUERADE);
- 将外部端口映射到内部服务器 → nat 表 PREROUTING 链(加 DNAT)。
3. 基础规则编写
iptables 命令语法结构如下:
iptables -t <表名> <命令> <链名> <匹配条件> -j <动作>
若不指定 -t,默认操作 filter 表。动作(-j)可以是:
ACCEPT:允许通过DROP:直接丢弃,不给对方任何回应REJECT:拒绝,并回复一个 ICMP 错误(更礼貌,便于对方排错)LOG:记录日志,然后继续匹配后续规则- 自定义链名:跳转到用户自定义链
常用命令选项:
-A:在链尾部追加一条规则-I:在链首部插入规则(可指定位置)-D:删除规则-F:清空链中所有规则-L:列出规则(配合-n不解析域名,-v显示详细统计)-P:设置链的默认策略(当没有规则匹配时执行的动作)
匹配条件可以非常灵活,常见的有:
-p tcp/udp/icmp:匹配协议--dport 22:匹配目标端口(需-p tcp或-p udp)--sport 1024:65535:匹配源端口范围-s 192.168.1.0/24:匹配源 IP 地址段-d 10.0.0.1:匹配目标 IP-i eth0:匹配进入接口(适用于 INPUT、FORWARD、PREROUTING)-o eth0:匹配发出接口(适用于 OUTPUT、FORWARD、POSTROUTING)-m state --state NEW,ESTABLISHED:匹配连接状态(需要加载 conntrack 模块)-m multiport --dports 80,443:多端口匹配
实用示例:
# 允许来自 192.168.1.0/24 网段的 SSH 连接
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
# 拒绝某个 IP 的所有访问
iptables -A INPUT -s 203.0.113.5 -j DROP
# 允许本机环回接口所有流量(非常重要的基础规则)
iptables -A INPUT -i lo -j ACCEPT
# 只允许已建立或相关联的连接通过,防止非法外部新建连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 开启 NAT 共享上网(假设 eth0 是外网接口)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# 将外网 8080 端口映射到内网 192.168.1.10 的 80 端口
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.10:80
规则是按顺序匹配的,一旦命中就执行动作,不再往下匹配。因此,通常的策略是:先放行必要的已连接流量和信任的流量,然后在链末端设置默认 DROP 策略(如 iptables -P INPUT DROP)。修改默认策略前,务必确保已添加允许自己 SSH 连接的规则,以防把自己锁在服务器外面。
4. 保存与恢复规则
iptables 规则存放在内存中,重启系统会丢失。要保存当前规则以便重启后自动加载:
- Debian/Ubuntu 系统通常安装
iptables-persistent包,规则保存在/etc/iptables/rules.v4和/etc/iptables/rules.v6。 - RHEL/CentOS 等使用
iptables-services,规则保存在/etc/sysconfig/iptables。 - 也可以手动执行
iptables-save > /etc/iptables.rules,然后在/etc/rc.local或网络启动脚本中用iptables-restore < /etc/iptables.rules恢复。
掌握 iptables 的四表五链和基础规则语法,就具备了对 Linux 主机进行精细网络访问控制的能力。虽然现在出现了 nftables 等更新的替代方案,但 iptables 的部署量依然巨大,理解它是排查网络问题和加固系统的必备技能。