【AWS AWSWAF】AWSWAFでブロックログのアラートをフィルタリングしつつSlackへ飛ばす

WAF → KinesisFirehose → Lambda → Slack
↓
→ S3バケット
KinesisiFirehoseにログ出力するようにする
kinesisFirehoseのJson出力をLambdaへ渡す
NoUserAgent_HEADER
とUserAgent_BadBots_HEADER
がやたらでるので、Slackへは飛ばしたくない
import base64 import json import os import urllib.request def lambda_handler(event, context): output = [] for record in event['records']: output_record = { 'recordId': record['recordId'], 'result': 'Ok', 'data': record['data'] } output.append(output_record) a = base64.b64decode(record['data']) b = json.loads(a) # if b['action'] != 'ALLOW': # print("action not ALLOW") if b["ruleGroupList"][0]["terminatingRule"]["ruleId"] != 'NoUserAgent_HEADER' and b["ruleGroupList"][0]["terminatingRule"]["ruleId"] != 'UserAgent_BadBots_HEADER': print("terminatingRule is not NoUserAgent_HEADER") response = post_slack(b) print(output_record) return {'records': output} def post_slack(msg): send_data = { "username": "notify_slack", "icon_emoji": ":vampire:", "color":"#D00000", "text": "WAF攻撃検知", "attachments":[ { "fallback":"fallback Test", "color":"#D00000", "fields":[ { "title":"詳細内容", "value":str(msg) } ] } ] } send_text = "payload=" + json.dumps(send_data) # send_text = "payload=" + json.dumps(jsondata) method = 'POST' headers = {'Content-Type': 'application/json'} WEB_HOOK_URL = os.environ['WEBHOOK_URL'] request = urllib.request.Request( WEB_HOOK_URL, data=send_text.encode('utf-8'), method=method ) with urllib.request.urlopen(request) as response: response_body = response.read().decode('utf-8') print("send ok")
{ "invocationId": "invocationIdExample", "deliverySteamArn": "arn:aws:kinesis:EXAMPLE", "region": "ap-northeast-1", "records": [ { "recordId": "49546986683135544286507457936321625675700192471156785154", "approximateArrivalTimestamp": 1495072949453, "kinesisRecordMetadata": { "sequenceNumber": "49545115243490985018280067714973144582180062593244200961", "subsequenceNumber": "123456", "partitionKey": "partitionKey-03", "shardId": "shardId-000000000000", "approximateArrivalTimestamp": 1495072949453 }, "data": "ew0KCSJ0aW1lc3RhbXAiOiAxNjA0Nzc0MzM1MTEyLA0KCSJmb3JtYXRWZXJzaW9uIjogMSwNCgkid2ViYWNsSWQiOiAiYXJuOmF3czp3YWZ2MjphcC1ub3J0aGVhc3QtMToxMTExMTExMTExMTpyZWdpb25hbC93ZWJhY2wvdmFtZGVtaWMtd2FmdjIveHh4eHh4eHgtY2UwYi00ZWYwLTkxZGUtYjQ0OTg1NmFmNDUxIiwNCgkidGVybWluYXRpbmdSdWxlSWQiOiAiQVdTTWFuYWdlZFJ1bGVzQ29tbW9uUnVsZVNldCIsDQoJInRlcm1pbmF0aW5nUnVsZVR5cGUiOiAiTUFOQUdFRF9SVUxFX0dST1VQIiwNCgkiYWN0aW9uIjogIkJMT0NLIiwNCgkidGVybWluYXRpbmdSdWxlTWF0Y2hEZXRhaWxzIjogW10sDQoJImh0dHBTb3VyY2VOYW1lIjogIkFMQiIsDQoJImh0dHBTb3VyY2VJZCI6ICIxMTExMTExMTExMS1hcHAvdmFtZGVtaWMtZGV2LWJ1c2luZXNzLWRldjItYWxiLzI4YWU3NjcyYzExMTExMWRjIiwNCgkicnVsZUdyb3VwTGlzdCI6IFsNCgkJew0KCQkJInJ1bGVHcm91cElkIjogIkFXUyNBV1NNYW5hZ2VkUnVsZXNDb21tb25SdWxlU2V0IiwNCgkJCSJ0ZXJtaW5hdGluZ1J1bGUiOiB7DQoJCQkJInJ1bGVJZCI6ICJOb1VzZXJBZ2VudF9IRUFERVIiLA0KCQkJCSJhY3Rpb24iOiAiQkxPQ0siLA0KCQkJCSJydWxlTWF0Y2hEZXRhaWxzIjogbnVsbA0KCQkJfSwNCgkJCSJub25UZXJtaW5hdGluZ01hdGNoaW5nUnVsZXMiOiBbXSwNCgkJCSJleGNsdWRlZFJ1bGVzIjogbnVsbA0KCQl9DQoJXSwNCgkicmF0ZUJhc2VkUnVsZUxpc3QiOiBbXSwNCgkibm9uVGVybWluYXRpbmdNYXRjaGluZ1J1bGVzIjogW10sDQoJImh0dHBSZXF1ZXN0Ijogew0KCQkiY2xpZW50SXAiOiAiMTI2LjIwOS4yMjEuNCIsDQoJCSJjb3VudHJ5IjogIkpQIiwNCgkJImhlYWRlcnMiOiBbDQoJCQl7DQoJCQkJIm5hbWUiOiAiSG9zdCIsDQoJCQkJInZhbHVlIjogImRldjIudmFtZGVtaWMuanAiDQoJCQl9LA0KCQkJew0KCQkJCSJuYW1lIjogIkFjY2VwdCIsDQoJCQkJInZhbHVlIjogIiovKiINCgkJCX0NCgkJXSwNCgkJInVyaSI6ICIvIiwNCgkJImFyZ3MiOiAiIiwNCgkJImh0dHBWZXJzaW9uIjogIkhUVFAvMS4xIiwNCgkJImh0dHBNZXRob2QiOiAiR0VUIiwNCgkJInJlcXVlc3RJZCI6ICIxLTVmYTZlOWJmLTIyMmU3NmNkNWJkNDQyYTEyYjg5YmM5YSINCgl9DQp9" } ] }
こちらの2パターンのテストを行い、挙動を見る
https://dev.classmethod.jp/articles/aws-waf-block-log-pipeline/