Как мне вернуть ведро S3 404 (вместо 403) для ключа, которого нет в ведре/

Я использую S3 для хранения некоторых важных для бизнеса документов. Я хочу, чтобы ведро возвращало код статуса 404 при попытке доступа к объекту, который не существует в ведре.

Однако я нахожу, что он продолжает возвращать мне "403

вот пример сеанса с использованием URL-адреса сайта S3.

> GET /foobar.txt HTTP/1.1
> User-Agent: curl/7.21.6 (x86_64-pc-linux-gnu) libcurl/7.21.6 OpenSSL/1.0.0e zlib/1.2.3.4 libidn/1.22 librtmp/2.3
> Host: <bucketname>.s3-website-us-east-1.amazonaws.com
> Accept: */*
> 
< HTTP/1.1 403 Forbidden
< Last-Modified: Mon, 09 Sep 2013 19:10:28 GMT
< ETag: "14e13b81b3ce5b129d1f206b3e514885"
< x-amz-error-code: AccessDenied
< x-amz-error-message: Access Denied
< x-amz-request-id: <snip>
< x-amz-id-2: <snip>
< Content-Type: text/html
< Content-Length: 11
< Date: Thu, 26 Sep 2013 20:01:45 GMT
< Server: AmazonS3
< 
Not found!

Обратите внимание: "Не найдено!" строка исходит из документа ошибки, установленного в свойствах ведра при включении хостинга сайта S3.

Я также попытался получить доступ, используя адрес bucket напрямую

Http://.s3.amazonaws.com/

и возвращает то же самое, за исключением того, что вместо документа с ошибкой я получаю XML-документ

Как решить эту проблему?

Ответ 1

S3 возвращает 403 вместо 404, когда пользователь не имеет права перечислить содержимое ведра.

Если вы запрашиваете объект и получаете 404, вы знаете, что объект не существует. Это информация, которую вы не должны знать, если у вас нет разрешения на перечисление содержимого ведра, поэтому вместо того, чтобы сообщать вам, что этого не существует, S3 просто сообщает вам, что вы пытаетесь сделать то, что вам не разрешено делать, Когда вы получаете 403 вместо 404, вы не можете знать, что запрошенный объект не существует. Возможно, он не существует или может существовать, и у вас просто нет доступа к нему. Вы не можете точно знать, и поэтому защита не обходится.

Я считаю, что любой, кто имеет доступ к списку содержимого ведра, получит 404 вместо 403.

Ответ 2

Точное требование, по-видимому, заключается в том, что у вашего пользователя есть разрешение ListBucket для вашего конкретного ведра, а ARN - это точно форма arn:aws:s3:::your_bucket_name.

Мне также нужно было добавить совершенно новую инструкцию в мою политику, потому что другие разрешения, такие как GetObject, все еще требуют, чтобы ARN заканчивался на /* или какой-либо другой подходящий шаблон.

{
  "Action": [
    "s3:ListBucket"
  ],
  "Sid": "StmtNNNNNNNNNNNNNNNwholebucket",
  "Resource": [
    "arn:aws:s3:::your_bucket_name"
  ],
  "Effect": "Allow"
},

Подводя итог, важным для меня было то, что если ARN не является формой arn:aws:s3:::your_bucket_name/* для ListBucket, или вы все равно получите 403 вместо 404.

Ответ 3

Убедитесь, что в ваших разрешениях Everyone есть View Permissions.

Вы также можете добавить политику ведра:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your_bucket_name/*"
        }
    ]
}

Ответ 4

Мне нужно было расширить политику следующим образом:

 "Action": [
   "s3:Get*",
   "s3:List*"
 ],
 "Resource": [
   "arn:aws:s3:::bucket_name",
   "arn:aws:s3::: bucket_name/*"
 ],

bucket_name необходим, потому что без него вы не получите 404 за отсутствующие объекты, но всегда 403, bucket_name/* необходим для реального доступа к содержимому в корзине.

Ответ 5

Не уверен, если вы ищете это. Сделайте ваши объекты общедоступными, чтобы решить проблему 404. Однако я не верю, что это идеальный способ пройти через это.

AWS Cloudfront предоставляет функцию под названием Origin Access Identity (OAI). Как это работает, подробно описано в здесь.

Короче говоря, свяжите OAI с вашим Origin в Cloudfront и обновите политику корзины, чтобы разрешить OAI с GetObject и ListBucket, как показано

{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "AllowOAIRead",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity your_OAI_ID"
        ]
      },
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::your_bucket_name/*",
        "arn:aws:s3:::your_bucket_name"
      ]
    }
  ]
}