Останнього разу, коли я перевіряв на Shodan (https://www.shodan.io/search?query=Kubernetes), мене не здивувало те, що більше ніж 1,6 мільйона Kubernetes API серверів були відкриті для публічного доступу через інтернет. Хоча не всі з них розміщені на Microsoft Azure Kubernetes Service (AKS), важливо зазначити, що за замовчуванням розгортання AKS залишає свій API сервер доступним для публіки. Причина такої конфігурації — зручність, що дозволяє організаціям швидко запускати сервіси.
Можливо, ви запитаєте: "А в чому проблема з тим, щоб AKS API сервер був доступний публічно?" Відповідь проста: безпека. Коли API сервер AKS доступний публічно, ризик компрометації вашого розгортання AKS значно зростає. Давайте розглянемо, як це може статися.
Уявіть, що ви розгорнули додаток, і він містить уразливість, що дозволяє віддалене виконання коду. Зловмисник може використати це для компрометації контейнера, зібрати облікові дані, а потім використати ці облікові дані зовні — наприклад, з їхнього ноутбука — для повторного доступу через відкритий API сервер.
Початковий доступ також може надійти з інших джерел, таких як вкрадені облікові дані з ноутбука розробника або підвищені секрети, закріплені в репозиторії GitHub компанії — чи навіть особистому репозиторії. Є також ймовірність використання вразливості нульового дня.
Щоб продемонструвати це, ми розгорнемо базовий AKS кластер і дослідимо кілька векторів атак на стандартне розгортання AKS. Додатково ми навмисно введемо уразливість у кластер.
Рисунок 1 — Домени стандартного розгортання AKS закінчуються доменом amzk8s.io. Запит curl, зроблений без аутентифікації через публічний інтернет, призведе до помилки або до несанкціонованої відповіді з кодом статусу 401.
Рисунок 2 — Розгортання контейнера Busybox в стандартному просторі імен і підключення до стандартного AKS ServiceAccount дає доступ до його JWT токену, який можна використовувати для взаємодії з AKS API сервером. У цьому випадку API сервер відкритий для зовнішнього доступу. Однак, як і очікувалось, стандартний ServiceAccount має обмежені права. Наприклад, він не може читати секрети в стандартному просторі імен. Це видно на скріншоті вище, де команда cURL, яка намагається отримати доступ до секрету під стандартним ServiceAccount, зазнає невдачі з помилкою 403, що вказує на відмову в дозволі.
Гіпотетичний сценарій
Уявіть, що ви працюєте в швидко змінному середовищі фондової біржі, де ваша інфраструктурна команда використовує AKS для розгортання і управління контейнерами. У цьому налаштуванні:
У вас є ClusterRole під назвою pod-creator-role
, який надає дозволи на перегляд і читання секретів.
Цей ClusterRole прив'язаний до RoleBinding під назвою pod-creator-rolebinding
.
RoleBinding зв'язується з ServiceAccount під назвою pod-creator-sa
.
ServiceAccount асоційований з простором імен apps
, який містить контейнер stocks
, що запускає ваш FTS500 додаток.
Тепер уявіть ситуацію, коли контейнер stocks
має уразливість, таку як експлойт для Directory Traversal, що дозволяє зовнішньому зловмиснику читати файли на сервері.
Ця уразливість може потенційно розкрити чутливу інформацію або скомпрометувати додаток, особливо зважаючи на підвищені дозволи, призначені ServiceAccount.
Нижче наведені визначення YAML для ClusterRole, RoleBindings і ServiceAccount, призначених для контейнера Stock в просторі імен apps
.
ClusterRole — pod-creator-role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: apps
name: pod-creator-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["list"]
Рисунок — 3 pod-creator-role ClusterRole з дозволами на список та створення секретів у просторі імен apps.
ClusterRoleBindings
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-creator-rolebinding
namespace: apps
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-creator-role
subjects:
- kind: ServiceAccount
name: pod-creator-sa
namespace: apps
Рисунок — 4 pod-creator-role-binding, а також ServiceAccount pod-creator-sa, призначений для простору імен додатка.
Рисунок 5 — Уявімо, що додаток Stock має уразливість для виконання коду. Оскільки API сервер AKS відкритий для публіки, зловмисник може використати це, скориставшись підключеним ServiceAccount. Це дозволить йому взаємодіяти безпосередньо з API сервером AKS з будь-якого місця, використовуючи дозволи ServiceAccount для доступу до ресурсів або маніпулювання ними в просторі імен apps.
Рисунок 6 — Озброєний привілейованим ServiceAccount, підключеним до додатка Stocks в просторі імен apps, зловмисник може безпосередньо взаємодіяти з API сервером AKS. Цей доступ дозволяє йому отримувати список облікових даних та секретів. У цьому випадку, коли чутливі секрети відкриті, а API сервер AKS доступний публічно, зловмисник може легко скомпрометувати середовище та встановити постійну присутність.
На цьому етапі зловмисник, маючи доступ до секретів у просторі імен apps
через відкритий API сервер AKS, може використати ключі для подальшої компрометації середовища AKS. Цей доступ дозволяє зловмиснику встановити та підтримувати постійну присутність в інфраструктурі AKS.
Мітки та рекомендації
Відкриття API сервера AKS для публіки несе потенційний ризик компрометації, що може статися через різні способи. Хоча AKS за замовчуванням відкритий для публіки, Microsoft впровадила потужні технічні засоби для мінімізації цього ризику. Зокрема, Microsoft дозволяє організаціям обмежити доступ до API сервера AKS лише для конкретних корпоративних IT IP-адрес, що значно знижує рівень відкритості. Крім того, AKS може бути розгорнутий як приватний кластер, що ще більше підвищує безпеку.
Рисунок 7 — Використано командний рядок Azure для оновлення API сервера TheGrid AKS, обмеживши доступ до однієї /32 IP-адреси для мінімізації відкриття API сервера для публічного інтернету.
Рисунок 8 — Використано командний рядок Azure (CLI) для перевірки, що API сервер TheGrid обмежений до однієї IP-адреси, а не доступний з публічного інтернету.
Перекладено з: Why Your AKS API Server Should Stay Private and How to Achieve It