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

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

困っていた内容

オリジンを 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

テクニカルサポートノートとは?

クラスメソッドのカルチャー(CLP) の「情報発信を通じて、全ての人々の創造活動に貢献し続ける」という考えから、クラスメソッド メンバーズをご利用のお客様よりいただいたお問い合わせより、他の AWS ユーザーにとっても 有益な情報を一般的な TIPS としてご紹介しています。