目录
- 核心概念:
iptables是什么? iptables的工作原理:表 和 链- 基本语法结构
- 参数详解
- 1. 控制操作
- 2. 链管理
- 3. 匹配条件
- 通用匹配
- 隐含匹配
- 显式匹配
- 实战示例
- 1. 允许特定端口访问
- 2. 禁止特定 IP 访问
- 3. 端口转发
- 4. NAT 配置(共享上网)
- 常用管理命令
iptables-save和iptables-restore- 重要提示:
iptablesvs.nftables
核心概念:iptables 是什么?
iptables 是一个在 Linux 内核中实现 包过滤 的工具,它像一个检查站,所有进出网络的数据包都必须经过这个检查站。iptables 根据你预先定义的规则来决定这些数据包是被 接受、拒绝 还是 丢弃。

- 包过滤:检查数据包的头部信息(如源/目的 IP、源/目的端口、协议类型等),然后根据规则采取行动。
- 状态无关:传统的
iptables规则主要检查单个数据包的静态信息,不关心连接的状态。 - 状态检测:通过
conntrack模块,iptables可以跟踪连接的状态(如NEW,ESTABLISHED,RELATED,INVALID),这是实现复杂防火墙规则的关键。
iptables 的工作原理:表 和 链
iptables 的规则被组织在 表 中,每个表又包含多个 链。
表
表是规则的集合,根据规则处理的数据包类型进行分类,主要有五种表:
| 表名 | 主要功能 |
|---|---|
filter |
默认表,用于数据包的过滤,绝大多数防火墙规则都在这个表里。 |
nat |
网络地址转换,用于修改数据包的 IP 地址或端口,实现端口转发、共享上网等。 |
mangle |
用于修改数据包的头部字段(如 TOS, TTL),通常用于 QoS(服务质量)或路由策略。 |
raw |
用于对数据包进行跟踪设置,通常在 conntrack 之前处理。 |
security |
用于 SELinux 等安全模块,对数据包进行安全标记。 |
链
链是规则的容器,数据包必须经过这些链,链分为两种:
-
内置链:由内核预定义,无法被删除或重命名。
(图片来源网络,侵删)PREROUTING:数据包进入网络栈后,进行路由决策之前,通常用于nat表,修改目的 IP/端口。INPUT:数据包的目标是本机,在进入用户空间之前,通常用于filter表,控制哪些数据可以进入本机。FORWARD:数据包需要被路由到其他主机,通常用于filter表,控制本机是否作为网关转发流量。OUTPUT:由本机产生的数据包,在离开网络栈之前,通常用于filter表,控制本机发出的流量。POSTROUTING:数据包完成路由决策之后,即将离开网络栈,通常用于nat表,修改源 IP/端口。
-
自定义链:由用户创建,可以被其他链通过
-j跳转来调用,用于组织规则,提高可读性。
数据包流程图:
基本语法结构
iptables 的命令结构非常清晰:
iptables [-t 表名] [命令] [链名] [匹配条件] [-j 动作/目标]
-t 表名:指定操作的表,默认是filter。- 命令:对规则执行的操作,如
-A,-D,-I等。 - 链名:指定操作的链,如
INPUT,FORWARD。 - 匹配条件:指定规则的筛选条件,如
-p tcp,--dport 80。 - -j 动作/目标:当数据包匹配所有条件时执行的操作。
参数详解
1. 控制操作
| 参数 | 全称 | 描述 | 示例 |
|---|---|---|---|
-A |
--append |
在指定链的末尾添加一条新规则。 | iptables -A INPUT -p tcp --dport 22 -j ACCEPT |
-I |
--insert |
在指定链的开头(或指定行号)插入一条新规则。 | iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT |
-D |
--delete |
删除一条规则,可以指定规则内容或规则序号。 | iptables -D INPUT -p tcp --dport 22 -j ACCEPTiptables -D INPUT 1 |
-R |
--replace |
替换指定链中某条规则的内容。 | iptables -R INPUT 1 -p tcp --dport 8080 -j ACCEPT |
-L |
--list |
列出指定链中的所有规则,默认列出 filter 表的 INPUT, FORWARD, OUTPUT 链。 |
iptables -L INPUTiptables -t nat -L |
-F |
--flush |
清空指定链中的所有规则,慎用! | iptables -F INPUT |
-Z |
--zero |
将指定链中的数据包和字节计数器清零。 | iptables -Z INPUT |
-N |
--new-chain |
创建一个新的自定义链。 | iptables -N MY_CUSTOM_CHAIN |
-X |
--delete-chain |
删除一个自定义链(必须为空)。 | iptables -X MY_CUSTOM_CHAIN |
-P |
--policy |
设置指定链的默认策略,默认策略通常是 ACCEPT 或 DROP。 |
iptables -P INPUT DROP |
2. 链管理
| 参数 | 全称 | 描述 |
|---|---|---|
-E |
--rename-chain |
重命名一个自定义链。 |
3. 匹配条件
匹配条件是 iptables 规则的核心,决定了规则何时触发。

通用匹配
这些匹配条件不依赖于其他内核模块。
| 参数 | 全称 | 描述 |
|---|---|---|
-p |
--protocol |
匹配协议,可以是 tcp, udp, icmp, all 或其他协议号。 |
-s |
--source |
匹配源 IP 地址,可以是单个 IP、网段(如 168.1.0/24)或 取反。 |
-d |
--destination |
匹配目标 IP 地址,用法同 -s。 |
-i |
--in-interface |
匹配数据包进入的网卡接口,如 eth0, lo。 取反。 |
-o |
--out-interface |
匹配数据包离开的网卡接口,用法同 -i。 |
隐含匹配
这些匹配条件需要内核模块支持,但无需手动加载。
| 参数 | 全称 | 描述 |
|---|---|---|
--sport |
--source-port |
匹配源端口,可以是单个端口或端口范围(如 1000:2000)。 |
--dport |
--destination-port |
匹配目标端口,用法同 --sport。 |
--tcp-flags |
匹配 TCP 标志位,格式为 FLAGS COMPARE_FLAGS。--tcp-flags SYN,ACK,FIN,RST SYN 表示“当 SYN 标志位为 1,而 ACK, FIN, RST 标志位为 0 时匹配”。 |
iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST SYN |
--icmp-type |
匹配 ICMP 类型,可以是数字或名称(如 echo-request, echo-reply)。 |
iptables -A INPUT -p icmp --icmp-type echo-request |
显式匹配
这些匹配条件需要手动加载对应的模块,使用 -m 选项。
| 模块 | 常用参数 | 描述 |
|---|---|---|
multiport |
--dports |
匹配多个离散的目标端口。 |
state |
--state |
匹配连接状态。NEW, ESTABLISHED, RELATED, INVALID。极其常用! |
mac |
--mac-source |
匹配源 MAC 地址。 |
limit |
--limit--limit-burst |
匹配速率。--limit 是平均速率(如 /minute),--limit-burst 是突发量。 |
string |
--string--algo |
匹配数据包中的字符串,可用于过滤恶意流量。 |
conntrack |
--ctstate |
state 模块的增强版,功能更多。 |
实战示例
重要前提:在修改 INPUT 链默认策略为 DROP 之前,务必确保你已经允许了 SSH 端口(22),否则你可能无法再通过 SSH 连接到服务器!
1. 允许特定端口访问(Web 服务器)
# 1. 允许所有访问本机 80 (HTTP) 和 443 (HTTPS) 端口的 TCP 流量 iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT # 2. 允许本地回环接口通信(非常重要!) iptables -A INPUT -i lo -j ACCEPT # 3. 允许已经建立的连接和相关连接返回(非常重要!) iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 4. 设置默认策略为 DROP,拒绝所有其他进入的流量 iptables -P INPUT DROP # 查看规则 iptables -L INPUT -n -v
-n 表示以数字形式显示 IP 和端口,-v 显示详细信息(如数据包和字节数计数)。
2. 禁止特定 IP 访问
# 禁止 IP 192.168.1.100 访问本机的所有服务 iptables -A INPUT -s 192.168.1.100 -j DROP # 或者只禁止它访问 SSH 端口 iptables -A INPUT -p tcp -s 192.168.1.100 --dport 22 -j REJECT # REJECT 会返回一个“连接被拒绝”的 ICMP 错误,比 DROP 更友好。
3. 端口转发(将本机的 8080 端口转发到内网 192.168.1.100 的 80 端口)
这需要开启 Linux 的 IP 转发功能。
# 1. 开启 IP 转发 echo 1 > /proc/sys/net/ipv4/ip_forward # 2. 在 nat 表的 PREROUTING 链中添加规则 # -i eth0: 数据从外部网卡 eth0 进入 # -p tcp: 协议为 TCP # --dport 8080: 目标端口是 8080 # -j DNAT --to-destination 192.168.1.100:80: 将目的地址和端口修改为内网服务器 iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80 # 3. 在 nat 表的 POSTROUTING 链中添加 MASQUERADE 规则(如果内网 IP 是动态的) # 这会将源 IP 伪装成网关的 IP iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
4. NAT 配置(共享上网)
假设你的服务器有两块网卡:eth0 (连接外网, IP: 1.2.3.4) 和 eth1 (连接内网, IP: 192.168.1.1)。
# 1. 开启 IP 转发 echo 1 > /proc/sys/net/ipv4/ip_forward # 2. 在 nat 表的 POSTROUTING 链中,将所有从内网 eth1 出去的数据包源 IP 伪装成外网 eth0 的 IP iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # 3. 允许内网设备的数据包被转发 iptables -A FORWARD -i eth1 -j ACCEPT iptables -A FORWARD -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
常用管理命令
| 命令 | 描述 |
|---|---|
service iptables save |
(CentOS/RHEL 6 及之前) 将当前规则保存到 /etc/sysconfig/iptables 文件。 |
iptables-save > /etc/iptables/rules.v4 |
(推荐, 通用) 将当前规则保存到文件。 |
iptables-restore < /etc/iptables/rules.v4 |
从文件恢复规则。 |
modprobe ip_tables |
加载 iptables 内核模块。 |
lsmod | grep iptables |
检查 iptables 模块是否已加载。 |
iptables-save 和 iptables-restore
这是持久化 iptables 规荐的方式。
-
iptables-save:将当前内存中的所有规则以文本格式输出到标准输出。# 保存 filter 表的规则到文件 iptables-save > /etc/iptables/rules.v4
*filter:表示filter表。INPUT ACCEPT [0:0]:表示INPUT链的默认策略是ACCEPT,以及计数器初始值。-A INPUT ...:表示向INPUT链追加一条规则。
-
iptables-restore:从标准输入读取由iptables-save生成的规则文本,并将其应用到内核中。# 从文件恢复规则 iptables-restore < /etc/iptables/rules.v4
重要提示:iptables vs. nftables
iptables 是一个成熟但有些过时的技术,Linux 内核从 3.13 版本开始引入了新一代的 nftables。
-
nftables的优势:- 更简洁的语法:
iptables需要为每个表/链单独处理,而nftables使用统一的nft命令。 - 更好的性能:规则集解析和执行效率更高。
- 更强大的功能:集成了
iptables,ip6tables,ebtables,arptables的功能,支持更复杂的表达式和集合。 - 更现代的内核集成:是未来发展的方向。
- 更简洁的语法:
-
现状:
- 在许多现代 Linux 发行版(如 Ubuntu 20.04+, Debian 10+, CentOS 8+)中,
iptables命令已经成为nftables的一个兼容性包装器,你执行iptables命令,底层实际调用的是nftables的规则引擎,这保证了现有脚本的兼容性。 - 对于新项目或新系统,建议直接学习和使用
nftables。
- 在许多现代 Linux 发行版(如 Ubuntu 20.04+, Debian 10+, CentOS 8+)中,
对于理解和维护现有系统,iptables 仍然是必备知识,但对于新环境,nftables 是更值得投入学习的技术。
