Iptables 详细使用指南
目录
1. 工作原理
2. 核心架构(四表五链)
2.1 四张表(优先级从高到低)
2.2 五条内置链(数据包流向)
3. Iptables规则
3.1 规则的匹配条件与目标动作
常见匹配条件(用于筛选数据包)
常见目标动作(满足条件后对数据包的处理)
3.2 规则的匹配顺序与默认策略
4. 操作命令
5. 工作流程
6. 常见案例
6.1 基础防火墙配置(只允许必要服务)
6.2 端口转发(将外部 80 端口转发到内部服务器 192.168.8.8:8080)
6.3 共享上网(局域网通过网关访问公网,网关公网 IP 为 88.88.88.88)
6.4 删除指定表指定链的规则
6.5 日志记录
6.6 防暴力破解(限制 SSH 连接频率)
6.7 禁止特定 IP / 网段访问
6.8 只允许特定 IP 访问敏感端口
6.9 单向通信控制(如禁止外部 ping 本机,但本机可 ping 外部)
6.10 保存与恢复规则
6.11 清空与重置规则
7. 高级应用案例
7.1 精细化流量控制与状态管理
场景:企业内网多区域隔离与访问控制
7.2 带宽限制与流量整形(结合 tc)
场景:限制非核心业务(如下载)的带宽,保障核心服务(如数据库)
7.3 高级 NAT 应用(端口复用、双向 NAT)
1. 端口复用(一个公网端口映射到内网多个服务)
2. 双向 NAT(内外网 IP 双向转换)
7.4 透明代理与流量劫持
场景:强制内网所有 HTTP 流量经过代理服务器(10.0.0.10:3128)
7.5 入侵检测与自动防御(结合脚本)
场景:自动封禁 10 分钟内 SSH 失败超过 5 次的 IP
7.6 特定协议的深度过滤(如 FTP、DNS)
场景:允许 FTP 服务(支持主动 / 被动模式)
7.7 容器与虚拟化环境的网络隔离
场景:限制 Docker 容器只能访问特定外网 IP
7.8 高可用集群中的规则同步
1. 工作原理
iptables 是 Linux 系统中一款经典的防火墙管理工具,它通过操作内核中的 Netfilter 框架(Linux 内核的数据包处理引擎),实现对网络数据包的过滤、转发、地址转换等功能。简单来说,Netfilter 是内核中负责 “干活” 的组件,而 iptables 是用户空间中用于 “指挥” Netfilter 的工具。
2. 核心架构(四表五链)
2.1 四张表(优先级从高到低)
表名 | 功能描述 | 典型应用场景 |
---|---|---|
raw | 连接跟踪(conntrack)前的预处理 | 禁用连接追踪(NOTRACK ) |
mangle | 修改数据包(TTL、TOS、MARK等) | 流量标记(QoS)、拆包重组 |
nat | 网络地址转换(SNAT/DNAT) | 端口转发、IP 伪装(MASQUERADE) |
filter | 包过滤(允许/拒绝/丢弃) | 防火墙规则 |
2.2 五条内置链(数据包流向)
链名 | 触发时机 |
---|---|
PREROUTING | 数据包进入网卡后、路由决策前(raw → mangle → nat) |
INPUT | 路由决策后,目标是本机的数据包(mangle → filter) |
FORWARD | 路由决策后,目标非本机的数据包(mangle → filter) |
OUTPUT | 本机进程发出的数据包(raw → mangle → nat → filter) |
POSTROUTING | 数据包离开网卡前(mangle → nat) |
3. Iptables规则
对数据包的具体处理逻辑,规则是链中的 “指令”,每条规则由匹配条件和目标动作两部分组成:
- 匹配条件:定义数据包的特征(如源 IP、目的端口、协议等)。
- 目标动作:满足条件时对数据包的处理方式(如允许、拒绝、修改地址等)。
3.1 规则的匹配条件与目标动作
常见匹配条件(用于筛选数据包)
-
基本匹配条件(无需额外模块,直接使用):
-s 源IP
:指定数据包的源 IP(如-s 192.168.1.100
)。-d 目标IP
:指定数据包的目标 IP(如-d 8.8.8.8
)。-p 协议
:指定协议(如-p tcp
、-p udp
、-p icmp
)。--sport 源端口
:指定源端口(仅用于 TCP/UDP,如--sport 80
)。--dport 目标端口
:指定目标端口(如--dport 22
,表示 SSH 端口)。-i 入站网卡
:数据包进入的网卡(如-i eth0
)。-o 出站网卡
:数据包离开的网卡(如-o eth1
)。
-
扩展匹配条件(需加载扩展模块,用
-m 模块名
指定):- 多端口匹配(
-m multiport
):如--dports 80,443
(匹配 80 或 443 端口)。 - IP 范围匹配(
-m iprange
):如--src-range 192.168.1.1-192.168.1.10
(源 IP 在该范围)。 - 状态匹配(
-m state
):如--state NEW,ESTABLISHED
(匹配新连接或已建立的连接)。
- 多端口匹配(
常见目标动作(满足条件后对数据包的处理)
- ACCEPT:允许数据包通过,继续后续流程。
- DROP:直接丢弃数据包,不返回任何响应(对方会等待超时)。
- REJECT:拒绝数据包,并返回 “拒绝” 响应(如 ICMP 不可达),对方能立即知道被拒绝。
- SNAT:修改数据包的源 IP(源地址转换),常用于局域网共享上网(如
--to-source 公网IP
)。 - DNAT:修改数据包的目的 IP 或端口(目的地址转换),常用于端口转发(如
--to-destination 192.168.1.2:8080
)。 - MASQUERADE:动态 SNAT(适用于公网 IP 不固定的场景,如 ADSL 拨号,无需指定具体 IP)。
- LOG:将数据包信息记录到系统日志(
/var/log/messages
),不影响数据包处理(需配合其他动作使用)。
3.2 规则的匹配顺序与默认策略
- 匹配顺序:链中的规则按 “从上到下” 依次匹配,一旦匹配成功,立即执行对应动作,不再检查后续规则。因此,规则的顺序至关重要(如 “允许 SSH” 需放在 “拒绝所有” 之前)。
- 默认策略:当数据包不匹配链中任何规则时,执行的默认动作(用
-P
设置)。例如:iptables -t filter -P INPUT DROP
(filter 表 INPUT 链默认拒绝所有未匹配的数据包)。
4. 操作命令
操作目的 | 命令示例 |
---|---|
查看规则(默认 filter 表) | iptables -L (详细信息加 -v ,显示编号加 --line-numbers ) |
查看指定表的规则 | iptables -t nat -L (查看 nat 表规则) |
添加规则(末尾) | iptables -A INPUT -p tcp --dport 22 -j ACCEPT (允许 SSH 入站) |
插入规则(指定位置) | iptables -I INPUT 1 -p icmp -j ACCEPT (在 INPUT 链第 1 位允许 ping) |
删除规则(按编号) | iptables -D INPUT 2 (删除 INPUT 链第 2 条规则) |
清空所有规则 | iptables -F (清空当前表,指定表加 -t 表名 ) |
设置默认策略 | iptables -P OUTPUT ACCEPT (OUTPUT 链默认允许) |
保存规则(CentOS) | service iptables save (保存到 /etc/sysconfig/iptables ) |
恢复规则(Ubuntu) | iptables-restore < /etc/iptables.rules (从文件恢复) |
5. 工作流程
-
规则匹配顺序:
-
按表优先级:
raw → mangle → nat → filter
-
按链内顺序:从上到下逐条匹配,命中即执行动作(
ACCEPT/DROP/REJECT
等)
-
-
默认策略:链末尾的
POLICY
(如INPUT DROP
)
6. 常见案例
6.1 基础防火墙配置(只允许必要服务)
# 设置默认策略(INPUT/Forward 拒绝,OUTPUT 允许)
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT# 允许已建立的连接(避免影响现有通信)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT# 允许本地回环(避免影响本机服务通信)
iptables -A INPUT -i lo -j ACCEPT# 允许 SSH 连接(端口 22,限制来源 IP 更安全)
iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT # 仅允许内网 SSH
# 若需公网访问,替换为:iptables -A INPUT -p tcp --dport 22 -j ACCEPT# 允许 HTTP/HTTPS 服务(Web 服务器)
iptables -A INPUT -p tcp --dports 80,443 -j ACCEPT# 允许 ICMP 协议(允许 ping 本机)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
6.2 端口转发(将外部 80 端口转发到内部服务器 192.168.8.8:8080)
# 开启内核转发(临时生效,重启失效)
echo 1 > /proc/sys/net/ipv4/ip_forward# 在 nat 表 PREROUTING 链设置 DNAT(修改目的地址)
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.8.8:8080# 允许转发流量(filter 表 FORWARD 链)
iptables -A FORWARD -p tcp -d 192.168.8.8 --dport 8080 -j ACCEPT
6.3 共享上网(局域网通过网关访问公网,网关公网 IP 为 88.88.88.88)
# 开启内核转发
echo 1 > /proc/sys/net/ipv4/ip_forward# 在 nat 表 POSTROUTING 链设置 SNAT(修改源地址为网关公网 IP)
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 88.88.88.88
# 若公网 IP 不固定(如拨号),用 MASQUERADE 替代 SNAT:
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
6.4 删除指定表指定链的规则
[root@lmzf ~]# iptables -t raw -L Bitdefender-80-out --line-numbers
# Warning: iptables-legacy tables present, use iptables-legacy to see them
Chain Bitdefender-80-out (0 references)
num target prot opt source destination
1 NFQUEUE tcp -- anywhere anywhere tcp dpt:http flags:FIN,SYN,RST,ACK/SYN ! owner GID match bitdefender NFQUEUE num 0
[root@lmzf ~]# iptables -t raw -D Bitdefender-80-out 1
[root@lmzf ~]# iptables -t raw -L Bitdefender-80-out --line-numbers
# Warning: iptables-legacy tables present, use iptables-legacy to see them
6.5 日志记录
为了监控和调试目的,你可能希望记录某些类型的流量。可以使用 LOG
目标来记录匹配的数据包。例如,记录所有尝试ping本机的行为:
iptables -A INPUT -p icmp --icmp-type echo-request -j LOG --log-prefix "ICMP packet: "
监控特定流量
# 记录所有访问 22 端口的流量(日志存于 /var/log/messages)
iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH_ACCESS: " --log-level info# 记录被拒绝的数据包(便于排查攻击)
iptables -A INPUT -j LOG --log-prefix "DROPPED_PACKET: " --log-level warning
6.6 防暴力破解(限制 SSH 连接频率)
# 限制每分钟最多 10 次 SSH 连接,突发不超过 3 次
iptables -A INPUT -p tcp --dport 22 -m limit --limit 10/min --limit-burst 3 -j ACCEPT
# 超过限制的连接直接丢弃
iptables -A INPUT -p tcp --dport 22 -j DROP
6.7 禁止特定 IP / 网段访问
# 禁止单个 IP(10.0.0.5)访问本机
iptables -A INPUT -s 10.0.0.5 -j DROP# 禁止整个网段(192.168.2.0/24)访问本机 80 端口
iptables -A INPUT -s 192.168.2.0/24 -p tcp --dport 80 -j DROP
6.8 只允许特定 IP 访问敏感端口
# 仅允许管理员 IP(10.0.0.100)访问 MySQL 端口(3306)
iptables -A INPUT -s 10.0.0.100 -p tcp --dport 3306 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -j DROP # 拒绝其他所有 IP
6.9 单向通信控制(如禁止外部 ping 本机,但本机可 ping 外部)
# 禁止外部 ping 本机(拒绝 ICMP 请求)
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP# 允许本机 ping 外部(不限制 ICMP 响应)
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT # 允许响应包进入
6.10 保存与恢复规则
# 保存规则(CentOS)
service iptables save # 保存到 /etc/sysconfig/iptables# 保存规则(通用方式)
iptables-save > /etc/iptables.rules# 恢复规则
iptables-restore < /etc/iptables.rules
6.11 清空与重置规则
# 清空所有规则(默认表)
iptables -F# 清空指定表的规则(如 nat 表)
iptables -t nat -F# 重置链的默认策略(如 INPUT 链恢复为 ACCEPT)
iptables -P INPUT ACCEPT
7. 高级应用案例
7.1 精细化流量控制与状态管理
基于连接状态(state
模块)和更细粒度的匹配条件,实现复杂业务逻辑的流量管控,适用于多服务、多网段的复杂网络环境。
场景:企业内网多区域隔离与访问控制
例如,将内网划分为 “办公区”“服务器区”“DMZ 区”,通过 iptables 实现:
- 仅允许办公区访问服务器区的特定服务(如 MySQL 3306 端口),且需验证源 IP 和连接状态;
- 禁止服务器区主动访问办公区,但允许办公区发起的 “已建立连接”(如服务器响应办公区的查询);
- DMZ 区(如 Web 服务器)仅允许公网访问 80/443 端口,且仅能主动访问服务器区的特定接口(如数据库查询)。
核心配置思路:
# 1. 创建自定义链(简化规则管理)
iptables -N OFFICE_TO_SERVER # 办公区到服务器区的规则链
iptables -N DMZ_TO_SERVER # DMZ到服务器区的规则链# 2. 办公区(192.168.1.0/24)到服务器区(10.0.0.0/24)的规则
iptables -A OFFICE_TO_SERVER -s 192.168.1.0/24 -d 10.0.0.0/24 -p tcp --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OFFICE_TO_SERVER -j DROP # 默认拒绝其他流量# 3. DMZ区(172.16.0.0/24)到服务器区的规则(仅允许特定接口)
iptables -A DMZ_TO_SERVER -s 172.16.0.0/24 -d 10.0.0.0/24 -p tcp --dport 3306 -m state --state ESTABLISHED -j ACCEPT # 仅允许响应
iptables -A DMZ_TO_SERVER -j DROP# 4. 将自定义链挂到 FORWARD 链
iptables -A FORWARD -i eth1 -o eth2 -j OFFICE_TO_SERVER # eth1=办公区网卡,eth2=服务器区网卡
iptables -A FORWARD -i eth0 -o eth2 -j DMZ_TO_SERVER # eth0=DMZ区网卡
7.2 带宽限制与流量整形(结合 tc
)
iptables 本身不直接支持带宽限制,但可与 Linux 流量控制工具 tc
(traffic control)协同,通过标记数据包(mark
模块),让 tc
对标记的流量进行限速或整形。
场景:限制非核心业务(如下载)的带宽,保障核心服务(如数据库)
实现思路:
- 用 iptables 标记非核心业务的数据包(如端口 8080 的下载流量);
- 用
tc
对标记的数据包设置带宽上限(如 1Mbps)。
配置示例:
# 1. iptables 标记下载流量(mark 值为 100)
iptables -t mangle -A PREROUTING -p tcp --dport 8080 -j MARK --set-mark 100# 2. tc 对标记 100 的流量限速(假设出口网卡为 eth0)
tc qdisc add dev eth0 root handle 1: htb default 10
tc class add dev eth0 parent 1: classid 1:10 htb rate 1000Mbps # 总带宽
tc class add dev eth0 parent 1:10 classid 1:100 htb rate 1Mbps # 下载流量上限
tc filter add dev eth0 parent 1: protocol ip prio 1 handle 100 fw flowid 1:100 # 匹配 mark=100
7.3 高级 NAT 应用(端口复用、双向 NAT)
超出基础端口转发的复杂 NAT 场景,适用于公网 IP 有限或需隐藏内网拓扑的场景。
1. 端口复用(一个公网端口映射到内网多个服务)
例如,公网 IP 的 443 端口同时映射到内网的 Web 服务器(443)和邮件服务器(993),通过 “源 IP 匹配” 区分流量:
# 公网 IP:203.0.113.1
# 规则:来自 1.2.3.4 的 443 请求转发到内网 Web 服务器(192.168.1.10:443)
iptables -t nat -A PREROUTING -d 203.0.113.1 -s 1.2.3.4 -p tcp --dport 443 -j DNAT --to 192.168.1.10:443
# 其他 IP 的 443 请求转发到邮件服务器(192.168.1.20:993)
iptables -t nat -A PREROUTING -d 203.0.113.1 -p tcp --dport 443 -j DNAT --to 192.168.1.20:993
2. 双向 NAT(内外网 IP 双向转换)
适用于内网与外部网络存在 IP 冲突的场景(如内网和合作方内网均使用 192.168.1.0/24),通过双向转换避免冲突:
# 外部访问内网:将外部请求的目的 IP(203.0.113.100)转换为内网 IP(192.168.1.5)
iptables -t nat -A PREROUTING -d 203.0.113.100 -j DNAT --to 192.168.1.5
# 内网响应外部:将内网源 IP(192.168.1.5)转换为外部可见 IP(203.0.113.100)
iptables -t nat -A POSTROUTING -s 192.168.1.5 -j SNAT --to 203.0.113.100
7.4 透明代理与流量劫持
将特定流量(如 HTTP/HTTPS)透明转发到代理服务器(如 Squid、Nginx),用户无需手动配置代理,适用于企业上网审计、广告过滤等场景。
场景:强制内网所有 HTTP 流量经过代理服务器(10.0.0.10:3128)
# 1. 开启内核转发
echo 1 > /proc/sys/net/ipv4/ip_forward# 2. 拦截内网 HTTP 流量(80 端口),转发到代理服务器
iptables -t nat -A PREROUTING -s 192.168.1.0/24 -p tcp --dport 80 -j DNAT --to 10.0.0.10:3128# 3. 允许代理服务器响应内网(避免被默认策略拒绝)
iptables -A FORWARD -s 10.0.0.10 -d 192.168.1.0/24 -p tcp --sport 3128 -j ACCEPT
7.5 入侵检测与自动防御(结合脚本)
通过 iptables 日志记录异常流量,结合脚本实时分析并自动添加封禁规则,抵御扫描、暴力破解等攻击。
场景:自动封禁 10 分钟内 SSH 失败超过 5 次的 IP
实现思路:
- iptables 记录 SSH 失败日志(如密码错误);
- 定时脚本(如
cron
)分析日志,统计失败次数; - 对超阈值的 IP 自动添加 iptables DROP 规则。
核心配置:
# 1. 记录 SSH 失败日志(假设 SSH 服务日志含 "Failed password")
iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH_FAILED: "# 2. 检测脚本(示例,需保存为 /usr/local/bin/ban_ssh.sh 并添加执行权限)
#!/bin/bash
# 提取 10 分钟内失败次数 >5 的 IP
awk '/SSH_FAILED/ && /Failed password/ {print $11}' /var/log/messages | grep -oE '([0-9]+\.){3}[0-9]+' | sort | uniq -c | awk '$1>5 {print $2}' | while read ip; do# 若未封禁则添加规则if ! iptables -C INPUT -s $ip -j DROP >/dev/null 2>&1; theniptables -A INPUT -s $ip -j DROPecho "Banned $ip at $(date)" >> /var/log/ssh_ban.logfi
done# 3. 添加 cron 任务(每 5 分钟执行一次)
echo "*/5 * * * * root /usr/local/bin/ban_ssh.sh" >> /etc/crontab
7.6 特定协议的深度过滤(如 FTP、DNS)
针对多端口或动态端口协议(如 FTP、SIP),结合 iptables 扩展模块(如 ip_conntrack_ftp
)实现精准控制。
场景:允许 FTP 服务(支持主动 / 被动模式)
FTP 主动模式使用 21 端口控制连接,数据连接由服务器主动发起(端口 20);被动模式数据端口随机,需内核跟踪动态端口:
# 1. 加载 FTP 连接跟踪模块
modprobe ip_conntrack_ftp# 2. 允许 FTP 控制连接(21 端口)
iptables -A INPUT -p tcp --dport 21 -j ACCEPT# 3. 允许 FTP 数据连接(依赖跟踪模块自动识别动态端口)
iptables -A INPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
7.7 容器与虚拟化环境的网络隔离
在 Docker、KVM 等虚拟化环境中,通过 iptables 控制宿主机与容器、容器之间的网络访问,弥补虚拟化平台自带防火墙的不足。
场景:限制 Docker 容器只能访问特定外网 IP
Docker 会自动创建 DOCKER
链,可在其上附加规则:
# 1. 清空 Docker 转发链(避免默认放通)
iptables -F FORWARD# 2. 允许容器(172.17.0.0/16)访问特定 IP(8.8.8.8)
iptables -A FORWARD -s 172.17.0.0/16 -d 8.8.8.8 -j ACCEPT# 3. 允许已建立的连接响应
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT# 4. 默认拒绝其他转发流量
iptables -P FORWARD DROP
7.8 高可用集群中的规则同步
在主备架构(如 Keepalived 双机热备)中,通过脚本或工具(如 csync2
)同步 iptables 规则,确保主备切换时防火墙策略一致。
示例流程:
- 主节点修改规则后,通过
iptables-save > /etc/iptables.rules
保存; - 用
csync2
将规则文件同步到备节点; - 备节点通过
iptables-restore < /etc/iptables.rules
加载规则; - 结合
inotify
监控文件变化,实现实时同步。