iptables/nftables 防火墙配置与安全策略实战

一、概述

Linux 防火墙是服务器安全的第一道防线。本文详细介绍 iptables 和 nftables 的配置方法、安全策略设计以及生产环境最佳实践。

1.1 iptables vs nftables

特性 iptables nftables
内核版本 2.4+ 3.13+
配置文件 /etc/sysconfig/iptables /etc/nftables.conf
性能 较低(多表处理) 较高(统一框架)
语法 复杂 简洁
原子更新 不支持 支持

建议:新部署优先使用 nftables,存量系统可继续使用 iptables。

二、iptables 基础配置

2.1 链与表结构

1
2
3
4
5
6
7
8
9
10
11
┌─────────────────────────────────────────┐
│ 表 (Tables) │
├─────────┬─────────┬─────────┬───────────┤
│ filter │ nat │ mangle │ raw │
├─────────┼─────────┼─────────┼───────────┤
│ INPUT │ PREROUTING│PREROUTING│PREROUTING│
│ FORWARD │ INPUT │ INPUT │ OUTPUT │
│ OUTPUT │ OUTPUT │ FORWARD │ │
│ │ POSTROUTING│OUTPUT │ │
│ │ │ POSTROUTING│ │
└─────────┴─────────┴─────────┴───────────┘

2.2 基本命令

1
2
3
4
5
6
7
8
9
10
11
12
13
# 查看规则
iptables -L -n -v
iptables -t nat -L -n -v

# 清空规则
iptables -F
iptables -X
iptables -Z

# 设置默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

2.3 生产环境配置脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/bin/bash
# /usr/local/bin/iptables-hardening.sh

# 清空现有规则
iptables -F
iptables -X
iptables -Z

# 设置默认策略
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 -m state --state NEW -j ACCEPT

# 允许 HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 允许 ICMP (ping)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# 防止 SYN 洪水攻击
iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT

# 防止端口扫描
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# 记录被拒绝的连接
iptables -A INPUT -j LOG --log-prefix "IPTABLES-DROPPED: " --log-level 4

# 保存规则 (CentOS/RHEL)
service iptables save

# 保存规则 (Debian/Ubuntu)
iptables-save > /etc/iptables/rules.v4

三、nftables 配置

3.1 安装与启用

1
2
3
4
5
6
7
8
9
# Ubuntu/Debian
apt install nftables
systemctl enable nftables
systemctl start nftables

# CentOS/RHEL
yum install nftables
systemctl enable nftables
systemctl start nftables

3.2 配置文件结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# /etc/nftables.conf
#!/usr/sbin/nft -f

flush ruleset

table inet filter {
chain input {
type filter hook input priority 0; policy drop;

# 允许回环
iif "lo" accept

# 允许已建立连接
ct state established,related accept

# 丢弃无效连接
ct state invalid drop

# 允许 SSH
tcp dport 22 accept

# 允许 HTTP/HTTPS
tcp dport { 80, 443 } accept

# 允许 ICMP
icmp type echo-request accept
icmpv6 type echo-request accept

# 限制 SSH 连接速率
tcp dport 22 ct state new limit rate 3/minute accept

# 记录并丢弃其他
log prefix "nftables-input-drop: " drop
}

chain forward {
type filter hook forward priority 0; policy drop;
}

chain output {
type filter hook output priority 0; policy accept;
}
}

3.3 常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看规则
nft list ruleset
nft list ruleset -a # 显示句柄

# 重载配置
nft -f /etc/nftables.conf

# 添加规则
nft add rule inet filter input tcp dport 8080 accept

# 删除规则 (使用句柄)
nft delete rule inet filter input handle 5

# 清空链
nft flush chain inet filter input

# 删除表
nft delete table inet filter

四、高级安全策略

4.1 DDoS 防护

1
2
3
4
5
6
7
8
9
10
# iptables - 限制新建连接速率
iptables -A INPUT -p tcp --syn -m limit --limit 25/s --limit-burst 50 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP

# 限制每个 IP 的连接数
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 20 -j DROP

# nftables 版本
nft add rule inet filter input tcp dport 80 ct state new limit rate 25/second accept
nft add rule inet filter input tcp dport 80 ct state new drop

4.2 端口敲门 (Port Knocking)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 实现简单的端口敲门:依次访问 7000->8000->9000 后开放 SSH
# 需要 recent 模块支持

# 第一步:记录访问 7000
iptables -A INPUT -p tcp --dport 7000 -m recent --set --name KNOCK1

# 第二步:检查是否访问过 7000,记录访问 8000
iptables -A INPUT -p tcp --dport 8000 -m recent --rcheck --seconds 5 --name KNOCK1 -m recent --set --name KNOCK2

# 第三步:检查是否访问过 8000,记录访问 9000
iptables -A INPUT -p tcp --dport 9000 -m recent --rcheck --seconds 5 --name KNOCK2 -m recent --set --name KNOCK3

# 第四步:检查完整敲门序列,开放 SSH
iptables -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 5 --name KNOCK3 -j ACCEPT

# 清理过期记录
iptables -A INPUT -m recent --rcheck --seconds 60 --name KNOCK1 -m recent --remove --name KNOCK1

4.3 地理位置封锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 使用 ipset + geoip 数据库
# 安装
apt install ipset geoip-database

# 创建 ipset
ipset create blocked_countries hash:net
ipset create allowed_countries hash:net

# 添加国家 IP 段 (示例:封锁特定国家)
# 需要从 geoip 数据库获取 IP 段
ipset add blocked_countries 1.0.1.0/24
ipset add blocked_countries 1.0.2.0/24

# 应用规则
iptables -A INPUT -m set --match-set blocked_countries src -j DROP

4.4 应用层防护

1
2
3
4
5
6
7
# 限制 HTTP 请求速率
iptables -A INPUT -p tcp --dport 80 -m recent --set --name HTTP
iptables -A INPUT -p tcp --dport 80 -m recent --update --seconds 1 --hitcount 50 --name HTTP -j DROP

# 防止 SQL 注入特征 (需要 string 模块)
iptables -A INPUT -p tcp --dport 80 -m string --string "UNION SELECT" --algo bm -j DROP
iptables -A INPUT -p tcp --dport 80 -m string --string "DROP TABLE" --algo bm -j DROP

五、故障排查

5.1 诊断命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看规则及计数器
iptables -L -n -v --line-numbers

# 查看 NAT 规则
iptables -t nat -L -n -v

# 实时查看被拒绝的连接
tail -f /var/log/messages | grep IPTABLES
# 或
journalctl -f | grep nftables

# 测试端口连通性
telnet <IP> <PORT>
nc -zv <IP> <PORT>

# 查看连接状态
ss -tunlp
netstat -tunlp

5.2 常见问题

问题 1:SSH 被锁在外面

1
2
3
# 解决方案:通过控制台访问,临时清空规则
iptables -F
iptables -P INPUT ACCEPT

问题 2:规则不生效

1
2
3
4
5
# 检查规则顺序
iptables -L -n --line-numbers

# 检查是否有更早的规则匹配
# 规则从上到下匹配,第一条匹配的规则生效

问题 3:NAT 转发不工作

1
2
3
4
5
6
7
# 开启 IP 转发
echo 1 > /proc/sys/net/ipv4/ip_forward
# 永久生效
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf

# 检查 NAT 规则
iptables -t nat -L -n -v

六、备份与恢复

6.1 iptables 备份

1
2
3
4
5
6
7
8
# 备份
iptables-save > /root/iptables-backup-$(date +%Y%m%d).rules

# 恢复
iptables-restore < /root/iptables-backup-20260315.rules

# 定时备份 (cron)
0 2 * * * /sbin/iptables-save > /root/iptables-backup-$(date +\%Y\%m\%d).rules

6.2 nftables 备份

1
2
3
4
5
6
# 备份
cp /etc/nftables.conf /root/nftables-backup-$(date +%Y%m%d).conf

# 恢复
cp /root/nftables-backup-20260315.conf /etc/nftables.conf
nft -f /etc/nftables.conf

七、安全加固建议

7.1 最小化开放原则

  • 只开放必要的端口
  • 使用非标准端口运行敏感服务
  • 定期审查防火墙规则

7.2 日志与监控

1
2
3
4
5
6
7
# 配置日志级别
iptables -A INPUT -j LOG --log-prefix "FW-DROP: " --log-level 4

# 使用 rsyslog 分离防火墙日志
# /etc/rsyslog.d/10-firewall.conf
:msg, contains, "IPTABLES" /var/log/iptables.log
& stop

7.3 定期审计

1
2
3
4
5
6
# 检查规则变更
auditctl -w /sbin/iptables -p x
auditctl -w /etc/nftables.conf -p wa

# 查看审计日志
ausearch -f /sbin/iptables -i

八、总结

防火墙配置是服务器安全的基础。关键要点:

  1. 默认拒绝:默认策略设为 DROP,只开放必要端口
  2. 分层防护:结合 iptables/nftables 与应用层安全
  3. 日志记录:记录被拒绝的连接用于分析
  4. 定期审查:定期审计规则,清理过期配置
  5. 备份恢复:定期备份规则,确保可快速恢复

生产环境部署前,务必在测试环境充分验证,并确保有带外管理方式(如 IPMI、控制台)以防配置失误导致无法访问。