一度にたくさん来るInspectorの通知を1つにまとめてSNSに送ってみた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/4101aa17-cdb2-5369-d062-ce2dd01e32a3.png)
# 一度にたくさん来るInspectorの通知を1つにまとめてSNSに送ってみた

## 背景

AWSのセキュリティサービスであるInspectorを導入したものの、その通知や管理方法に悩まされていました。多くのAWSユーザーが直面する問題です。

最初は、ネット上の情報を参考にEventBridgeを使用して通知を設定してみました。しかし、この方法では脆弱性の数×インスタンス数、またはLambda関数の数だけ通知が来てしまい、非常に煩わしい状況になってしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/d7a228ae-6ec3-433b-1d01-b8096fea5422.png)


これは明らかに効率的ではありません。そこで、この問題を解決するための独自のソリューションを開発することにしました。

## 一度にたくさん来る通知をどうやって処理するか

通知をまとめる方法を考える際、最初に思いついたのはDynamoDBの使用でした。しかし、コストを抑えたいので別のアプローチを模索しました。

そこで注目したのが、SNSのメトリクスがCloudWatchで取得できるという点です。これをトリガーとして使用できれば、効率的に通知をまとめることができるのではないかと考えました。

具体的には、CloudWatch Alarmを使用してLambda関数を実行する方法を採用しました。この方法により、以下のようなワークフローを実現できました：
1. SNSのダミートピックスを作る。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/ff7252e9-45d0-9feb-8f15-34e8602467d9.png)
    ダミーなのでサブスクリプションは登録しない。 

1. Inspector FindingをまとめるLambda関数を作る
    1. コードを[Github](https://github.com/koishitori/Lambda_InspectorSummeryNotify/blob/main/lambda_function.py)から持ってくる
    2. ロールの設定。 
    デフォルトのロールに以下を追加
    - AWSIoTDeviceDefenderPublishFindingsToSNSMitigationAction
    - AmazonInspectorReadOnlyAccess
    3. 環境変数を入力する。 
    - AWS_REGION: Findingの対象リージョン
    - LANG: サマリの言語(デフォルト:en, 日本語はjp)
    - TOPIC_ARN: 実際に通知するSNSトピックのARN
1. InspectorからEventBridge経由でサブスクリプションを設定していないダミーのSNSに通知
    1. EventBridgeでInspectorにおいてCRITICALな脆弱性が発見されたときのルール作成
        ルールの詳細
        ![ルールの詳細](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/756731cc-c810-23b1-0349-493c3e25bf9f.png)
        ターゲットの選択でカスタムパターンで参考ページのJSONを貼り付ける。とりあえずここで、緊急度の高いCRITICALのみにする。
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/cb26c6a0-7249-e02a-9aa8-4fd6ec895ab9.png)
        ```
        {
             "source": ["aws.inspector2"],
             "detail-type": ["Inspector2 Finding"],
             "detail": {
               "severity": ["CRITICAL"],
               "status": ["ACTIVE"]
             }
        }  
        ```
        ![作成したダミーのSNSに通知](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/3f6f6a4d-ba0b-b364-ffe6-d76abee28349.png)

   [参考： Step 2. Amazon Inspector の検出結果の EventBridge ルールを作成する](https://docs.aws.amazon.com/ja_jp/inspector/latest/user/findings-managing-automating-responses.html)

2. CloudWatchがSNSのメトリクス(Fill関数を通したNumberOfMessagesPublished)を監視
    1. テストでダミーのSNSにpublishしてみる。 
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/7320283c-7139-4d6c-02c6-c806ad8da1b2.png)
    2. CloudWatchのメトリクスで前項のpublishにより上がることを確認する。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/5c27fb89-8488-3433-a511-d884f13536f9.png)
    3.集計時間を1分にして集計方法を合計または最大にする。またFill関数でデータがない期間を0にする。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/f9aa87af-8faa-a9bf-7a69-b397208bcbd4.png)

   [参考： Metric Math のサポートされている関数](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/using-metric-math.html)
3. メトリクスが1を超えた場合、CloudWatch Alarmを設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/7fa5cab9-eca6-70de-2205-c65d99c47d9a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/cbed9c93-c558-edc1-9c4d-d71da5d1733a.png)

4. Lambda関数が通知をまとめてSNSに送信
[Inspector通知をまとめてSNSに送るサンプル](https://github.com/koishitori/Lambda_InspectorSummeryNotify/blob/main/lambda_function.py)

この方法により、大量の個別通知を1つにまとめることができ、管理が非常に楽になりました。

## まとめ

このソリューションの詳細な実装方法については、GitHubリポジトリで公開しています。興味のある方は是非チェックしてみてください。(まだlambda_function.pyしか置いてないですがそのうち、Readmeを書きます)

このアプローチを採用することで、Inspectorの通知管理が大幅に改善され、セキュリティ監視の効率が向上しました。AWSのサービスを組み合わせることで、コスト効率の良い、カスタマイズされたソリューションを作成できることを実感しました。

皆さんも同様の問題に直面していたら、ぜひ参考にしてみてください。