はじめに
初めまして!ブログでは初登場のSRE部の新沼です。
さっそくですが皆さんがお使いのAWSで作成したリソースは「いつ・誰が・どのような」操作を行ったの記録や脅威検知できていますか?
今回はそのようなAWSにおける監査機能について私たちが取り組んでいる内容を交えてお話したいと思います。
検知要件
例えば、運用していると下記のような項目が検知対象として挙げられると思います。
- セキュリティグループの新規作成・変更・削除
- セキュリティグループのインバウンド・アウトバウンドのルールへ追加・変更・削除
- SSHポート解放検知
- 通知用のサブスクリプションの変更・削除
- SNSトピックの削除
- Guard DutyのFindingsの確認
これは一例なので、他にも多岐に渡る要件が挙がると思います。
検知内容の通知手段
上記の検知できるようになったとして、通知手段がメールとなるとメールボックス内の他のメールに埋もれてしまい見逃してしまうなんてことがあるかもしれません。
皆さんは、日頃様々なチャットツールを使って仕事をすることが多いと思います。 ならば、メッセージとしてきたら見てもらえると思います。さらにグループチャットなど特定の場所に通知されると関係者の目に触れる可能性が上がると思います。
余談にはなりますが、通知手段としてAmazon SNSによってメール送れますが、あまりの大量メールが送信された場合、不正利用と判断されて停止されてしまうことがあります。
利用する場合はご注意ください。
証跡記録・脅威検知
APIのコールやオペレーション証跡記録や脅威検知はこのように対策するのが良いです。
実現方法(設計)
ここでは例として3つのパターンについて実現方法をイラストで表してみました。
見てお分かりの通り、『CloudWatch EventからSNSへ通知してサブスクライブされているLambdaが起動しイベントを解析してChatwork APIを通じて通知』という流れが基本です。
セキュリティグループ操作検知
SSHポート解放検知
Guard DutyのFindings通知
実現方法(実装)
いろんなチャットツールがあるかと思いますが、私たちのサービスであるChatworkのグループチャットへの通知を作成しました。
Lambdaを使ってChatwork APIからメッセージ送信
ここではCloudTrailによるセキュリティグループの操作検知を例に挙げます。
import boto3 import json import logging import os import requests # 環境変数から取得 ENDPOINT = os.environ['endpoint'] ROOM_ID = os.environ['roomid'] API_KEY = os.environ['token'] logger = logging.getLogger() logger.setLevel(logging.INFO) # Chatwork APIを通じてメッセージ送信 def send_msg(msg): post_message_url = '{}/rooms/{}/messages'.format(ENDPOINT, ROOM_ID) headers = {'X-ChatWorkToken': API_KEY} params = {'body': msg} requests.post(post_message_url, headers=headers, params=params) def lambda_handler(event, context): message = event['Records'][0]['Sns']['Message'] message_dist = json.loads(message) type = message_dist['detail']['eventName'] # 何の操作が行われたことによるイベントなのか判別 if type == "AuthorizeSecurityGroupIngress": type = "セキュリティーグループのインバウンドルールに追加されました。" elif type == "AuthorizeSecurityGroupEgress": type = "セキュリティーグループのアウトバウンドルールに追加されました。" elif type == "RevokeSecurityGroupIngress": type = "セキュリティーグループがインバウンドルールが変更または削除されました。" elif type == "RevokeSecurityGroupEgress": type = "セキュリティーグループがアウトバウンドルールが変更または削除されました。" elif type == "CreateSecurityGroup": type = "セキュリティーグループが作成されました。" elif type == "DeleteSecurityGroup": type = "セキュリティーグループが削除されました。" groupId = message_dist['detail']['requestParameters']['groupId'] requestParameters = message_dist['detail']['requestParameters'] text = u"[info][title]CloudTrailによるセキュリティグループオペレーション検知[/title]%s\nグループID: %s\nリクエストパラメータ: \n[code]\n%s\n[/code]\n[/info]" % ( type, groupId, type, json.dumps(requestParameters, indent=2)) send_msg(text)
まとめ
AWSには非常にたくさんのサービスがあるので、今回紹介したサービスを上手に活用することで自分たちの要件に合わせたものを作っていくことができると思います。
ここでは紹介仕切れないもっと上手な活用方法などもありますので、今後はそのような内容もご紹介できたらと思います。
参考
- APIトークンを発行する – サポート | Chatwork
- AWS Configが検出した構成変更をAWS LambdaでChatworkに通知する – AWS Advent Calendar 2014:10日目
次回もお楽しみください。