CloudTrail の通知に暗号化された SNS Topic を利用した場合に発生する Policy エラーに対応する

記事タイトルとURLをコピーする

営業部 佐竹です。
本日は AWS CloudTrail の通知先に「暗号化された SNS トピック」を利用した場合に発生する SNS トピックポリシーエラーを修正する方法を記載します。

はじめに

Security Hub 「AWS Foundational Security Best Practices v1.0.0」をクリアする目的で設定変更中、既存の CloudTrail を更新する必要が出ました。

The SNS topic policy might not have adequate permissions for CloudTrail to access it

しかし、設定を変更して「Save changes」を行うと以下のエラーが発生してしまいます。

f:id:swx-satake:20220209132943p:plain
The SNS topic policy might not have adequate permissions for CloudTrail to access it. Learn more

SNS Topic Policy に問題がある、と出ています。

CloudTrail と SNS の設定を確認したところ、CloudTrail の通知先として利用されている SNS トピックは CloudTrail 作成時に同時に自動作成されたものでした。

CloudTrail では設定のオプションで、「Create a new SNS topic」が選択できます。これを選んだ場合、SNS トピックは自動的に作成され、CloudTrail へと紐づけされます。

自動作成される SNS Topic Policy

以下が自動作成された SNS トピックにアタッチされているポリシーです。

{
  "Version": "2008-10-17",
  "Id": "__default_policy_ID",
  "Statement": [
    {
      "Sid": "__default_statement_ID",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "SNS:GetTopicAttributes",
        "SNS:SetTopicAttributes",
        "SNS:AddPermission",
        "SNS:RemovePermission",
        "SNS:DeleteTopic",
        "SNS:Subscribe",
        "SNS:ListSubscriptionsByTopic",
        "SNS:Publish"
      ],
      "Resource": "arn:aws:sns:ap-northeast-1:123456789012:aws-cloudtrail-logs-123456789012-652cb4db",
      "Condition": {
        "StringEquals": {
          "AWS:SourceOwner": "123456789012"
        }
      }
    },
    {
      "Sid": "AWSCloudTrailSNSPolicy20150319",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Action": "SNS:Publish",
      "Resource": "arn:aws:sns:ap-northeast-1:123456789012:aws-cloudtrail-logs-123456789012-652cb4db",
      "Condition": {
        "StringEquals": {
          "AWS:SourceArn": "arn:aws:cloudtrail:ap-northeast-1:123456789012:trail/management-events"
        }
      }
    }
  ]
}

トピックポリシーも自動生成されるもののため、ここに問題があるとは考えにくい状況です。

では何故、このエラーが発生してしまっているのでしょうか?

Security Hub と SNS Topic Encryption

話を Security Hub に戻します。

Security Hub の AWS Foundational Security Best Practices controls では、以下のコントロールが存在します。

[SNS.1] SNS topics should be encrypted at rest using AWS KMS です。

AWS Config rule: sns-encrypted-kms で管理されるこれは、SNS トピックは必ず KMS で暗号化されていないといけない、というコントロールです。

このコントロールを「Passed」ステータスとなるように、以前 SNS トピックを KMS の鍵を利用して暗号化していました。

どうやら、これが今回のエラーに関連していそうです。

暗号化に利用されている AWS managed key

f:id:swx-satake:20220209135019p:plain
Encryption

CloudTrail の通知先 SNS トピックとして利用されている SNS トピックの暗号化設定を確認すると、キャプチャの通り暗号化の鍵(Customer master key (CMK))は「(Default) alias/aws/sns」になっていました。

この AWS managed key のキーポリシーを KMS のマネジメントコンソールから確認します。以下がキーポリシーです。

{
    "Version": "2012-10-17",
    "Id": "auto-sns-1",
    "Statement": [
        {
            "Sid": "Allow access through SNS for all principals in the account that are authorized to use SNS",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": [
                "kms:Decrypt",
                "kms:GenerateDataKey*",
                "kms:CreateGrant",
                "kms:ListGrants",
                "kms:DescribeKey"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "kms:CallerAccount": "123456789012",
                    "kms:ViaService": "sns.ap-northeast-1.amazonaws.com"
                }
            }
        },
        {
            "Sid": "Allow direct access to key metadata to the account",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": [
                "kms:Describe*",
                "kms:Get*",
                "kms:List*",
                "kms:RevokeGrant"
            ],
            "Resource": "*"
        }
    ]
}

実のところ、このキーポリシーには CloudTrail と連携する SNS トピックとして利用するための設定が不足しています。

どのような問題があるのかと言いますと、CloudTrail がこの鍵を利用しての複合化ができないというものです。

以下は公式ドキュメントからの抜粋です。

AWS KMS で暗号化された Amazon SNS トピックを使用して通知を送信するには、以下のステートメントを AWS KMS key のポリシーに追加して、イベントソース (CloudTrail) と暗号化されたトピックの間の互換性も保つ必要があります。

https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/cloudtrail-permissions-for-sns-notifications.html#kms-key-policy

こちらもドキュメントからの抜粋ですが、具体的に以下のキーポリシーを設定する必要があります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": [
                "kms:GenerateDataKey*",
                "kms:Decrypt"
            ],
            "Resource": "*"
        }
    ]
}

この表記は、AWS managed key のキーポリシー内に記載がありません。また、AWS managed key のキーポリシーは修正ができません。

つまり対応として、CloudTrail の通知先 SNS トピックのために、上記のキーポリシーが 記載された CMK を 新規に用意する必要があります

対応方法

Customer managed key のキーポリシーサンプル

新規に作成した CMK に対して、そのキーポリシーには以下のように記載を行い、CloudTrail からの参照が可能なよう修正します。

{
    "Version": "2012-10-17",
    "Id": "key-consolepolicy-3",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": [
                "kms:GenerateDataKey*",
                "kms:Decrypt"
            ],
            "Resource": "*"
        }
    ]
}

SNS トピックの設定変更

f:id:swx-satake:20220209140122p:plain

キャプチャの通り、既存の SNS トピックの暗号化の設定を (Default) alias/aws/sns から先ほど作成した CMK(今回は alias/SNS-Key)に修正してください。

f:id:swx-satake:20220209142649p:plain
設定確認

この通り変更すれば The SNS topic policy might not have adequate permissions for CloudTrail to access it. のエラーメッセージが CloudTrail の設定更新時に発生しなくなります。

まとめ

本日は AWS CloudTrail の通知先に「暗号化された SNS トピック」を利用した場合に発生する SNS トピックポリシーエラーを修正する方法を記載しました。

結論としては、CloudTrail の通知先に「暗号化された SNS トピック」を利用したい場合は、SNS トピックの暗号化を (Default) alias/aws/sns ではなくCustomer managed key を必ず使う必要があるということです。その理由は、CloudTrail で暗号化された SNS トピックを設定するためには CMK のキーポリシーの修正が必須であり、AWS managed key はキーポリシーの修正ができないためです。

今回このエラーにハマってしまい、かなり時間を浪費してしまいました。エラーメッセージからも SNS トピックのポリシーが怪しいと四苦八苦していたのですが、直接的な原因は KMS の CMK キーポリシーの設定であり、それに気付くのが遅れました。

同じようにハマってしまう方が減るようにと本ブログを書かせて頂きました。

では、またお会いしましょう。

佐竹 陽一 (Yoichi Satake) エンジニアブログの記事一覧はコチラ

営業部カスタマーサクセス課所属。AWS資格12冠。2010年1月からAWSを利用してきました。2021 Japan APN Ambassador /2020-2021 APN ALL AWS Certifications Engineer。AWSのコスト削減、最適化を得意としています。