0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DENSOAdvent Calendar 2024

Day 16

SNSトピックを暗号化してもBudgetsから通知したい!

Last updated at Posted at 2024-12-16

背景

ある日、AWSからメールが届きました。

You requested that we notify you regarding the status of your <cost-all-services-manage> budget on the following SNS topic: <arn:aws:sns:ap-northeast-1:111111111111:xxxxx_topic>.

Unfortunately, we are unable to successfully publish to this SNS topic at this time. Please ensure that AWS Budgets has been added to the list of services that are allowed to publish to this SNS topic. You can find additional information on how to add AWS Budgets to your SNS topic permissions here. You can also log in to your AWS Budgets Dashboard to check the status of your budget.

Please note that if you do not adjust your SNS topic permissions, it is likely that budget notifications will not be sent to your SNS topic subscribers.

どうやら権限不足によりBudgetsが検知したアラートをSNSトピックに配信できなかったようです。
以前までは問題なくアラートが飛んでいたようなのですが今回から何故か飛ばなくなりました。

この事象の原因を調べ、対策を考えていきます。

調査

権限まわりが原因ということで真っ先にSNSのアクセスポリシーを確認しましたが、
budgets.amazonaws.comがAllowされていますし、ARNに誤りもなく、問題があるようには見えませんでした。

改めて公式ドキュメントを確認してみます。
image.png

ここで、「暗号化...そういえばちょっと前にSNSトピックを暗号化するみたいな話をしていたような...」ということを思い出しました。

実際にSNSトピックを確認すると、マネージド鍵で暗号化していました。
これが原因でBudgetsがSNSトピックに到達できなくなっていた可能性が高いですね。
image.png

試しに、暗号化したSNSトピックと暗号化していないSNSトピックをそれぞれ用意して、メッセージが飛ばないことを確認していきます。
公式ドキュメントに沿って、Budgetsからのアクセスポを許可したSNSトピックを用意します。

  • 暗号化したSNSトピック : shimazu_test_dev_cost_alert_topic
  • 暗号化していないSNSトピック : shimazu_test_dev_cost_alert_topic_no_encryption

次に、Budgetsに設定していきます。
暗号化したSNSトピック : shimazu_test_dev_cost_alert_topicを設定しようとしたところエラーメッセージが出て弾かれました。
image.png

暗号化していないSNSトピック : shimazu_test_dev_cost_alert_topic_no_encryptionは設定できました。

image.png

ここで以前から使っていたSNSトピックに設定し直そうとすると、エラーメッセージが出て弾かれました。

image.png

ここまでの検証で、暗号化したSNSトピックはそもそもBudgetsには設定できないこと、一度暗号化していないSNSトピックをBudgetsに設定してから暗号化することはできてしまう(ただし、BudgetsはSNSトピックに到達できない)ことがわかりました。

対策

対策としては2つ考えられます。

  1. SNSトピックの暗号化を無効にする
  2. Budgetsが復号化を行えるような鍵を作成し、その鍵でSNSトピックを暗号化する

1. SNSトピックの暗号化を無効にする

これは単純な話です。
暗号化したSNSトピックが使えないのであれば、暗号化を無効化すればよいのです。
これはSNSトピックを作り直すことなく暗号化を無効にできます。

しかし、セキュリティの観点では暗号化しておいたほうが良いような気がしますし、会社のポリシーにも準拠できそうです。
そんなときは2.の対策が考えられます。

2. Budgetsが復号化を行えるような鍵を作成し、その鍵でSNSトピックを暗号化する。

CloudTrail の通知に暗号化された SNS Topic を利用した場合に発生する Policy エラーに対応するではCloudTrailの通知先に暗号化したSNSトピックを設定できない事例が紹介されていました。
おそらくBudgetsに関しても同様で、Budgetsが暗号化したSNSトピックに到達できない理由は、復号化が行えないからだと考えられます。

マネージドキーのキーポリシーを見ればBudgetsが復号化を許可されていないことがわかります。

マネージド鍵`aws/sns`のキーポリシー ``` { "Version": "2012-10-17", "Id": "auto-sns-2", "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": "111111111111", "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::111111111111:root" }, "Action": [ "kms:Describe*", "kms:Get*", "kms:List*", "kms:RevokeGrant" ], "Resource": "*" }, { "Sid": "Allow SNS to decrypt archived messages", "Effect": "Allow", "Principal": { "Service": "sns.amazonaws.com" }, "Action": "kms:Decrypt", "Resource": "*", "Condition": { "StringEquals": { "aws:SourceAccount": "111111111111" }, "ArnLike": { "aws:SourceArn": "arn:*:sns:ap-northeast-1:111111111111:*" } } } ] } ```

Budgetsによる復号化を許可するには鍵のポリシーを書き換える必要があります。
しかし、マネージド鍵のポリシーは編集不可なので、自分たちで管理できる鍵(CMK)を作ってBudgetsによる許可するポリシーを書いてやれば、BudgetsからSNSに到達できると考えられます。
例えば以下のようなポリシーを持つCMKを作ると良さそうです。

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

実際にCMKを使って動作確認してみます。

検証

まずは通知の仕組みを作ります。
Budgets+暗号化していないSNS+Chatbotを組み合わせて、通知成功パターンを構築します。
以下のようなSNSをトピックを作成しChatbotの通知元に設定します。

image.png

公式ドキュメントを参考にしてSNSをトピックにBudgetsからの配信を許可するポリシーを設定します。

{
  "Sid": "E.g., AWSBudgetsSNSPublishingPermissions",
  "Effect": "Allow",
  "Principal": {
    "Service": "budgets.amazonaws.com"
  },
  "Action": "SNS:Publish",
  "Resource": "your topic ARN",
   "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "<account-id>"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:budgets::<account-id>:*"
        }
      }
}

次にBudgetsを作成します。
先にSNSのアクセスポリシーでBudgetsからの配信を許可しておかないとBudgetsにSNSトピックを設定できないので注意してください。
image.png

すぐに通知したいため、しきい値を現在の利用実績より低い金額に設定しました。
Budgetsの作成が完了するとすぐにアラートが上がります。

image.png

期待通りSlackまで通知が届きました。
image.png

下準備は完了したので次はSNSを暗号化していきます。
まずは暗号化するためのCMKを作ります。

image.png

image.png

一度鍵を作成してから以下のようなキーポリシーを追記します。

{
    "Effect": "Allow",
    "Principal": {
        "Service": "budgets.amazonaws.com"
    },
    "Action": [
        "kms:GenerateDataKey*",
        "kms:Decrypt"
    ],
    "Resource": "*"
}

image.png

作成したCMKを使って暗号化します。

image.png

もう一度アラートを発生させるとBudgetsが復号化できるようになったので
期待通りSlackに通知が届きました。

image.png

まとめ

Budgetsの通知が飛ばなくなった原因調査と暗号化したSNSを使ってBudgetsの通知を行う方法を紹介しました。
今までCMKをつくるユースケースがあんまり思いつかなかったのですが、今回の検証でユースケースを一つ学ぶことができました。
Budgets以外にもSNSトピックを経由して通知を行う場合は今回のようにCMKを使うことが考えられます。
暗号化をやめるのか、CMKを使うのかは会社のポリシーとCMKのコストを考慮して決定するのが良いと考えます。まぁ基本的にエンタープライズなら暗号化一択かとは思いますが。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?