第 8 章 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
命令安装的规则集,因为它使用了同样的内核基础架构。
8.1. 创建和管理 nftables 表、链和规则 复制链接链接已复制到粘贴板!
您可以显示 nftables
规则集并管理它们。
8.1.1. nftables 表的基础知识 复制链接链接已复制到粘贴板!
nftables
中的表是一个包含链、规则、集合和其他对象集合的名字空间。
每个表都必须分配一个地址系列。地址系列定义此表处理的数据包类型。在创建表时,您可以设置以下地址系列之一:
-
ip
:仅匹配 IPv4 数据包。如果没有指定地址系列,这是默认设置。 -
ip6
:仅匹配 IPv6 数据包。 -
inet
:匹配 IPv4 和 IPv6 数据包。 -
arp
:匹配 IPv4 地址解析协议(ARP)数据包。 -
bridge
:匹配通过网桥设备的数据包。 -
netdev
:匹配来自入口的数据包。
如果要添加表,所使用的格式取决于您的防火墙脚本:
在原生语法的脚本中,使用:
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
8.1.2. nftables 链的基础知识 复制链接链接已复制到粘贴板!
表由链组成,链又是规则的容器。存在以下两种规则类型:
- Base chain :您可以使用基本链作为来自网络堆栈的数据包的入口点。
-
Regular chain :您可以使用常规链作为
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 将分号解释为命令的结尾,请将
\
转义字符放在分号前面。
这两个示例都创建 基本链。要创建 常规链,请不要在大括号中设置任何参数。
链类型
以下是链类型以及您可以使用的地址系列和钩子的概述:
类型 | 地址系列 | Hook | 描述 |
---|---|---|---|
| all | all | 标准链类型 |
|
|
| 这个类型的链根据连接跟踪条目执行原生地址转换。只有第一个数据包会遍历此链类型。 |
|
|
| 如果 IP 头的相关部分已更改,则接受的遍历此链类型的数据包会导致新的路由查找。 |
链优先级
priority 参数指定数据包遍历具有相同 hook 值的链的顺序。您可以将此参数设为整数值,或使用标准优先级名称。
以下列表是标准优先级名称及其数字值的一个概述,以及您可以使用它们的哪个地址系列和钩子:
文本值 | 数字值 | 地址系列 | 钩子 |
---|---|---|---|
|
|
| all |
|
|
| all |
|
|
|
|
|
|
| |
|
|
| all |
|
| all | |
|
|
| all |
|
|
|
|
|
|
| |
|
|
|
|
链策略
如果此链中的规则没有指定任何操作,则链策略定义 nftables
是否应该接受或丢弃数据包。您可以在链中设置以下策略之一:
-
accept
(默认) -
drop
8.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
。
8.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
命令,而不是在单独的命令中手动删除所有规则、链和表。