nftables使用教程
一、引言:为什么是 nftables?
随着 CentOS 8 和 RHEL 8 的发布,一个重要的变化是:**nftables 框架已取代 iptables 成为默认的网络包过滤工具**。如果你还在使用 iptables,现在是时候了解它的继任者了。
nftables 是什么?
它是 netfilter 项目推出的新框架,旨在全面替代现有的 {ip,ip6,arp,eb}tables。它提供了一个全新的包过滤框架、用户空间工具 nft 以及向后兼容层。
核心优势对比 iptables:
- 数据结构:iptables 使用数组式布局,nftables 使用链式布局(链表),更灵活。
- 可扩展性:iptables 功能扩展需修改内核;nftables 大部分工作在用户态完成,添加功能更容易。
- 性能:iptables 存在内置链和计数器,有空链开销;nftables 无内置链,按需创建。
- 易用性:原生支持集合、字典和映射,简化了 IPv4/IPv6 双栈管理。
本文主要介绍用户空间命令行工具 nft 的使用方法。
二、基础概念与快速开始
2.1 核心组件
nftables 由三个核心层级构成:
- 内核:提供 netlink 配置接口和规则集评估。
- libnl:提供与内核通信的基础库。
- **nft (用户空间)**:供用户交互的命令行工具。
2.2 规则结构
与 iptables 类似,nftables 也由 表(Table) -> 链(Chain) -> 规则(Rule) 层级构成。规则是真正的执行动作。
检查当前规则集:
1 | nft list ruleset |
初始状态下,如果没有启用 firewalld 等服务,输出为空,这印证了 nftables 没有内置链的特性。
三、实战操作:从创建到管理
3.1 创建表(Table)
表是规则的顶级容器,每个表只属于一个特定的“地址簇”。
| nftables 地址簇 | 对应的传统工具 | 说明 |
|---|---|---|
ip |
iptables | 仅处理 IPv4 数据包 |
ip6 |
ip6tables | 仅处理 IPv6 数据包 |
inet |
iptables & ip6tables | 处理 IPv4 和 IPv6(推荐) |
arp |
arptables | 处理 ARP 层数据包 |
bridge |
ebtables | 处理桥接数据包 |
创建表示例(使用 inet 簇):
1 | nft add table inet my_table |
列出所有规则以验证:
1 | nft list ruleset |
3.2 创建链(Chain)
链是规则的载体,必须显式创建。链有两种类型:
- 常规链:用于规则分类和跳转,无需指定钩子。
- 基本链:数据包的入口点,必须指定钩子类型和优先级。
创建常规链:
1 | nft add chain inet my_table my_utility_chain |
创建基本链(作为数据包入口):
1 | nft add chain inet my_table my_filter_chain '{ type filter hook input priority 0; }' |
type filter:链类型为过滤。hook input:钩子点为输入。priority 0:优先级(数值越小,优先级越高)。- 注意:分号
;需要用反斜杠\转义,或直接用引号包裹整个参数。
3.3 创建规则(Rule)
规则由语句构成,放置在链中。
在链末尾添加规则(允许 SSH):
1 | nft add rule inet my_table my_filter_chain tcp dport ssh accept |
在链开头插入规则(允许 HTTP):
1 | nft insert rule inet my_table my_filter_chain tcp dport http accept |
在指定位置插入规则:
有两种方式,推荐使用稳定的 handle 而非易变的 index。
- 使用
index(从0开始):1
2# 在索引1的规则前插入(即第二条规则前)
nft insert rule inet my_table my_filter_chain index 1 tcp dport nfs accept - 使用
handle(句柄值唯一且不变):创建规则时获取句柄:1
2
3
4
5# 首先查看规则的句柄
nft --handle list ruleset
# 假设 `tcp dport http accept` 的句柄是 4
# 在该句柄的规则后添加新规则
nft add rule inet my_table my_filter_chain handle 4 tcp dport 2345 accept1
2nft --echo --handle add rule inet my_table my_filter_chain udp dport 3333 accept
# 输出会包含新规则的句柄,例如 `# handle 10`
3.4 删除规则
规则只能通过其唯一的 handle 删除。
1 | # 1. 查找要删除规则的句柄 |
3.5 查看规则
支持不同粒度的查看。
1 | # 查看所有规则 |
四、高级特性:集合与字典
4.1 集合(Sets)
集合用于匹配多个条件(如多个IP、端口),分为匿名集合和命名集合。
匿名集合(适用于固定条件):
1 | # 允许来自两个特定IP的流量 |
命名集合(可动态修改):
- 创建集合(指定元素类型):
1
nft add set inet my_table my_set '{ type ipv4_addr; }'
- 在规则中引用集合(使用
@符号):1
nft add rule inet my_table my_filter_chain ip saddr @my_set drop
- 向集合添加/删除元素:
1
2nft add element inet my_table my_set { 10.10.10.22, 10.10.10.33 }
nft delete element inet my_table my_set { 10.10.10.33 }
支持区间的集合(需添加 interval 标志):
1 | nft add set inet my_table my_range_set '{ type ipv4_addr; flags interval; }' |
级联类型集合(组合匹配):
1 | # 创建可同时匹配IP、协议、端口的集合 |
4.2 字典(Maps)
字典提供高效的键值映射,用于根据条件跳转到不同链或执行不同动作,避免链式跳转的性能开销。
创建字典并用于规则跳转:
1 | # 1. 创建目标链 |
命名字典:
1 | # 1. 创建字典(键类型: 值类型) |
五、架构设计与命名空间
nftables 中,每个表都是一个独立的命名空间。这意味着不同表中的链、集合可以同名,互不干扰。
1 | nft add table inet table_one |
重要提示:数据包必须通过所有表中相关链的允许,才能被放行。链的执行顺序由 priority 决定,值越小优先级越高。
六、持久化配置
命令行配置是临时的。要使规则永久生效,需进行备份和恢复。
备份当前规则集:
1 | nft list ruleset > /root/nftables.conf |
从文件恢复规则集:
1 | nft -f /root/nftables.conf |
在 CentOS 8/RHEL 8 中:
- 系统服务
nftables.service默认从/etc/nftables.conf加载规则。 - 该文件通常会 include 其他配置文件,如
/etc/sysconfig/nftables.conf(默认被注释)。
七、总结
nftables 作为 iptables 的现代替代品,通过更清晰的数据结构、原生集合/字典支持、独立的命名空间等特性,提供了更强大、灵活且高效的防火墙配置体验。
学习路径建议:
- 理解 表 -> 链 -> 规则 的核心层级。
- 掌握基础的 增(add/insert)、删(delete)、查(list) 操作。
- 熟练使用 集合 来简化多条件规则。
- 在复杂策略中应用 字典 进行高效跳转。
- 最后通过 备份/恢复 实现配置持久化。