目录
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
监控文件变化,实现实时同步。