iptables 防火墙配置实战指南 | Linux 网络安全教程

iptables 是 Linux 系统中最强大的网络防火墙工具,通过内核级的 netfilter 框架实现数据包过滤、网络地址转换(NAT)和端口转发。本文将带你从零开始,系统掌握 iptables 的核心概念与实战配置。
一、iptables 基础概念
1.1 表与链的结构
iptables 由 表(Tables) 和 链(Chains) 组成,不同表负责不同功能:
| 表名 | 作用 | 包含的链 |
|---|---|---|
| filter | 数据包过滤(防火墙) | INPUT、FORWARD、OUTPUT |
| nat | 网络地址转换 | PREROUTING、POSTROUTING、OUTPUT |
| mangle | 数据包修改(TOS、TTL) | 全部 5 个链 |
| raw | 连接跟踪前处理 | PREROUTING、OUTPUT |
数据包流经顺序:
进入 → PREROUTING (raw → mangle → nat)
↓
路由判断
↓
本地进程?── 是 ──→ INPUT (mangle → filter) → 本地应用 → OUTPUT (raw → mangle → nat → filter) → POSTROUTING → 发出
↓ 否
FORWARD (mangle → filter)
↓
POSTROUTING (mangle → nat) → 发出1.2 链的默认策略
每个链都有默认策略(Policy),决定没有匹配规则时的处理方式:
- ACCEPT:允许数据包通过
- DROP:丢弃数据包(不回复)
- REJECT:拒绝数据包(回复拒绝信息)
二、iptables 基本命令
2.1 查看规则
# 查看 filter 表所有规则(默认)
iptables -L -n -v --line-numbers
# 查看 nat 表规则
iptables -t nat -L -n -v --line-numbers
# 查看指定链规则
iptables -L INPUT -n -v --line-numbers参数说明:
-L:列出规则-n:数字形式显示 IP 和端口(不解析)-v:详细信息(包数、字节数)--line-numbers:显示规则编号-t <表名>:指定表
2.2 添加规则
# 在链末尾追加规则
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 在链开头插入规则
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
# 在指定位置插入规则(第 3 条)
iptables -I INPUT 3 -p tcp --dport 443 -j ACCEPT2.3 删除规则
# 按编号删除 INPUT 链第 2 条规则
iptables -D INPUT 2
# 按内容删除规则
iptables -D INPUT -p tcp --dport 22 -j ACCEPT
# 清空指定链的所有规则
iptables -F INPUT
# 清空所有链
iptables -F
# 清空 nat 表
iptables -t nat -F2.4 修改默认策略
# 设置 INPUT 链默认策略为 DROP(谨慎操作!)
iptables -P INPUT DROP
# 设置 FORWARD 链默认策略为 DROP
iptables -P FORWARD DROP
# 设置 OUTPUT 链默认策略为 ACCEPT
iptables -P OUTPUT ACCEPT⚠️ 警告:远程操作时,切勿将 INPUT 默认策略设为 DROP 且未允许 SSH 端口,否则会被锁在服务器外!
三、常用匹配条件
3.1 协议与端口
# 匹配 TCP 协议
iptables -A INPUT -p tcp -j ACCEPT
# 匹配指定端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 匹配端口范围
iptables -A INPUT -p tcp --dport 8000:8100 -j ACCEPT
# 匹配源端口
iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT
# 匹配 ICMP(ping)
iptables -A INPUT -p icmp -j ACCEPT3.2 IP 地址匹配
# 匹配源 IP
iptables -A INPUT -s 192.168.1.100 -j ACCEPT
# 匹配源 IP 段
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT
# 匹配目的 IP
iptables -A OUTPUT -d 8.8.8.8 -j DROP
# 匹配接口
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
# 匹配出站接口
iptables -A FORWARD -o eth1 -j ACCEPT3.3 状态匹配(连接跟踪)
# 允许已建立和相关的连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许新连接
iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT
# 丢弃无效数据包
iptables -A INPUT -m state --state INVALID -j DROP状态说明:
NEW:新连接的第一个包ESTABLISHED:已建立连接的包RELATED:与已有连接相关的包(如 FTP 数据连接)INVALID:无法识别的无效包
四、实战:基础防火墙配置
4.1 完整防火墙脚本
#!/bin/bash
# 清空所有规则
iptables -F
iptables -X
iptables -Z
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
# 设置默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# 允许已建立和相关连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许 SSH(先放好,避免被锁)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许常见服务端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT # HTTP
iptables -A INPUT -p tcp --dport 443 -j ACCEPT # HTTPS
# 允许 ping(可选)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# 丢弃无效包
iptables -A INPUT -m state --state INVALID -j DROP
echo "防火墙配置完成!"保存为 firewall-setup.sh,执行:
chmod +x firewall-setup.sh
./firewall-setup.sh4.2 规则保存与恢复
# Debian/Ubuntu 保存规则
iptables-save > /etc/iptables/rules.v4
# 安装 iptables-persistent 实现开机自动加载
apt install -y iptables-persistent
# 手动恢复规则
iptables-restore < /etc/iptables/rules.v4
# CentOS/RHEL 保存规则
service iptables save
# 或
iptables-save > /etc/sysconfig/iptables五、NAT 与端口转发
5.1 SNAT(源地址转换)
用于内网机器共享公网 IP 上网:
# 启用 IP 转发
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
# SNAT:内网 192.168.1.0/24 通过 eth0 的公网 IP 上网
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 公网IP
# 动态 IP 用 MASQUERADE(如拨号上网)
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE5.2 DNAT(目的地址转换 / 端口映射)
将公网端口映射到内网服务器:
# 将公网 8080 端口映射到内网 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
# 允许 FORWARD 转发(确保目标可达)
iptables -A FORWARD -d 192.168.1.100 -p tcp --dport 80 -j ACCEPT
# 同时映射多个端口(范围)
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8000:8100 -j DNAT --to-destination 192.168.1.100:8000-81005.3 本机端口重定向
# 将 80 端口重定向到 8080(透明代理常用)
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
# 本机访问也重定向(OUTPUT 链)
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 8080六、高级应用场景
6.1 防端口扫描
# 限制同一 IP 每秒新建连接数(防 SYN 洪水)
iptables -A INPUT -p tcp --syn -m limit --limit 10/s --limit-burst 20 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP
# 限制同一 IP 并发连接数
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j REJECT
# 检测端口扫描并记录日志
iptables -N PORT_SCAN
iptables -A PORT_SCAN -p tcp --tcp-flags ALL NONE -j DROP
iptables -A PORT_SCAN -p tcp --tcp-flags ALL ALL -j DROP
iptables -A PORT_SCAN -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
iptables -A INPUT -j PORT_SCAN6.2 按时间控制访问
# 仅工作日 9:00-18:00 允许 SSH
iptables -A INPUT -p tcp --dport 22 -m time --timestart 09:00 --timestop 18:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT
# 周末不允许访问某服务
iptables -A INPUT -p tcp --dport 3306 -m time --weekdays Sat,Sun -j DROP6.3 字符串匹配(简单应用层过滤)
# 阻止包含特定字符串的 HTTP 请求
iptables -A INPUT -p tcp --dport 80 -m string --string "admin.php" --algo bm -j DROP
# 阻止特定 User-Agent
iptables -A INPUT -p tcp --dport 80 -m string --string "sqlmap" --algo bm -j DROP⚠️ 字符串匹配对 HTTPS 无效,且无法替代专业的 WAF。
6.4 日志记录
# 记录被拒绝的 SSH 连接尝试
iptables -A INPUT -p tcp --dport 22 -m limit --limit 5/min -j LOG --log-prefix "iptables-ssh: " --log-level 4
# 记录所有被丢弃的包(先定义 DROP_LOG 链)
iptables -N DROP_LOG
iptables -A DROP_LOG -m limit --limit 10/min -j LOG --log-prefix "iptables-drop: " --log-level 4
iptables -A DROP_LOG -j DROP
# 使用自定义链
iptables -A INPUT -j DROP_LOG日志默认记录在 /var/log/syslog 或 /var/log/messages。
七、企业级防火墙最佳实践
7.1 规则优化原则
- 最小权限原则:默认拒绝,按需开放
- 规则顺序优化:高频匹配规则放在前面
- 使用状态检测:减少规则数量,提高效率
- 合理注释:每条重要规则说明用途
- 定期审计:清理不再使用的规则
7.2 安全加固建议
# 1. 防止 IP 欺骗(私网地址从公网接口进来)
iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP
iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP
iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP
iptables -A INPUT -i eth0 -s 127.0.0.0/8 -j DROP
# 2. 防止 SYN Flood
iptables -A INPUT -p tcp --syn -m limit --limit 5/s --limit-burst 10 -j ACCEPT
# 3. 防止 Ping of Death
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 10 -j ACCEPT
# 4. 碎片包检测
iptables -A INPUT -f -j DROP7.3 常见服务端口配置清单
| 服务 | 端口 | 协议 | 建议开放 |
|---|---|---|---|
| SSH | 22 | TCP | ✅ 按需 |
| HTTP | 80 | TCP | ✅ 网站服务 |
| HTTPS | 443 | TCP | ✅ 网站服务 |
| DNS | 53 | TCP/UDP | ⚠️ DNS 服务器 |
| FTP | 21 | TCP | ❌ 建议用 SFTP |
| MySQL | 3306 | TCP | ❌ 仅内网 |
| Redis | 6379 | TCP | ❌ 仅内网 |
| MongoDB | 27017 | TCP | ❌ 仅内网 |
八、故障排查
8.1 常见排查命令
# 查看规则匹配计数(哪些规则生效了)
iptables -L -n -v
# 实时跟踪数据包(调试用)
iptables -A INPUT -p tcp --dport 80 -j LOG --log-prefix "DEBUG-80: "
tail -f /var/log/syslog | grep DEBUG-80
# 清空计数器
iptables -Z
# 查看 NAT 表规则
iptables -t nat -L -n -v8.2 被锁在服务器外怎么办?
如果你远程操作 iptables 时不小心把自己封了:
- VNC/控制台:通过云服务商的 VNC 或控制台登录
- 重启服务器:如果规则没保存,重启会恢复默认
- 定时任务保险:配置前先设置定时任务回滚
安全操作建议:
# 配置前先设置 5 分钟后自动清空规则(保险)
echo "iptables -F; iptables -P INPUT ACCEPT" | at now + 5 minutes
# 确认配置无误后,取消定时任务
at -l # 查看任务
atrm <ID> # 删除任务九、iptables 与 ufw / firewalld
- iptables:底层工具,灵活强大,适合高级配置
- ufw:Ubuntu 默认,iptables 的简化封装
- firewalld:CentOS/RHEL 默认,支持区域(zone)概念
它们本质上都是 iptables/nftables 的前端工具,底层原理一致。
十、总结
iptables 是 Linux 系统管理员的必备技能,掌握它可以:
- ✅ 构建坚固的网络防火墙
- ✅ 实现 NAT 和端口转发
- ✅ 控制进出站流量
- ✅ 防范常见网络攻击
- ✅ 实现复杂的网络策略
建议在测试环境中多加练习,熟练掌握后再应用到生产环境。配置防火墙时一定要做好回滚预案,避免远程操作时把自己锁在外面。
相关阅读: