MSKクラスターにおけるCMKでの暗号化について

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

今回は、Amazon Managed Streaming for Kafka (MSK) クラスターがAWS所有キーで暗号化されており、カスタマー管理キー (CMK) 以上のレベルで暗号化されていない状態について、そのリスクと対策を解説します。

リスク

Amazon MSKは、Apache Kafkaクラスターを簡単に構築、管理、スケールできるフルマネージドサービスです。MSKはデフォルトで保管時の暗号化をサポートしており、AWSが所有するKMSキー(AWS owned key)が使用されます。このデフォルト設定のまま運用している場合、以下のようなセキュリティおよびコンプライアンス上のリスクが発生します。

  • 鍵管理の制御不足: AWS所有キーはAWSによって管理され、ユーザーは鍵のライフサイクル(作成、ローテーション、無効化、削除)やアクセス制御を詳細に制御できません。高いセキュリティ要件を持つ組織では、鍵の生成、保管、利用、ローテーションなどを自身で完全に管理できるカスタマー管理キー (CMK) またはそれ以上のセキュリティレベルのキーの利用が不可欠となります。
  • 機密データの露出リスク: Kafkaクラスターは、アプリケーション間の重要なデータストリームを扱います。これには、ユーザー行動データ、金融取引情報、個人を特定できる情報(PII)など、機密性の高い情報が含まれることがよくあります。これらのデータが、より厳格な制御が可能なCMKで暗号化されていない場合、不正アクセスや内部犯行のリスクが高まり、機密データが露出する可能性があります。
  • コンプライアンス要件の未達: 多くの業界規制やコンプライアンス基準(例: PCI DSS、HIPAA、GDPR、FedRAMP)では、機密データの保管時の暗号化が義務付けられており、特に使用される暗号化キーに対する厳格な管理と監査が求められます。AWS所有キーでは、鍵のライフサイクルに対する十分な制御ができないため、これらのコンプライアンス要件を満たせず、監査での指摘、法的リスク、高額な罰金につながる可能性があります。
  • 鍵の使用状況の可視性不足: AWS所有キーの使用状況はKMSのログに詳細に記録されないため、誰がいつ暗号化/復号化操作を行ったかといった詳細な監査証跡を追跡することが困難です。CMKを使用すると、KMSのAPI呼び出しがCloudTrailに記録され、鍵の使用状況を完全に可視化できます。

対策

Amazon MSKクラスターのデータをKMSのカスタマー管理キー (CMK) またはCloudHSMキーで暗号化することは、上記のすべてのリスクを軽減し、セキュリティ体制を大幅に強化するための重要なベストプラクティスです。

  • KMS カスタマー管理キー (CMK) の使用: MSKクラスターを作成する際に、AWS KMS (Key Management Service) で作成したカスタマー管理キーを指定します。CMKを使用することで、鍵の生成、ローテーション、無効化、削除、およびアクセス権限(キーポリシー)をユーザー自身が完全に制御できるようになります。これは、最も一般的なセキュリティ強化策です。
  • CloudHSMキーの使用 (最高レベルのセキュリティ): FIPS 140-2 Level 3認証のハードウェアセキュリティモジュール (HSM) に保管されたキーを使用したい場合は、AWS CloudHSMと統合できます。これは、最も厳格なセキュリティおよびコンプライアンス要件を持つ組織に適しており、鍵がAWSのデータセンター内でFIPS検証済みのハードウェアに安全に保管されることを保証します。
  • 最小特権の原則に基づくキーポリシー: CMKのキーポリシーを設定する際には、MSKサービスがクラスターの暗号化および復号化に必要な最小限の権限のみを付与するようにします。具体的には、MSKサービスプリンシパル(kafka.amazonaws.com)に kms:Encrypt, kms:Decrypt, kms:ReEncrypt*, kms:GenerateDataKey*, kms:DescribeKey などの権限を許可します。
  • 新規クラスターでの有効化: MSKクラスターの暗号化設定は、クラスター作成時のみに指定できます。既存のクラスターをCMKで暗号化するには、新しいクラスターを作成し、データを移行する必要があります。
  • AWS CloudTrailとの統合: CMKまたはCloudHSMキーの使用状況はAWS CloudTrailに記録されます。これにより、誰がいつ暗号化/復号化操作を行ったかを監査し、セキュリティイベントを監視できます。

修復方法

Amazon MSKクラスターの暗号化をKMSカスタマー管理キー(CMK)で有効にする方法は、AWSコンソールまたはTerraformで行えます。CloudHSMキーを使用する場合は、先にAWS CloudHSMクラスターとそれに統合されたKMSキーを作成する必要があります。

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

AWSコンソールを使用して、Amazon MSKクラスターの作成時にKMS CMKで暗号化を有効にします。

前提:

  • MSKクラスターを暗号化するためのAWS KMS カスタマー管理キー (CMK) が既に存在すること。
    • CMKのキーポリシーには、MSKサービス (kafka.amazonaws.com) がキーを使用するための適切な権限(kms:Encrypt, kms:Decrypt など)が付与されている必要があります。
  1. Amazon MSKサービスへ移動: AWSコンソールにログインし、Amazon Managed Streaming for Apache Kafka サービスを開きます。
  2. クラスターの作成:クラスターを作成」をクリックします。
  3. クラスターのプロパティ設定:
    • 作成方法」で「カスタム作成」を選択します。(「クイック作成」ではCMKを選択できません)
    • クラスター名、Kafkaバージョン、プロビジョニングタイプなどを設定します。
  4. ストレージと暗号化の設定:
    • ストレージと暗号化」セクションまでスクロールします。
    • 保管時の暗号化」セクションで、デフォルトで「有効」にチェックが入っていることを確認します。
    • カスタマー管理のキー (CMK) を選択する」を選択します。
    • ドロップダウンメニューから、使用したい既存のKMS CMKを選択します。
      • もし適切なCMKがリストに表示されない場合は、正しいIAM権限があるか、またはCMKが作成されているか確認してください。
  1. ネットワーク設定、セキュリティ設定、監視設定など、残りの設定を構成します。
  2. 確認と作成: 設定内容を確認し、「クラスターを作成」をクリックしてクラスターをプロビジョニングします。

これで、Amazon MSKクラスターに保存されるデータは、指定したKMS CMKを使用して保管時に暗号化されるようになります。既存のクラスターを変更することはできないため、既存のクラスターをCMKで暗号化したい場合は、新しいクラスターにデータを移行する必要があります。

Terraformでの修復手順

TerraformでAmazon MSKクラスターの暗号化をKMSカスタマー管理キー(CMK)で有効にするには、aws_msk_cluster リソースの encryption_info ブロックにある encryption_at_rest_kms_key_arn パラメータを設定します。

# (例) MSKクラスター暗号化用のKMSカスタマー管理キー (CMK)
resource "aws_kms_key" "msk_cmk" {
  description             = "KMS key for MSK cluster encryption"
  deletion_window_in_days = 10 # キーの削除をスケジュールするまでの日数
  enable_key_rotation     = true # キーの自動ローテーションを有効にする
  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Sid    = "Enable IAM User Permissions",
        Effect = "Allow",
        Principal = {
          AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" # アカウントルートユーザーにアクセス許可
        },
        Action   = "kms:*",
        Resource = "*"
      },
      {
        Sid = "Allow MSK Service to use the key"
        Effect = "Allow",
        Principal = {
          Service = "kafka.amazonaws.com"
        },
        Action = [
          "kms:Encrypt",
          "kms:Decrypt",
          "kms:ReEncrypt*",
          "kms:GenerateDataKey*",
          "kms:DescribeKey"
        ],
        Resource = "*"
      }
    ]
  })
  tags = {
    Name = "MSK_CMK"
  }
}

# (前提) VPC, サブネット, セキュリティグループ
# MSKクラスターをデプロイするVPC, サブネット, セキュリティグループを定義します
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "subnet1" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "${data.aws_region.current.name}a"
}

resource "aws_subnet" "subnet2" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = "${data.aws_region.current.name}b"
}

resource "aws_security_group" "msk_sg" {
  name        = "msk-security-group"
  description = "Security group for MSK brokers"
  vpc_id      = aws_vpc.main.id

  # Kafkaクライアントからのインバウンドトラフィックを許可 (例: 9092, 9094など)
  ingress {
    from_port   = 9092
    to_port     = 9092
    protocol    = "tcp"
    cidr_blocks = ["10.0.0.0/16"] # VPC内のクライアントからのアクセスを許可
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# Amazon MSKクラスター
resource "aws_msk_cluster" "my_encrypted_msk_cluster" {
  cluster_name           = "my-secure-msk-cluster"
  kafka_version          = "2.8.1" # 利用可能なKafkaバージョンを指定
  number_of_broker_nodes = 3

  broker_node_group_info {
    instance_type = "kafka.t3.small"
    client_subnets = [
      aws_subnet.subnet1.id,
      aws_subnet.subnet2.id,
    ]
    security_groups = [aws_security_group.msk_sg.id]
    storage_info {
      ebs_storage_info {
        volume_size = 100 # GB
      }
    }
  }

  # 暗号化設定
  encryption_info {
    # KMS CMKを指定して保管時の暗号化を有効にする
    encryption_at_rest_kms_key_arn = aws_kms_key.msk_cmk.arn
  }

  open_monitoring {
    prometheus {
      jmx_exporter {
        enabled_in_broker = true
      }
      node_exporter {
        enabled_in_broker = true
      }
    }
  }

  tags = {
    Name        = "MySecureMSKCluster"
    Environment = "Production"
  }
}

# 現在のAWSアカウント情報を取得
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}

上記のTerraformコードでは、aws_msk_cluster リソースの encryption_info ブロック内で encryption_at_rest_kms_key_arn パラメータに、KMSカスタマー管理キー(CMK)のARNを指定しています。

  • aws_kms_key.msk_cmk: MSKクラスターの暗号化に使用するKMSカスタマー管理キー (CMK) を作成します。このキーのポリシーには、MSKサービスプリンシパル (kafka.amazonaws.com) がキーを使用するための適切な権限が必要です。
  • aws_msk_cluster.my_encrypted_msk_cluster.encryption_info.encryption_at_rest_kms_key_arn: ここに作成したKMS CMKのARNを指定します。

my-secure-msk-cluster10.0.0.0/16 などのプレースホルダーは、実際の環境に合わせて修正してください。

最後に

この記事では、Amazon MSKクラスターのデータをKMSカスタマー管理キー(CMK)以上で暗号化することの重要性について解説しました。この設定は、ストリーミングデータとそのストレージを保護し、厳格なセキュリティおよびコンプライアンス要件を満たすために不可欠です。CMKやCloudHSMキーを使用することで、鍵管理の制御を強化し、機密データの露出リスクを大幅に軽減できます。 貴社のMSKクラスターは、カスタマー管理キー以上のレベルで暗号化されていますか?この機会にぜひ設定を確認・強化してみてください。 こちらの内容の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。運用が非常にラクに出来る製品になっていますのでぜひ興味がある方はお問い合わせお待ちしております。

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

この記事をシェアする

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

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

料金プランを詳しく見る