ClamAVとCloudWatch Logsを連携してウィルス検出をメールで通知する
こんにちは、せーのです。このところClamAVをよく触っているわけですが、今日はClamAVでウイルスを検出した時にCloudWatch Logsのアラートの仕組みを使って通知する、というアーキテクチャをご紹介します。
EC2からメールを飛ばすのは手続きがある
ClamAVはEC2の中に入っているのだから、そこから直接メールを飛ばせばいいじゃん、と思う方もいらっしゃるかもしれません。ですがEC2からメールを飛ばすには事前にAWSに対してメール送信制限の解除申請というのを行う必要があります。まあ、出してしまえばいいんですが、この1ステップがめんどくさい。メールを送るだけなのでサクッとやっつけたい、というエンジニアの心、よくわかります。 このような場合に一番簡単なのはSNSからメールを通知することです。でもEC2にSDKを入れてSNSのトピックを叩くのはスマートではありません。ここはスキャン結果をCloudWatch Logsに吐き出して、そこからフィルタリングしてカスタムメトリクスを作成し、それとSNSを紐付けることにします。そうすることでコードを一行も書くことなくウィルス検出からメール送信までほぼリアルタイムでの通知が可能となります。
やってみた
ClamAVのインストールとテスト
それではやってみましょう。まずはこちらの記事を元にAmazon LinuxにClamAVをインストールします。
インストールが完了したら一旦手動でウイルススキャンをかけてみます。
$ sudo clamscan -r -i ~ ----------- SCAN SUMMARY ----------- Known viruses: 3897909 Engine version: 0.98.7 Scanned directories: 2 Scanned files: 6 Infected files: 0 Data scanned: 0.00 MB Data read: 0.00 MB (ratio 0.00:1) Time: 7.509 sec (0 m 7 s)
オプションを確認
ここでウイルススキャンのコマンド[clamscan]のオプションについて確認しておきましょう。clamscanコマンドの詳細は[man clamscan]と打ち込む事で出てきます。
clamscanはclamscan [option] [file/directory/-]という形で認識され、オプションの種類はその下に説明があります。主なオプションを以下に書きます。
- -v : 出力を詳細にする
- -l FILE: 結果をファイルへ出力
- -i: ウイルスに感染したファイルのみを出力
- -r: サブディレクトリごと再帰的に検査。圧縮ファイルは再帰的に解凍して検査
- --exclude=PATT: パターンにマッチするファイルを検査しない
- --include=PATT: パターンにマッチするファイルのみを検査する
- --quiet: エラー情報のみ出力
- --remove: ウイスルに感染したファイルを削除する
- --move=DIRECTORY: ウイスルに感染したファイルをDIRECTORYへ移動する
ちなみに単独のファイルを検査した時に限りclamscanは戻り値を返します。戻り値は - 0: ウィルスは検出されなかった - 1: 1つ以上のウイルスが検出された - その他: 何らかの理由でclamscanが正常に実行されなかった の3種類です。
今回はroot権限で/home/ec2-user/フォルダ以下をスキャンし、その結果をエラー情報のみログファイルに記すcronを書きます。実際の運用時は専用のグループ、ユーザーを作って動作させたほうが良いかと思います。
$ sudo su - # mkdir /var/log/clamav # cd /var/log/clamav/ # touch clam.log # chmod 666 clam.log
ログファイルに入るかどうかテストします。
# clamscan -r -l /var/log/clamav/clam.log -i --quiet /home/ec2-user # cat clam.log ----------- SCAN SUMMARY ----------- Known viruses: 3897909 Engine version: 0.98.7 Scanned directories: 2 Scanned files: 7 Infected files: 0 Data scanned: 0.00 MB Data read: 0.00 MB (ratio 0.00:1) Time: 7.713 sec (0 m 7 s)
問題なく入っているようです。
CloudWatch Logsのインストールと設定
次にCloudWatch Logsのエージェントをインストールし、設定します。まずはCloudWatch Logsのエージェントをインストールします。
# yum install -y awslogs
設定ファイルを見直します。リージョンを東京に変えます。
# vi /etc/awslogs/awscli.conf
[plugins] cwlogs = cwlogs [default] region = ap-northeast-1
次に監視対象ファイルを先ほどのClamAVのログファイルがあるパスにて設定します。ここらへんの細かい設定はこちらの記事を御覧ください。
# vi /etc/awslogs/awslogs.conf
... ... [/var/log/clamav/clam.log] log_group_name=/var/log/clamav log_stream_name={hostname}_clamav_error file = /var/log/clamav/clam.log datetime_format = [%a %b %d %H:%M:%S %Y] initial_position = start_of_file buffer_duration = 5000
一旦テストしてみます。
# clamscan -r -l /var/log/clamav/clam.log -i --quiet /home/ec2-user
CloudWatchを確認してみましょう。
とれているようです。
CloudWatch Logsでウイルスを検出してメールを投げる
後は設定関係でおしまいです。まずウイルスを検出した時のパターンを特定します。こちらの記事のようにeicar.comを使ってウイルスを検出してみます。
vi ~/eicar.com # clamscan -r -l /var/log/clamav/clam.log -i --quiet /home/ec2-user
どうやらウイルスを検出すると[◯◯ FOUND」と出るようですので[FOUND]という文字をフィルタリングし、アラートを投げてみたいと思います。 まず警告用のSNSトピックを作成します。
トピックでは私宛にメールを投げるように設定しました。
次にCloudWatch Logsより[FOUND]という文字列でログをフィルタリングします。 まずフィルタリングメトリクスを開きます。
「メトリックスフィルタの追加」より新しいフィルタを作成します。
文字列「FOUND」をフィルタリングするように設定します。
完成したフィルタに対してアラートを作成します。先ほどのフィルタメトリクスが1以上になったらSNSトピックへのアクション、つまりメールが飛ぶように設定します。
テスト
これで準備は完成です。テストしてみましょう。
# clamscan -r -l /var/log/clamav/clam.log -i --quiet /home/ec2-user
無事メールが飛んできました。
まとめ
いかがでしょうか。このようにメール通知はSNSやCloudWatch Logsと併用することで簡単に実装することが出来ます。ClamAVは大きく分けて「ウイルスをスキャンする(clamscan)」と「ウイルスのDBを更新する(freshclam)」の2つしかコマンドがないので、そちらをログに吐くようにしてCloudWatch Logsで監視すればClamAV関連で異常が起きた時にはすぐにメール通知で知ることが出来るようになります。 ちなみにウイルスが検知されていない時は作成したフィルタメトリクスは「0」ではなく「no point data」となるので普段は上記のアラートは「OK」ではなく「INSUFFICIENT_DATA(データ不足)」というステータスに置かれます。動きには特に関係がないのでこのままで行きましょう。 次回はウイルススキャンとDBの更新を自動化します。