S3バケットのアクセス制御でマネコンからは特定ユーザのみ、リソースからはVPCエンドポイント経由のみに限定するS3バケットポリシーの設定方法

2021.11.27

Jumpアカウントからスイッチロールして各アカウントへログインする環境でS3バケットのアクセス制御を考えていました。

特定のS3バケットへEC2などのVPC内のリソースからはVPCエンドポイントを経由したアクセスのみを許可したいです。あとはメンテナンス用にマネージメントコンソールから特定のIAMロールにスイッチロールしたユーザだけはアクセスできるようにしておきたいです。

S3バケットポリシーと、IAMポリシーを使った設定例を紹介します。

以下のリンクで紹介されている内容の組み合わせです。

S3バケットでしたいこと

S3バケットへのアクセスを保護しつつ、管理者、運用者はマネージメントコンソールからも操作できるような設計としたいです。

  • 特定のS3バケットに対して、特定のVPCエンドポイント以外のアクセスを拒否したい
  • メンテナンスするときに不便だからマネコンから特定のユーザーだけはアクセスさせておきたい

今回は以下の様なJumpアカウントからスイッチロールする環境を想定しています。

画像引用: AWS におけるマルチアカウント管理の手法とベストプラクティス

スイッチロールについては以下のリンクを参考にしてください。

S3バケットの設定例

S3バケットの暗号化と、S3バケットへのアクセス制御の2つに分けて考えていきます。

暗号化

S3バケットはSSE-KMSで暗号化します。暗号化する鍵(CMK)に対してのアクセス制御できることと、利用状況をCloudTrailで追うことができます。 SS3-S3に比べると利用費はかかりますが、それでも2020年12月のアップデートで追加されたS3バケットキーにより利用費は下がりました。

CMKに対するアクセス権限はIAMポリシーが寄せることにし、デフォルトのキーポリシーを採用しています。

キーポリシー例

{
    "Version": "2012-10-17",
    "Id": "key-default-1",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        }
    ]
}

アクセス制御

アクセス元のリソースに設定するIAMロールのIAMポリシーと、S3バケットのバケットポリシーでアクセスを制限します。

IAMポリシー設定例

S3バケットはCMKで暗号化しています。そのためデータの暗号化、複合のためにCMKに対してもアクセス権限が必要になります。

  • S3バケットを暗号化したCMKに対する暗号化、複合できる権限
  • S3バケットに対してアップロード、ダウンロードできる権限
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "kms:Decrypt",
                "kms:Encrypt",
                "kms:GenerateDataKey"
            ],
            "Resource": "arn:aws:kms:ap-northeast-1:123456789012:key/15dfcb2a-6625-4f70-b9a6-edcecFFFFFF",
            "Effect": "Allow",
            "Sid": "SamplePolicy"
        },
        {
            "Action": [
                "s3:ListBucket",
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::sample-dev-blog-bucket",
                "arn:aws:s3:::sample-dev-blog-bucket/*"
            ],
            "Effect": "Allow"
        }
    ]
}

S3バケットポリシー設定例

S3FullAceessや、S3ReadOnly権限をもったユーザーがいてもS3バケットにアクセスできないように特定のもの以外は除外する設定します。

仮に意図しないIAMユーザ、IAMロールが保護対象のS3バケットへの権限が振られてもS3バケットポリシーにより意図しないアクセス許可を防げます。

  • 特定のIAMロールからのすべてのアクションを許可
    • ※ アクションの制限はIAMポリシーに寄せています
  • 特定のVPCエンドポイントからのすべてのアクションを許可
    • ※ アクションの制限はIAMポリシーに寄せています
  • それ以外はすべて拒否
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::sample-dev-blog-bucket",
                "arn:aws:s3:::sample-dev-blog-bucket/*"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:userId": "AROAQ4BT4DH1234567890:*"
                },
                "StringNotEquals": {
                    "aws:SourceVpce": "vpce-0112ccda334ee2dc3"
                }
            }
        }
    ]
}

補足:IAMロールのID確認方法

aws iam get-role --role-name [RoleName]

補足:VPCエンドポイントID確認方法

マネコンから確認

CMKのS3バケットポリシーで"aws:userId": "AROAQ4BT4DH1234567890:*"で指定したIAMロールにスイッチロールしてマネコンから対象のS3バケットを確認しました。通常通りオブジェクトを確認できます。

次に指定したIAMロール以外のIAMロールにスイッチロールして確認しました。オブジェクトの確認すらできません。これで必要な担当者以外のマネコンからのアクセスを保護できます。

VPC内のリソースがVPCエンドポイント経由でアクセスできるか否かは想像に容易いので省略します。

おわりに

キーポリシーでもっと追い込もめるかと思ったのですが、実データの保存されるS3のS3バケットポリシーで厳しく制限できるためCMKへのアクセス制限はIAMポリシーに寄せました。セキュリティと利便性を両立させる、そんな落とし所を狙っていきたい今日このごろです。

参考