Amazon S3 で静的ウェブサイトホスティングとして公開しているバケットに対して、書き込みを VPC エンドポイントを経由する経路のみに制限する方法

VPC エンドポイントを作成し、VPC 内のリソースから S3 へのアクセスを VPC エンドポイント経由にします。その後、バケットポリシーにて VPC エンドポイント以外からの書き込みを拒否する設定を追加ください。
2023.03.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

困っていた内容

Amazon S3 で静的ウェブサイトホスティングでウェブページを公開しています。

当該の S3 バケットに対しての読み込みについては、パブリックアクセスを許可していますが、書き込みは VPC エンドポイントを経由する経路のみに制限したいです。

何か良い方法はありますか?

どう対応すればいいの?

始めに、S3 VPC エンドポイントを作成します。

これを行うことで、VPC 内のリソースから S3 へのアクセスは、VPC エンドポイントを経由するようになります。

静的ウェブサイトホスティングに関する設定を行った S3 バケットに対して、以下のバケットポリシーを設定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<s3-bucket-name>/*"
        },
        {
            "Sid": "access-to-specific-VPC-endpoint-only-for-s3",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::<s3-bucket-name>/*",
            "Condition": {
                "StringNotEquals": {
                    "aws:sourceVpce": "vpce-<endpointid>"
                }
            }
        }
    ]
}

VPC 内のリソース(S3 への書き込みを許可する IAM ポリシーをアタッチした EC2)から、S3 に対して VPC エンドポイント経由の書き込みが成功し、それ以外の書き込みが失敗することを下記のコマンドで確認しました。

$ aws s3 cp index.html s3://<s3-bucket-name>
upload failed: ./index.html to s3://<s3-bucket-name>/index.html An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

$ aws s3 cp index.html s3://<s3-bucket-name> --endpoint http://vpce-<endpointid>-<AvailabilityZone>.s3.<region>.vpce.amazonaws.com
upload: ./index.html to s3://<s3-bucket-name>/index.html

参考資料

Amazon S3 におけるエンドポイント - Amazon Virtual Private Cloud

バケットポリシーを使用した VPC エンドポイントからのアクセスコントロール - Amazon Simple Storage Service