カスタマー管理キーの無効化及び削除に対しての監視設定手順について

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。

今回は、AWS KMS (Key Management Service) のカスタマー管理キー (CMK) の無効化または削除が監視できるようにログメトリクスフィルターが設定されていない状態について、そのリスクと対策を解説します。

リスク

AWS KMSは、暗号化キーを簡単に作成および管理できるサービスで、多くのAWSサービス(S3、RDS、EBSなど)がデータの暗号化に利用しています。特に、カスタマー管理キー (CMK) は、ユーザーがキーのライフサイクルを完全に制御できるため、セキュリティ要件の高いワークロードで広く利用されます。しかし、このCMKの無効化や削除といった変更を適切に監視していない場合、以下のような重大なセキュリティおよび運用上のリスクが発生します。

  • データアクセス不可とサービス停止: CMKが無効化または削除されると、そのキーで暗号化されたすべてのデータやリソース(例: 暗号化されたS3オブジェクト、EBSボリューム、RDSデータベース、Lambda環境変数など)にアクセスできなくなり、関連するアプリケーションやサービスが停止します。これは、悪意のある行為者による意図的な妨害、またはオペレーターによる不注意な操作によって引き起こされる可能性があります。
  • データ損失のリスク: CMKが削除され、キーの復旧期間(Deletion Window)が経過してしまうと、そのキーで暗号化されたデータは恒久的に失われる可能性があります。これは、データの損失を意味し、ビジネスに壊滅的な影響を与える可能性があります。
  • セキュリティインシデントの兆候見落とし: CMKの無効化や削除は、不正アクセスの試みや、内部の不正行為の兆候である可能性があります。これらの重要なイベントをリアルタイムで検知できなければ、セキュリティ侵害の発見が遅れ、被害が拡大するリスクが高まります。
  • 復旧の遅延と運用上の負担: キーの変更が検知されない場合、問題発生時の原因究明と復旧に時間がかかります。これにより、緊急対応が必要となり、運用チームに多大な負担がかかります。

対策

KMSカスタマー管理キーの無効化または削除といった重要なイベントを監視するために、AWS CloudTrailログとCloudWatchログメトリクスフィルターを組み合わせてアラートを設定することが最も効果的な対策です。これにより、意図せぬCMKの変更をリアルタイムで検知し、迅速な対応を可能にします。

  • AWS CloudTrailの有効化: AWSアカウント内のすべてのアクションはCloudTrailによってログに記録されます。CMKの無効化(DisableKey)や削除(ScheduleKeyDeletion)といったKMS API呼び出しもCloudTrailログに記録されます。CloudTrailトレイルが適切に設定され、CloudWatch Logsにログを送信していることを確認します。
  • CloudWatch Logsメトリクスフィルターの作成: CloudWatch Logs内のCloudTrailログを対象に、特定のKMS API呼び出しを検出するためのメトリクスフィルターを作成します。これにより、監視したいイベントが発生した際に、カスタムメトリクスが生成されます。
  • CloudWatchアラームの設定: 作成したカスタムメトリクスに基づいて、CloudWatchアラームを設定します。このアラームは、メトリクスの値が閾値(例: 0より大きい)を超えた場合にトリガーされます。
  • Amazon SNSによる通知: CloudWatchアラームがトリガーされた際に、Amazon SNS (Simple Notification Service) トピックを介して通知を送信するように設定します。SNSトピックは、メール、SMS、Lambda関数、Slack通知など、さまざまなエンドポイントにアラートを配信できます。
  • 自動修復または調査ワークフロー: SNS通知を受け取った際に、AWS Lambda関数をトリガーして自動修復アクション(例: キーの再有効化)を試みる、またはセキュリティオペレーションセンター(SOC)に通知して緊急調査を開始するといったワークフローを構築することを検討します。
  • 最小特権の原則: CMKの管理権限は、厳密に必要最小限のユーザーやロールに限定し、kms:DisableKeykms:ScheduleKeyDeletion などのアクションに対するMFA(多要素認証)を義務付けるなどの追加のセキュリティ対策も併用します。

修復方法

AWSコンソールでの修復手順

KMSカスタマー管理キーの無効化または削除イベントを監視するためのCloudWatchログメトリクスフィルターとアラームを設定する手順は、AWSコンソールとTerraformのいずれでも可能です。

AWSコンソールでの修復手順

AWSコンソールを使用して、CloudTrailログからKMSキーの無効化/削除イベントを検出し、アラートを発報する仕組みを構築します。

前提:

  • AWS CloudTrailが有効になっており、ログをCloudWatch Logsグループに送信するように設定されていること。
  • アラート通知を受け取るためのAmazon SNSトピックが設定済みであること(例: メールアドレスのサブスクライブ済み)。
  1. CloudWatchサービスへ移動: AWSコンソールにログインし、Amazon CloudWatch サービスを開きます。
  2. ロググループへ移動: 左側のナビゲーションペインで「ログ」の下にある「ロググループ」を選択します。
  3. CloudTrailロググループを選択: CloudTrailがログを送信しているロググループ(通常は /aws/cloudtrail/ で始まる名前)を選択します。
  4. メトリクスフィルターの作成:
    • ロググループの詳細ページで、「メトリクスフィルター」タブをクリックし、「メトリクスフィルターを作成」をクリックします。
    • フィルターパターンを入力します。KMSキーの無効化または削除を監視するためのパターンは以下のようになります。 { ($.eventName = "DisableKey") || ($.eventName = "ScheduleKeyDeletion") }
      • DisableKey: CMKを無効にするAPI呼び出し。
      • ScheduleKeyDeletion: CMKの削除をスケジュールするAPI呼び出し。
    • フィルターのテスト」でロググループを選択し、パターンをテストして、期待されるイベントが検出されることを確認します。
    • 次へ」をクリックします。
  5. メトリクスフィルターの詳細設定:
    • フィルター名: 任意の名前を付けます(例: KMSKeyLifecycleChanges)。メトリクス名前空間: 任意の名前空間を付けます(例: CloudTrailMetrics)。メトリクス名: 任意のメトリクス名を付けます(例: KMSKeyModificationCount)。メトリクス値: 1 を入力します(イベントが一致するたびにメトリクスが1増加するように)。「次へ」をクリックします。
  1. アラームの作成:
    • アラームを作成」をクリックします。
    • メトリクス: 自動的に設定されます。
    • 条件:
      • 指定した期間中にメトリクスが指定したしきい値を」: 「以上
      • しきい値」: 0 (つまり、イベントが1回でも発生したらアラームをトリガー)
    • 追加設定:
      • データポイント」: 評価期間とデータポイントの数を設定します(例: 「1つのデータポイント中1つのデータポイント」でリアルタイムに近い監視)。
    • 通知:
      • 状態トリガー」: 「アラーム状態」を選択します。
      • SNS トピックの選択」: 既存のSNSトピックを選択するか、新しいトピックを作成します。
    • アラーム名: 任意の名前を付けます(例: KMSKeyLifecycleAlarm)。
    • アラームの作成をクリックします。

これで、CloudTrailログにKMSキーの無効化または削除イベントが記録されると、CloudWatchアラームがトリガーされ、指定されたSNSトピックを通じて通知が送信されるようになります。

Terraformでの修復手順

TerraformでKMSキーの無効化または削除イベントを監視するためのCloudWatchログメトリクスフィルターとアラームを設定するには、aws_cloudwatch_log_metric_filteraws_cloudwatch_metric_alarm、および関連するSNSリソースを使用します。

# (前提) CloudTrailログが送信されるCloudWatchロググループ
# CloudTrailが作成するロググループは通常以下の形式です
data "aws_cloudwatch_log_group" "cloudtrail_log_group" {
  name = "/aws/cloudtrail/${var.cloudtrail_log_group_name}" # あなたのCloudTrailロググループ名に置き換え
}

# アラート通知用のSNSトピック
resource "aws_sns_topic" "kms_lifecycle_alert_topic" {
  name = "kms-key-lifecycle-alert-topic"
  tags = {
    Environment = "Production"
  }
}

# SNSトピックの購読者 (例: メールアドレス)
resource "aws_sns_topic_subscription" "kms_lifecycle_email_subscription" {
  topic_arn = aws_sns_topic.kms_lifecycle_alert_topic.arn
  protocol  = "email"
  endpoint  = "security-team@example.com" # 通知を受け取るメールアドレスに置き換え
}

# CloudWatch Logs メトリクスフィルター
# KMSキーの無効化または削除イベントを検出
resource "aws_cloudwatch_log_metric_filter" "kms_key_lifecycle_filter" {
  name           = "KMSKeyLifecycleChanges"
  pattern        = "{ ($.eventName = \\"DisableKey\\") || ($.eventName = \\"ScheduleKeyDeletion\\") }"
  log_group_name = data.aws_cloudwatch_log_group.cloudtrail_log_group.name

  metric_transformation {
    name          = "KMSKeyModificationCount"
    namespace     = "CloudTrailMetrics"
    value         = "1" # イベントが一致するたびに1をカウント
  }

  tags = {
    Environment = "Production"
  }
}

# CloudWatch アラーム
# メトリクスフィルターが検出された場合にトリガー
resource "aws_cloudwatch_metric_alarm" "kms_key_lifecycle_alarm" {
  alarm_name          = "KMSKeyLifecycleAlarm"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "1" # 1期間で評価
  metric_name         = aws_cloudwatch_log_metric_filter.kms_key_lifecycle_filter.metric_transformation[0].name
  namespace           = aws_cloudwatch_log_metric_filter.kms_key_lifecycle_filter.metric_transformation[0].namespace
  period              = "300" # 5分間 (300秒)
  statistic           = "Sum"
  threshold           = "0" # 0より大きければトリガー

  alarm_description = "Alerts when a KMS Customer Managed Key is disabled or scheduled for deletion."
  
  # アラームの状態変化時に通知を送信
  alarm_actions = [aws_sns_topic.kms_lifecycle_alert_topic.arn]
  ok_actions    = [aws_sns_topic.kms_lifecycle_alert_topic.arn] # OK状態に戻った時にも通知する場合

  tags = {
    Environment = "Production"
  }
}

上記のTerraformコードでは、以下のリソースを使用しています。

  1. aws_sns_topicaws_sns_topic_subscription: アラート通知の送信先となるSNSトピックと、その購読者(例: メールアドレス)を定義します。
  2. aws_cloudwatch_log_metric_filter: CloudTrailロググループ(data.aws_cloudwatch_log_group.cloudtrail_log_group.name で参照)内のログを監視し、DisableKey または ScheduleKeyDeletion イベントを検出するフィルターパターンを定義します。イベントが検出されると、KMSKeyModificationCount というカスタムメトリクスが CloudTrailMetrics 名前空間で生成され、値が 1 になります。
  3. aws_cloudwatch_metric_alarm: 上記で定義したカスタムメトリクス(KMSKeyModificationCount)を監視するアラームを設定します。
    • comparison_operator = "GreaterThanThreshold"threshold = "0" は、メトリクスの値が0より大きくなったら(つまり、イベントが1回でも発生したら)アラームをトリガーするように設定します。
    • alarm_actions: アラームがトリガーされた際に通知を送信するSNSトピックのARNを指定します。

注意点:

  • var.cloudtrail_log_group_namesecurity-team@example.com などのプレースホルダーは、実際の環境に合わせて修正してください。CloudTrailロググループ名は、CloudTrailトレイルの設定によって異なります。
  • この設定は、AWSアカウント内のすべてのKMS CMKのライフサイクル変更を監視します。特定のCMKのみを監視したい場合は、フィルターパターンをさらに詳細化する必要があります(例: $.requestParameters.keyId = "arn:aws:kms:...")。

最後に

この記事では、KMSカスタマー管理キーの無効化または削除イベントを監視するために、CloudTrailログメトリクスフィルターとCloudWatchアラームを設定することの重要性について解説しました。この監視体制は、意図せぬキーの変更によるサービス停止やデータ損失のリスクを軽減し、セキュリティインシデントの早期発見と迅速な対応を可能にするために不可欠です。 貴社のAWS環境では、KMSカスタマー管理キーのライフサイクル変更に対する監視が適切に設定されていますか?この機会にぜひ設定を確認・強化してみてください。 こちらの内容の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。運用が非常にラクに出来る製品になっていますのでぜひ興味がある方はお問い合わせお待ちしております。

最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。

この記事をシェアする

クラウドセキュリティ対策実践集一覧へ戻る

貴社の利用状況に合わせた見積もりを作成します。

料金プランを詳しく見る