S3 Object Lock, механизм WORM (write once, read many) в Amazon S3, запрещает удалять или перезаписывать конкретную версию объекта, пока не истёк retention period или пока не снят legal hold. Срок неизменяемости версия получает в момент загрузки, и ни скрипт, ни администратор, ни владелец ключей доступа не меняет её раньше срока.
Для резервных копий это критично. Ransomware и скомпрометированные учётные записи атакуют бэкапы первыми: их удаляют, перезаписывают шифрованными данными, затирают версии, чтобы лишить компанию возможности восстановиться. Object Lock переносит защиту на сторону хранилища: обладатель валидных ключей не стирает защищённую версию раньше срока.
Границы возможностей стоит понимать сразу. Object Lock работает только на бакетах с включённым versioning, включается на бакете и обратно не отключается, не спасает от удаления бакета под root-учётной записью с полными правами и не заменяет офлайн-копию и проверку восстановления. Это слой защиты, а не абсолютная гарантия.
Что такое S3 Object Lock и зачем он нужен резервным копиям
Object Lock удерживает объект в неизменяемом состоянии через API S3: право s3:PutObjectRetention задаёт срок, право s3:PutObjectLegalHold включает и снимает удержание. Настройки живут на уровне отдельной версии объекта, поэтому в одном бакете спокойно соседствуют версии с разными сроками и разными статусами удержания.
Бакет с Object Lock создают либо включают блокировку сразу после активации versioning. Отключить её потом нельзя, и это ключевое отличие от большинства настроек S3: решение принимается один раз. Официальное описание механизма приведено в документации AWS по Object Lock.
WORM-модель и чем она отличается от обычного бэкапа в S3
Обычный объект в S3 живёт до первого DELETE или перезаписи. Скрипт бэкапа загружает daily-backup.tar.gz каждый день, и учётка с правом s3:DeleteObject стирает вчерашнюю копию за секунды. Ошибка в кроне, испорченный скрипт, украденный ключ, и данных больше нет.
Под Object Lock каждая загрузка создаёт новую версию, и у каждой версии свой срок неизменяемости. Дневной бэкап с retention 30 дней означает: 30 дней эту версию нельзя удалить и нельзя перезаписать. Блокировка привязана к object version ID, а не к бакету целиком, поэтому продление срока или отдельные условия для архива настраиваются точечно.
Что Object Lock не защищает
- Удаление бакета. Учётная запись root с полными правами удаляет бакет целиком, и Object Lock этот сценарий не закрывает.
- Обход в Governance. Если у атакующего есть роль с s3:BypassGovernanceRetention, он снимает блокировку легальным вызовом API.
- Рост расходов. Каждая версия хранится и тарифицируется. Чем длиннее retention, тем выше счёт.
- Отсутствие офлайн-копии и проверки восстановления. Object Lock не подменяет ни одну из этих практик.
Режимы S3 Object Lock: Governance и Compliance
Режим выбирают один раз на весь бакет, и он определяет, кто может снять или укоротить блокировку. Пока retention на версии не установлен, она удаляется обычным DELETE с version ID, поэтому сам факт включённого Object Lock защищает меньше, чем ожидают.
| Параметр | Governance | Compliance |
|---|---|---|
| Снятие retention до срока | Разрешено с правом s3:BypassGovernanceRetention | Запрещено всем, включая root-аккаунт |
| Сокращение retention period | Разрешено при bypass | Запрещено, срок только увеличивают |
| Удаление защищённой версии | Разрешено при bypass | Запрещено |
| Типовой сценарий | Внутренние операционные бэкапы | Регуляторные требования и аудит |
Governance mode: гибкость с контролем
В Governance блокировку снимает вызов API от пользователя с правом s3:BypassGovernanceRetention. Для эксплуатации это удобно: ошибочный скрипт залил мусор, дежурный инженер с нужной ролью удаляет версию, не дожидаясь конца срока. То же право позволяет удалить объект, защищённый Governance, даже в течение срока хранения, в том числе через AWS CLI с параметром --bypass-governance-retention.
Право s3:BypassGovernanceRetention закрепляют за отдельной ролью break-glass, доступ к которой защищён MFA и выдаётся на время. У бэкап-учётки такого права нет. Аварийное снятие блокировки стоит логировать и отслеживать: настраивайте аудит вызовов, меняющих retention, чтобы у каждого такого действия оставался инициатор и время.
Слабое место Governance: тот, кто получил роль с bypass, обходит защиту целиком. Если злоумышленник скомпрометировал учётную запись администратора с bypass, Object Lock уже не помешает удалить версии.
Compliance mode: неизменяемость без исключений
В Compliance блокировку не отменяет никто до конца срока: ни администратор, ни root-аккаунт. Чтобы окончательно удалить такой объект, нужно дождаться окончания срока хранения или удалить связанный аккаунт AWS. Сократить retention period нельзя, срок только увеличивают. Любое lifecycle-правило, которое попытается убрать такой объект раньше срока, тоже не сработает.
Обратная сторона, необратимость. Retention 3650 дней, выставленный по ошибке вместо 30, означает десять лет оплаты хранения каждого объекта. Проверку режима делают на отдельном бакете с тестовыми данными, а не на проде.
Compliance закрывает сценарии, где нужна юридическая неизменяемость записей. S3 Object Lock был оценён Cohasset Associates для использования в средах, подпадающих под регулирование SEC 17a-4, CFTC и FINRA. При этом настройка бакета сама по себе соответствие не подтверждает: итоговый вывод делают аудитор и юристы по вашим процессам, а не по режиму Object Lock. Упоминания других регуляторных режимов, включая HIPAA, в подтверждённых материалах нет, поэтому опираться на них как на прямое основание для Compliance-режима не стоит.
Legal hold: удержание без срока
Legal hold это флаг ON/OFF на конкретной версии объекта. Срока у него нет: пока флаг включён, версию не удалить, даже если retention period давно истёк. Снимают его только явным вызовом API с правом s3:PutObjectLegalHold.
Retention ставит бэкап-скрипт автоматически при каждой загрузке. Legal hold включают вручную или отдельным процессом, когда объекту нужен бессрочный запрет на удаление: судебный запрос, расследование инцидента, внутренний аудит, разбор доступа уволенного сотрудника к данным.
Забытый legal hold превращается в вечное хранение и растущий счёт: версия с флагом не удаляется ни lifecycle-правилом, ни ручной командой. Держите реестр объектов под legal hold и сверяйте его при закрытии дела.
Versioning и Object Lock: как они работают вместе
Object Lock работает только в бакетах с включённым S3 Versioning. При включении блокировки версионирование включается автоматически, а отключить блокировку объектов, как и версионирование, после этого невозможно. Retention задаётся на конкретный object version ID, поэтому срок одного дня и срок в год уживаются в одном бакете без конфликтов.
Скрипт заливает backup.tar.gz ежедневно, каждая загрузка создаёт новую версию, и у каждой свой срок. Через 30 дней версия освобождается, и её можно удалить вручную или правилом lifecycle. Подробности настройки с готовыми конфигурациями собраны в гайде по версионированию и lifecycle-политикам в S3.
Delete marker и что происходит при попытке удалить защищённый объект
Простой DELETE без version ID можно выполнить для любого объекта в бакете с Object Lock независимо от настроек блокировки, и данные при этом не удаляются. S3 создаёт delete marker: объект пропадает из обычного листинга, а все версии остаются на месте. Сроки хранения и legal hold не мешают созданию новых версий объекта и добавлению delete-маркеров поверх него. Так выглядит типичная паника «бэкапов нет»: в консоли пусто, в хранилище всё цело.
Проверить, что версии живы и retention выставлен, можно листингом версий объекта (list-object-versions) и запросом retention по каждой версии. Удаление бакета root-учётной записью с полными правами Object Lock не предотвращает, поэтому защита самих данных и защита контейнера, в котором они лежат, это разные задачи.
Права IAM и политики для Object Lock
Права на Object Lock раздают точечно, а не пакетом. Что за чем закрепляется:
- s3:PutObjectRetention, установка и увеличение срока. Нужно бэкап-скрипту.
- s3:PutObjectLegalHold, включение и снятие удержания. Отдельная роль, не бэкап-скрипт.
- s3:GetObjectRetention и s3:GetObjectLegalHold, чтение настроек для проверок и аудита.
- s3:BypassGovernanceRetention, обход Governance. Только break-glass роль с MFA.
- s3:DeleteObjectVersion, удаление версий. Бэкап-учётке не выдавать.
Принцип least privilege здесь работает буквально: учётка с s3:* в Governance-режиме обходит защиту целиком, потому что получает и bypass, и удаление версий.
Пример политики для бэкап-скрипта
Политику собирают из двух частей. Allow на s3:PutObject и s3:PutObjectRetention для конкретного префикса бэкап-бакета, например arn:aws:s3:::backup-bucket/daily/*. Явный Deny на s3:BypassGovernanceRetention и s3:DeleteObjectVersion. Deny перекрывает любые Allow из других политик, и это его главная ценность.
Привязывайте политику к IAM-роли, а не к пользователю: временные креды роли живут ограниченное время, их сложнее передать коллеге и забыть. Как устроены IAM-политики и вызовы API на практике, разобрано в обзоре S3-протокола: архитектура, API и настройка клиентов.
Защита от компрометации учётных данных
Сценарий: ключи бэкап-учётки утекли. Если у неё нет BypassGovernanceRetention и DeleteObjectVersion, атакующий может только дописывать новые версии. Прочитать и удалить защищённые копии он не сможет, а лишние версии вы вычистите позже. Если такие права есть, защита обходится за один вызов API.
Ущерб снижают: отдельный AWS-аккаунт под бэкапы, MFA для роли с bypass, алерты на снятие retention и удаление версий, GuardDuty для аномальной активности ключей. Ротацию сервисных ключей и разбор аудит-логов описывает материал про аудит и ротацию паролей в корпоративном хранилище секретов. Дополнительно нужна защита самих данных: сравнение клиентской и серверной моделей шифрования собрано в статье про шифрование данных при передаче и хранении. Object Lock спасает от удаления, но не от чтения, если ключи расшифровки ушли на сторону.
Архитектура неизменяемых резервных копий в S3
Схема, при которой бэкап не удалить даже с украденными ключами основной инфраструктуры, собирается по шагам.
- Отдельный AWS-аккаунт под резервные копии, вне основного контура администраторов.
- Бакет с включённым versioning и Object Lock. Режим выбирается сразу и не меняется.
- Retention period по классу данных: 30 дней для операционных бэкапов, год и больше для архивных и регуляторных.
- Lifecycle-правила: перевод в Glacier Instant Retrieval или Deep Archive после истечения retention, удаление, когда срок прошёл.
- IAM-роль бэкап-скрипта с минимумом прав: PutObject и PutObjectRetention на префикс.
- Bucket policy, запрещающая удаление версий всем, кроме отдельной роли администратора бэкапов.
- Аудит, метрики и алерты на снятие retention, удаление версий и изменение политик.
Правило 3-2-1-1-0: три копии данных, два разных носителя, одна копия вне основной площадки, одна неизменяемая, ноль ошибок при проверке восстановления. Object Lock закрывает пункт «одна неизменяемая», но не заменяет офлайн-слой. Разбор этой схемы и смежных мер защиты есть в руководстве по защите резервных копий от удаления и шифрования.
Пример: основной аккаунт скомпрометирован, у атакующего админские права в проде. Cross-account доступ настроен только на PutObject, ключей от бэкап-аккаунта у него нет. Версии в бэкап-бакете остаются неизменными, восстановление идёт из них. Если бэкапы лежат в том же аккаунте, этот же сценарий заканчивается потерей копий.
Retention period и lifecycle: как не переплатить
Retention period задаёт минимальный срок, в течение которого версию нельзя удалить. Lifecycle решает, что делать после. Пример связки: retention 30 дней, перевод версий в Glacier Instant Retrieval через 30 дней, удаление через 365.
Lifecycle не обходит retention. Правило с expire на 7-й день для версии под retention 30 дней просто не сработает, версия останется до конца срока. Это защищает от ошибки в правилах, но создаёт неожиданный для новичка расход: в биллинге версии продолжают копиться.
S3 Standard дороже Glacier, зато восстановление быстрее. Глубокий архив дешевле, но вернуть объект можно часами. Для операционного восстановления держите горячий слой хотя бы на последние 7-14 дней, старые и редкие версии уводите в холодные классы. Точные цены, минимальные сроки хранения и время извлечения по классам сверяйте в актуальном прайсе AWS: они меняются по регионам.
Отдельный аккаунт для бэкапов: зачем и как
Бэкап-бакет в том же аккаунте, что прод, защищает плохо: одна скомпрометированная админская учётка открывает оба контура. Отдельный аккаунт с собственными креденшелами разрывает эту связь.
Схема доступа: основной аккаунт имеет право только на PutObject в бэкап-бакет. Чтение и удаление делают отдельной ролью внутри бэкап-аккаунта под MFA. AWS Organizations и SCP позволяют централизованно запретить удаление бакетов и изменение политик во всех аккаунтах организации.
Защита от ransomware: что реально блокирует Object Lock
Object Lock закрывает часть векторов атаки и не закрывает остальные. Разбор по пунктам:
| Вектор атаки | Реакция Object Lock |
|---|---|
| Удаление бэкапов | Блокирует: защищённую версию нельзя удалить до конца срока |
| Перезапись шифрованными данными | Блокирует: новая версия создаётся, старая остаётся неизменной |
| Удаление версий через API | Блокирует: нет прав или нет bypass |
| Учётка с s3:BypassGovernanceRetention | Не блокирует в Governance-режиме |
| Удаление бакета root-аккаунтом | Не блокирует |
| Кража ключей расшифровки | Не относится: защита от удаления не защищает от чтения |
Типовые атаки на бэкапы Object Lock ломает, но окно восстановления всё равно нужно держать. Если retention 30 дней истёк, а атака обнаружена на 40-й день, восстанавливать нечего. Комбинируйте неизменяемые копии с офлайн-слоем и мониторингом: скорость обнаружения важнее срока хранения.
Как проверить восстановление из неизменяемых бэкапов
Неизменяемая версия в бакете не доказывает, что бэкап рабочий. Проверку делают регулярно, по документу, а не по памяти дежурного.
- Выбрать тестовую версию в бэкап-бакете, посмотреть её retention и legal hold.
- Восстановить данные в отдельный тестовый бакет или на отдельный инстанс, не трогая прод.
- Сверить целостность: размер, контрольные суммы, содержимое каталогов, успешный запуск восстановленного сервиса.
- Замерить RTO (время восстановления) и RPO (насколько свежие данные в копии).
- Записать результат, время, версию объекта и исполнителя в журнал проверок.
Периодичность: для критичных сервисов ежемесячно, для остального раз в квартал. Проверять нужно до истечения retention: если lifecycle уже удалил версию, восстановление невозможно по определению.
Чек-лист проверки восстановления
- Версия доступна и открывается в бэкап-бакете.
- Retention period на версии соответствует политике хранения.
- Скачивание версии проходит от учётки с правом чтения.
- Контрольная сумма восстановленного файла совпадает с эталонной.
- Сервис из восстановленной копии стартует и отвечает на запросы.
- RTO и RPO укладываются в целевые значения.
- Legal hold на объектах расследований актуален, лишние флаги сняты.
- Результат проверки записан и подписан ответственным.
Ограничения Object Lock и типичные ошибки
- Object Lock нельзя отключить после включения.
- Versioning нельзя отключить.
- Retention нельзя сократить, только увеличить.
- Стоимость растёт с числом версий, долгий retention оборачивается дорогим сюрпризом в биллинге.
- Compliance-режим необратим: ошибка в сроке означает оплату хранения до его конца.
- Удаление бакета с правами root-аккаунта Object Lock не предотвращает.
- Офлайн-копию Object Lock не заменяет.
- Без проверки восстановления неизменяемая копия может оказаться бесполезной.
Перед продакшеном поднимите тестовый бакет и прогоните полный цикл: загрузка, установка retention, попытка удаления версии, попытка снять блокировку, срабатывание lifecycle, восстановление. Точные ограничения по регионам, версиям API и поддерживаемым классам хранения сверяйте в официальной документации AWS по S3 Object Lock, versioning и lifecycle: детали там обновляются чаще, чем в сторонних пересказах.
Итог: как выбрать режим и построить защиту
Governance берут для внутренних операционных бэкапов, где нужна гибкость и аварийное снятие через отдельную роль с MFA. Compliance выбирают для регуляторных сценариев, где неизменяемость нужна без исключений. Legal hold добавляют точечно под юридические удержания без срока.
Рабочая связка: отдельный аккаунт под бэкапы, бакет с versioning и Object Lock, retention по классу данных, lifecycle для холодных классов, минимальные права IAM, bucket policy против удаления версий, аудит с алертами, регулярная проверка восстановления. Object Lock здесь один из слоёв, а не гарантия абсолютной защиты.
Первый шаг: поднимите тестовый бакет, включите versioning и Object Lock, прогоните сценарий удаления версии и восстановление из неё. Задокументируйте процедуру и периодичность проверок: это занимает пару часов и снимает большинство будущих инцидентов с резервными копиями.