执行 restore ipset 时如何组织 IPs/CIDR?

执行 restore ipset 时如何组织 IPs/CIDR?

我有这个 ipset v7.15 的 bash 脚本(在 ubuntu 22.04 中运行),由马丁(我针对这个问题做了一些修改):

ipset create -! blacklist hash:net family inet hashsize 1024
ipset save -! > /tmp/ipset.txt

cat list.txt | sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n | while read line; do
    echo "add blacklist $line" >> /tmp/ipset.txt
done
ipset restore -! < /tmp/ipset.txt

内容list.txt

125.74.0.0/15
1.0.132.249
125.73.0.0/16
130.255.128.0/20
125.76.0.0/17

出去/tmp/ipset.txt

create blacklist hash:net family inet hashsize 1024 maxelem 65536 bucketsize 12 initval 0xf164f1c6
add blacklist 1.0.132.249
add blacklist 125.73.0.0/16
add blacklist 125.74.0.0/15
add blacklist 125.76.0.0/17
add blacklist 130.255.128.0/20

ipset -L(问题):

sudo ipset -L
Name: blacklist
Type: hash:net
Revision: 7
Header: family inet hashsize 1024 maxelem 65536 bucketsize 12 initval 0xf164f1c6
Size in memory: 696
References: 0
Number of entries: 5
Members:
125.74.0.0/15
1.0.132.249
125.73.0.0/16
130.255.128.0/20
125.76.0.0/17

如您所见,输出中的 IP/CIDRblacklist很混乱(没有sort)。

Ipset有这个选项

-s, -sorted
Sorted output. When listing or saving sets, the entries are listed sorted.

但是我尝试使用以下命令,输出是相同的(没有sort。也许我使用不正确):

ipset restore -! -s < /tmp/ipset.txt

如果我-!从命令中删除选项restore,我会收到以下错误:

ipset v7.15: Error in line 1: Set cannot be created: set with the same name already exists

因此,我认为我的脚本有错误,因为它添加了一行我认为不应该存在的行:

create blacklist hash:net family inet hashsize 1024 maxelem 65536 bucketsize 12 initval 0xf164f1c6

然后我可以删除该save行以避免错误,使其保持如下状态:

ipset -! create blacklist hash:net family inet hashsize 1024
cat list.txt | while read line; do
    echo "add blacklist $line" >> /tmp/ipset.txt
done
ipset -s restore -f /tmp/ipset.txt

但是当我运行时,输出仍然相同,没有排序ipset -L,所以-sorted(-s)选项不起作用restore

我该如何修复此问题以便输出有序?

答案1

一些背景信息ipset:这是一个命令行工具,用于操作在内核内存中调整大小的数据集。因此,ipset 只是一个调用实际代码的包装器,该代码驻留在内核中 - 包括列出集合内容的代码。下面是棘手的部分:

您传递了一个选项,您希望以排序的方式输出集合 - 但负责此操作的内核模块不知道该选项,只是忽略了它。在内核上下文中执行的所有函数都必须快速,如果它们花费的时间太长,可能会冻结您的系统。这就是为什么内核开发人员在代码不是严格必要时会非常挑剔的原因(排序在 CPU 时间方面很昂贵,而且没有必要 - 这也可以在用户空间中完成)。

我不知道需要什么版本的内核才能“启用”集合的排序输出,我使用内核版本 6.0.9 进行了测试,其中对输出进行排序的选项可以正常工作。遗憾的是,他们删除了一些手册页上的提示,这里是手册页的一个版本,其中仍然有该提示。

集合按这样的顺序排列并不是错误,而是一个特性:在列表中,您必须检查每个项目以检查传入的 IP 是否属于该列表。这使得每次查找都取决于列表的大小。哈希则不同:功能用于计算数据(本例中为 IP)的哈希值。此哈希值用作数据中位置的参考 - 如果其中有条目,则 IP 位于该列表中。

这种组织集合的方式使得查找值所需的时间保持不变 - 与集合的大小无关!当涉及到网络流量时,快速响应时间始终很重要。

我希望这有助于更好地理解事情......

相关内容