跳转到内容

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

iptables 防火墙配置

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 查看规则

bash
# 查看 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 添加规则

bash
# 在链末尾追加规则
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 ACCEPT

2.3 删除规则

bash
# 按编号删除 INPUT 链第 2 条规则
iptables -D INPUT 2

# 按内容删除规则
iptables -D INPUT -p tcp --dport 22 -j ACCEPT

# 清空指定链的所有规则
iptables -F INPUT

# 清空所有链
iptables -F

# 清空 nat 表
iptables -t nat -F

2.4 修改默认策略

bash
# 设置 INPUT 链默认策略为 DROP(谨慎操作!)
iptables -P INPUT DROP

# 设置 FORWARD 链默认策略为 DROP
iptables -P FORWARD DROP

# 设置 OUTPUT 链默认策略为 ACCEPT
iptables -P OUTPUT ACCEPT

⚠️ 警告:远程操作时,切勿将 INPUT 默认策略设为 DROP 且未允许 SSH 端口,否则会被锁在服务器外!


三、常用匹配条件

3.1 协议与端口

bash
# 匹配 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 ACCEPT

3.2 IP 地址匹配

bash
# 匹配源 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 ACCEPT

3.3 状态匹配(连接跟踪)

bash
# 允许已建立和相关的连接
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 完整防火墙脚本

bash
#!/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,执行:

bash
chmod +x firewall-setup.sh
./firewall-setup.sh

4.2 规则保存与恢复

bash
# 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 上网:

bash
# 启用 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 MASQUERADE

5.2 DNAT(目的地址转换 / 端口映射)

将公网端口映射到内网服务器:

bash
# 将公网 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-8100

5.3 本机端口重定向

bash
# 将 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 防端口扫描

bash
# 限制同一 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_SCAN

6.2 按时间控制访问

bash
# 仅工作日 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 DROP

6.3 字符串匹配(简单应用层过滤)

bash
# 阻止包含特定字符串的 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 日志记录

bash
# 记录被拒绝的 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 规则优化原则

  1. 最小权限原则:默认拒绝,按需开放
  2. 规则顺序优化:高频匹配规则放在前面
  3. 使用状态检测:减少规则数量,提高效率
  4. 合理注释:每条重要规则说明用途
  5. 定期审计:清理不再使用的规则

7.2 安全加固建议

bash
# 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 DROP

7.3 常见服务端口配置清单

服务端口协议建议开放
SSH22TCP✅ 按需
HTTP80TCP✅ 网站服务
HTTPS443TCP✅ 网站服务
DNS53TCP/UDP⚠️ DNS 服务器
FTP21TCP❌ 建议用 SFTP
MySQL3306TCP❌ 仅内网
Redis6379TCP❌ 仅内网
MongoDB27017TCP❌ 仅内网

八、故障排查

8.1 常见排查命令

bash
# 查看规则匹配计数(哪些规则生效了)
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 -v

8.2 被锁在服务器外怎么办?

如果你远程操作 iptables 时不小心把自己封了:

  1. VNC/控制台:通过云服务商的 VNC 或控制台登录
  2. 重启服务器:如果规则没保存,重启会恢复默认
  3. 定时任务保险:配置前先设置定时任务回滚

安全操作建议:

bash
# 配置前先设置 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 和端口转发
  • ✅ 控制进出站流量
  • ✅ 防范常见网络攻击
  • ✅ 实现复杂的网络策略

建议在测试环境中多加练习,熟练掌握后再应用到生产环境。配置防火墙时一定要做好回滚预案,避免远程操作时把自己锁在外面。


相关阅读: