はじめに
こんにちは/こんばんはー。
クラウドCoEユニットの矢吹です。
「ファイアーエムブレム 風花雪月」が発売されまして、毎日楽しく過ごしています!
クラウドCoEユニットは5月末からメンバーが1人増えまして、現在3人体制で頑張っていて、
新しい方にはGCP領域において大活躍して頂いてるので、いつかこのブログにも登場してもらいたいなーって思っています。
クラウドCoEとしての動き(AWSのみ)
せっかくなんで、今期(2019年4月~)どんなことをやったかをさらっと書きまして、主題に移ろうかなと思います。
現在アドウェイズではAWS環境・GCP環境・vCenter(オンプレ)環境がありますが、年々AWSアカウントやGCPプロジェクトも増え、色んな方面での管理や改善が必要になりました。
その上で今期AWSに関してはセキュリティ・コストに着目して動き出しました。
以下が今期AWSにおいてクラウドCoE主導で動いたところです。(細かいものは省略)
- セキュリティ関連
- Trusted Advisorを利用したセキュリティ通知 ⇨ 今回のブログ
- IAM管理
- インフラ/サービス側のIAM権限の取り決め
- SwitchRole導入 (ブログ書かれてます)
- MFA(ルートユーザーもIAMも)
- コスト関連
- RI購入ルール決め
- AWS Budgets機能を利用した予算アラート設定
動けば動くほど、あれもこれもってなってやることが積まれていくので、優先順位つけて取り組んでる日々です。
今回の話
さて、今回はAWS Trusted Advisorを利用しまして、アドウェイズ で管理しているAWSアカウント全体に対して、セキュリティの項目がアラートになった場合にSlackに通知する仕組みを作ったお話です。
実現したこと
Trusted Advisorのセキュリティの項目がERRORになった時に・・・
Slackに流す!!
仕組み
1.Lambdaの設定(Slack通知する部分)
Lambdaのソースコード(Python3.7)
import json import os import boto3 from botocore.vendored import requests import logging # Slack Incomming Webhooks URL SLACK_POST_URL ="https://hooks.slack.com/services/WebHookURL記入してください" logger = logging.getLogger() # ステータス def webhook_icon(status=''): if status == 'INFO': return ':information_source:' elif status == 'WARN': return ':warning:' elif status == 'ERROR': return ':error:' elif status == 'OK': return ':ok:' else: return ':rotating_light:' # slack表示の時のバー def attachement_color(status=''): if status == 'INFO': return '#CCCCCC' # 灰 elif status == 'WARN': return '#FFFF00' # 黄 elif status == 'ERROR': return '#FF0000' # 赤 else: return '00ff00' # 緑 # メイン def lambda_handler(event, _context): account_id = event.get('account','123456789012') time = event.get('time') region = event.get('region','null') detail = event.get('detail', {}) status = detail.get('status', 'ERROR') resource = detail.get('resource_id','null') check_name = detail.get('check-name','null') check_detail = detail.get('check-item-detail','null') # pythonでAWSアカウントのエイリアスを表示する iam = boto3.client('iam') paginator = iam.get_paginator('list_account_aliases') for response in paginator.paginate(): account_aliases = response['AccountAliases'] print(event) print(type(account_aliases)) slack_post_template = { "text": "*AWS Trusted Advisorのステータス変更を検知しました*", "username": "Trusted Advisor", "icon_emoji": webhook_icon(status=status), "attachments": [ { "fallback": check_name, "color": attachement_color(status=status), "author_name": "Trusted Advisor セキュリティ URLリンク", "author_link": "https://console.aws.amazon.com/trustedadvisor/home?#/category/security", "fields": [ { "title": "ステータス", "value": status, "short": False }, { "title": "対応必要箇所", "value": check_name }, { "title": "対象AWSアカウント", "value": account_aliases[0] + "(" + account_id + ")" #"value": "{account_aliases}({account_id})".format(account_aliases = account_aliases[0], account_id = account_id) }, { "title": "リソース", "value": resource, "short": False }, ] }, { "title": '詳細', "fallback": check_name, "color": attachement_color(status=status), "text": "```\n{0}\n```".format(check_detail) } ] } requests.post(SLACK_POST_URL, data=json.dumps(slack_post_template))
2.CloudWatch Eventsのトリガー設定(Trusted Advisorのチェックに引っかかったらLambda動かす)
イベントパターン内容
{ "detail-type": [ "Trusted Advisor Check Item Refresh Notification" ], "source": [ "aws.trustedadvisor" ], "detail": { "check-name": [ "Exposed Access Keys", "Amazon S3 Bucket Permissions", "Amazon RDS Public Snapshots", "Amazon RDS Security Group Access Risk", "Amazon EBS Public Snapshots", "ELB Listener Security", "ELB Security Groups", "Security Groups - Unrestricted Access", "Security Groups - Specific Ports Unrestricted", "IAM Password Policy" ], "status": [ "ERROR" ] } }
3.cron設定(Trusted Advisorが1週間に一回しかチェックしない仕様のため)
定期的に動かしているシェルスクリプト
profile_list=($(cat ~/.aws/credentials | grep -oe "[a-z].*@adways.net")) for profile in ${profile_list[@]}; do security_id_list=($(aws support describe-trusted-advisor-checks --region us-east-1 --language en --profile $profile | jq -c ".checks[] | [ .category , .name , .id]" | grep security | sort | cut -f 3 -d "," | cut -f 2 -d "\"")) for check_id in ${security_id_list[@]}; do aws support refresh-trusted-advisor-check --check-id "$check_id" --region us-east-1 --profile $profile done done
仕組みは上記の感じです!
また、実際の展開の時はCloudFormationで書いて、CLIでばっと全体に配布しちゃいました。
最後に
仕組みを作ったのが4月で全体展開したのが8月だったので、ちょっと忘れかけでドキドキしながら展開しましたが、設定の展開自体は上手くいったので良かったです。(大量にアラート流れたけど)
では、またいつか〜。