Перейти до вмісту

Безпека в хмарі

Банк переносить обробку заявок на кредитні картки в публічну хмару, ставить перед застосунком фаєрвол, дає йому роль для доступу до сховища, і все працює. Через кілька років з’ясовується, що дані 106 мільйонів людей скопіював той, хто зумів змусити цей фаєрвол зробити один неправильний запит. Жодного «злому хмари» не було: провайдер свою частину виконав, а частину клієнта не виконав ніхто.

Цей модуль про те, що лишається на боці клієнта після того, як провайдер зробив свою роботу: як точно розділено відповідальність, як шифрувати дані й тримати секрети так, щоб їх витік не означав кінця, як бачити, що відбувається в акаунті, і як розбиратися з інцидентами, які повторюються з року в рік: SSRF до метаданих, публічні бакети, майнери на чужий рахунок.

Передумови. Ідентичності, ролі й політики розібрано в модулі 3: тут ми спираємося на нього й не повторюємо. Сервіс метаданих і IMDSv2 — у модулі 4, публічні бакети як властивість сховища — у модулі 6, бюджети й алерти — в модулі 2. Основи безпеки ОС описано в курсі ОС: захист і безпека.

Спільна відповідальність детально

Section titled “Спільна відповідальність детально”

Модель спільної відповідальності (shared responsibility model) уже згадувалась у модулі 1 одним реченням. Тепер її розберемо докладно, бо від неї залежить, чиє це завдання.

AWS формулює її як «безпека хмари» проти «безпеки в хмарі»: провайдер відповідає за інфраструктуру, на якій працюють сервіси, а клієнт за те, що він у цій інфраструктурі налаштував і розмістив. Microsoft описує те саме таблицею за рівнями сервісу й наголошує, що незалежно від типу розгортання клієнт завжди відповідає за дані, пристрої та облікові записи з ідентичностями, а провайдер завжди за фізичну інфраструктуру. Google додає поняття спільної долі (shared fate): провайдер пропонує безпечні шаблони й налаштування за замовчуванням, а не лише розмежовує відповідальність.

Таблиця спільної відповідальності: дані та ідентичність завжди на клієнті, гіпервізор і фізичний рівень завжди на провайдері, а ОС, мережа й застосунок залежать від рівня сервісуIaaSвіртуальна машинаPaaSкерований сервісSaaSготовий застосунокдані та їхня класифікаціявививиідентичності й доступвививикод застосункувивипровайдерконфігурація сервісу й політикививиспільноОС і патчівипровайдерпровайдермережеві правилависпільнопровайдергіпервізор і хостпровайдерпровайдерпровайдерфізичний датацентрпровайдерпровайдерпровайдервипровайдерспільнови відповідаєте за налаштування, провайдер за платформу
Межа зсувається залежно від рівня сервісу. Чим вище рівень, тим більше бере провайдер, але дані та ідентичність лишаються на вас завжди.

Практичні наслідки з цієї таблиці такі.

Керований сервіс переносить безпеку, але не знімає її. У IaaS ви патчите ОС. У керованій базі даних патчі бере провайдер, але паролі, мережеві правила, шифрування й хто має доступ залишаються на вас. У SaaS лишається ще менше, проте увімкнути MFA й перевірити, кому надано доступ, теж доведеться вам.

Провайдер відповідає за працездатність механізму, а вмикаєте його ви. Шифрування S3 може бути надійним, але якщо бакет доступний усім, розшифровувати нічого не треба: сервіс сам віддасть дані будь-кому, хто попросить. Так само з політиками IAM і мережевими правилами.

Відповідальність не переходить разом із роботою. Якщо безпеку хмари налаштовує підрядник, за наслідки все одно відповідає власник даних: регулятор і клієнти запитають саме з нього.

Шифрування: KMS і envelope encryption

Section titled “Шифрування: KMS і envelope encryption”

Шифрування в спокої (at rest) захищає диски, бакети й бази даних, а шифрування в русі (in transit) захищає мережеві з’єднання. Усі три хмари вмикають шифрування в спокої за замовчуванням для більшості сховищ. Питання в тому, чиїм ключем і хто ним керує, бо ключ, доступний усім, шифруванням не є.

Ключі зберігає сервіс керування ключами (Key Management Service, KMS): AWS KMS, Azure Key Vault і Google Cloud KMS. Головний принцип полягає в тому, що головний ключ ніколи не залишає сервіс: ви передаєте йому дані й просите зашифрувати, а самого ключа не отримуєте. Але передавати через KMS кожен гігабайт нема сенсу: прямий виклик Encrypt в AWS KMS приймає лише до 4 КБ даних. Тому всюди застосовують envelope encryption, шифрування «у конверті».

Схема envelope encryption: KMS створює ключ даних, сервіс шифрує ним дані й зберігає поруч лише зашифрований ключ; для читання ключ повертається до KMS на розшифруванняваш сервіс або сховищеKMSголовний ключне залишає KMSсховищезашифровані данізашифрований ключ даних123451сервіс просить KMS створити ключ даних2KMS повертає ключ у двох виглядах: відкритий і зашифрований головним ключем3сервіс шифрує дані відкритим ключем і стирає його з памʼяті4зашифровані дані й зашифрований ключ даних зберігаються поруч5для читання сервіс віддає зашифрований ключ у KMS; якщо політика дозволяє, отримує відкритий
KMS створює й охороняє лише головний ключ. Дані шифрує ключ даних, а поруч із даними лежить тільки його зашифрована копія.

Такий двоступеневий устрій дає кілька властивостей одночасно. Об’єм даних не впливає на навантаження KMS: він викликається один раз на створення ключа даних, а не для кожного блока. Ключ даних можна мати свій для кожного об’єкта, тож компрометація одного ключа зачіпає один об’єкт. Ротація головного ключа не вимагає перешифровувати всі дані: перешифровують лише малі ключі даних. Найважливіше те, що право читати дані й право використовувати ключ окремі: щоб прочитати зашифрований об’єкт, доступу до бакета мало, потрібен ще й дозвіл на розшифрування ключем у KMS. Це два замки, і їх відкривають різні політики.

Це працює і в зворотний бік. Якщо ключ у KMS вимкнути або запланувати його видалення, усі дані, зашифровані під ним, стають нечитабельними незалежно від того, скільки копій існує. Тому видалення ключів у всіх трьох хмарах відкладене (AWS: 7–30 днів, за замовчуванням 30), а в Azure Key Vault додатково вмикають захист від остаточного видалення (purge protection).

Ключами можна керувати по-різному. Ключі провайдера працюють непомітно, але політики над ними ви не контролюєте. Ключі клієнта (customer-managed keys) створюються у вашому KMS, мають вашу політику, ротацію й журнал; їх обирають, коли регулятор вимагає контролю над ключем або коли доступ до даних і до ключа треба розділити.

resource "aws_kms_key" "data" {
description = "Ключ шифрування даних застосунку"
enable_key_rotation = true
deletion_window_in_days = 30
}
resource "aws_kms_alias" "data" {
name = "alias/app-data"
target_key_id = aws_kms_key.data.key_id
}

Ротація в AWS увімкнена явно (enable_key_rotation). У Azure вона описана політикою ключа, у GCP задана періодом у секундах (7 776 000 с — це 90 днів). Зверніть увагу на prevent_destroy у GCP: ключі Cloud KMS не видаляються з проєкту, а Terraform при destroy лише прибере їх зі стану й знищить версії, залишивши дані назавжди нечитабельними. Тому знищення ключа має бути свідомим рішенням, а не побічним ефектом команди.

Секрет (secret) є значенням, що дає доступ: пароль бази даних, токен API, приватний ключ. Місце для секретів визначає їхню долю. У коді чи в змінній середовища, записаній у файл конфігурації, секрет потрапляє в історію git, в образи контейнерів і в логи. Менеджер секретів (AWS Secrets Manager, Azure Key Vault, Google Secret Manager) вирішує це так: значення зберігається зашифрованим, кожна зміна створює нову версію, доступ регулюється політиками, кожне читання потрапляє в журнал, а ротацію можна автоматизувати.

Застосунок дістає секрет у момент запуску, автентифікуючись власною ідентичністю (роллю, керованою ідентичністю, сервісним акаунтом) із модуля 3. Так рішення не потребує ще одного ключа, щоб дістати секрети. Проблема першого секрету (secret zero) вирішується ідентичністю платформи, а не значенням, поміщеним у конфігурацію.

Terminal window
aws secretsmanager get-secret-value \
--secret-id prod/db/password \
--query SecretString --output text

Кожен такий виклик залишає запис у журналі аудиту: хто, коли і з якої адреси читав секрет. Це головна перевага менеджера секретів перед файлом на диску.

Кожен виклик API хмари залишає запис: хто, що, коли, звідки й з яким результатом. Три провайдери роблять це по-різному, але за однією моделлю: записи керування (створення, зміна, видалення ресурсів) і записи доступу до даних (читання конкретного об’єкта).

AWS CloudTrail Azure Activity Log GCP Cloud Audit Logs
Записи керування у Event History 90 днів безкоштовно 90 днів безкоштовно Admin Activity, 400 днів, вимкнути не можна
Записи доступу до даних не ведуться, доки не ввімкнути в trail окремо в діагностичних налаштуваннях ресурсу Data Access вимкнено за замовчуванням (крім BigQuery)
Довге зберігання trail в S3 діагностичне налаштування в сховище чи Log Analytics синк у бакет або BigQuery

Дві речі з цієї таблиці виявляються критичними під час розслідування.

Перша: дані про читання об’єктів за замовчуванням не пишуться. Якщо зловмисник скопіював сотні бакетів (у розборі нижче саме так), а журнал доступу до даних не був увімкнений, ви побачите, що щось було, але не дізнаєтеся, скільки саме й чого. Журнал доступу до даних коштує грошей пропорційно до обсягу, тому його вмикають вибірково: на чутливі сховища.

Друга: журнал, який зловмисник може стерти, нічого не вартий. Журнали відправляють в окремий акаунт або підписку з обмеженим доступом, де у клієнта, чиї дії вони фіксують, прав на запис і видалення немає.

Terminal window
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=DeleteBucket \
--max-results 5

Виявлення: CSPM і моніторинг загроз

Section titled “Виявлення: CSPM і моніторинг загроз”

Керування станом безпеки хмари (Cloud Security Posture Management, CSPM) постійно порівнює фактичну конфігурацію з правилами: публічний бакет, відкритий SSH з інтернету, користувач без MFA, незашифрований диск, ключ, який давно не ротували. Це відповідь на питання «що в нас налаштовано неправильно просто зараз», без очікування, доки це спричинить інцидент.

Іншу задачу вирішує виявлення загроз (threat detection): воно шукає підозрілу поведінку в журналах і мережевому трафіку, наприклад виклик API із незвичної країни, раптове створення сотні інстансів чи спробу дістатися до метаданих. CSPM каже, що двері незамкнені, а виявлення загроз каже, що хтось у них увійшов.

Функція AWS Azure GCP
Оцінка конфігурації (CSPM) Security Hub CSPM Microsoft Defender for Cloud Security Command Center
Виявлення загроз GuardDuty Microsoft Defender for Cloud SCC Event Threat Detection

Ці сервіси знаходять проблему, але причину не усувають: CSPM, який щодня повідомляє про тисячу порушень, ігнорують так само, як і його відсутність. Тому обов’язково пріоритизують (що зачіпає доступний ззовні ресурс із чутливими даними) і ставлять запобіжники на вході, які не дають створити небезпечну конфігурацію. У коді це виглядає так: публічний доступ вимикається на рівні самого ресурсу, і навіть помилка в політиці нічого не відкриє.

variable "bucket_name" {
type = string
}
resource "aws_s3_bucket" "data" {
bucket = var.bucket_name
}
resource "aws_s3_bucket_public_access_block" "data" {
bucket = aws_s3_bucket.data.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}

Традиційна модель безпеки будувалась навколо периметра: усередині мережі довіряють, ззовні ні. У хмарі периметра мало що визначає: API доступне з інтернету, співробітники працюють звідусіль, а сервіси розмовляють між собою через різні акаунти й регіони. Zero trust (нульова довіра) виходить із протилежного: розташування в мережі саме по собі не дає жодної довіри, і кожен запит перевіряється за ідентичністю, станом пристрою та контекстом.

Найвідоміший опис моделі — NIST SP 800-207. У хмарній практиці вона зводиться до правил, більшість яких уже була в курсі. Доступ визначає ідентичність, а не підмережа (модуль 3). Облікові дані тимчасові, права найменші. Кожен запит перевіряється в контексті: Conditional Access в Entra ID, Verified Access в AWS, Identity-Aware Proxy в GCP зважають на пристрій, місце й ризик. І виходять із припущення, що компрометація можлива: сегментація, шифрування всюди й журнали обмежують шкоду та дають змогу побачити зловмисника, який уже всередині.

AWS Azure GCP
Модель відповідальності security of / in the cloud таблиця за рівнями сервісу shared fate
Керування ключами AWS KMS Key Vault (ключі, секрети, сертифікати) Cloud KMS
Менеджер секретів Secrets Manager Key Vault Secret Manager
Аудит керування CloudTrail Activity Log Cloud Audit Logs
Оцінка конфігурації Security Hub CSPM Defender for Cloud Security Command Center
Заборона публічного доступу до сховища S3 Block Public Access allow_nested_items_to_be_public public access prevention

Чим це відрізняється і що з цього випливає. У Azure ключі, секрети й сертифікати живуть в одному сервісі Key Vault, а в AWS і GCP ключі шифрування й секрети розділені на окремі сервіси. Один сервіс зручніший, але політика доступу до нього частіше стає надто широкою; у двох сервісах права на ключі й на секрети видають окремо. У GCP Data Access логи вимкнено за замовчуванням для всіх сервісів окрім BigQuery, у CloudTrail та Azure записи про читання даних теж треба вмикати самому. Тому «у нас є аудит» без перевірки, що саме записується, нічого не означає.

Це один із найдокладніше задокументованих хмарних інцидентів. Розбирати його корисно за ланками, бо кожну з них можна було розірвати.

Ланцюг інциденту Capital One: запит зловмисника, WAF на інстансі AWS виконує запит до сервісу метаданих, отримує тимчасові облікові дані ролі, за якими зловмисник читає понад 700 бакетів S3; під кожною ланкою вказано контроль, що міг розірвати ланцюгзапитзловмисникадо WAFWAF на EC2робить запитвід свого іменісервіс метаданих169.254.169.254видає ключі роліключі ролі WAFтимчасові, алез широкими правамиAmazon S3понад 700 бакетів:список, копіюванняконтролі, що розривають ланцюгперевіркавхідних URLобмеженнявихідних запитівIMDSv2(модуль 4)вузька рольнайменших правжурнали даних,виявлення аномалій
Кожну ланку можна було розірвати контролем на боці клієнта.

Capital One повідомив про інцидент 29 липня 2019 року. За його даними, несанкціонований доступ стався 22 і 23 березня 2019 року, а виявили його 19 липня. Постраждали приблизно 100 мільйонів людей у США й 6 мільйонів у Канаді, серед іншого близько 140 000 номерів соціального страхування (SSN) клієнтів кредитних карток, близько 1 мільйона канадських номерів соціального страхування (SIN) і близько 80 000 пов’язаних номерів банківських рахунків. За заявою банку, номери кредитних карток і облікові дані для входу скомпрометовано не було.

Про інцидент банк дізнався не від власного моніторингу. За даними Міністерства юстиції США, 17 липня 2019 року користувач GitHub побачив допис зловмисниці про викрадення й повідомив банк, який 19 липня підтвердив вторгнення й звернувся до ФБР. 29 липня ФБР заарештувало Пейдж Томпсон (Paige Thompson, псевдонім erratic), яка раніше працювала інженеркою в AWS.

Заява Міністерства юстиції називає причиною неправильно налаштований вебзастосунковий фаєрвол (WAF). Технічні деталі відомі з матеріалів справи й розборів дослідників, зокрема Брайана Кребса. Фаєрвол працював на інстансі EC2 (за Кребсом, це був ModSecurity), і його можна було змусити виконати запит від власного імені: атака типу server-side request forgery (SSRF). Запит потрапляв до сервісу метаданих за адресою 169.254.169.254, який видає інстансу тимчасові облікові дані його ролі. У матеріалах справи роль фігурує як «WAF-Role».

Отримавши ці дані, зловмисниця діяла вже як легітимна роль: перелічила бакети S3 (за матеріалами справи, понад 700 «папок чи бакетів») і копіювала їх вміст командою синхронізації. Роль дозволяла й перелік, і читання вмісту в усіх бакетах, хоча WAF для роботи ця здатність була не потрібна.

Де ланцюг можна було розірвати

Section titled “Де ланцюг можна було розірвати”
  1. Запит зсередини. Фаєрвол, що виконує довільні URL, відкриває SSRF. Перевірка адреси призначення (список дозволених, заборона внутрішніх діапазонів) закриває вхід. За словами дослідника Cloudflare, у типовому наборі правил ModSecurity не було виявлення SSRF.
  2. Сервіс метаданих. Версія 1 сервісу видавала облікові дані на простий GET-запит, а це саме те, що відтворює SSRF. Версію 2 (IMDSv2), що вимагає попередньо отриманого токена через PUT-запит, AWS випустила 19 листопада 2019 року, за 113 днів після оголошення інциденту. Її механізм розібрано в модулі 4.
  3. Права ролі. Роль WAF мала право читати всі бакети. Вузька роль (модуль 3), що обмежена потрібними префіксами, обмежила б шкоду до одного сховища.
  4. Доступ до даних. Політики бакетів з умовою на джерело (наприклад, лише з певного мережевого ендпоінта VPC) відкидають запити, що прийшли з інтернету з тимчасовими ключами.
  5. Виявлення. Журнали доступу до даних, виявлення незвичних викликів API (перелік сотні бакетів за короткий час, запити з анонімізаторів) і контроль витоку даних. Цього не сталося: про подію повідомила стороння людина.

Управління контролера грошового обігу США (OCC) 6 серпня 2020 року наклало на Capital One цивільний штраф у 80 мільйонів доларів. У постанові йшлося про те, що банк не провів ефективної оцінки ризиків перед перенесенням значної частини ІТ у публічну хмару (що сталося близько 2015 року), не створив ефективного мережевого захисту, контролю витоку даних і системи сповіщень. Постанову скасовано у вересні 2022 року. У лютому 2022 року суд попередньо затвердив мирову угоду в груповому позові.

У червні 2022 року присяжні визнали Томпсон винною в шахрайстві з використанням електронних засобів (wire fraud) і комп’ютерних вторгненнях. Крім Capital One, обвинувачення стосувалось понад 30 інших організацій, на серверах яких вона також запускала майнери криптовалюти. У вересні 2022 року її засудили до відбутого терміну й п’яти років нагляду. Апеляційний суд вирок скасував як надто м’який, але в листопаді 2025 року суд першої інстанції ухвалив те саме рішення, а відшкодування становить 40,7 мільйона доларів.

Провайдер не був зламаний: сервіси AWS працювали як задумано. Постраждало те, що лежало на боці клієнта: конфігурація фаєрвола, права ролі, налаштування виявлення. Зверніть увагу й на те, скільки різних контролів було пропущено. Розраховувати на одну «правильну» мітигацію (лише IMDSv2 або лише вузьку роль) означає лишити систему крихкою. Стійкість дає їхня сукупність.

Публічний бакет залишається найчастішою причиною витоків у хмарі. У липні 2017 року дослідник UpGuard знайшов на S3 бакет партнера Verizon, компанії NICE Systems, який був відкритий для читання будь-кому з посиланням. Він виявив його 8 червня, повідомив Verizon 13 червня, а закрито бакет було лише 22 червня. Verizon оцінила зачеплені дані як 6 мільйонів клієнтів (імена, телефони, PIN-коди акаунтів), UpGuard говорила про до 14 мільйонів записів.

Механізм простий: політика чи ACL бакета дають доступ анонімному користувачеві, а хтось перебирає адреси бакетів. Захисту ніхто не зламував.

Відтоді провайдери змінили значення за замовчуванням, і це найкраща ілюстрація принципу «безпечно за замовчуванням»:

  • AWS. З квітня 2023 року S3 автоматично вмикає Block Public Access і вимикає ACL для всіх нових бакетів, як би їх не створювали (консоль, CLI, CloudFormation, Terraform).
  • Azure. Для нових облікових записів сховища анонімний доступ вимкнено за замовчуванням: з серпня 2023 року для створених через портал, а для створених через API, CLI, SDK та Terraform — з листопада 2023 року.
  • GCP. Для організацій, створених з 3 травня 2024 року, базові обмеження безпеки (в тому числі щодо сховища) увімкнено за замовчуванням.

Нові значення не зачіпають наявних ресурсів, і їх легко скасувати: хтось свідомо додає публічну політику, бо «так швидше». Тому запобіжники закріплюють явно (приклад вище) й перевіряють CSPM.

Криптомайнінг у зламаному акаунті

Section titled “Криптомайнінг у зламаному акаунті”

Гроші — найпростіша ціль, коли зловмисник отримує доступ до хмарного акаунта. Зловмисник краде обчислювальні потужності: запускає майнери на ваш рахунок. Для нього чужа хмара безкоштовна, а платите ви.

У лютому 2018 року дослідники RedLock повідомили, що зловмисники скористались консоллю Kubernetes компанії Tesla, яка не була захищена паролем. У ній були відкриті облікові дані AWS до сховища S3. Зловмисники розгорнули там ПЗ для майнінгу й приховали адресу пулу за Cloudflare, що утруднювало виявлення. RedLock знайшов проблему під час звичайного сканування небезпечних конфігурацій і повідомив Tesla, яка усунула проблему протягом кількох годин.

Схема в атаках, які описала AWS у грудні 2025 року (розібрана в модулі 3), інша за способом входу, але така сама за наслідками: дійсні облікові дані, розгортання майнерів за десять хвилин, вимкнення захисту від видалення для ускладнення реагування. Вхід у всіх випадках стався через слабо захищений доступ: відкриту консоль, витеклий ключ, слабкий пароль. За даними звіту Google Cloud Threat Horizons за першу половину 2025 року, слабкі або відсутні облікові дані були початковим вектором у 47,1% спостережених інцидентів, а неправильні конфігурації в 29,4%.

Ознаки, за якими майнінг помічають: інстанси в регіонах, де ви ніколи не працювали, запуск GPU чи великих інстансів без запиту, стрибок рахунку, нові користувачі чи ролі IAM, яких ніхто не створював. Перші дві ознаки ловить виявлення загроз, третю бюджетні алерти з модуля 2.

Типові помилки розуміння

Section titled “Типові помилки розуміння”

«Хмара шифрує все, отже дані захищені». Шифрування в спокої захищає від викрадення носія, а не від запиту з валідними обліковими даними. Якщо доступ до бакета й до ключа є в кожного, шифрування нічого не змінює.

«Ми в керованому сервісі, отже безпека на провайдері». Провайдер патчить платформу, але паролі, мережевий доступ, ідентичності й конфігурація залишаються на клієнті.

«У нас увімкнено CloudTrail (Activity Log, Audit Logs)». Записи про керування є, а записів про читання даних може не бути. Перевірте, що саме записується, до того, як знадобиться розслідування.

«Одна мітигація закриває інцидент». У Capital One було п’ять місць для розриву ланцюга. Захист будують шарами.

Перевір себе

1. Команда використовує керовану базу даних (PaaS). Пароль адміністратора лежить у репозиторії, а мережеве правило дозволяє доступ звідусіль. Чия це відповідальність?
2. Для чого потрібен ключ даних в envelope encryption, якщо є головний ключ у KMS?
3. Вас просять розслідувати, які обʼєкти скопіював зловмисник із бакета S3. У акаунті ввімкнено лише стандартний CloudTrail. Що ви побачите?
4. Застосунок дозволяє користувачеві вказати URL, який сервер завантажує. Чому це може призвести до витоку ключів ролі інстанса?
5. Що з перерахованого найкраще обмежило б шкоду в інциденті Capital One навіть за наявності SSRF і метаданих версії 1?
6. В акаунті раптом зʼявилися десятки великих GPU-інстансів у регіоні, де компанія не працює. Що найшвидше вкаже на майнінг у зламаному акаунті?