ブロックパブリックアクセスをオンにした S3 バケットに CloudFront 経由でアクセスできなくなった時の対処方法

2020.12.26

困っていた内容

以前、静的ウェブサイトホスティングで公開していた S3 バケットを CloudFront のオリジンアクセスアイデンティティ(以降 OAI)を使用して、S3 への直アクセスは制限したいです。

OAI を使った CloudFront 経由のアクセス制限は成功しましたが、S3 バケット設定のブロックパブリックアクセスをオンにするとアクセスに失敗します。OAI を使いつつ、ブロックパブリックアクセスをオンにしたいです。

どう対応すればいいの?

静的ウェブサイトホスティングで使用されていた S3 バケットに OAI を設定した場合、バケットポリシーが以下のようになっている可能性が高いです。

ブロックパブリックアクセスをオンにするとアクセスに失敗するバケットポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadForGetBucketObjects",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<S3 バケット名>/*"
        },
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXX"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<S3 バケット名>/*"
        }
    ]
}

上記前半のポリシー(Sid: PublicReadForGetBucketObjects)は、静的ウェブサイトホスティングで S3 バケットのリソースをパブリックへ公開するためのポリシーです。このポリシーが残った状態で、S3 バケット設定のブロックパブリックアクセスをオンにすると、OAI を使用したアクセスも権限エラーとなります。

$ curl -sLI <CloudFront ドメイン>/<S3 のファイルパス>
HTTP/2 403
...

$ curl -sL <CloudFront ドメイン>/<S3 のファイルパス> | xmllint --format -
<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>AccessDenied</Code>
  <Message>Access Denied</Message>
  <RequestId>xxx</RequestId>
  <HostId>xxx</HostId>
</Error>

バケットポリシーからパブリックアクセスを許可するポリシーを削除することで、OAI を使用した CloudFront 経由のアクセスが可能となります。

ブロックパブリックアクセスをオンしてもアクセス可能なバケットポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXX"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<S3 バケット名>/*"
        }
    ]
}
$ curl -sLI <CloudFront ドメイン名>/<S3 のファイルパス>
HTTP/2 200
...

まとめ

静的ウェブサイトホスティングを無効にした際は、パブリックアクセスを許可するバケットポリシーは忘れずに削除しましょう。

S3 静的ウェブサイトホスティングから CloudFront OAI の使用に変更した環境のブロックパブリックアクセスの挙動は以下のとおりです。

  • 既存のパブリックアクセス可能な S3 バケットポリシーが存在する場合でも、ブロックパブリックアクセスは有効にできる
    • 有効にすると CloudFront の OAI を使用していても S3 バケットへのアクセスは拒否される
  • ブロックパブリックアクセスがオンの状態で、既存のバケットポリシーからパブリックアクセスに関するポリシーは削除できる
  • ブロックパブリックアクセスがオンの状態で、パブリックアクセス可能なバケットポリシーは追加できない

S3 のオブジェクトをパブリックへ公開しない、または公開しなくなった環境では、ブロックパブリックアクセスをオンに設定することで安全な運用が行えます。運用では防ぎづらい人的なミスを S3 サービス側で防いでくれる機能なのでオススメです。

参考資料