第 2 章 nftables 入门
			如果您的场景不在 firewalld 涵盖的典型数据包过滤情况下,或者您希望完全控制规则,您可以使用 nftables 框架。
		
			nftables 框架对数据包进行分类,它是 iptables、ip6tables、arptables、ebtables 和 ipset 工具的后续者。与之前的数据包过滤工具相比,它在方便、特性和性能方面提供了大量改进,最重要的是:
		
- 内置查找表而不是线性处理
- 
					IPv4和IPv6协议的单一框架
- 通过事务更新内核规则集,而不是获取、更新和存储整个规则集
- 
					支持在规则集(nftrace)和监控追踪事件(nft)中调试和追踪
- 更加一致和压缩的语法,没有特定协议的扩展
- 用于第三方应用程序的 Netlink API
			nftables 框架使用表来存储链。链包含执行动作的独立规则。nft 工具替换了之前数据包过滤框架中的所有工具。您可以使用 libnftables 库通过 libnftnl 库与 nftables Netlink API 进行低级交互。
		
			要显示规则集变化的影响,请使用 nft list ruleset 命令。要清除内核规则集,请使用 nft flush ruleset 命令。请注意,这也可能会影响 iptables-nft 命令安装的规则集,因为它使用了相同的内核基础架构。
		
2.1. 创建和管理 nftables 表、链和规则
				您可以显示 nftables 规则集并管理它们。
			
2.1.1. nftables 表的基础知识
					nftables 中的表是一个包含链、规则、集合和其他对象集合的名字空间。
				
每个表都必须分配一个地址系列。地址系列定义此表处理的数据包类型。在创建表时,您可以设置以下地址系列之一:
- 
							ip:仅匹配 IPv4 数据包。如果没有指定地址系列,这是默认设置。
- 
							ip6:仅匹配 IPv6 数据包.
- 
							inet:匹配 IPv4 和 IPv6 数据包。
- 
							arp:匹配 IPv4 地址解析协议(ARP)数据包。
- 
							bridge:匹配通过网桥设备的数据包。
- 
							netdev:匹配来自 ingress 的数据包。
如果要添加表,所使用的格式取决于您的防火墙脚本:
- 在原生语法的脚本中,使用: - table <table_address_family> <table_name> { }- table <table_address_family> <table_name> { }- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 在 shell 脚本中,使用: - nft add table <table_address_family> <table_name> - nft add table <table_address_family> <table_name>- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
2.1.2. nftables 链的基础知识
表由链组成,链又是规则的容器。存在以下两种规则类型:
- 基本链 :您可以使用基本链作为来自网络堆栈的数据包的入口点。
- 
							常规链 :您可以将常规链用作 jump目标来更好地组织规则。
如果要向表中添加基本链,所使用的格式取决于您的防火墙脚本:
- 在原生语法的脚本中,使用: - Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 在 shell 脚本中,使用: - nft add chain <table_address_family> <table_name> <chain_name> { type <type> hook <hook> priority <priority> \; policy <policy> \; }- nft add chain <table_address_family> <table_name> <chain_name> { type <type> hook <hook> priority <priority> \; policy <policy> \; }- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 为了避免 shell 将分号解释为命令的结尾,请将 - \转义字符放在分号前面。
这两个示例都创建 基本链。要创建 常规链,请不要在大括号中设置任何参数。
链类型
以下是链类型以及您可以使用的地址系列和钩子的概述:
| 类型 | 地址系列 | 钩子 | 描述 | 
|---|---|---|---|
| 
									 | all | all | 标准链类型 | 
| 
									 | 
									 | 
									 | 这个类型的链根据连接跟踪条目执行原生地址转换。只有第一个数据包会遍历此链类型。 | 
| 
									 | 
									 | 
									 | 如果 IP 头的相关部分已更改,则接受的遍历此链类型的数据包会导致新的路由查找。 | 
链优先级
priority 参数指定数据包遍历具有相同 hook 值的链的顺序。您可以将此参数设为整数值,或使用标准优先级名称。
以下列表是标准优先级名称及其数字值的一个概述,以及您可以使用它们的哪个地址系列和钩子:
| 文本值 | 数字值 | 地址系列 | 钩子 | 
|---|---|---|---|
| 
									 | 
									 | 
									 | all | 
| 
									 | 
									 | 
									 | all | 
| 
									 | 
									 | 
									 | 
									 | 
| 
									 | 
									 | 
									 | |
| 
									 | 
									 | 
									 | all | 
| 
									 | 
									 | all | |
| 
									 | 
									 | 
									 | all | 
| 
									 | 
									 | 
									 | 
									 | 
| 
									 | 
									 | 
									 | |
| 
									 | 
									 | 
									 | 
									 | 
链策略
					如果此链中的规则没有指定任何操作,则链策略定义 nftables 是否应该接受或丢弃数据包。您可以在链中设置以下策略之一:
				
- 
							accept(默认)
- 
							drop
2.1.3. nftables 规则的基础知识
					规则定义对通过包含此规则的链的数据包执行的操作。如果规则还包含匹配表达式,则 nftables 仅在所有之前的表达式都应用时才执行操作。
				
如果要在链中添加一条规则,所使用的格式取决于您的防火墙脚本:
- 在原生语法的脚本中,使用: - Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 在 shell 脚本中,使用: - nft add rule <table_address_family> <table_name> <chain_name> <rule> - nft add rule <table_address_family> <table_name> <chain_name> <rule>- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 此 shell 命令在链的末尾附加新规则。如果要在链的开头添加一条规则,请使用 - nft insert命令而不是- nft add。
2.1.4. 使用 nft 命令管理表、链和规则
					要在命令行上或 shell 脚本中管理 nftables 防火墙,请使用 nft 工具。
				
						此流程中的命令不代表典型的工作流,且没有被优化。此流程只演示了如何使用 nft 命令来管理表、链和规则。
					
流程
- 创建一个带有 - inet地址系列的名为- nftables_svc的表,以便表可以处理 IPv4 和 IPv6 数据包:- nft add table inet nftables_svc - # nft add table inet nftables_svc- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 将处理传入网络流量的、名为 - INPUT的基本链添加到- inet nftables_svc表中:- nft add chain inet nftables_svc INPUT { type filter hook input priority filter \; policy accept \; }- # nft add chain inet nftables_svc INPUT { type filter hook input priority filter \; policy accept \; }- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 为了避免 shell 将分号解释为命令的结尾,请使用 - \字符转义分号。
- 向 - INPUT链添加规则。例如,允许端口 22 和 443 上的传入 TCP 流量,并作为- INPUT链的最后一条规则,拒绝其他传入的流量,并伴有互联网控制消息协议(ICMP)端口无法访问的消息:- nft add rule inet nftables_svc INPUT tcp dport 22 accept nft add rule inet nftables_svc INPUT tcp dport 443 accept nft add rule inet nftables_svc INPUT reject with icmpx type port-unreachable - # nft add rule inet nftables_svc INPUT tcp dport 22 accept # nft add rule inet nftables_svc INPUT tcp dport 443 accept # nft add rule inet nftables_svc INPUT reject with icmpx type port-unreachable- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 如果您输入 - nft add rule命令,则- nft会将按与运行命令相同的顺序将规则添加到链。
- 显示包括句柄的当前规则集: - Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 在句柄为 3 的现有规则前面插入一条规则。例如,要插入一个允许端口 636 上 TCP 流量的规则,请输入: - nft insert rule inet nftables_svc INPUT position 3 tcp dport 636 accept - # nft insert rule inet nftables_svc INPUT position 3 tcp dport 636 accept- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 在句柄为 3 的现有规则后面附加一条规则。例如,要插入一个允许端口 80 上 TCP 流量的规则,请输入: - nft add rule inet nftables_svc INPUT position 3 tcp dport 80 accept - # nft add rule inet nftables_svc INPUT position 3 tcp dport 80 accept- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 再次显示带有 handle 的规则集。验证是否后添加的规则已添加到指定位置: - Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 删除 handle 为 6 的规则: - nft delete rule inet nftables_svc INPUT handle 6 - # nft delete rule inet nftables_svc INPUT handle 6- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 要删除规则,您必须指定 handle。 
- 显示规则集,并验证删除的规则是否不再存在: - Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 从 - INPUT链中删除所有剩余的规则:- nft flush chain inet nftables_svc INPUT - # nft flush chain inet nftables_svc INPUT- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 显示规则集,并验证 - INPUT链是否为空:- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 删除 - INPUT链:- nft delete chain inet nftables_svc INPUT - # nft delete chain inet nftables_svc INPUT- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 您还可以使用此命令删除仍然包含规则的链。 
- 显示规则集,并验证 - INPUT链是否已被删除:- nft list table inet nftables_svc - # nft list table inet nftables_svc table inet nftables_svc { }- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 删除 - nftables_svc表:- nft delete table inet nftables_svc - # nft delete table inet nftables_svc- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 您还可以使用此命令删除仍然包含链的表。 注意- 要删除整个规则集,请使用 - nft flush ruleset命令,而不是在单独的命令中手动删除所有规则、链和表。