必须停止混合使用iptables和nftables,因二者在内核中争夺同链控制权,导致规则覆盖、conntrack状态不同步、日志冲突;兼容模式仅为过渡,无法解决遗留规则和误调用问题。

直接选 nftables,别再混用 iptables —— 这不是升级建议,而是生产环境的底线要求。
为什么必须停止混合使用
iptables 和 nftables 共存时,不是“两个工具并行”,而是内核里两套规则引擎在抢同一条链的控制权。比如 INPUT 链:iptables 写入的规则和 nftables 定义的 chain 会互相覆盖,导致实际生效的规则和你写的完全不一致。更隐蔽的问题是 conntrack 状态不同步——iptables 删除连接后,nftables 可能还按旧状态放行;日志里同一包出现两条冲突记录,排查时根本分不清哪条真生效。
兼容模式(如 iptables-nft)只是过渡手段,本质是让 iptables 命令翻译成 nftables 指令执行。它不能解决历史遗留规则残留问题,也不能避免脚本中误调用 legacy 二进制(如 /usr/sbin/iptables-legacy)引发的静默失败。
迁移前必须确认的三件事
-
查清当前真实状态:运行
nft list ruleset和iptables-save | head -1。如果后者输出含Generated by nftables,说明已在兼容模式;若显示# Generated by iptables-save,则存在纯 legacy 规则,必须先清理。 -
检查扩展依赖:iptables 中常用的
ipset、geoip、recent模块,在 nftables 中需改用sets或ct timeout等原生机制。没有对应替代方案的模块(如某些私有 match),就得重写逻辑。 -
评估连接跟踪压力:执行
cat /proc/sys/net/netfilter/nf_conntrack_count。若接近/proc/sys/net/netfilter/nf_conntrack_max的 80%,说明现有连接跟踪已吃紧,nftables 的轻量级 ct 处理会明显改善,但迁移过程需避开业务高峰。
规则转换的关键实操要点
-
别信全自动转换:
iptables-translate对简单 filter 规则尚可,但遇到-j LOG --log-prefix、-m physdev(桥接设备)、或自定义 chain 跳转时,生成的 nft 规则常缺 priority 或 hook 参数,必须人工补全。 -
NAT 规则要重审顺序:iptables 的 nat 表分 PREROUTING/POSTROUTING,而 nftables 中所有 nat 都在
inet表下,靠priority控制先后。例如 SNAT 必须设为priority 100,否则可能被其他 chain 拦截。 -
IPv4/IPv6 合并处理:用
inet地址族统一管理,避免再维护两套规则。比如允许 SSH:nft add rule inet filter input tcp dport 22 ct state { new, established } accept,自动覆盖 IPv4 和 IPv6 流量。
上线后验证与兜底机制
-
原子切换,拒绝 reload:用
nft -f /etc/nftables.conf一次性载入整套规则,而非逐条nft add rule。避免中间态规则缺失导致服务中断。 -
保留 legacy 快照但禁用服务:执行
iptables-save > /root/iptables-legacy-backup.v4后,立即停用iptables.service和ip6tables.service,并屏蔽它们(systemctl mask iptables),防止任何 systemd 单元意外触发。 -
监控规则命中率:定期运行
nft list ruleset -a(带句柄号),对比各 rule 的 packet 计数变化。零命中规则要及时删减,高频匹配规则要考虑是否该合并进 set 或 map 提升效率。










