我有这个 ipset v7.15 的 bash 脚本(在 ubuntu 22.04 中运行),由Martin提供(我对这个问题做了一些修改):
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
如您所见,blacklist
输出中的 IP/CIDR 乱七八糟(没有sort
)。
-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
我怎样才能解决这个问题,以便组织输出?
一些背景信息
ipset
:这是一个命令行工具,用于操作在内核内存中调整大小的数据集。因此,ipset 只是调用实际代码的包装器,它驻留在内核中——包括列出集合内容的代码。棘手的部分来了:您传递了一个选项,您希望以排序的方式输出集合 - 但负责此操作的内核模块不知道该选项,只是简单地忽略了它。所有在内核上下文中执行的函数都必须快速,如果它们花费的时间太长,可能会冻结您的系统。这就是为什么当代码不是绝对必要的时候内核开发人员非常挑剔(排序在 CPU 时间方面很昂贵而且不是必需的 - 这也可以在用户空间中完成)。
我不知道要“启用”集合的排序输出需要什么内核版本,我使用内核版本 6.0.9 对其进行了测试,其中对输出进行排序的选项起到了应有的作用。遗憾的是,他们删除了某些手册页上的提示,这是仍然具有该提示的手册页版本。
以这种顺序排列的集合不是错误,它实际上是一个特征:在列表中,您必须遍历每个项目以检查传入 IP 是否是该列表的一部分。这使得每次查找都取决于列表的大小。散列不同:函数用于从您的数据(在本例中为 IP)计算散列值。此哈希值用作数据内位置的参考 - 如果那里有条目,则 IP 位于该列表内。
这种组织集合的方式使得查找值所需的时间保持不变——与集合的大小无关!当涉及网络流量时,快速响应时间始终很重要。
我希望这有助于更好地理解事物......