My Note

自己理解のためのブログ

AWS LambdaでClamAVのスキャン結果をSlackに通知する

環境

  • AWS Lambda
    • ランタイム: Python3.6
    • 連携: CloudwatchLogs (Filter有)
    • 環境変数: SLACK_WEBHOOK_URL
      • webhook_urlをバリューに入力する
  • CloudWatch Logs
    • ロググループとフィルタ

CloudWatch Logsのログデータ

CloudWatch LogsのログデータはJSON形式でbase64エンコードされ、gzipで圧縮されている。 なので、Pythonevent['awslogs']['data']に対して、base64でデコードして、解凍する必要がある。

Lambdaの設定

  • clamavのスキャンチェックするlambdaの実行ログで出力されるロググループを指定する

f:id:yhidetoshi:20190617214321p:plain

f:id:yhidetoshi:20190617214544p:plain
clamav-lambda

CloudWatch Logsのフィルタ

  • cloudwatch logsのオブジェクトスキャン結果の1行を取得するためにフィルタを作成する

f:id:yhidetoshi:20190617214643p:plain

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

f:id:yhidetoshi:20190617214726p:plain

まとめ

Lambda Python3 Clamavを用いて、S3にputされたオグジェクトのスキャン結果をSlackに通知するところを実装しました。 今後、ClamAVとLambdaを使って、S3バケットにオブジェクトがPUTされたら、自動でウイルススキャンをするところについて記事を書きたい。