Другие статьи серии о работе с объектным хранилищем S3:
Как работать с коммунальным бакетом в S3
Объясняем, как настроить работу с данными в многопользовательской системе хранения.
Это третья статья из цикла материалов о работе с объектным хранилищем S3. В первых двух мы рассказывали, как надо и как не стоит работать с таким хранилищем:
Object Storage — это многопользовательская система хранения со сложной структурой управления правами доступа. Основные компоненты этой структуры описаны в документации.
А в этой статье сосредоточимся на том, как корректно выстроить работу с данными, к которым будет обращаться большое количество пользователей. И как сделать это безопасно и без потерь производительности.
Разбираться будем на примере: попробуем запустить высоконагруженное приложение, используя в качестве хранилища S3.
Самое простое решение
Самый простой подход к управлению правами доступа: один конечный пользователь приложения — это один S3-бакет. Но количество бакетов ограничено и для каждого нужно выделить слой метаданных, а также вписать его во множество политик (Bucket policy, Life circle). Вряд ли получится выдать больше 10 000 бакетов, а конечных клиентов у многопользовательского сервиса может быть миллион.
Поэтому в реальном проекте придётся хранить данные нескольких конечных пользователей в одном бакете. Такие бакеты будем называть коммунальными.
Принципы работы с коммунальным бакетом
Чтобы поместить данные разных пользователей в один бакет, нужно разграничить права доступа так, чтобы ни у кого не было доступа к чужим файлам. Рассмотрим пять подходов к решению этой задачи:
1. Один в поле — воин
Взять ответственность на себя: разделять доступы на уровне приложения или бизнес-логики и проксировать запросы к S3. В этом случае аутентификация и авторизация пользователей проводятся на уровне приложения или бизнес-логики: прописываются в правилах взаимодействия и зависимостей объектов и пользователей. А бизнес-логика, в свою очередь, обращается к S3 от одного сервисного аккаунта.
При таком подходе у S3 есть один пользователь, но все данные проксируются через бизнес-логику. А значит, нужно строить отказоустойчивую систему проксирования данных, готовую обработать запросы миллиона пользователей. Однако в S3 достаточно средств, чтобы решить эти проблемы на уровне хранилища.
Выгоднее и удобнее будет разделить Control Plane и Data Plane. В таком случае:
-
виртуальные машины и балансировщики будут значительно менее нагружены;
-
повысится производительность.
При этом вы сможете воспользоваться готовыми решениями Yandex Cloud, чтобы обеспечить безопасный доступ к данным.
2. PUT и GET по pre-signed URL
Этот вариант более усовершенствованный по сравнению с предыдущим подходом.
S3 поддерживает pre-signed URL — подписанные запросы, которые позволяют и создавать объекты и получать их. Бизнес-логика выписывает для каждого такого запроса специальную ссылку в формате KeyID + Signature. Приложение конечного пользователя может сразу применить подписанную ссылку для размещения или скачивания файла. Поскольку приложение будет обращаться напрямую к S3, проксировать данные не потребуется.
Более того, бизнес-логика сможет контролировать в подписанной ссылке какие именно данные будут заливаться в S3. Можно создать подписанную ссылку, ограниченную не только для загрузки данных по определённому ключу, но и задать размер загружаемого файла. Можно даже задать MD5 от загружаемого контента (использовать e-tag в headers). Это позволит быть уверенным в том, что приложение (без участия бизнес-логики) не загрузит в S3 что попало.
3. Secure token в CDN
Этот способ работает на уровне CDN, а не S3. Он подойдёт, если вы планируете только раздавать контент и не собираетесь получать данные от пользователей. Например, для распространения видеокурсов.
Механика такая же, как и для подписанных ссылок для получения данных, только на уровне CDN. CDN-сервер получает токен и сверяет его по хешу с секретным ключом CDN-ресурса и переданными в HTTP-запросе данными, а потом разрешает или запрещает доступ к файлу.
Подробнее читайте в нашей документации.
4. Бакетные политики
Эти политики регулируют, как пользователи и системные аккаунты могут взаимодействовать с бакетами, объектами и их группами. Политика срабатывает, когда пользователь отправляет запрос к какому-либо ресурсу.
С помощью политики можно ограничить доступ к бакету по IP или, наоборот, расшарить данные по префиксу в бакете и выдать определённым пользователям права на запись или чтение. Подробности вы найдёте в документации.
У этого метода есть важное ограничение: размер пользовательских политик не может превышать 20 КБ, а пользователи и сервисные аккаунты должны существовать в IAM. Подход рабочий, но неудобный, если у вашего приложения миллион конечных пользователей.
5. STS — Security Token Service
Обойти создание пользователей в IAM всё-таки можно. Для этого достаточно воспользоваться временными токенами, совместимыми с AWS S3 API.
Security Token Service — компонент сервиса Identity and Access Management. Он помогает объединить множество пользователей в одном сервисном аккаунте.
Временные ключи позволяют гранулярно разграничить доступы в бакеты Object Storage. Только не забудьте, что права доступа сервисного аккаунта должны включать в себя все разрешения, которые вы хотите предоставлять с помощью временных ключей.
Подробнее о том, как это работает, рассказали в документации. Напоследок необходимо добавить, что STS — самый передовой способ работы с коммунальным бакетом. Он совместим с AWS S3 API, а значит — и с SDK, и с приложениями.
Заключение
Мы рассказали о коммунальном бакете, принципах его работы и доступных политиках. А также об особенностях использования механизма STS, бакетных политиках, secure token в CDN, запросах к подписанным ссылкам и разделении доступов на уровне бизнес-логики вашего приложения.
Надёжное и быстрое хранилище — базовая потребность для ваших приложений.
Yandex Object Storage обеспечивает строгую согласованность данных и синхронно сохраняет данные в три зоны доступности, обеспечивая высочайший уровень надёжности и удобства использования.
Если ранее вы не работали с S3-хранилищем в Yandex Cloud, рекомендуем ознакомиться с сервисом Object Storage, который позволит не только надёжно хранить данные и резервные копии, но и быстрее обучать ML-модели и загружать статические веб-сайты.
Протестируйте сервис на платформе Yandex Cloud: с нашим стартовым грантом или условиями free tier.
Принципы работы с коммунальным бакетом: