Code Day's Night

ichikawayのブログ

ポートが閉じてることを外部から監視するポートスキャナー(slack通知付き)

IP制限しているTCP 22(sshd)や3306(MySQL)のようなポートが空いていないかチェックするツールを作りました。

たとえば設定ミスで22番ポートがすべてのIPを許可している状態になってしまっていたというケースがありそうで、サーバ台数が数百台になってくるといちいち気にしているのが面倒なのでチェックする簡易ポートスキャナーを作りました。

github.com

 

外部監視ツールだとポートが空いてるか、任意の文字列が返るかなどのチェックはできますが、ポートが閉じられてることというのを簡単に管理するのが意外と手間だと感じたのがきっかけです。

Go言語で作ってるのでバイナリにして実行もできます。

 

使い方

goが動く環境を用意して、

    echo "example.com\nexample.net" | go run aite9 -tcp 22,3306

のようにすると次のように一気にポートをスキャンします。
example.com:22 
example.com:3306

example.net:22 
example.net:3306

 

サーバのリストは標準入力で与えるため、 

    go run aite9 -tcp 22,3306 < serverlist.txt

のようにしてもできます。

 

環境変数でslackの情報を与えるとスキャンしたポートが空いてる場合にslackでアラート通知し、このツール自体は終了ステータス0以外が返ります。

 

指定したサーバFQDNがDNSで引けない場合はそのサーバはスキャンをスキップします。ですのでとりあえず考えられるサーバを全てスキャン対象にしておけば、そのうちサーバが減ったりしてもうまく動きます。

課題

与えられたサーバとポートの組み合わせを直列でスキャンしていくため、サーバ台数やポートの指定が多いと時間がかかります。だいたい1ポート1秒です。

ここは並列処理を入れれば簡単に実現できそうなのでそのうちやるかもしれません。ただ、400台で5ポートぐらいであれば2時間ぐらいで終わってしまうので、cronで毎日1回検査する程度であれば今のままでもまぁいいかなという感じです。


UDPも仮実装しましたが、うまく空いてるポートの判定ができずまだ動くレベルに達していません。
TCPの場合はsyn -> ackという動きになるので空いてるポートの判定が簡単なのですが、UDPはパケットを送ってもアプリケーションが無効なフォーマットだと無視するような場合にポートが閉じてるのかどうかわかりません。この辺りはどうすべきか今は分からない状態です。