Bashで何千ものCIDR /ネットマスク範囲のIPホストアドレスを素早く効率的にカウントする方法はありますか?


4

私はIPSetを使って何万ものIPv4 CIDR /ネットマスク範囲を管理していましたが、それらはその後IPTablesルールにリンクされます。この設定はうまく機能していますが、IPSetがクライアントのレポート目的で機能するIPホストアドレスの概要を正確に把握したいと思います。

IPSetエントリのフォーマットは一貫して次のようになっています。

123.456.0.0/16 timeout 86400

だから私は持っている行にgrepすることができます timeout エントリに含まれるCIDR /ネットマスク範囲に基づいて動作する値を取得します。

たとえば、IPSetの出力を(次のようにして)保存したとします。 ipset -L -n > ipset-20181228.txt )というテキストファイルに ipset-20181228.txt そして、の組み合わせを実行します grep そして wc -l このような:

grep  "timeout" ipset-20181228.txt  | wc -l

39,000以上のCIDR /ネットマスクの範囲に相当する39,000以上の項目があります。しかし、それは(もちろん)CIDR /ネットマスクの範囲を数えるだけで、その範囲のIPホストアドレスの全数を数えることはできません。

使用しようとしました prips grepを使用して、CIDR /ネットマスクの範囲をBIDで実際のIPアドレスに拡張します(CIDR /ネットマスクの値を実際のIPアドレスに拡張します)。

grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([0-9]{1,2})' ipset-20181228.txt | awk 'NF { system( "prips " $0)  }' | wc -l

そして、2018年のMacBook Airで(ファンがキックして)なんと20〜30分後(!!!)、得た数は736,000,000+であり、これは私が考えているものです…しかし、20〜30分は長すぎます。私はこれを可能な限りスクリプト可能で邪魔にならないようにしたいと思います。また、リソースを消費することなく本番サーバーで実行するようなコマンドを信頼することはできません。私の地元の2018年のMacBook Air開発環境でそれがどのように振る舞うのかを見ることを意味します。

単にCIDR /ネットマスク値に基づいてCIDR /ネットマスク範囲カウントを計算する方法はありますか?私は、コマンドラインツール、または私が使用している既存のツールの中のオプションしかないことを願っています。


どの変換が必要ですか。オプションA 1.2.3.0/241.2.3.0-1.2.3.255 オプションB 1.2.3.0-1.2.3.2551.2.3.0/24。 Nmap、tracerouteにはいくつかの機能があります。
Biswapriyo

1
@Biswapriyoどちらでもない。あなたも質問を読みましたか?私は単にCIDR /ネットマスク表記に基づいてIPアドレスの数を取得するように求めています。ある形式の範囲表記から別の形式の表記に変換しないでください。
JakeGould

2
私が正しく理解したならば、あなたは与えられたIP /マスクの組にいくつのホストがあるか知りたいです。ホスト番号は 2^(32-mask)-2。マスクはネットビットを表すので、他の部分はホストビットを表します。 -2 ネットアドレスとブロードキャストIPアドレス用です。あなたが持っている場合 ipcalc インストールして実行するとそれらの情報が表示されます。 (あなたの質問を誤解した場合は申し訳ありません)。
Paulo

1
@パウロ:2を引かないでください。各範囲が直接サブネットに対応するとは想定しないでください。ルートとフィルタリストは物理的なレイアウトには対応していません - エントリはサブネットの一部だけに一致したり、一度に複数のサブネットをカバーしたり、そもそも「サブネット」の概念がないネットワークにも適用されます。ポイントリンク)。実際、アドレスがホストを表すかどうかは、フィルタリングには関係ありません。各接頭辞は正確に 2^(32-mask) アドレスとそれだけです。
grawity

あなたの主張を見て、私はサブネット範囲の概念にこだわっていたと思います。あなたが言ったように、質問からのその範囲はipsの範囲になることができます。説明してくれてありがとう。購読しています 2^(32-mask)
Paulo

回答:


2

もしあなたの grep 以下のようなコマンド出力行 123.456.0.0/16それから、それらをパイプする必要があります

awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'

このコマンドはマスクのみを抽出します / )と各マスクの出現回数を数えます。最後に、発生した各マスクについてホスト数が計算されます( 2^(32-mask) )をオカレンス数で掛けて合計します。

ノート:

  • 健全性チェックは行われません。例えば。のように入力 1.2.3.4/40 受け入れられ、整数以外の出力が計算されます。あなたの予備を向上させる grep 必要に応じてフィルタリングします。
  • 各範囲は独立して総数に寄与します。あなたの範囲が重なるならば、あなたは膨らんだ結果を得るでしょう prips これで良くなかった)。

これは素晴らしいです。次のように実行するとかなり速く動作します。最後に使用したコマンドは次のとおりです。 grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([0-9]{1,2})' ipset-*.txt | awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'
JakeGould

0

オリジナルのポスターはgrepを実行してCIDRを次の行から取得しているので、このようなことでうまくいくと思いました。 timeout

awk -F'[ /]' '/timeout/ {hosts+=2^(32-$2)};ENDFILE{print "Hosts number in "FILENAME": "hosts;total+=hosts;hosts=0};END {print "Total: "total}' ipset*.txt

編集 - awk 上記のプログラムは以下でのみOKです。 GNU awkENDFILE はGNUの拡張です。

私は推測する BSD awk 無視する ENDFILE メインプログラムセクションの一部である場合は、そのセクションを実行します。

これはGNUおよびBSDのawkと互換性があります。

awk -F'[ /]' '{if (filename != FILENAME) hosts=0};/timeout/ {hosts+=2^(32-$2)};{filename=FILENAME;file_total[filename]=hosts};END{for (i in file_total) {print "Hosts number in "i": "file_total[i];total+=file_total[i]};{print "Total: "total};}' ipset*.txt

修正したスクリプトはmacOSで動作しますが、前に説明したように、Linuxと同様に今ではmacOSでカウントするのがひどく行き過ぎています。承認された回答と一緒にファイルする prips。すみません、努力をありがとう、これは控えめに言っても働いていません。
JakeGould

1
@ jakegouldわかりました、まったく問題ありません。おそらくそれを正しくフィルタリングするための出力が理解できませんでした。その上、私はインストールする簡単な方法を手に入れることができませんでした prips そしてそれがどのように機能し、出力されるかを見てみましょう。とにかくそれを得るために運動の価値がある awk GNUの拡張子なしで報告する。
Paulo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.