AWS LambdaでClamAVのスキャン結果をSlackに通知する
- 環境
- CloudWatch Logsのログデータ
- Lambdaの設定
- CloudWatch Logsのフィルタ
- Lambdaのソースコード ( slack_post.py )
- Slackへの通知結果
- まとめ
環境
- AWS Lambda
- ランタイム: Python3.6
- 連携: CloudwatchLogs (Filter有)
- 環境変数: SLACK_WEBHOOK_URL
- webhook_urlをバリューに入力する
- CloudWatch Logs
- ロググループとフィルタ
CloudWatch Logsのログデータ
CloudWatch LogsのログデータはJSON形式でbase64でエンコードされ、gzipで圧縮されている。
なので、Pythonでevent['awslogs']['data']
に対して、base64でデコードして、解凍する必要がある。
Lambdaの設定
- clamavのスキャンチェックするlambdaの実行ログで出力されるロググループを指定する
- 環境変数の追加 (Slack通知)
CloudWatch Logsのフィルタ
- cloudwatch logsのオブジェクトスキャン結果の1行を取得するためにフィルタを作成する
Lambdaのソースコード ( slack_post.py )
from __future__ import print_function from urllib.request import urlopen from base64 import b64decode import os import sys import urllib.request import base64 import json import zlib import datetime import boto3 import logging slack_webhoo_url = os.environ['SLACK_WEBHOOK_URL'] def get_value(event): value = zlib.decompress(base64.b64decode(event['awslogs']['data']), 16+zlib.MAX_WBITS) value_json = json.loads(value) message = json.loads(json.dumps(value_json["logEvents"][0]["message"])) return message def post_slack(msg): set_fileds = [{ "title": "TITLE", "value": msg, "short": False }] data = { 'attachments': [{ #'color': '#FF0000', 'color': 'danger', 'fields': set_fileds }] } method = 'POST' url = slack_webhoo_url request_headers = { 'Content-Type': 'application/json; charset=utf-8' } body = json.dumps(data).encode("utf-8") request = urllib.request.Request( url=url, data=body, method=method, headers=request_headers ) urllib.request.urlopen(request) def lambda_handler(event, context): value = get_value(event) post_slack(value)
Slackへの通知結果
- テスト用のウイルスデータを取得して、ファイルをclamavスキャン対象のバケットにputする
$ curl http://www.eicar.org/download/eicar.com -o eicar.com
まとめ
Lambda Python3 Clamavを用いて、S3にputされたオグジェクトのスキャン結果をSlackに通知するところを実装しました。 今後、ClamAVとLambdaを使って、S3バケットにオブジェクトがPUTされたら、自動でウイルススキャンをするところについて記事を書きたい。