kubell Creator's Note

ビジネスチャット「Chatwork」のエンジニアのブログです。

ビジネスチャット「Chatwork」のエンジニアのブログです。

読者になる

AWSの監査機能を使ってリソースを安全に守ろう

はじめに

初めまして!ブログでは初登場のSRE部の新沼です。

さっそくですが皆さんがお使いのAWSで作成したリソースは「いつ・誰が・どのような」操作を行ったの記録や脅威検知できていますか?

今回はそのようなAWSにおける監査機能について私たちが取り組んでいる内容を交えてお話したいと思います。

f:id:cw-niinuma:20190625133458j:plain

検知要件

例えば、運用していると下記のような項目が検知対象として挙げられると思います。 

  • セキュリティグループの新規作成・変更・削除
  • セキュリティグループのインバウンド・アウトバウンドのルールへ追加・変更・削除
  • SSHポート解放検知
  • 通知用のサブスクリプションの変更・削除
  • SNSトピックの削除
  • Guard DutyのFindingsの確認

これは一例なので、他にも多岐に渡る要件が挙がると思います。

検知内容の通知手段

上記の検知できるようになったとして、通知手段がメールとなるとメールボックス内の他のメールに埋もれてしまい見逃してしまうなんてことがあるかもしれません。

皆さんは、日頃様々なチャットツールを使って仕事をすることが多いと思います。 ならば、メッセージとしてきたら見てもらえると思います。さらにグループチャットなど特定の場所に通知されると関係者の目に触れる可能性が上がると思います。

余談にはなりますが、通知手段としてAmazon SNSによってメール送れますが、あまりの大量メールが送信された場合、不正利用と判断されて停止されてしまうことがあります。

利用する場合はご注意ください。

証跡記録・脅威検知

APIのコールやオペレーション証跡記録や脅威検知はこのように対策するのが良いです。

実現方法(設計)

ここでは例として3つのパターンについて実現方法をイラストで表してみました。

見てお分かりの通り、『CloudWatch EventからSNSへ通知してサブスクライブされているLambdaが起動しイベントを解析してChatwork APIを通じて通知』という流れが基本です。

セキュリティグループ操作検知

f:id:cw-niinuma:20190625114641p:plain

SSHポート解放検知

f:id:cw-niinuma:20190625115938p:plain

Guard DutyのFindings通知

f:id:cw-niinuma:20190625123732p:plain

実現方法(実装)

いろんなチャットツールがあるかと思いますが、私たちのサービスである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には非常にたくさんのサービスがあるので、今回紹介したサービスを上手に活用することで自分たちの要件に合わせたものを作っていくことができると思います。

ここでは紹介仕切れないもっと上手な活用方法などもありますので、今後はそのような内容もご紹介できたらと思います。

参考

次回もお楽しみください。