-2

現在、bashでスキャナーを実行しています。
アイデアは、入力としてネットワークを受け取り、それを反復しながら、IP に ping を実行し、ポートが開いているかどうかを調べることです。

変数の説明(例):
入力 -> スキャンするネットワーク: 192.168.1.0/24

開始 IP: 192.168.1.0 -> $i1.$i2.$i3.$i4
最後の IP: 192.168.1.255 -> $m1.$m2.$m3.$m4

for oct1 in $(seq $i1 1 $m1); do
    for oct2 in $(seq $i2 1 $m2); do
        for oct3 in $(seq $i3 1 $m3); do
            for oct4 in $(seq $i4 1 $m4); do
                 ping -c 1 $oct1.$oct2.$oct3.$oct4 | grep "64 bytes" | cut -d" " -f4 | tr -d ":" >> scan.txt
                 nc -nvz $oct1.$oct2.$oct3.$oct4 80 2>&1 | grep succeeded | cut -d" " -f4 >> scan.txt
             done
         done
     done
done

ファイルscan.txtは次のようになります。

192.168.1.1
80
192.168.1.2
192.168.1.4
192.168.1.5
192.168.1.7
80
192.168.1.9
(...)

私の唯一の問題は、このソリューションは機能しますが、時間がかかりすぎることです。
192.168.1.0/24 ネットワークをスキャンすると、スクリプトが正常に起動することがわかりましたが、約 10 個の IP をスキャンした後、速度が低下し始め、ほとんど動けなくなりました。

これは、ジョブをバックグラウンドで実行している ping および nc コマンドと関係があると思います。ping および nc コマンドの最後に追加& disownすると、実行ははるかにスムーズになりますが、出力が乱れます。

.1 から .254 になる代わりに、次のようになります。

192.168.1.6
80
192.168.1.10
80

80
192.168.1.1
192.168.1.5
192.168.1.3
(...)

より高速に実行するために、このコードを最適化 (または別の方法で実行) できますか?

4

1 に答える 1

2

ping -c 1 $oct1.$oct2.$oct3.$oct4 | grep "64 バイト" | カット -d" " -f4 | tr -d ":" >> scan.txt

ping が「64 バイト」メッセージを生成しない場合はどうなりますか? スクリプトがしばらく停止します。私のシステムでは、失敗するまでに 10 秒かかりますが、そのタイムアウトについて特に標準的なものがあるかどうかはわかりません。

$ time ping -c1 192.168.0.123
PING 192.168.0.123 (192.168.0.123) 56(84) bytes of data.

--- 192.168.0.123 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms


real    0m10.004s
user    0m0.000s
sys     0m0.000s

最近のほとんどの Linux ディストリビューションにはタイムアウト(1) が含まれているため、スクリプトの待機時間を制限できます。

$ timeout 2 ping -c1 192.168.0.123 || echo no
PING 192.168.0.123 (192.168.0.123) 56(84) bytes of data.
no

並行処理 (一度に複数のホストに ping を送信する) の場合は、make (1) を-jオプションとともに使用することを検討してください。スクリプトを使用して一連のアドレス (それぞれがファイル名) を生成し、Makefile ルールを定義して各入力の出力ファイルを生成します。最後のステップとして、すべての出力を連結します。

入力ファイルが.pingで、出力ファイルが.pongの場合、ルールは次のようになります。

.ping.pong:
        ping -c 1 $^ \
        | grep "64 bytes" \
        | cut -d" " -f4 \
        | tr -d ":" > $@~
        nc -nvz $^ 80 2>&1 \
        | grep succeeded | cut -d" " -f4 >> $@~
        mv $@~ $@

すべての .ping ファイルを .pong ファイルに「コンパイル」します。(コマンドライン引数として使用するには、ファイル名から接尾辞を削除する必要があるため、上記はうまく機能しません。)

最後に 1 つのアドバイス: パイプラインで grep、cut、sed、および tr を使用していることに気付いた場合、awk (1) はあなたの味方です。100 の理由がありますが、おそらく最善の理由は、awk スクリプトを簡単に記述して、予期しない入力を「通過」させて、それを確認して対処できるようにすることです。grep を使用すると、予期しないものはすべて破棄され、何が欠けているかを推測 (または SO に尋ねる) する必要があります。

于 2021-11-06T03:15:01.463 に答える