🌟

【CloudFront】オリジンのS3にないオブジェクトにアクセスしたら404を返したい

2025/01/03に公開

CloudFront のオリジンである S3 にないオブジェクトへのリクエストに 403 が返ってきます。

// S3に noobject というフォルダはない
$ curl -I https://<CloudFrontのドメイン>/noobject
HTTP/2 403
content-type: application/xml
date: Sun, 30 Jul 2023 12:49:10 GMT
server: AmazonS3
x-cache: Error from cloudfront
via: 1.1 ×××××××××××××××.cloudfront.net (CloudFront)
x-amz-cf-pop: ×××××
x-amz-cf-id: ××××××××××××××××××××××××××××××

403 Forbiddenであり、

オブジェクトがないのに**「権限で見れません」が返ってきているのに違和感**があります。

なので、404 Not Found が返ってくるように設定していきます!

Terraformを使って設定していきます

・バージョン

$ terraform providers -version
Terraform v1.4.2
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v4.67.0

原因

https://dev.classmethod.jp/articles/tsnote-cloudfront-s3-notexistobject-403-001/

↑ の記事より、S3 のバケットポリシーで許可している権限が足りていないことが原因

s3:GetObject だけでなく、s3:ListBucket も必要だということ。

GetObject だけだと、

オブジェクトがない → とってこれなかった(List ないのでオブジェクトの有無はわからん) → 404 Not Found ではなく、403 Forbidden 返しておくか

みたいな流れでエラーコードが返ってきているのでしょうか?

ドキュメントはなかったので、完全に憶測ですが。。。

設定

S3 のバケットポリシーを定義している aws_iam_policy_document に追記します。

data "aws_iam_policy_document" "example" {
  # CloudFrontに対して GetObject , ListBucket を許可
  statement {
    principals {
      type = "Service"
      identifiers = [ "cloudfront.amazonaws.com" ]
    }
    actions = [
      "s3:GetObject",
      "s3:ListBucket"
    ]
    resources = [
      "${aws_s3_bucket.example.arn}/*",
      "${aws_s3_bucket.example.arn}"
    ]
    condition {
      test = "StringEquals"
      variable = "aws:SourceArn"
      values = [ aws_cloudfront_distribution.example.arn ]
    }
  }
}

resources の aws_s3_bucket.example.arncondition > values の aws_cloudfront_distribution.example.arnは、ご自身の値に書き換えてください

paln および apply をして、AWS へ反映させます。

動作確認

$ curl -I https://<CloudFrontのドメイン>/noobject
HTTP/2 404
content-type: application/xml
date: Sun, 30 Jul 2023 13:45:27 GMT
server: AmazonS3
x-cache: Error from cloudfront
via: 1.1 ×××××××××××××××.cloudfront.net (CloudFront)
x-amz-cf-pop: ×××××
x-amz-cf-id: ××××××××××××××××××××××××××××××

404 返ってきてますねー、設定完了!!!

参考記事

https://dev.classmethod.jp/articles/tsnote-cloudfront-s3-notexistobject-403-001/

https://qiita.com/celeron1ghz/items/ee3cf7ac720da0e81227

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document

Discussion