🏗️ 核心概念与架构
iptables 遵循 表 → 链 → 规则 的三层架构
- 表(Table):根据不同功能对规则进行分类。最核心的有以下四张表:
- filter:默认表,用于数据包的过滤(允许或拒绝)。
- nat:用于网络地址转换,如端口转发。
- mangle:用于修改数据包的特定字段(如 TTL),实现QoS等。
- raw:优先级最高,用于配置连接跟踪,提升性能。
- 链(Chain):同一张表中的规则集合,是规则应用的路径点。关键链包括:
- INPUT:处理进入本机的数据包。
- OUTPUT:处理本机发出的数据包。
- FORWARD:处理本机转发的数据包(充当路由器时。
- PREROUTING:在路由决策之前处理数据包(常用于 DNAT。
- POSTROUTING:在路由决策之后处理数据包(常用于 SNAT)。
- 规则(Rule):链中的具体指令,包含匹配条件(如 IP 地址、端口)和目标动作(如 ACCEPT、DROP)
命令的基本结构如下:
1
| iptables [-t 表名] 操作选项 [匹配条件] -j 目标动作
|
⚙️ 常用命令与规则管理
查看当前规则:
1 2
| iptables -nvL iptables -t nat -nvL
|
- 基本操作:
- 追加规则 (
-A):将规则添加到链末尾。
- 插入规则 (
-I):将规则插入到链首或指定位置 (-I INPUT 2)。
- 删除规则 (
-D):按规则内容或行号 (-D INPUT 2) 删除。
- 清空规则 (
-F):清空指定链或所有链的规则。
- 默认策略(Policy):设置链的默认行为(如
DROP 或 ACCEPT)。
💾 规则持久化
iptables 规则在重启后会自动丢失,可通过以下方法持久化保存:
- 方法一:使用
iptables-persistent (Debian/Ubuntu)
- 安装:
sudo apt install iptables-persistent
- 手动保存:
sudo netfilter-persistent save
- 方法二:使用
iptables-save / iptables-restore (通用)
- 保存规则:
sudo iptables-save > /etc/iptables/rules.v4
- 设置开机自启:在
/etc/network/if-pre-up.d/ 目录下创建一个脚本,chmod +x 使其可执行,并写入:
#!/bin/sh
/sbin/iptables-restore < /etc/iptables/rules.v4
- 方法三:使用
iptables.service (CentOS/RHEL 7+)
- 保存规则:
sudo iptables-save > /etc/sysconfig/iptables
- 启动服务:
sudo systemctl enable iptables && sudo systemctl start iptables
🚀 真实场景应用
以下是几个可直接使用的配置命令:
1. 基础防火墙(开放端口,白名单模式)
此模式先设置默认拒绝,再允许必要端口。
1 2
| iptables -P INPUT DROP iptables -P FORWARD DROP
|
1 2 3 4
| iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
- 开放服务端口(如 SSH 22, HTTP 80)
1 2
| iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT
|
1 2
| iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -A INPUT -s 192.168.1.100 -p icmp --icmp-type echo-request -j ACCEPT
|
限制 Ping 速率(防止 flood)
使用 limit 模块限制每秒/每分钟的 ping 数量:
1 2
| iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 5/second --limit-burst 10 -j ACCEPT iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
|
2. DNAT(端口转发)
1 2 3 4
| sysctl net.ipv4.ip_forward
sysctl net.ipv4.ip_forward=1 echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
|
- 将外部请求转发至内网其它服务器。
将访问本机8080端口的TCP请求,转发至内网192.168.179.11的80端口
1 2 3 4 5 6 7
| iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.179.11:80
iptables -A FORWARD -d 192.168.179.11 -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -d 192.168.179.11 -p tcp --dport 80 -j SNAT --to-source 192.168.179.10
|
- 将外部请求转发至本机服务器。
将访问本机60022端口的TCP请求,转发至本机的22端口
1 2
| iptables -t nat -A PREROUTING -p tcp --dport 60022 -j DNAT --to-destination 127.0.0.1:22 iptables -A INPUT -d 127.0.0.1 -p tcp --dport 22 -j ACCEPT
|
🔥Linux 内核默认禁止任何从外部网络接口接收、目标地址为 127.0.0.1 的数据包,这是一种安全机制。
开启route_localnet
1 2
| echo "net.ipv4.conf.all.route_localnet=1" >> /etc/sysctl.conf sysctl -p
|
3. SNAT(源地址转换/共享上网)
- 让内网主机通过防火墙访问外网。
为从eth0口出去的、源IP为192.168.179.11的数据包做源地址转换
1 2 3 4 5
| iptables -t nat -A POSTROUTING -s 192.168.179.11 -o eth0 -j MASQUERADE
iptables -A FORWARD -s 192.168.179.11 -j ACCEPT
iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
4.删除规则