Безопасность облаков: типовые мисконфиги

Облако не «безопасно по умолчанию»: 9 из 10 утечек данных в облаке — это чья-то ошибка конфигурации, а не пробитый файрвол.

Мисконфигурация (misconfiguration) — настройка облачного ресурса, которая открывает доступ или права шире, чем требуется задаче. Это не «уязвимость в коде провайдера», а ваша ответственность по модели разделённой ответственности (shared responsibility).

Облачные провайдеры (AWS, GCP, Azure, Yandex Cloud) отвечают за безопасность самого облака — железо, гипервизор, сеть ЦОД. А вот безопасность в облаке — кто и что может читать в вашем бакете, какие права у сервис-аккаунта, не лежит ли ключ в публичном репозитории — это полностью на клиенте. Защитнику (Blue Team) важно понимать три самых частых мисконфига, потому что именно их в первую очередь ищет и атакующий, и автоматический сканер, который круглосуточно перебирает интернет.

Зачем это знать защитнику

Открытый бакет или утёкший ключ не требуют «взлома» в киношном смысле: их находят за минуты обычным перебором и публичными поисковиками по облачным ресурсам. Если вы умеете думать как атакующий — «а что тут открыто наружу и какие права это даёт?» — вы закрываете дыру раньше, чем её найдут. Всё ниже относится только к вашим собственным аккаунтам и разрешённой лаборатории: сканировать чужие облачные ресурсы — несанкционированный доступ к информации (ст. 272 УК РФ).

Открытые бакеты объектного хранилища

Объектное хранилище (S3, GCS, Object Storage) хранит файлы в «бакетах». Классическая ошибка — выставить бакету или его объектам публичный доступ «чтобы фронтенд забирал картинки», а заодно туда же положить бэкапы базы, логи с токенами и пользовательские документы. Дальше любой, кто угадал или подсмотрел имя бакета, скачивает всё содержимое.

Как это возникает

Чаще всего — через ACL или bucket policy с принципом * (все). Вот как выглядит опасная политика, которую нельзя применять на проде:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": "*",
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::my-app-backups/*"
  }]
}

"Principal": "*" означает «кто угодно из интернета». Для приватных данных это и есть утечка.

Как обнаружить и закрыть

Принцип защиты — «закрыто по умолчанию, публично — осознанно». Включите блокировку публичного доступа на уровне аккаунта (Block Public Access), чтобы даже случайная политика не сделала бакет открытым. Аудит — регулярно перечисляйте бакеты и проверяйте их флаги. Иллюстрация аудита в вашем аккаунте:

# Перечислить свои бакеты и проверить публичность (свой аккаунт!)
aws s3api list-buckets --query 'Buckets[].Name'
aws s3api get-public-access-block --bucket my-app-backups
# Включить блокировку публичного доступа
aws s3api put-public-access-block --bucket my-app-backups \
  --public-access-block-configuration \
  BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true

Чрезмерные IAM-права

IAM (Identity and Access Management) — система прав в облаке. Самый частый мисконфиг — выдать роли или сервис-аккаунту политику вида «всё на всё» (Action: "*", Resource: "*"), потому что «так быстрее заработает». Проблема: если такой ключ или под скомпрометируют, атакующий получает права уровня администратора и может повысить привилегии — например, через право создавать новые роли или прикреплять политики.

Принцип наименьших привилегий

Least privilege — каждому субъекту выдаются ровно те права, что нужны для его задачи, и ни одним больше. Это главный приём защиты в облаке.

Вместо «звёздочки» опишите конкретные действия над конкретными ресурсами. Сравните:

ОпасноПравильно
"Action": "*""Action": ["s3:GetObject"]
"Resource": "*""Resource": "arn:aws:s3:::my-app-uploads/*"
один ключ «на всё»отдельная роль на каждую задачу

Хороший рабочий процесс: начать с пустых прав, запустить сервис, по логам отказов (Access Denied) добавлять только реально нужные действия. Так вы приходите к минимальному набору, а не урезаете «всё» наугад.

Утёкшие ключи и секреты

Долгоживущие ключи доступа (access key) утекают чаще всего через git: разработчик коммитит .env или конфиг с ключом, пушит в публичный репозиторий — и боты находят его за секунды. Дальше — доступ к облаку с правами этого ключа.

Как защититься

  • Не хранить секреты в коде. Используйте менеджеры секретов (AWS Secrets Manager, Vault, GCP Secret Manager) и переменные окружения, выдаваемые в рантайме.
  • Короткоживущие учётки вместо ключей. Для сервисов — IAM-роли и временные токены (STS), а не статические ключи. Утёкший токен на час куда менее опасен, чем вечный ключ.
  • Сканеры секретов в CI. Инструменты вроде gitleaks или trufflehog проверяют коммиты на ключи до того, как они попадут в репозиторий.
  • Ротация и отзыв. Если ключ всё же утёк — немедленно деактивируйте его и заведите новый.
# Проверить свой репозиторий на утёкшие секреты (локально, до коммита)
gitleaks detect --source . --verbose

Как это работает под капотом

Облако управляется через API: каждое действие — это HTTP-запрос, подписанный учётными данными. «Безопасность» здесь — это связка аутентификации (кто ты, по ключу/токену) и авторизации (что тебе можно, по IAM-политике). Открытый бакет — это политика, разрешающая анонимный GetObject. Чрезмерные права — политика со «звёздочкой» в Action. Утёкший ключ — компрометация шага аутентификации. Поэтому вся оборона сводится к двум вопросам: «кто может предъявить эти учётки?» и «что именно эти учётки позволяют сделать?».

Как защититься

  • Включите Block Public Access на уровне аккаунта; публичный доступ открывайте точечно и осознанно.
  • Применяйте least privilege: конкретные Action и Resource, отдельная роль под каждую задачу.
  • Откажитесь от долгоживущих ключей в пользу временных токенов и ролей; секреты — только в менеджере секретов.
  • Поставьте сканер секретов в CI и инструмент аудита конфигураций (CSPM, например prowler или scout suite) — они находят мисконфиги автоматически.
  • Включите аудит-логи (CloudTrail и аналоги) и алёрты на подозрительные действия: создание новых ключей, изменение политик, доступ из необычных регионов.

Итоги

  • Большинство облачных утечек — это мисконфиги клиента, а не взлом провайдера (модель разделённой ответственности).
  • Три главных риска: открытые бакеты, чрезмерные IAM-права, утёкшие ключи.
  • Главный приём защиты — наименьшие привилегии и «закрыто по умолчанию».
  • Секреты не хранят в коде; долгоживущие ключи заменяют временными токенами; CI проверяет коммиты сканером.
  • Сканировать можно только свои аккаунты и разрешённую лабораторию: чужое облако — это ст. 272 УК РФ.
Проверьте себя
1. Что описывает модель разделённой ответственности (shared responsibility) в облаке?
AПровайдер отвечает за всё, включая настройку доступа к вашим бакетам
BПровайдер защищает само облако (железо, гипервизор), а клиент — настройки и данные в облаке
CКлиент отвечает только за пароль от консоли, остальное — провайдер
DОтветственность делится поровну между провайдером и государством
2. Какой приём лучше всего снижает ущерб от утечки облачного ключа или токена?
AВыдать сервис-аккаунту права 'Action: *', чтобы точно ничего не сломалось
BХранить ключ в коде, но в приватном репозитории
CПринцип наименьших привилегий плюс короткоживущие токены вместо долгоживущих ключей
DПереименовать бакеты так, чтобы их нельзя было угадать