nftables全面替代iptables:从原理到实战的配置指南
📖 文章目录导读
- 为什么需要从iptables迁移到nftables
- nftables与iptables的核心架构差异
- nftables配置基础:命令行与语法
- 关键配置迁移对照表(常见场景)
- 实战案例:用nftables替代iptables配置防火墙规则
- 性能优化与调试技巧
- 常见问题解答(FAQ)
- 总结与建议
为什么需要从iptables迁移到nftables
iptables作为Linux内核Netfilter框架的传统用户空间工具,已经服务了超过20年,随着网络复杂度的提升,其局限性日益明显:规则集线性遍历导致性能瓶颈、单一大表难以管理、IPv4/IPv6配置分离、脚本化配置冗长。nftables作为Netfilter的新一代框架,自内核3.13起被引入,并在RHEL 8、Debian 10、Ubuntu 20.04等主流发行版中成为默认防火墙工具。

关键优势:
- 统一性:IPv4和IPv6共享同一规则集,无需单独配置
iptables和ip6tables - 性能:原生支持集合(sets)和映射(maps),避免线性匹配,规则数越多优势越明显
- 语法:引入类JSON结构化语法,减少错误,支持变量、函数、模块化文件
- 原子更新:
nft -f命令支持原子提交整个规则集,避免iptables逐条增删导致的中间状态漏洞
问答:Q:我的服务器是CentOS 7,能使用nftables吗?
A:CentOS 7默认使用iptables,但内核(3.10+)支持nftables,需安装nftables包并启用,但推荐直接升级到CentOS 8/9或Rocky Linux 8+,因为iptables在CentOS 7中仍为主流,但迁移后性能提升明显。
nftables与iptables的核心架构差异
| 对比维度 | iptables | nftables |
|---|---|---|
| 表结构 | 固定4张过滤表(filter, nat, mangle, raw) + 安全表 | 用户自定义表(table),表内包含链(chain),链内包含规则(rule) |
| 链类型 | 固定5条钩子链(INPUT, OUTPUT, FORWARD等) | 链类型为基础链(base chain,绑定钩子)或普通链(非钩子,用于跳转) |
| 规则存储 | 内核通过iptables命令逐行操作 | 通过nft命令或nft -f加载整个规则集文件 |
| 匹配扩展 | 依赖-m模块(如conntrack) |
原生支持大部分匹配,语法更统一(如ct state代替-m conntrack --ctstate) |
| 性能特点 | 线性遍历,匹配大量规则时CPU开销高 | 使用集合(set)实现O(1)哈希查找,配合verdict映射实现跳转优化 |
核心概念解析:
- Table:类似“容器”,一个表包含一个或多个链,例如
table inet filter创建一个支持双栈的过滤表 - Chain:基础链必须指定钩子(如
type filter hook input priority 0),普通链通过jump或goto调用 - Rule:由匹配条件(matchers)和动作(verdict)组成,如
tcp dport {80,443} accept
nftables配置基础:命令行与语法
1 基本命令结构
nft add table inet my_table # 创建双栈表
nft add chain inet my_table input { type filter hook input priority 0\; } # 添加基础链
nft add rule inet my_table input tcp dport 22 accept # 添加规则
2 规则语法要素
- 数据集表达式:
tcp dport {80,443}匹配多个端口,比iptables的多个规则更简洁 - 集合(set):定义命名集合,可动态更新
nft add set inet my_table allowed_ips { type ipv4_addr\; } nft add rule inet my_table input ip saddr @allowed_ips accept - 映射(map):实现键值对路由
nft add map inet my_table port_map { type inet_service : verdict\; } nft add element inet my_table port_map { 80 : accept, 443 : drop }
3 原子加载规则集(推荐方式)
将规则写入文件/etc/nftables.conf:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
tcp dport 22 accept
ip protocol icmp accept
}
}
然后执行nft -f /etc/nftables.conf。
问答:Q:iptables的
-A INPUT -p tcp --dport 80 -j ACCEPT在nftables中如何写?
A:对应的nftables规则为nft add rule inet filter input tcp dport 80 accept,注意tcp dport直接匹配,无需-p tcp和--dport分离,且默认使用双栈inet表。
关键配置迁移对照表(常见场景)
| 功能需求 | iptables命令 | nftables规则 |
|---|---|---|
| 允许SSH | iptables -A INPUT -p tcp --dport 22 -j ACCEPT |
tcp dport 22 accept |
| 允许已建立连接 | iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT |
ct state established,related accept |
| 允许ICMP | iptables -A INPUT -p icmp -j ACCEPT |
ip protocol icmp accept(IPv4)/ icmpv6 type echo-request accept(IPv6) |
| DNAT端口转发 | iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10:8080 |
table ip nat; chain prerouting { type nat hook prerouting priority dstnat; tcp dport 80 dnat to 192.168.1.10:8080 } |
| 记录日志并丢弃 | iptables -A INPUT -j LOG --log-prefix "DROPPED: " + iptables -A INPUT -j DROP |
log prefix "DROPPED: " drop(单条规则实现日志+丢弃) |
| 速率限制 | iptables -A INPUT -p tcp --dport 80 -m limit --limit 10/s -j ACCEPT |
tcp dport 80 limit rate 10/second accept |
| IP集合批量放行 | 需ipset配合 |
table inet filter { set whitelist { type ipv4_addr; elements={192.168.1.1, 10.0.0.0/8} } chain input { ip saddr @whitelist accept } } |
问答:Q:nftables如何实现iptables的
-j REJECT?
A:使用reject动作,例如tcp dport 80 reject with tcp reset可发送TCP RST包,默认reject不指定参数时发送ICMP端口不可达。
实战案例:用nftables替代iptables配置防火墙规则
需求:一台Web服务器(双栈),需开放SSH(22)、HTTP(80)、HTTPS(443),限制ICMP速率,放行内部管理IP段(10.0.0.0/8),丢弃其余流量并记录日志。
1 旧版iptables配置(简化)
iptables -P INPUT DROP iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -s 10.0.0.0/8 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT iptables -A INPUT -p icmp -m limit --limit 1/s -j ACCEPT iptables -A INPUT -j LOG --log-prefix "Denied: " iptables -A INPUT -j DROP
2 新版nftables配置(推荐文件方式)
创建文件/etc/nftables.d/webserver.conf:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# 允许已建立连接和回环接口
ct state established,related accept
iif lo accept
# 内部管理IP段
ip saddr 10.0.0.0/8 accept
# 开放服务端口
tcp dport {22,80,443} accept
# ICMP速率限制(IPv4)
ip protocol icmp limit rate 1/second accept
# (IPv6类似:icmpv6 type echo-request limit rate 1/second accept)
# 记录被丢弃的流量(日志前缀可自定义)
log prefix "nftables-denied: " drop
}
chain output {
type filter hook output priority 0; policy accept;
}
chain forward {
type filter hook forward priority 0; policy drop;
}
}
加载:nft -f /etc/nftables.d/webserver.conf。
验证配置:
nft list ruleset # 查看所有规则 nft monitor # 实时跟踪匹配(类似iptables -L -v动态跟踪)
问答:Q:nftables配置如何持久化?
A:在systemd系统中,将规则文件保存为/etc/nftables.conf并启用systemctl enable nftables即可,注意:nftables.service默认会加载/etc/nftables.conf,需确保文件包含完整的规则集(含flush ruleset)。
性能优化与调试技巧
1 使用集合桶(set)替代规则列表
当需要匹配大量IP或端口时,使用nft add set并借助ip saddr @set匹配,内核自动使用哈希表,匹配速度远快于逐条规则,例如白名单5000个IP,用set只需一次规则匹配。
2 利用verdict跳转减少重复匹配
创建普通链执行公共操作,如日志记录、限速等:
chain log_and_drop {
log prefix "drop: " drop
}
chain input {
tcp dport 22 jump log_and_drop # 只有SSH匹配失败时记录日志
}
3 调试命令
nft list ruleset -a:显示规则句柄,便于nft delete rule inet filter input handle 3删除指定规则nft monitor:动态跟踪每条规则匹配次数,类似iptables -L -v -xnft --debug=all add rule ...:查看内核扩展调试信息
常见问题解答(FAQ)
Q1:nftables和iptables能共存吗? A:可以共存,但强烈不推荐,两者都操作Netfilter钩子,混合使用会导致规则冲突和难以调试,建议完全替代。
Q2:如何从复杂的iptables脚本平滑迁移?
A:使用iptables-translate工具(部分发行版提供iptables-nft-compat)尝试自动转换单条规则,但复杂场景需手动重写,推荐先用nft -v查看内核支持情况,逐步将核心规则迁移。
Q3:nftables支持SNAT/MASQUERADE吗? A:支持,例如MASQUERADE用于NAT:
table ip nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oif eth0 masquerade # 等同于iptables的-A POSTROUTING -j MASQUERADE
}
}
Q4:CentOS 8中nftables与firewalld的关系?
A:火墙服务(firewalld)在RHEL 8/9中底层已使用nftables,通过firewall-cmd配置会自动生成nftables规则,无需直接操作nft命令,但纯路由/NAT场景建议直接使用nftables。
总结与建议
nftables并非简单的“iptables替代品”,而是Linux防火墙配置的范式升级,其结构化语法、原子提交、高性能集合机制,更适合现代数据中心和云原生环境。建议行动步骤:
- 在测试环境安装nftables,使用
nft命令熟悉基础语法 - 将现有iptables规则对照迁移文档手动转换为nftables文件
- 部署时先清空iptables规则,仅启用nftables服务,观察务连续性
- 利用
nft monitor持续优化规则性能
你会发现规则量减少30%-50%,CPU占用降低(特别是大规则集场景),且配置可读性大幅提升,Linux社区已明确nftables为未来方向,现在迁移是对运维体系的一次高效投资。