虾米一家
分享生活,分享技术,我们一直在努力

nftables 防火墙进阶:从 iptables 迁移到 Linux 内核级网络防护

nftables 防火墙进阶:从 iptables 迁移到 Linux 内核级网络防护

如果你还在用 iptables 管理服务器或软路由的防火墙规则,这篇文章可能比你想象的更重要。2024 年初,Debian 12 已经将 nftables 设为默认防火墙框架;2025 年,RHEL 系列全面弃用 iptables;而到了 2026 年,大多数 Linux 发行版的 iptables 命令实际上只是一个指向 nftables 的兼容层。

迁移不是选择,而是必然。 但很多人卡在「iptables 规则怎么写」到「nftables 规则怎么写」的转换环节。本文将以实战为导向,带你完成从 iptables 到 nftables 的平滑迁移,并构建一套生产级别的家庭/服务器防火墙体系。

为什么要从 iptables 迁移到 nftables?

这不是一个「新版本更好看」的升级,而是架构层面的根本性改进。

iptables 的历史包袱

iptables 诞生于 2001 年,基于 Netfilter 框架设计。经过二十多年的发展,它积累了几个无法忽视的问题:

  • 多套工具并存:IPv4 用 iptables,IPv6 用 ip6tables,arp 过滤用 arptables,桥接用 ebtables。管理一个完整的防火墙需要维护四套独立的规则集,规则重复且容易不一致。
  • 线性匹配性能差:规则按顺序逐条匹配,当规则数量达到几百条时,每个数据包的匹配开销显著增加。
  • 原子更新困难:修改规则时需要 flush 整个链,这会导致短暂的网络中断——在生产环境中这是不可接受的。
  • 规则可读性差:一条复杂的 NAT + 过滤规则可能需要十几行 iptables 命令,逻辑关系不够直观。

nftables 的架构优势

nftables 从 2014 年进入 Linux 3.13 内核开始,经过十余年的迭代,已经非常成熟。它的核心设计解决了 iptables 的所有痛点:

特性 iptables nftables
统一框架 四套独立工具 单一线程管理 IPv4/IPv6/arp/bridge
匹配性能 线性匹配 O(n) 集合/映射 O(1)
原子更新 需要 flush 单条命令原子替换
规则语法 命令堆叠 声明式配置
日志输出 固定格式 自定义前缀和内容

最关键的一点:nftables 的集合(set)和映射(map)功能,让 IP 黑白名单、端口开放列表等操作从「逐条添加规则」变成了「维护一个数据结构」,在规则数量多的场景下性能差距可达数十倍。

核心概念对照:从 iptables 思维到 nftables 思维

迁移的第一步是理解概念的映射关系。iptables 和 nftables 不是简单的命令替换,而是思维方式的转变。

层级结构对照

iptables 的层级是:Table → Chain → Rule。
nftables 的层级是:Table → Chain → Rule,但更加灵活:

iptables 概念 nftables 概念 说明
filter/nat/mangle/raw 表 任意命名的表(type 字段指定用途) nftables 的表没有预定义名称,通过 type 字段区分 filter/nat 等用途
INPUT/FORWARD/OUTPUT 链 hook 链(指定 hook 类型和优先级) nftables 用 hook filter input priority 0 这样的声明替代固定链名
-A / -I / -D 操作 add / insert / delete rule 命令语义更清晰,接近自然语言
无集合概念 set / map(核心优势) IP 列表、端口列表可动态增删,无需重载规则

常用规则对照速查

下面是日常运维中最常用的规则转换对照:

# ===== 基础过滤规则 =====

# iptables: 允许已建立连接
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# nftables: 等价写法
nft add rule inet filter input ct state established,related accept

# iptables: 允许回环接口
iptables -A INPUT -i lo -j ACCEPT

# nftables
nft add rule inet filter input iifname lo accept

# iptables: 丢弃无效连接
iptables -A INPUT -m conntrack --ctstate invalid -j DROP

# nftables
nft add rule inet filter input ct state invalid drop

# ===== NAT 规则 =====

# iptables: 端口转发 8080 → 80
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80

# nftables
nft add rule ip nat prerouting tcp dport 8080 redirect to :80

# iptables: MASQUERADE(软路由常见场景)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# nftables
nft add rule ip nat postrouting oifname eth0 masquerade

# ===== 速率限制 =====

# iptables: 限制 SSH 每分钟最多 4 个新连接
iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-above 4 -j REJECT

# nftables
nft add rule inet filter input tcp dport 22 ct state new limit rate 4/minute accept

实战:构建完整的家庭/服务器防火墙

理论说再多不如动手做。下面我们以一台运行 Debian 12 的服务器(或软路由)为例,从零构建一套完整的 nftables 防火墙配置。

第一步:确认 nftables 环境

# 检查 nft 版本
nft --version
# 输出示例:nftables v1.0.6 (Supports Old Service (Liberty) v3)

# 检查内核模块
lsmod | grep nf_tables

# 查看当前规则(应该是空的或只有 iptables 兼容层规则)
nft list ruleset

第二步:编写声明式配置文件

nftables 的最大优势之一是支持声明式配置文件。我们将所有规则写在一个文件中,然后通过一条命令加载:

# /etc/nftables.conf
#!/usr/sbin/nft -f

# 清空现有规则(原子操作,避免中断)
flush ruleset

# ===== 定义可复用的集合 =====

# 允许访问的管理 IP 列表(白名单)
# 生产环境中建议使用 CIDR 范围,不要只写单个 IP
define ADMIN_IPS = { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 }

# 对外提供服务的端口
define PUBLIC_TCP_PORTS = { 22, 80, 443 }

# 需要限速的敏感服务端口
define RATE_LIMIT_PORTS = { 22, 3306, 5432 }

# 内网接口(根据你的实际情况修改)
define LAN_IFACE = "eth1"
define WAN_IFACE = "eth0"

# ===== 基础过滤表 =====

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

        # 1. 回环接口无条件放行
        iifname lo accept

        # 2. 已建立连接和 Related 连接放行
        ct state established,related accept

        # 3. 无效连接直接丢弃
        ct state invalid drop

        # 4. ICMP 放行(允许 ping,但限制速率)
        ip protocol icmp limit rate 10/second accept
        ip6 nexthdr icmpv6 limit rate 10/second accept

        # 5. 管理端口仅允许内网 IP 访问
        tcp dport 22 ip saddr $ADMIN_IPS accept

        # 6. 公共服务端口放行
        tcp dport $PUBLIC_TCP_PORTS accept

        # 7. 记录并丢弃其余所有入站流量
        log prefix "[nft-dropped-input] " level info
        drop
    }

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

        # 内网到外网的转发允许
        iifname $LAN_IFACE oifname $WAN_IFACE accept

        # 外网到内网的转发仅允许已建立连接
        iifname $WAN_IFACE oifname $LAN_IFACE ct state established,related accept

        # 记录并丢弃其余转发
        log prefix "[nft-dropped-forward] " level info
        drop
    }

    chain output {
        type filter hook output priority 0; policy accept;
        # 出站默认放行,按需添加限制
    }
}

# ===== NAT 表 =====

table ip nat {
    chain prerouting {
        type nat hook prerouting priority -100; policy accept;
        # 端口转发示例:外部 8080 → 内网 Web 服务
        tcp dport 8080 dnat to 192.168.1.100:80
    }

    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        # 内网 MASQUERADE(软路由必备)
        oifname $WAN_IFACE masquerade
    }
}

第三步:加载配置并验证

# 语法检查(不实际应用)
nft -c -f /etc/nftables.conf

# 加载配置(会先 flush ruleset)
nft -f /etc/nftables.conf

# 查看当前生效的规则
nft list ruleset

# 验证规则数量
nft list chain inet filter input
nft list chain ip nat postrouting

第四步:配置开机自启

# Debian/Ubuntu
systemctl enable nftables
systemctl start nftables

# 确认服务状态
systemctl status nftables

⚠️ 重要提示: 在远程服务器上操作防火墙时,务必在加载新规则之前准备好回退方案。建议在另一个终端窗口保持 SSH 连接,并设置一个定时任务在 5 分钟后恢复 iptables 兼容规则:

# 5 分钟后自动 flush nftables(给自己留退路)
echo 'nft flush ruleset' | at now + 5 minutes

# 确认规则没问题后,取消定时任务
atrm <job_id>

高级技巧:动态 IP 黑名单与自动封禁

nftables 真正的杀手级功能是动态集合。与 iptables 的 ipset 相比,nftables 的 set 内建于框架之中,使用更简单、性能更好。

场景:自动封禁暴力破解 SSH 的 IP

我们可以利用 nftables 的 set 配合 timeout 功能,实现一个轻量级的自动封禁系统,无需依赖 fail2ban:

table inet filter {
    # 定义一个带自动过期功能的集合
    # 被封禁的 IP 在 1 小时后自动移除
    set ssh_blocklist {
        type ipv4_addr
        flags timeout
        timeout 1h
    }

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

        # 先检查是否在黑名单中
        ip saddr @ssh_blocklist drop

        # 正常规则...
        ct state established,related accept
        ct state invalid drop
        iifname lo accept

        # SSH 连接追踪:同一 IP 1 分钟内超过 3 个新连接 → 加入黑名单
        tcp dport 22 ct state new add @ssh_blocklist { ip saddr timeout 1h } limit rate over 3/minute drop

        # 其余规则...
    }
}

这段配置的精髓在于:limit rate over 3/minute 触发了 add @ssh_blocklist 动作,将来源 IP 加入黑名单并设置 1 小时过期。整个过程完全在内核态执行,零性能损耗。

查看和管理黑名单

# 查看当前被封禁的 IP
nft list set inet filter ssh_blocklist

# 手动添加 IP 到黑名单
nft add element inet filter ssh_blocklist { 203.0.113.50 }

# 手动移除 IP
nft delete element inet filter ssh_blocklist { 203.0.113.50 }

迁移 checklist:从 iptables 到 nftables

如果你有一台正在运行的 iptables 服务器,按以下步骤安全迁移:

步骤 操作 验证方法
1 备份现有 iptables 规则 iptables-save > /tmp/iptables-backup.txt
2 安装 nftables apt install nftables && nft –version
3 使用 iptables-translate 工具自动转换 iptables-translate -c /tmp/iptables-backup.txt
4 手动优化转换后的规则 用 set/map 替换重复规则
5 语法检查 nft -c -f /etc/nftables.conf
6 加载并测试 保留 SSH 会话 + at 回退机制
7 禁用 iptables 服务 systemctl disable iptables
8 设置 nftables 开机自启 systemctl enable nftables

常见问题与排错

Q1: nftables 和 iptables 能共存吗?

可以,但强烈不建议。两者操作的是同一个 Netfilter 框架,混合使用会导致规则冲突、调试困难和难以预测的行为。迁移时应该一次性切换。

Q2: Docker 的防火墙规则会和 nftables 冲突吗?

Docker 20.10+ 原生支持 nftables 后端。确保 Docker 配置文件中设置 "iptables": false 并使用 "firewalld": false,Docker 会自动通过 nftables 管理其规则。如果仍有问题,可以在 nftables 配置中为 Docker 的 bridge 接口(通常是 docker0)添加例外规则。

Q3: 如何排查规则不生效的问题?

# 开启规则计数器(每条规则显示命中次数)
nft --handle list chain inet filter input

# 查看命中计数为 0 的规则,可能就是这些规则没生效

# 查看内核日志
journalctl -k | grep nft

# 使用 nft monitor 实时查看规则匹配
nft monitor

Q4: IPv6 需要单独配置吗?

不需要。使用 table inet filter(注意是 inet 而不是 ip)就可以同时处理 IPv4 和 IPv6 流量。唯一的例外是 ICMP:IPv4 用 ip protocol icmp,IPv6 用 ip6 nexthdr icmpv6,需要分别处理。

总结:迁移的最佳时机就是现在

nftables 不是 iptables 的”替代品”,而是它的进化。经过十余年的发展,nftables 已经成为 Linux 网络防护的事实标准。对于还在使用 iptables 的系统管理员和运维工程师来说:

  • 新部署:直接使用 nftables,不要再碰 iptables
  • 现有服务器:制定迁移计划,利用 iptables-translate 工具降低迁移成本
  • 软路由/OpenWrt:OpenWrt 23.05+ 已原生支持 nftables,建议启用

防火墙是系统安全的第一道防线。用更现代、更高效、更可维护的工具来守护它,是每个 Linux 管理员应该做出的选择。

作者简介:虾米,专注 Linux 系统运维与网络安全实践。本文基于 Debian 12 / Ubuntu 24.04 环境编写,规则经过实际测试验证。
相关标签:nftables · iptables · Linux · 防火墙 · 网络安全 · 软路由 · OpenWrt

赞(0) 打赏
未经允许不得转载:虾米生活分享 » nftables 防火墙进阶:从 iptables 迁移到 Linux 内核级网络防护

评论 抢沙发

评论前必须登录!

 

虾米一家,生活分享!

关于我们收藏本站

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏