security · advanced · 9d
Лаборатория харденинга облака
Возьми облачный аккаунт, которым владеешь сам, и проведи его от состояния «работает» к состоянию «защищаемо». Ты измеришь реальную текущую posture, ужмёшь IAM до least privilege, не сломав приложение, закроешь сеть и секреты и докажешь каждое изменение диффом «до/после». Это и есть суть работы по облачной безопасности: не добавлять фичи, а убирать постоянный доступ и тихие мисконфигурации, которыми воспользовался бы атакующий.
Результат
Захардененное облачное окружение в твоём собственном аккаунте и закоммиченный отчёт «до/после»: базовый скан posture, суженные IAM-политики, закрытые сетевые пути, секреты, перенесённые в управляемое хранилище с ротацией, включённое аудит-логирование и журнал ремедиации, связывающий каждое находку с устранившим её изменением.
Этапы
0/6 · 0%- 01Измерь то, что у тебя реально есть
Нельзя захарденить то, что не измерил, а «вроде нормально» — это не базовая линия. Натрави опенсорсный CSPM-инструмент вроде Prowler или ScoutSuite на собственный аккаунт и дай ему перечислить posture: публичные бакеты, нараспашку открытые security groups, пользователей без MFA, незашифрованные тома, протухшие access-ключи. Пока ничего не чини — твоя единственная задача здесь честный снимок. Выгрузи находки, отсортируй их по радиусу поражения, а не по присвоенной инструментом severity, и выпиши три самых болезненных при эксплуатации. Этот снимок — половина «до» в каждом утверждении, которое ты сделаешь дальше; без него ты можешь только заявлять, что что-то улучшил, но не показать это.
Критерии готовности- CSPM-скан твоего собственного аккаунта сохранён в репозиторий, сырой вывод закоммичен как базовая линия.
- Три главные находки задокументированы с однострочным обоснованием, почему у каждой наибольший радиус поражения.
- 02Ужми IAM до least privilege
Большинство облачных взломов — это проблема identity в сетевом костюме: роль с '*' в действиях и ресурсах, долгоживущий ключ, который должен был быть короткоживущей assumed-ролью. Найди слишком широкие гранты, отмеченные сканом, и перепиши их. Замени wildcard-действия на конкретные вызовы, которые рабочая нагрузка действительно делает, — прочитай access-логи или CloudTrail, чтобы узнать, чем она реально пользуется, а не угадывай. Предпочитай короткоживущее assume-role статическим ключам и убери постоянный admin у людей, которым он нужен лишь изредка. Сложность не в том, чтобы ужать, а в том, чтобы ужать, не сломав работающее приложение, — поэтому меняй по одному principal за раз и проверяй, что нагрузка ещё работает после каждого среза.
Критерии готовности- Хотя бы одна wildcard- или admin-политика заменена на суженную, и рабочая нагрузка по-прежнему проходит smoke-тест.
- Повторный скан показывает, что отмеченные переприви́легированные identity больше не появляются, JSON политик «до/после» закоммичен.
- 03Закрой открытые пути
0.0.0.0/0 на порту базы данных — это приглашение, а «ограничим потом» — это то, как «потом» не наступает никогда. Пройдись по сетевой экспозиции, которую нашёл скан: security groups, правила фаервола, публичные IP на том, что должно быть приватным, и управляющие порты (SSH, RDP, база), достижимые из всего интернета. Сузь каждый до минимального источника, которому он реально нужен, — bastion, диапазон VPN, конкретный сервис. Поучительное напряжение в том, что минимальная экспозиция и удобство тянут в разные стороны: как только ты закроешь порт, что-то забытое может перестать работать, и эта поломка — карта твоих настоящих зависимостей. Задокументируй каждый закрытый путь и что теперь до него дотягивается.
Критерии готовности- Ни один управляющий порт или порт БД не достижим из 0.0.0.0/0; доступ ограничен именованным диапазоном-источником или bastion.
- Тест связности подтверждает, что нужный путь по-прежнему работает, а закрытый путь теперь отклоняется.
- 04Вытащи секреты из открытого текста
Секреты в переменных окружения, закоммиченном конфиге или «на память» в user-data утекают в тот же миг, когда кто-то читает снимок или лог. Найди учётные данные, которые приложение гоняет в открытом виде, и перенеси их в управляемое хранилище секретов провайдера, забираемое в рантайме по identity, а не зашитое в образ. Зашифруй данные at rest через KMS и убедись, что у ключа своя жёсткая политика — хранилище секретов под нараспашку открытым KMS-ключом это театр. Затем сделай то, что все пропускают: проротируй хотя бы один секрет и докажи, что приложение переживает ротацию. Секрет, который ты не можешь проротировать, — это секрет, который ты не можешь отозвать при утечке, а значит он уже обязательство, а не контроль.
Критерии готовности- Хотя бы один захардкоженный секрет убран из кода/конфига и забирается в рантайме из управляемого хранилища.
- Один секрет проротирован от начала до конца, и приложение продолжает работать; шаг ротации задокументирован.
- 05Сделай аккаунт аудируемым
Харденинг, который потом никто не может проверить, — это вера, а не безопасность. Включи аудит-трейл уровня аккаунта (CloudTrail или его аналог), чтобы каждый вызов API оставлял запись, отправляй эти логи в место, устойчивое к подделке, и убедись, что удаление или изменение прав действительно в них появляется. Смысл не в том, чтобы читать логи целыми днями, — а в том, что когда что-то пойдёт не так в три ночи, разница между пятиминутной триажем и неделей гаданий в том, писались ли события до инцидента. Реши, что стоит логировать, а что шум, потому что трейл, по которому никто не может искать, лишь немногим лучше отсутствия трейла.
Критерии готовности- Аудит-трейл уровня аккаунта включён и отправляется в долговечное хранилище с контролем доступа.
- Намеренное тестовое действие (например, изменение прав) найдено в логах, что доказывает: трейл его фиксирует.
- 06Останови следующую мисконфигурацию до того, как она уедет
Всё до этого чинило прошлое. Этот этап чинит будущее, потому что posture гниёт в тот момент, когда коллега добавляет wildcard-роль или открывает порт «просто для теста». Напиши guardrail как policy-as-code — правило OPA/Rego поверх твоего Terraform-плана или Service Control Policy на границе организации, — которое отклоняет именно те плохие формы, что ты только что несколько дней вычищал. Затем докажи, что у него есть зубы: подай ему намеренно плохое изменение и посмотри, как оно блокируется, и хорошее изменение — и посмотри, как оно проходит. Это разница между безопасностью как разовой уборкой и безопасностью как свойством, которое система поддерживает сама. Guardrail, который никогда не говорит «нет», — украшение; ценность в том deny, который ты можешь продемонстрировать.
Критерии готовности- Правило policy-as-code (OPA/Rego или SCP) кодирует хотя бы одно из исправлений, сделанных тобой ранее в этой лаборатории.
- Плохое изменение отклоняется guardrail, а хорошее проходит — оба показаны в закоммиченном выводе.
Рубрика
| Джуниор | Миддл | Сеньор | |
|---|---|---|---|
| Ограничение IAM до наименьших привилегий | Wildcard admin-политики опознаны и признаны. Одна убрана или ограничена, но замена всё ещё слишком широка (например, 'Allow: s3:*' вместо конкретных операций). | Access-логи или CloudTrail изучены, чтобы понять, что каждая нагрузка реально вызывает; wildcard-действия заменены точным нужным набором. Статические долгоживущие ключи заменены assume-role там, где платформа позволяет. Smoke-тест нагрузки проходит после каждого среза. | Ты рассуждаешь о радиусе поражения каждого оставшегося разрешения: что мог бы сделать атакующий с этой ролью при её компрометации? Ты используешь условия на уровне ресурса (например, ограничение конкретным префиксом ARN бакета), а не только область действия действий, и добавляешь break-glass путь, аудируемый и ограниченный по времени, чтобы экстренный admin не требовал восстановления постоянного доступа. |
| Сетевая сегментация и закрытие экспозиции | CSPM-скан выявляет открытые пути; некоторые отмечены. 0.0.0.0/0 на порту базы или управляющем порту опознан, но не полностью закрыт — порт сужен до «меньшего диапазона», который по-прежнему шире необходимого. | Каждый управляющий порт и порт БД ограничен именованным источником (bastion, диапазон VPN, конкретная SG сервиса). Тест связности подтверждает: нужный путь работает, а закрытый отклоняется. Зависимости, обнаруженные при поломке порта (недокументированный вызывающий), задокументированы. | Ты классифицируешь оставшуюся поверхность экспозиции по возможностям атакующего: что может противник, добравшийся до периметра сети, в сравнении с тем, кто уже внутри приватной подсети? Решения о сегментации привязаны к рассуждениям о радиусе поражения — скомпрометированный веб-слой не должен иметь возможности напрямую запрашивать базу, и ты показываешь правило security group, которое держит эту границу. |
| Управление секретами и позиция по шифрованию | Секреты в открытом тексте в переменных окружения или конфиге опознаны. Хотя бы один перенесён в управляемое хранилище, но ранее закоммиченные секреты не ротированы. | Все живые секреты забираются в рантайме из управляемого хранилища. Хотя бы один секрет ротирован от начала до конца, и приложение переживает ротацию. Политика KMS-ключа ограничена — без 'allow: *'. Аудит-логирование подтверждено: событие ротации фиксируется. | Ты рассуждаешь о том, что происходит после утечки секрета: SLA ротации (сколько между утечкой и отзывом), требует ли сам доступ к управляемому хранилищу отдельного учётного материала, который можно украсть, и каков радиус поражения при слишком широкой политике KMS-ключа. Нараспашку открытый KMS-ключ, охраняющий хранилище секретов, опознан как составной отказ защиты, а не независимый контроль. |
| Аудит-логирование и покрытие обнаружения | Аудит-логирование уровня аккаунта включено. Тестовое действие найдено в логах вручную, что подтверждает: что-то фиксируется. | Логи отправляются в устойчивое к подделке хранилище с контролем доступа. Период хранения задан и обоснован. Намеренно плохое действие (эскалация прав или переключение публичного доступа) найдено в логах разумным поиском — не прокруткой, а нужным фильтром. | Ты определяешь события, которые атакующий попытался бы подавить (остановка CloudTrail, удаление log-группы), и убеждаешься, что сами эти попытки появляются в трейле. Ты различаешь сигнал и шум: какие типы событий являются высокоточными индикаторами, а какие — фоновой болтовнёй API, скрывающей реальный алерт. Хотя бы одно правило алерта подключено, чтобы будущая мисконфигурация порождала уведомление, а не ждала обнаружения сканом. |
Эталонный разбор (спойлер)
Большинство облачных взломов начинается с identity, а не с сети: роль с 'Action: *' или долгоживущий ключ — точка входа. Сетевой периметр тоже важен, но корректно ограниченная IAM-роль сдерживает действия атакующего даже после того, как он до неё добрался — снижение радиус поражения и есть причина, почему least-privilege является контролем, а не просто галочкой в compliance.
Guardrail'ы policy-as-code чинят будущее, а не только прошлое: posture гниёт в момент появления новой wildcard-роли или открытого порта. Правило OPA/Rego или SCP, отклоняющее плохую форму, означает, что следующая мисконфигурация провалится на этапе plan, а не в три ночи при триаже взлома. Цена — поддержка политики по мере эволюции приложения; альтернативная цена — неограниченная поверхность регрессий.
Хранилище секретов под нараспашку открытым KMS-ключом — это театр: модель безопасности сворачивается к тому, что защищает политику KMS-ключа. Настоящая цепочка для аудита: кто может вызывать secrets manager, кто может использовать KMS-ключ и кто может менять любую из политик — эта цепочка и есть реальный радиус поражения при мисконфигурации любого звена.
Доказательство «до/после» — дисциплина, отделяющая ремедиацию от утверждения: заявлять, что posture улучшилась, не имея двух сканов, значит, что ты не можешь доказать это будущему аудитору, коллеге или себе через шесть месяцев. Diff CSPM-сканов — это проверяемый артефакт, делающий работу по безопасности читаемой.
Сделай по-сеньорски
- Встрой CSPM-скан и проверку policy-as-code в CI-пайплайн, чтобы pull request, ухудшающий posture, падал до merge, а не после деплоя.
- Оцифруй улучшение: преврати сканы «до/после» в небольшую дельту posture-скора и короткий журнал ремедиации, связывающий каждую находку с коммитом, который её закрыл.
- Добавь least-privilege break-glass: жёстко суженную, аудируемую, ограниченную по времени роль эскалации, чтобы аварии не искушали никого вернуть постоянный admin.