Должен ли я получать ошибку Cloudfront «MissingKey» при использовании неподписанного URL-адреса для доступа к общедоступному объекту S3?

Допустим, я создаю клон Dropbox: Filebox. Я храню все свои пользовательские файлы на S3 и использую Cloudfront в качестве CDN.

Итак, у меня есть ограниченная корзина S3 (files.filebox.com) с политикой корзины, которая позволяет s3:GetObject использовать только удостоверение Origin Access, которое я создал через Cloudfront. Это заставляет все запросы «файла» проходить через Cloudfront и запрещает кому-либо доступ к файлу через URL-адреса S3.


Политика корзины для files.filebox.com

{
    "Version": "2008-10-17",
    "Id": "AllowCloudfrontGet",
    "Statement": [
        {
            "Sid": "AllowCloudFrontGet",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXXX"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::files.filebox.com/*"
        }
    ]
}


Неожиданное поведение

Скажем, для простоты я храню все файлы с готовым ACL public-read.

Так что этот URL должен работать:
https://files.filebox.com/<userID>/some-file.txt

Но это должно привести к 403: https://s3.amazonaws.com/files.filebox.com/<userID>/some-file.txt

Но я вижу противоположные результаты. URL-адрес S3 работает нормально, но URL-адрес files.filebox.com, который проходит через Cloudfront, выдает ошибку MissingKey.

URL-адрес files.filebox.com действительно работает, но только если я подписываю URL-адрес, даже для объектов, имеющих ACL public-read.


Вопросы

Учитывая, что политика корзины разрешает только s3:GetObject для OAI CF, не должен ли URL-адрес S3 завершаться с ошибкой 403, даже если объект имеет ACL-список public-read?
Я не могу найти никакой информации. об этом в документации, кроме расплывчатых формулировок, которые, по-видимому, указывают на то, что сегмент с ограниченным доступом должен 403 для любых запросов, которые не проходят через Cloudfront.

Когда я устанавливаю для ACL объекта значение public-read, не устраняет ли это необходимость подписывать URL-адрес Cloudfront даже в сегменте с ограниченным доступом?

Нужно ли мне добавить еще один Statement в политику сегмента, который разрешает неподписанным URL-адресам доступ к объектам public-read?
Я пытался это сделать, но это не сработало. Я даже не знаю, как написать Statement вот так...

Как мне действительно отклонить любые запросы, поступающие через URL-адреса S3?
Я хочу выдавать ошибку 403 для любых запросов которые проходят через URL-адреса S3, даже для объектов с ACL public-read.


person AJB    schedule 25.10.2017    source источник


Ответы (1)


Учитывая, что политика корзины разрешает только s3:GetObject для OAI CF, не должен ли URL-адрес S3 завершаться с ошибкой 403, даже если у объекта есть открытый доступ для чтения?

public-read означает, что общедоступное чтение (без проверки подлинности) разрешено непосредственно из S3. Поскольку владелец корзины разрешил загрузку объекта с помощью public-read ACL, объект становится общедоступным с неявного согласия владельца корзины, даже при отсутствии политики для корзины.

Списки управления доступом к объектам и параметры политики корзины Allow являются аддитивными. Если вы не хотите, чтобы объект был доступен через конечные точки S3, не делайте его общедоступным.

Когда я устанавливаю ACL объекта для общедоступного чтения, не устраняет ли это необходимость подписывать URL-адрес Cloudfront даже в сегменте с ограниченным доступом?

Нет, это не так. CloudFront не оценивает ACL объекта. На основе параметров Cache Behavior он решает, требуется ли аутентификация. Если настроено требование проверки подлинности для данного шаблона пути, она требует проверки подлинности независимо от того, является ли сущностью, стоящей за CloudFront, S3 или что-то еще. Если CloudFront отказывает в доступе, запрос на S3 даже не отправляется.

Нужно ли мне добавить еще одно заявление в мою политику корзины, которое разрешает доступ неподписанных URL-адресов к общедоступным объектам?

Нет. Ничто в политике корзины не изменяет поведение внешней проверки подлинности CloudFront.

Типичный подход заключается в том, чтобы обозначить одни префиксы как общедоступные, а другие — как закрытые, а также настроить поведение CloudFront Cache Behaviors с соответствующими соответствующими шаблонами пути, т.е. /public/* может быть настроено не требовать подписанных URL-адресов, но /private/* может требовать их.

Этот параметр называется Restrict Viewer Access и задается на уровне поведения кэша (таким образом, на уровне шаблона пути).

Я хотел бы выдавать ошибку 403 для любых запросов, поступающих по URL-адресам S3, даже для объектов с ACL для публичного чтения.

Установка для ACL объекта значения public-read означает, по определению, что объект должен быть доступен непосредственно из конечной точки корзины S3 без учетных данных. Ни больше ни меньше.

В этом свете то, что вы говорите, аналогично высказыванию: «Я хотел бы предотвратить кражу моей машины, даже если я планирую оставить ключи в зажигании». Это можно сделать, но это решает не ту задачу... и очень быстро усложняется, потому что приходится прибегать к тактике типа Deny с NotPrincipal условиями, включать исключения не только для CloudFront, но и для себя в консоли как а также ваши приложения, роли и т. д., которые обращаются к корзине.

Пункт Origin Access Identity заключается в том, что у CloudFront есть набор учетных данных, которые он может использовать при отправке запросов в корзину, независимо от того, требует ли CloudFront от пользователя предоставления учетных данных для аутентификации или нет. При наличии OAI нет причин использовать public-read в списках управления доступом к объектам.

person Michael - sqlbot    schedule 25.10.2017
comment
Спасибо за отличный ответ @Michael-sqlbot, теперь я намного лучше понимаю отношения CF/S3. - person AJB; 25.10.2017