restore ipset を実行するときに IP/CIDR を整理するにはどうすればよいですか?

restore ipset を実行するときに IP/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

ご覧のとおり、blacklist出力内の IP/CIDR は間違っています (いいえ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 はそのリスト内にあります。

セットをこのように整理すると、セットのサイズに関係なく、値の検索に必要な時間が一定になります。ネットワーク トラフィックに関しては、応答時間が速いことが常に重要です。

これが物事をよりよく理解するのに役立つことを願っています...

関連情報