オリジンを S3 とした CloudFront に対して、存在しないオブジェクトへアクセスした際の HTTP ステータスコードが 403 Forbidden になったときの対処方法

オリジンを S3 とした CloudFront に対して、存在しないオブジェクトへアクセスした場合、デフォルトの設定では HTTP ステータスコード 403 Forbidden が返ります。こちらの事象に対して、HTTP ステータスコード 404 Not Found を返す方法をご紹介いたします。
2020.05.14

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

困っていた内容

オリジンを S3 として CloudFront を使用している。 存在しないオブジェクトにアクセスすると HTTP ステータスコード 403 Forbidden が返ってきてしまう。 これを、HTTP ステータスコード 404 Not Found を返すようにしたい。

どう対応すればいいの?

オリジンとして設定している S3 のバケットポリシーに、s3:ListBucket アクションを許可する設定を追加します。 また、Resource 句にバケットのルートを追加します。

設定前

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E012345EXAMPLE"
            },
            "Action": [
                "s3:GetObject", 
            ],   
            "Resource": [
                "arn:aws:s3:::<bucket_name>/*",
            ]
        }
    ]
}

設定後

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E012345EXAMPLE"
            },
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"             
            ],   
            "Resource": [
                "arn:aws:s3:::<bucket_name>/*",
                "arn:aws:s3:::<bucket_name>"
            ]
        }
    ]
}

挙動の確認(やってみた)

事前準備

今回は、返却される HTTP ステータスコードが分かりやすくなるように、CloudFront のカスタムエラーページの機能を使用します。 S3 バケットには以下のオブジェクトのみを配置しています。

test.html

test

403.html

403 Forbidden

404.html

404 NotFound

カスタムエラーページ設定は下記の画面の通りに設定します。

CloudFront_CustomErrorPage_Setting

返却されるステータスコードの確認

CloudFront ディストリビューションのドメイン名を使用して、S3 バケット配下のファイル test.html へアクセスします。

$ curl http://<CloudFront ディストリビューションのドメイン名>.cloudfront.net/test.html
test

問題なく、test.html の情報が取得できます。

存在しないオブジェクト notexistobject.html にアクセスした場合、HTTP ステータスコード 403 が返るため、カスタムエラーページで設定した、403.html の内容が取得されます。

$ curl http://<CloudFront ディストリビューションのドメイン名>.cloudfront.net/notexistobject.html
403 Forbidden

HTTP ステータスコード 404 を返したい場合は、S3 のバケットポリシーに、s3:ListBucket アクションを許可する設定、及び、Resource 句にバケットのルートを追加します。

追加した後は、HTTP ステータスコード 404 が返り、カスタムエラーページで設定した、404.html の内容が取得されます。

$ curl http://<CloudFront ディストリビューションのドメイン名>.cloudfront.net/notexistobject.html
404 Notfound

参考情報

Amazon S3 からの HTTP 404 NoSuchKey エラーをトラブルシューティングする

特定の HTTP ステータスコードのカスタムエラーページを作成する - Amazon CloudFront