简介
在nftables
中,集合(sets)是一个非常有用的特性,它允许你以集合的形式管理IP地址、端口号等网络元素,从而简化规则的配置和管理。
nftables
提供了两种类型的集合:匿名集合和命名集合。
匿名集合(Anonymous Sets)
特点:匿名集合在规则中被直接定义,没有特定的名称。集合成员被包含在花括号{}
中,元素之间用逗号,
分隔。
使用场景:当你需要临时定义一个集合,且这个集合只在定义它的规则中使用时,匿名集合非常有用。
限制:一旦包含匿名集合的规则被删除,该匿名集合也会随之消失。此外,匿名集合一旦定义就无法更新,即不能添加或删除元素,除非修改或删除使用该匿名集合的规则。
命名集合(Named Sets)
特点:命名集合需要在规则中引用之前先定义。与匿名集合不同,命名集合的元素可以在任何时间被添加或删除。
使用场景:当你需要在一个或多个规则中频繁引用同一组网络元素时,命名集合非常有用。通过更新命名集合,你可以轻松地管理这些元素,而无需修改引用它们的规则。
引用方式:在规则中引用命名集合时,需要在集合名称前加上@
符号。
集合操作
集合的行为可以通过在创建集合时指定的标志(flags)进行调整
操作行为
Operation | Description |
---|---|
add | 在指定表中添加一个新的集合。查看下面的集合规格表以获取更多关于如何指定集合属性的信息。 |
delete | 删除指定的集合。如果集合不存在,则可能会失败。 |
destroy | 删除指定的集合。如果集合不存在,则不会失败。 |
list | 显示指定集合中的元素。 |
flush | 从指定集合中移除所有元素。 |
reset | 重置所有包含元素的状态,例如计数器和配额语句的值。 |
集合规格(Set Specifications)
Keyword | Description | Type |
---|---|---|
type | 集合元素的数据类型 | string: ipv4_addr, ipv6_addr, ether_addr, inet_proto, inet_service, mark |
typeof | 用于从表达式中推导集合元素的数据类型(较少见,可能特定于实现) | expression |
flags | 集合的标志,描述集合的属性 | string: constant, dynamic, interval, timeout |
timeout | 元素在集合中保留的时间(如果集合用于数据包处理) | string, decimal followed by unit (d, h, m, s) |
gc-interval | 垃圾收集间隔(当使用timeout或flag timeout时) | string, decimal followed by unit (d, h, m, s) |
elements | 集合包含的元素(通常在添加时指定) | set data type (depends on 'type') |
size | 集合中元素的最大数量(如果集合用于数据包处理) | unsigned integer (64 bit) |
policy | 集合的策略,优化存储和访问性能 | string: performance (default), memory |
auto-merge | 自动合并相邻/重叠的集合元素(仅适用于interval集合) | boolean or specific parameters |
配置集合
配置匿名集合
大家可以回顾一下,我们在iptables和firewalld中如何使用集合的功能的?当匹配一类信息的时候在iptables和firewalld中我们可以使用ipset来实现对应的功能,但是在nftables中,直接就可以使用集合来实现。
其实匿名集合在我们上篇文章配置比如端口范围的时候就已经使用过,例如允许来自源 IP地址为 192.168.140.10-192.168.140.20
这个区间内的主机的流量
配置命名集合
命名集合是在规则中引用之前需要首先定义集合。与匿名集合不同,元素可以随时添加到命名集合或从命名集合中删除。使用集名称前的@前缀从规则中引用集和。
创建集合
add set [family] table set { type type | typeof expression ; [flags flags ;] [timeout timeout ;] [gc-interval gc-interval ;] [elements = { element[, ...] } ;] [size size ;] [comment comment ;] [policy 'policy ;] [auto-merge ;] }
{delete | destroy | list | flush | reset } set [family] table set
list sets [family]
delete set [family] table handle handle
{add | delete | destroy } element [family] table set { element[, ...] }
具体参数含义在我们上面集合操作中有具体介绍
配置举例
例如,现在需要创建一个类型为Ipv4地址的集合
向集合中添加元素,即允许的地址信息
引用集合
前面我们都是先创建集合,然后添加元素、引用集合,其实也可以一步到位,直接创建集合并添加元素信息。如下所示:
root@debian:~# nft add set ip filter allow-host2 { type ipv4_addr\; elements={ 192.168.142.1,192.168.142.2 }\; comment \"accept all packets from these ip\" \; }
直接通过elements={}添加对应的元素信息,此时就不需要再次通过元素添加命令添加元素
集合flags
我们前面创建的集合allow-host,我们都是添加的单个IP地址,如果要给此集合中添加连续的IP地址,或者网段会发生什么呢?
在使用 nftables
(nft)时,如果你尝试向一个集合(set)中添加元素,需要确保该集合是以正确的方式声明的,以便它能够接受你想要添加的元素类型(如IP地址范围或CIDR块)。错误信息提示,试图向一个集合中添加IP地址范围或CIDR块,但集合没有被正确地声明为接受这种类型的元素。需要添加flags interval参数。
集合auto-merge
自动合并相邻/重叠的集合元素,这只对区间集和有效。如上图所示,如果我们在一个集合中创建了很多单独IP地址,但是这些IP地址是连续的,那么通过auto-merge就可以将连续的IP地址合并起来。
上面都是ip地址,当然端口号也适用该配置,如下所示:
查看集合信息
可以通过nft list sets命令查看所有集合,也可以通过nft list set _____后面跟上对应的表和集合名称进行查看。这个我们在上面都有演示,再次不在重新展示了。
那么我如果想要看某个元素有没有在集合中,该如何查看呢?
高级参数配置
集合timeout
它决定了元素在集合中停留的时间。时间字符串遵循如下格式:"dhms":
Element timeouts
集合元素有两个属性:
timeout:该时间值,以秒(s)、分(m)、小时(h)或它们的组合(hms)为单位。
expires:该值是一个倒计时时间计数器,从超时值开始,可以从数据包路径中重置,或者当达到0值时将删除该元素。
那么在此集合中我如果要设置端口范围该如何操作呢?
总结
集合(sets)是一种非常重要的数据结构,用于存储一组元素,如IP地址、端口号、MAC地址等,以便在规则中引用。集合的使用可以极大地简化防火墙规则的配置,提高管理效率。通过合理使用集合,可以简化规则配置、提高管理效率,并增强防火墙的灵活性。