Публичный S3 bucket — это не только настройка public-read. Доступ может открывать ACL объекта, bucket policy, website endpoint, CDN origin или роль с чрезмерными правами. Сначала нужно закрыть текущую выдачу, не ломая легитимный сайт, затем определить, какие объекты могли быть доступны и скачаны.

Зафиксируйте текущие policies и логи, включите block public access там, где он поддерживается, и проверьте анонимный GET/LIST из внешней сети. Если файлы должны раздаваться публично, используйте отдельный bucket или CDN с ограниченным origin, а приватные данные выдавайте подписанными URL.

Что проверить в первую очередь

Начните с воспроизводимого сценария: зафиксируйте время сбоя, идентификатор объекта, версию приложения или конфигурации и последнее известное рабочее состояние. Не меняйте несколько параметров одновременно. Один контролируемый шаг должен подтверждать или исключать одну гипотезу, иначе временное исчезновение симптома легко принять за исправление. Перед работой с данными и настройками подготовьте резервную копию и понятный способ отката.

  • Проверьте public access block на уровне аккаунта и bucket.
  • Просмотрите bucket policy, ACL bucket и ACL нескольких объектов.
  • Уточните, включены ли static website и публичный CDN origin.
  • Проверьте анонимные LIST, GET известных и случайных ключей.

Почему возникает проблема

Внешний симптом часто появляется не в том компоненте, где возникла первичная ошибка. Интерфейс может показывать неверное состояние из-за backend, очереди, кеша, прав доступа или внешнего API. Полезно проследить данные от источника до результата и найти первую точку расхождения. Это надежнее, чем исправлять последнее сообщение об ошибке или бесконечно перезапускать сервис.

  • Policy содержит Principal * без узкого условия.
  • Загрузчик назначает объектам ACL public-read.
  • Старые объекты сохранили ACL после изменения bucket policy.
  • CDN имеет публичный origin URL и позволяет обходить правила.
  • Infrastructure as Code не управляет ручной настройкой или применяет неверное окружение.

Пошаговая диагностика

Диагностику проводите на тестовой записи или отдельном окружении. В журналах скрывайте токены, пароли, персональные данные и содержимое документов. Для каждого шага сохраняйте измеримый результат: код ответа, версию записи, идентификатор события, состояние процесса, контрольную сумму или время выполнения. Сравнение одной и той же операции до и после изменения помогает отделить причину от совпадения.

  • Экспортируйте policies и ACL до изменения для расследования.
  • Проверьте access logs/CloudTrail на анонимные запросы и массовое перечисление.
  • Классифицируйте объекты: публичные материалы, персональные данные, backup и секреты.
  • Найдите приложения, которые пишут ACL при upload.
  • Сравните фактическую конфигурацию с Terraform/CloudFormation.

Как разделить публичную раздачу и приватное хранение

Один bucket со смешанными данными усложняет политику и делает ошибку опаснее. Явное разделение снижает вероятность случайно открыть backup вместе с изображениями сайта.

  • Публичные статические assets хранятся отдельно и проходят собственную публикацию.
  • Приватные файлы доступны только сервисной роли с минимальными действиями.
  • Клиент получает короткоживущий signed URL после авторизации.
  • CDN обращается к закрытому origin через специальную identity/policy.
  • Логи доступа и inventory позволяют доказать текущую экспозицию.

Как исправить проблему

Разбейте исправление на небольшие обратимые изменения. Сначала устраните подтвержденную причину, затем повторите исходный сценарий и проверьте соседние функции. Массовое обновление данных запускайте на ограниченной выборке с отчетом и только после сверки расширяйте на весь объем. Не отключайте авторизацию, валидацию, шифрование или проверку сертификатов ради быстрого исчезновения ошибки.

  • Включите запрет публичных ACL/policies и удалите существующие public grants.
  • Разделите публичные и приватные объекты по bucket или четким контролируемым контурам.
  • Закройте прямой origin и настройте доступ только для CDN.
  • Ротируйте ключи и секреты, если они находились в доступных файлах.
  • Добавьте policy checks в CI и alert на изменение публичности.

Безопасный порядок внедрения

  • Сохраните затрагиваемые данные, конфигурацию и текущие журналы, заранее проверив реальный способ восстановления.
  • Повторите проблему на тестовом объекте без реальных списаний, рассылок и необратимых изменений клиентских данных.
  • Зафиксируйте изменение в системе контроля версий или журнале работ вместе с причиной и планом отката.
  • Проведите тест на нормальном сценарии, ошибочном вводе, повторном запросе, параллельной операции и временной недоступности зависимости.
  • После выпуска наблюдайте логи, метрики и полный пользовательский путь, а не только один успешный запрос.

Как проверить результат

Разовый успешный тест недостаточен. Повторите операцию, проверьте крайние значения, одновременные действия и восстановление после перезапуска или временного сбоя. Для важного сценария сохраните автоматический тест либо короткий регрессионный чек-лист. Итог должен подтверждаться не только интерфейсом, но и состоянием базы, очереди, внешнего сервиса и журналом действий.

  • Анонимный LIST и GET приватного объекта возвращают отказ из внешней сети.
  • Авторизованный сценарий загрузки и скачивания продолжает работать через signed URL.
  • CDN отдает только разрешенные публичные файлы и не раскрывает origin.
  • Сканер конфигурации не находит public ACL или wildcard policy без условий.

Типичные ошибки при исправлении

  • Удалять bucket до сохранения доказательств и оценки ущерба.
  • Закрывать policy, но не проверять ACL старых объектов.
  • Считать секретный URL защитой от публичного доступа.
  • Публиковать персональные файлы через долгоживущие signed URL.

Как предотвратить повторение

Профилактика строится вокруг явных контрактов, повторяемых релизов и наблюдаемости. Система должна не только работать сейчас, но и позволять быстро увидеть нарушение правила при следующем обновлении, росте нагрузки или сбое внешнего сервиса. Проверки полезно автоматизировать там, где ошибка уже привела к потерям времени, данных или заявок.

  • Включите account-level block public access по умолчанию.
  • Проверяйте IaC policy-as-code и запрещайте ручной дрейф.
  • Ведите inventory объектов и классификацию данных.
  • Мониторьте изменения policy/ACL и аномальный объем скачиваний.

Что подготовить для технического разбора

  • Описание ожидаемого и фактического поведения с точной последовательностью действий.
  • Время проблемы, идентификатор тестового объекта и версии затронутых компонентов.
  • Фрагменты журналов до и после ошибки без секретов и персональных данных.
  • Перечень последних изменений и уже выполненных проверок.
  • Безопасный доступ к тестовой среде либо способ воспроизвести сбой без влияния на клиентов.

Частые вопросы

Достаточно ли отключить LIST?

Нет. Если GET разрешен, файл остается публичным по известному URL. Нужно проверить оба действия и все уровни policy.

Нужно ли менять ссылки после закрытия?

Для приватных файлов обычно внедряют выдачу подписанных URL. Публичные assets можно оставить через CDN с закрытым origin.

Когда нужна помощь специалиста

Если Object Storage оказался публичным, я могу быстро закрыть доступ, сохранить рабочую раздачу через CDN или signed URL, проверить логи и настроить защиту от повторной публикации.