Залишати Kubernetes із дефолтними налаштуваннями – це свідомо давати хакерам ключі від інфраструктури. Архітектура системи складна, тому безпека там з коробки фактично відсутня. Матеріал створено для українського ком’юніті HackYourMom та інженерів, які хочуть перестати покладатися на удачу в питаннях захисту. Тут зібрано базу про правильний підхід до налаштування кластера, створення безпечного ізольованого полігону для тестів та логіку пошуку вразливих місць.
Тема захисту конфігурації кластерів Kubernetes часто нагадує спробу побудувати неприступну фортецю на піску, якщо ігнорувати базові принципи роботи цієї екосистеми. Спочатку це програмне забезпечення створювалося з прицілом на максимальну гнучкість, швидке масштабування та зручність для розробників. Тому безпека «з коробки» тут часто просто відсутня як явище. Залишити кластер із параметрами за замовчуванням – це рівнозначно тому, щоб вивісити в інтернет неонову табличку з проханням зламати інфраструктуру.
Величезна кількість налаштувань, прихованих параметрів та складних мережевих абстракцій перетворює адміністрування на серйозний виклик навіть для інженерів із багаторічним стажем. Більше про філософію системи та її початкові архітектурні рішення завжди корисно почитати в офіційній документації Kubernetes.
Цей матеріал чудово підійде DevOps-фахівцям, адміністраторам платформи HackYourMom та всім інженерам, для кого щоденне управління кластером є звичною рутиною, але є чіткий запит перевести інфраструктуру на якісно новий рівень захисту (hardening). Йдеться насамперед про досвід роботи з інсталяціями vanilla, які розгортаються на власних серверах (on-premises) за допомогою стандартної утиліти kubeadm. Керовані хмарні рішення (EKS, GKE, AKS) зазвичай беруть значну частину відповідальності на себе, закриваючи доступ до майстер-вузлів. Натомість при самостійному розгортанні абсолютний контроль, а також уся відповідальність за помилки конфігурації, лежать виключно на адміністраторі інфраструктури.
Теоретична база має колосальне значення, але експерименти з безпекою на живих, продуктових серверах зазвичай закінчуються тривалими простоями та гарячковим відновленням із бекапів. Найкраще інформація засвоюється через глибокі практичні вправи в повністю ізольованому середовищі, де можна ламати архітектуру без жодних наслідків для бізнесу.
Існує багато готових інструментів, таких як minikube, kind або k3s, які дозволяють підняти кластер буквально однією командою. Проте для якісного аудиту безпеки вкрай важливо розуміти систему без зайвих шарів абстракції. Готові міні-інструменти часто ховають «під капотом» реальні системні процеси, мережеві інтерфейси та конфігураційні файли життєво важливих компонентів (наприклад, маніфести API-сервера чи etcd), що унеможливлює проведення реалістичних тестів.
Самостійно розгорнутий кластер на кількох повноцінних віртуальних машинах є безальтернативно найкращим вибором для таких завдань. Процес створення такого полігону дуже легко автоматизується за допомогою утиліти Multipass від компанії Canonical, яка дозволяє миттєво створювати оптимізовані віртуальні машини на базі Ubuntu. Для швидкого старту необхідно лише встановити Multipass на робочий комп’ютер, завантажити консольний клієнт kubectl, клонувати підготовлений репозиторій та запустити bash-скрипт.
git clone https://github.com/reynardsec/kubernetes-security-guide cd kubernetes-security-guide ./bootstrap-kubernetes.sh
Для користувачів операційної системи Windows у репозиторії завбачливо лежить аналогічний скрипт PowerShell, який виконує ті самі дії через Hyper-V:
.\bootstrap-kubernetes.ps1
Цей скрипт автоматично підтягує образи операційної системи, створює віртуальні мережі, встановлює контейнерне середовище виконання (containerd) та ініціалізує кластер за допомогою kubeadm. Після швидкого завершення процесу система надасть повний доступ до локального кластера, що складається з одного керівного вузла (control-plane) та двох робочих вузлів (worker). Перевірити статус цих віртуальних серверів можна звичною командою:
kubectl get nodes
Для видалення створених віртуальних машин та повного очищення дискового простору й оперативної пам’яті передбачено окремий скрипт очищення:
./cleanup.sh
Завдяки глибокій інтеграції Multipass взаємодія з командним рядком будь-якої створеної віртуальної машини відбувається миттєво. Немає необхідності генерувати SSH-ключі чи вручну прописувати доступи, достатньо використати команду exec:
multipass exec control-plane -- bash ubuntu@control-plane:~$ hostname control-plane ubuntu@control-plane:~$ exit
Розуміння того, як саме складові частини системи спілкуються між собою, є тим самим надійним фундаментом захисту. Архітектура складається з десятків мікросервісів, і кожен такий елемент є потенційною мішенню. Кластер логічно розділений на площину управління (Control Plane) та робочі вузли (Worker Nodes).
API Server (
kube-apiserver) виконує роль центрального мозку і єдиної точки входу. Він працює як дуже суворий фейсконтроль: приймає абсолютно всі REST-запити від користувачів та внутрішніх компонентів, перевіряє їхню автентичність, прискіпливо валідує права доступу (RBAC) і лише після цього дозволяє системі виконати запитувану дію або записати зміни. Компрометація цього вузла завжди означає миттєву і повну втрату контролю над усією інфраструктурою. Жоден інший компонент не спілкується з базою даних напряму – тільки через API Server.
База даних etcd є розподіленим високодоступним сховищем формату «ключ-значення». Саме тут лежить уся конфігурація кластера, інформація про поточний стан подів та, що найважливіше, критично важливі секрети. Специфіка etcd полягає в тому, що вона не має внутрішніх механізмів гранулярного розмежування доступу до окремих таблиць чи записів. Вона повністю довіряє будь-якому підключенню, що має валідний криптографічний сертифікат. Прямий доступ до файлів etcd на диску (дамп бази) гарантує атакуючому абсолютну владу над усім середовищем, оскільки стандартні Secret у Kubernetes зберігаються там просто в кодуванні base64, що не є шифруванням. Більше про внутрішню будову цього сховища варто почитати на офіційному ресурсі проєкту etcd.
Агент
kubeletцілодобово працює на кожному вузлі як системний сервіс (зазвичай під управлінням systemd). Він реєструє вузол у кластері, отримує інструкції від панелі управління (через API Server) і безпосередньо смикає контейнери, забезпечуючи їхній запуск, зупинку та перевірку працездатності.
Мережевий проксі (
kube-proxy) відповідає за мережеву взаємодію на базовому рівні. Він хитро керує правилами маршрутизації прямо на рівні ядра операційної системи (через iptables або IPVS), гарантуючи, що мережевий трафік безпомилково знайде потрібний мікросервіс, навіть якщо його IP-адреса змінилася через перезапуск контейнера.
Планувальник (
kube-scheduler) тим часом постійно моніторить систему на наявність нових подів без призначеного вузла і шукає ідеальне місце для їх запуску, враховуючи вимоги до пам’яті, процесора та політики спорідненості. А контролери (kube-controller-manager) невпинно стежать за тим, щоб фактичний стан системи (кількість запущених реплік) ідеально збігався із заданими конфігураціями в маніфестах.
Структурувати хаотичний пошук вразливих місць чудово допомагає методологія моделювання загроз. Без чіткого плану аудиту легко загрузнути в сотнях дрібних налаштувань і пропустити критичну діру. Для таких специфічних завдань ідеально підходить класифікація STRIDE від Microsoft, яка дуже логічно розбиває потенційні вектори атак на шість зрозумілих і практичних категорій.
Ця категорія фокусується на підробці ідентифікаційних даних. Основною загрозою тут є використання старих незахищених протоколів для внутрішнього зв’язку. Наприклад, якщо трафік між вузлами та компонентами управління літає в незашифрованому вигляді (без налаштованого mTLS), хитрий зловмисник, що вже проник у внутрішню мережу підприємства, може легко здійснити атаку перехоплення (Man-in-the-Middle). Він почне перехоплювати пакети, успішно імітуючи легітимні системні сервіси, і відправляти фальшиві команди від імені API-сервера до агентів kubelet.
Тут розглядаються сценарії серйозного порушення цілісності системи. Найпоширеніший та найболючіший вектор полягає в атаках на ланцюг постачання програмного забезпечення (Supply Chain Attacks). Зловмисники можуть знайти вразливість у системі CI/CD і непомітно підмінити легітимний Docker-образ додатка в реєстрі на модифіковану версію з хитрим бекдором або майнером. Система на автоматі розгорне цей заражений образ під час чергового релізу (наприклад, під час оновлення блоку статей на порталі HackYourMom), і шкідливий код спокійно почне працювати прямо в ядрі проєкту. Сюди також належить несанкціонована модифікація мережевих політик (NetworkPolicies) недосвідченими розробниками, що випадково знімає ізоляцію та відкриває внутрішні бази даних всьому інтернету.
Категорія повністю пов’язана з відсутністю належного журналювання системного аудиту. Якісне логування API-запитів часто свідомо вимикають для сумнівної економії ресурсів жорсткого диска та зниження навантаження на процесор. У разі виникнення критичного інциденту (наприклад, хтось видалив цілий простір імен із базою даних) розслідувати його стає просто неможливо. Кластер банально не фіксує, який саме сервісний акаунт чи адміністратор виконав деструктивну команду. Відсутність цифрових слідів робить систему абсолютно сліпою перед внутрішніми загрозами.
Це завжди залишається найпростішим і найшвидшим шляхом для ескалації масштабної атаки. Відкриті сервісні порти, наприклад сумнозвісний порт агента kubelet 10250 (якщо на ньому дозволено анонімний доступ), дозволяють будь-яким неавторизованим сканерам виконувати довільні команди безпосередньо в чужих продуктових контейнерах. Крім того, неправильно налаштовані політики рольового доступу (RBAC) – класичний біль Kubernetes. Досить часто вони дають звичайному стажеру чи скомпрометованому CI-сервісу необмежені права на читання всіх об’єктів типу Secret у системі, включаючи мастер-паролі до головних баз даних та ключі шифрування від платіжних шлюзів.
У суворих реаліях контейнеризації потужний DoS найчастіше прилітає зсередини, а не від зовнішніх хакерів чи ботнетів. Якщо процесам у подах забути жорстко обмежити споживання оперативної пам’яті (limits: memory) та ресурсів процесора, один криво написаний скрипт, який потрапив у безкінечний цикл, може надзвичайно швидко виснажити всі апаратні ресурси залізного вузла. Операційна система запанікує і через механізм OOM Killer почне хаотично вбивати процеси для власного порятунку. Це ланцюговою реакцією призводить до неминучої зупинки сусідніх критично важливих компонентів бізнесу, що розміщені на тому ж сервері.
Остання ланка ланцюга і фінальна мета будь-якої комплексної кібератаки. Запуск контейнерів із правами привілейованого користувача root (або з прапорцем privileged: true) створює пряму загрозу втечі з ізольованого середовища (Container Breakout) на рівень хостової операційної системи. Активно використовуючи відомі вразливості ядра Linux, атакуючий виривається за межі віртуального оточення і отримує повний, беззаперечний контроль над фізичним сервером. А відсутність жорсткої мережевої ізоляції тільки допомагає йому спокійно і комфортно пересуватися від одного зламаного незначного тестового сервісу до найкритичніших елементів корпоративної інфраструктури.
Ну що, перший крок зроблено. Ми не просто розібрали архітектуру Kubernetes на папері, а підготували реальний майданчик для експериментів, де можна ламати все без страху «покласти» прод. Тепер ми знаємо, що кластер – це не моноліт, а купа взаємопов’язаних сервісів, і кожен із них має свої слабкі місця, які ми розклали по поличках через STRIDE.
Це був наш фундамент. Попереду – найцікавіше: ми переходимо від теорії до «закручування гайок». У наступній частині почнемо реально посилювати захист, розберемося, як правильно закрити API-сервер від зайвих очей і що робити, щоб ваші секрети в etcd не стали здобиччю першого-ліпшого хакера.