AWS-チープなりなセキュリティとコンプラ その4 SNS編

金は無くとも、使い続ける以上やるために監視や保護を入れたら通知もしときましょうです。
configとWAFの定義は入れましたが毎日ニラメッコというのもゾッとしません。Amazon SNSを利用して必要な情報を通知するようにします。

Amazon SNS トピックの作成

まずはメール通知をするためのアクセスポイントとなるトピックを作成します。今回はお手軽に通知するのでメール通知の口だけを作成します。

Amazon SNSのページからトピックを選択し「トピックの作成」をクリックします。
タイプ:スタンダードを選択します
名前:任意の名前を入力します
表示名:メールの件名に表示されます、任意の表示名を入力します
コンテンツベースのメッセージ重複排除:チェック無し

今回は単純にメールを送りたいだけなので、以下のオプションは何も設定せずに「トピックの作成」をクリックします。

次にトピックからメールへの送信のためのサブスクリプションを作成します。
メニューからサブスクリプションを選択し「サブスクリプションの作成」をクリックします。

トピックARN:作成したトピックのARNを選択します
プロトコル:Eメールを選択します
エンドポイント:送付したいメールアドレスを入力します


オプションは選択せず「サブスクリプションの作成」をクリックします。
作成後、送信先のメールアドレスに以下のような確認メールが届きます。「Confirm subscription」がリンクになっているのでクリックし確認を完了します。

件名:AWS Notification - Subscription Confirmation

You have chosen to subscribe to the topic: 
arn:aws:sns:xxxxxxxx:xxxxxxx:config-info

To confirm this subscription, click or visit the link below (If this was in error no action is necessary): 
Confirm subscription

Please do not reply directly to this email. If you wish to remove yourself from receiving all future SNS subscription confirmation requests please send an email to sns-opt-out

configのメール通知

configで設定したルールで検出された場合にメールを通知するようにしたいと思います。
config設定自体でSNSトピックに紐付けることもできますが、その場合以下のようなJSON形式で容赦なく送られてきます。
セキュリティグループで無制限なSSHの解放を検出した場合ですが、これだけでなくS3にログを格納した時のSnapshotの実行とかのアクションも含めてこのようにJSONでメール送信されきます。

New Compliance Change Record:
----------------------------
{
 "awsAccountId": "○○○○○○○○○",
 "configRuleName": "restricted-ssh",
 "configRuleARN": "arn:aws:config:ap-northeast-1:○○○○○○○○○:config-rule/config-rule-3pilru",
 "resourceType": "AWS::EC2::SecurityGroup",
 "resourceId": "sg-○○○○○○○○○",
 "awsRegion": "ap-northeast-1",
 "newEvaluationResult": {
   "evaluationResultIdentifier": {
     "evaluationResultQualifier": {
       "configRuleName": "restricted-ssh",
       "resourceType": "AWS::EC2::SecurityGroup",
       "resourceId": "sg-○○○○○○○○○"
     },
     "orderingTimestamp": "2021-05-17T13:42:15.466Z"
   },
   "complianceType": "NON_COMPLIANT",
   "resultRecordedTime": "2021-05-17T13:42:32.439Z",
   "configRuleInvokedTime": "2021-05-17T13:42:32.281Z",
   "annotation": null,
   "resultToken": null
 },
 "oldEvaluationResult": {
   "evaluationResultIdentifier": {
     "evaluationResultQualifier": {
       "configRuleName": "restricted-ssh",
       "resourceType": "AWS::EC2::SecurityGroup",
       "resourceId": "sg-○○○○○○○○○"
     },
     "orderingTimestamp": "2021-05-14T16:13:04.453Z"
   },
   "complianceType": "COMPLIANT",
   "resultRecordedTime": "2021-05-17T13:35:32.654Z",
   "configRuleInvokedTime": "2021-05-17T13:35:32.527Z",
   "annotation": null,
   "resultToken": null
 },
 "notificationCreationTime": "2021-05-17T13:42:33.215Z",
 "messageType": "ComplianceChangeNotification",
 "recordVersion": "1.0"
}

なので、Amazon EventBridgeを使って検出が行われた場合にメールをわかりやすく通知することにします。
要は迂闊にconfigにトピック紐付けてバシバシメールが来たんです。
まずはメニューからAmazon EventBridgeを選択して、ルールの作成をクリックします。

以下を設定
名前:わかりやすい名前を入力
説明:こちらもわかりやすい名前を入力
パターン定義:パターンを選択

イベントパターンを選択すると以下のようになります。
イベント一致パターンにカスタムパターンを選択し、イベントパターンに検出パターンをJSON形式で入力します。

以下はaws.configで設定項目の変更(Config Rules Compliance Change)が行われ、configRuleNameで指定したマネージドのconfigルールの評価するリソースのコンプライアンスタイプが非準拠(NON_COMPLIANT)になった場合を条件にしています。

{
  "source": ["aws.config"],
  "detail-type": ["Config Rules Compliance Change"],
  "detail": {
    "messageType": ["ComplianceChangeNotification"],
    "configRuleName": ["s3-bucket-public-write-prohibited", "s3-bucket-public-read-prohibited", "ec2-stopped-instance", "restricted-ssh", "restricted-common-ports"],
    "newEvaluationResult": {
      "complianceType": ["NON_COMPLIANT"]
    }
  }
}

次にターゲットの設定を行います。
ターゲットにSNSトピックを選択します、トピックのプルダウンから今回の送信用に設定したトピック名を選択します。
入力の設定に入力トランスフォーマーを選択すると入力パスと入力テンプレートのが表示されます。

入力パスに非準拠以下のパスを入力します。
こちらは、「AWS リソースが準拠していない場合に AWS Config を使用して通知を受けるにはどうすればよいですか?」でも紹介されています。

{"awsAccountId":"$.detail.awsAccountId","awsRegion":"$.detail.awsRegion","compliance":"$.detail.newEvaluationResult.complianceType","resourceId":"$.detail.resourceId","resourceType":"$.detail.resourceType","rule":"$.detail.configRuleName","time":"$.detail.newEvaluationResult.resultRecordedTime"}

入力テンプレートにメールで出力される本文を入力します。改行したいときは以下にも書かれているように各行は必ず二重引用符(「””」)で閉じる必要があります。
入力トランスフォーマーを使用して、 API コールの人が判読できる CloudWatch イベント通知を設定する方法を教えてください。

"発生時刻 : <time>"
"ルール名 : <rule> "
"リソースタイプ : <resourceType>"
"リソースID : <resourceId>"
"AWSアカウント : <awsAccountId>"


"非準拠のリソースが存在します。"
"configから状態を確認してください。"

入力後、「作成」をクリックします。作成後はAmazon EventBridgeの左のメニューのルールに表示されるので選択・編集できます。
試しに、セキュリティーグループのconfigルールで非準拠に引っかかるように インバウンドに22 番ポートを0.0.0.0/0で設定してみます。
非準拠が検出されると以下のようなメールが送信されてきます。

"発生時刻 : YYYY-MM-DDTtt:mm:ss.xxxx"
"ルール名 : restricted-ssh "
"リソースタイプ : AWS::EC2::SecurityGroup"
"リソースID : sg-○○○○○○○○○○○○○"
"AWSアカウント : ○○○○○○○○○○○○○"


"非準拠のリソースが存在します。"
"configから状態を確認してください。"

WAFイベントのメール通知

WAFのイベントに関してもメールで通知するようにしましょう。
WAFに関しては、基本的に攻撃の防御のための設定です。ブロックイベントは正常に動作した結果なのでリアルタイムのイベントを通知するよりはどのルールで一日でどれほどブロックがあったかを通知するようします。
WAFの通知はCloudWatachアラームで設定します。

CloudWatchを選択し、アラームを選択し「アラーム」の作成をクリックします。

メトリクスと条件の指定に遷移したら、「メトリクスの選択」をクリックします。

選択できるメトリクスの一覧が出るので、WAFV2をクリックします。

さらにWAFで設定したグループルールに基づく一覧が表示されます。
ここではRegion,Rule,WebACLを選択します。

メトリクス名がBlockedRequestsのメトリクスを選択します。
メトリクスは一つしか選択できないので、確認したいルール毎に作成します。
※SQLインジェクションのルールであるSQLi_QueryStringはCountedRequestsとなっていますが手順は同様でOKなはず

メトリクスの条件と指定に遷移したら以下を設定します。

  • メトリクス名:そのまま
  • WebACL:そのまま
  • Regeon:利用しているリージョンが選択されていること
  • Rule:そのまま
  • 統計:サンプル数を選択(※ブロックされた件数をみたいので)
  • 期間:1日(※お好みでどうぞ)

しばらたってから設定すると以外とけっこう引ける数が出たりしますがこんなもんみたいです。

さらに条件を設定します

  • 条件:静的を選択
  • BlockRequestsが次の時:以上(>=しきい値)を選択
  • ...よりも:1を入力します(発生したら通知としたいので)
  • その他の設定
    アラームを実行するデータポイント:何もしない
    欠損データの処理:「欠損データを適正(しきい値を超えてない)と処理」を選択

設定したら「次へ」クリックします。
アクションの設定画面に遷移したら、通知を設定します。

  • アラーム状態トリガー:アラーム状態を選択
  • SNSトピックの選択:既存のSNSトピックを選択
  • 通知の送信先:設定したSNSトピックを選択します

その他の項目は何をせずに

アラーム名とアラームの説明を入力し「次へ」をクリックします。

設定の確認画面に遷移するので、「アラームの作成」をクリックします。
作成されると必要なデータが取得されるまで、「データ不足」として表示されます。

しばらくしてデータが集まると設定した内容により、「OK」または「アラーム」として検知されます。
またアラームとして検知されると以下のようにメールが通知されます。

BlockedRequests
CountedRequests


You are receiving this email because your Amazon CloudWatch Alarm "ManagedRulesCommonRuleSet" in the Asia Pacific (Tokyo) region has entered the ALARM state, because "Threshold Crossed: 1 out of the last 1 datapoints [1.0 (27/05/21 03:49:00)] was greater than or equal to the threshold (1.0) (minimum 1 datapoint for OK -> ALARM transition)." at "Thursday 27 May, 2021 03:54:07 UTC".

View this alarm in the AWS Management Console:
https://ap-northeast-1.console.aws.amazon.com/cloudwatch/deeplink.js?region=ap-northeast-1#alarmsV2:alarm/ManagedRulesCommonRuleSet

Alarm Details:
- Name:                       ManagedRulesCommonRuleSet
- Description:                
- State Change:               OK -> ALARM
- Reason for State Change:    Threshold Crossed: 1 out of the last 1 datapoints [1.0 (27/05/21 03:49:00)] was greater than or equal to the threshold (1.0) (minimum 1 datapoint for OK -> ALARM transition).
- Timestamp:                  Thursday 27 May, 2021 03:54:07 UTC
- AWS Account:                ○○○○○○○○○○○○○○○
- Alarm Arn:                  arn:aws:cloudwatch:ap-northeast-1:○○○○○○○○○○○○○○○:alarm:ManagedRulesCommonRuleSet

Threshold:
- The alarm is in the ALARM state when the metric is GreaterThanOrEqualToThreshold 1.0 for 300 seconds. 

Monitored Metric:
- MetricNamespace:                     AWS/WAFV2
- MetricName:                          BlockedRequests
- Dimensions:                          [WebACL = waf-base-001] [Region = ap-northeast-1] [Rule = AWS-AWSManagedRulesCommonRuleSet]
- Period:                              300 seconds
- Statistic:                           SampleCount
- Unit:                                not specified
- TreatMissingData:                    notBreaching


State Change Actions:
- OK: 
- ALARM: [arn:aws:sns:ap-northeast-1:○○○○○○○○○○○○○○○:xxxxxxxx]
- INSUFFICIENT_DATA: 

これで設定はしたものがマネコンに入って確認しなければ見れませんの状態から少しだけ前に進んだ感じでしょうか。