iptables:Linux 内核包过滤防火墙
FreeGuideOnline
最新
2026-07-03
bash iptables --version
如果系统中同时存在 `firewalld` 或 `ufw`,它们可能会重建规则导致冲突,建议关掉其中一种再练习:
```bash
# 临时停用 ufw
sudo ufw disable
# 临时停用 firewalld
sudo systemctl stop firewalld
sudo systemctl disable firewalld
查看现有规则
# 查看 filter 表所有链规则(默认就是 filter 表)
sudo iptables -L -n -v
# 查看 nat 表规则
sudo iptables -t nat -L -n -v
# 以更清晰的行号显示规则(方便删除)
sudo iptables -L INPUT --line-numbers
选项说明:
-L:列出链中规则-n:以数字形式显示 IP 和端口,避免反向 DNS 解析慢-v:显示详细信息(计数器等)-t <表名>:指定要查看的表
编写你的第一条规则
命令通用格式
iptables [-t 表名] <命令> <链名> [匹配条件] -j <目标动作>
- 若不指定
-t,默认为filter表 <命令>常用:-A(追加)、-I(插入)、-D(删除)、-P(设置默认策略)
实例:允许或禁止特定流量
-
允许所有进入本机的 SSH 连接(端口22)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT -
允许来自特定 IP 的流量进入
sudo iptables -A INPUT -s 192.168.1.100 -j ACCEPT -
禁止某个 IP 访问本机所有服务
sudo iptables -A INPUT -s 203.0.113.5 -j DROP -
允许已建立或相关联的连接(让服务器能正常响应外部请求)
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT这条规则非常关键:放行本身由本机主动发起连接后返回的数据包,确保你能使用 curl、apt 更新等。
设置链的默认策略
一个安全加固的服务器通常采用“默认拒绝所有入站流量,按需开放”策略:
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT # 本机发出通常信任
⚠️ 特别注意:如果你远程连接到服务器,请在设置
INPUT DROP之前先放行 SSH 连接,否则你将被立刻踢出。
高级匹配与常用实战场景
基于接口的过滤
# 只允许从 eth0 网卡进入的 SSH
sudo iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
# 丢弃从 docker0 桥接网卡进来的所有流量
sudo iptables -A INPUT -i docker0 -j DROP
端口范围与多端口匹配
# 一次性开放 8000:9000 端口范围
sudo iptables -A INPUT -p tcp --dport 8000:9000 -j ACCEPT
# 同时匹配多个不连续端口(需要 multiport 模块)
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443,8080 -j ACCEPT
防止端口扫描与简单攻击
限制单个 IP 发起新连接的速率:
# 针对 SSH 的新连接限制每分钟最多 3 次
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
网络地址转换(NAT)
场景:将内网服务器端口 80 映射到本机公网 IP 的 8080 端口。
-
开启内核转发
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward # 永久生效记得修改 /etc/sysctl.conf -
添加 DNAT 规则(PREROUTING 链)
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.10:80 -
添加 SNAT 规则(让应答包能正确返回,也可是 MASQUERADE)
sudo iptables -t nat -A POSTROUTING -d 10.0.0.10 -p tcp --dport 80 -j MASQUERADE
规则的维护与持久化
删除规则
- 按行号删除(先查看带行号的列表):
sudo iptables -L INPUT --line-numbers # 假设要删 INPUT 链第 3 条规则 sudo iptables -D INPUT 3 - 按内容精确删除:
sudo iptables -D INPUT -s 203.0.113.5 -j DROP
清空所有规则(重置)
sudo iptables -F # 清空所有链的规则
sudo iptables -X # 删除用户自定义链
sudo iptables -t nat -F # 清空 nat 表
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
警告:执行后会瞬间开放所有流量,生产环境慎用。
保存与恢复规则
iptables 规则存储在内存中,重启会丢失。根据发行版不同,使用对应工具持久化:
-
使用 iptables-save/restore(通用)
sudo iptables-save > /etc/iptables/rules.v4 sudo iptables-restore < /etc/iptables/rules.v4 -
Debian/Ubuntu 安装
iptables-persistent,规则会保存在/etc/iptables/rules.v4和/etc/iptables/rules.v6,开机自动加载。sudo apt install iptables-persistent sudo netfilter-persistent save -
RHEL/CentOS 7+
sudo yum install iptables-services sudo systemctl enable iptables sudo service iptables save
构建一个安全服务器的规则集示例
下面是一个可直接运行的入门级规则脚本(适用 filter 表)。使用前请确保你已有其他控制台访问方式。
#!/bin/bash
# 清空现有规则
iptables -F
iptables -X
iptables -t nat -F
# 默认策略:入站和转发丢弃,出站允许
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 允许本地回环接口
iptables -A INPUT -i lo -j ACCEPT
# 允许已建立和关联的连接
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 开放 SSH (22)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 开放 HTTP (80) 和 HTTPS (443)
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
# 允许 ping(可选)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# 拒绝其他所有入站(由默认策略 DROP 处理)
将脚本保存为 iptables_setup.sh,赋予执行权限后运行:
chmod +x iptables_setup.sh
sudo ./iptables_setup.sh
排查故障的思路
- 规则没有生效?检查顺序:iptables 规则按顺序匹配,前面的规则一旦命中就不再继续,所以
ACCEPT要放在DROP的前面。 - 无法建立连接?确认是否允许了状态为
ESTABLISHED,RELATED的回复包。 - 想知道当前有多少包被某条规则处理?使用
iptables -L -n -v查看计数器。 - 临时调试可手动插入一条 LOG 规则来抓取数据包:
sudo iptables -I INPUT 1 -p tcp --dport 3306 -j LOG --log-prefix "MYSQL-DEBUG: "