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

Модуль 2.2: Безпека вузлів

Складність: [СЕРЕДНЯ] - Основні знання

Час на виконання: 25-30 хвилин

Передумови: Модуль 2.1: Безпека площини управління


Що ви зможете робити

Розділ «Що ви зможете робити»

Після завершення цього модуля ви зможете:

  • Оцінити ризик привілейованих контейнерів та доступу до просторів імен хоста на робочих вузлах
  • Оцінити налаштування безпеки kubelet, включаючи автентифікацію, авторизацію та read-only порти
  • Визначити вектори атак на рівні вузла: відкритий API kubelet, записуваний hostPath, експлойти ядра
  • Пояснити стратегії зміцнення вузлів, включаючи мінімальні образи ОС та автоматичне оновлення

Чому цей модуль важливий

Розділ «Чому цей модуль важливий»

Робочі вузли виконують ваші реальні навантаження. Вони мають прямий доступ до ваших контейнерів та чутливих даних. Скомпрометований вузол означає скомпрометовані поди - і потенційно весь кластер, якщо атакуючий зможе підвищити привілеї від вузла до площини управління.

Розуміння безпеки вузлів допомагає оцінити ризик привілейованих контейнерів та атак на рівні вузла.


┌─────────────────────────────────────────────────────────────┐
│ ВУЗОЛ KUBERNETES │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ KUBELET │ │
│ │ • Агент вузла │ │
│ │ • Керує життєвим циклом подів │ │
│ │ • Комунікує з API server │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ СЕРЕДОВИЩЕ ВИКОНАННЯ │ │
│ │ containerd, CRI-O │ │
│ │ • Безпосередньо запускає контейнери │ │
│ │ • Завантажує образи │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ КОНТЕЙНЕР │ │ КОНТЕЙНЕР │ │ КОНТЕЙНЕР │ │
│ │ Pod A │ │ Pod B │ │ Pod C │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ KUBE-PROXY │ │
│ │ • Мережеві правила (iptables/IPVS) │ │
│ │ • Маршрутизація сервісів │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

kubelet - найкритичніший для безпеки компонент на вузлі.

kubelet надає API, який може бути небезпечним при відкритті:

┌─────────────────────────────────────────────────────────────┐
│ БЕЗПЕКА API KUBELET │
├─────────────────────────────────────────────────────────────┤
│ │
│ МОЖЛИВОСТІ API KUBELET (при відкритті) │
│ • Виконання команд у контейнерах │
│ • Читання логів контейнерів │
│ • Port-forward до контейнерів │
│ • Перегляд подів на вузлі │
│ │
│ НЕБЕЗПЕЧНІ ТОЧКИ ДОСТУПУ │
│ • /exec - Виконання довільних команд │
│ • /run - Запуск команд у контейнерах │
│ • /pods - Список всіх подів │
│ • /logs - Читання логів контейнерів │
│ │
│ СЦЕНАРІЙ АТАКИ │
│ 1. Атакуючий знаходить відкритий kubelet (порт 10250) │
│ 2. Підключається без автентифікації │
│ 3. Виконує команди у будь-якому контейнері на вузлі │
│ 4. Краде секрети, переходить до інших систем │
│ │
└─────────────────────────────────────────────────────────────┘

Конфігурація безпеки kubelet

Розділ «Конфігурація безпеки kubelet»
ПрапорецьПризначенняБезпечне значення
--anonymous-authДозвіл анонімних запитівfalse
--authorization-modeЯк авторизуватиWebhook (перевіряє через API server)
--client-ca-fileCA для клієнтських сертифікатівВстановити CA кластера
--read-only-portПорт API лише для читання0 (вимкнено)
--protect-kernel-defaultsЗахист налаштувань ядраtrue
--hostname-overrideПеревизначення імені хостаУникати (може обійти авторизацію)
# Приклад конфігурації kubelet (kubelet-config.yaml)
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
anonymous:
enabled: false
webhook:
enabled: true
authorization:
mode: Webhook
readOnlyPort: 0
protectKernelDefaults: true

Безпека середовища виконання контейнерів

Розділ «Безпека середовища виконання контейнерів»

Середовище виконання контейнерів (containerd, CRI-O) відповідає за ізоляцію контейнерів.

┌─────────────────────────────────────────────────────────────┐
│ ІЗОЛЯЦІЯ СЕРЕДОВИЩА ВИКОНАННЯ │
├─────────────────────────────────────────────────────────────┤
│ │
│ МЕХАНІЗМИ ІЗОЛЯЦІЇ LINUX │
│ │
│ NAMESPACES (Ізоляція процесів) │
│ ├── pid - Ідентифікатори процесів │
│ ├── net - Мережевий стек │
│ ├── mnt - Точки монтування │
│ ├── uts - Ім'я хоста │
│ ├── ipc - Міжпроцесна комунікація │
│ ├── user - Ідентифікатори користувачів/груп │
│ └── cgroup - Членство в cgroup │
│ │
│ CGROUPS (Обмеження ресурсів) │
│ ├── Ліміти CPU │
│ ├── Ліміти пам'яті │
│ └── Ліміти блочного вводу/виводу │
│ │
│ МОДУЛІ БЕЗПЕКИ │
│ ├── seccomp - Фільтрація системних викликів │
│ ├── AppArmor - Обов'язковий контроль доступу (Ubuntu) │
│ └── SELinux - Обов'язковий контроль доступу (RHEL) │
│ │
└─────────────────────────────────────────────────────────────┘

Kubernetes підтримує різні класи runtime для сильнішої ізоляції:

┌─────────────────────────────────────────────────────────────┐
│ ОПЦІЇ СЕРЕДОВИЩ ВИКОНАННЯ │
├─────────────────────────────────────────────────────────────┤
│ │
│ СТАНДАРТНІ RUNTIME │
│ ├── containerd (за замовчуванням) │
│ └── CRI-O │
│ Добра ізоляція, спільне ядро з хостом │
│ │
│ ІЗОЛЬОВАНІ RUNTIME (Сильніша ізоляція) │
│ ├── gVisor (runsc) │
│ │ └── Ядро у просторі користувача, перехоплює syscalls │
│ │ │
│ └── Kata Containers │
│ └── Легкі ВМ, окреме ядро │
│ │
│ Використовуйте ізольовані runtime для: │
│ • Ненадійних навантажень │
│ • Багатоорендних середовищ │
│ • Обробки чутливих даних │
│ │
└─────────────────────────────────────────────────────────────┘

Атаки на рівні вузла

Розділ «Атаки на рівні вузла»

Втеча з контейнера

Розділ «Втеча з контейнера»
┌─────────────────────────────────────────────────────────────┐
│ ВЕКТОРИ ВТЕЧІ З КОНТЕЙНЕРА │
├─────────────────────────────────────────────────────────────┤
│ │
│ НА ОСНОВІ НЕПРАВИЛЬНОЇ КОНФІГУРАЦІЇ │
│ │
│ Привілейовані контейнери │
│ ├── privileged: true │
│ ├── Повний доступ до пристроїв хоста │
│ └── Може монтувати файлову систему хоста, модулі ядра │
│ │
│ Простори імен хоста │
│ ├── hostPID: true - Бачити процеси хоста │
│ ├── hostNetwork: true - Використовувати мережу хоста │
│ └── hostIPC: true - Спільний IPC хоста │
│ │
│ Монтування шляхів хоста │
│ ├── Монтування чутливих шляхів (/, /etc, /var/run/...) │
│ └── Може читати/писати файлову систему хоста │
│ │
│ НА ОСНОВІ ВРАЗЛИВОСТЕЙ │
│ │
│ Вразливості runtime │
│ ├── CVE-2019-5736 (runc) │
│ └── CVE-2020-15257 (containerd) │
│ │
│ Вразливості ядра │
│ └── Підвищення привілеїв через експлойти ядра │
│ │
└─────────────────────────────────────────────────────────────┘

Найкращі практики безпеки вузлів

Розділ «Найкращі практики безпеки вузлів»

Зміцнення операційної системи

Розділ «Зміцнення операційної системи»
┌─────────────────────────────────────────────────────────────┐
│ ЗМІЦНЕННЯ ОС ВУЗЛА │
├─────────────────────────────────────────────────────────────┤
│ │
│ МІНІМІЗАЦІЯ ПОВЕРХНІ АТАКИ │
│ ├── Використовуйте мінімальну ОС (Bottlerocket, Talos) │
│ ├── Видаліть непотрібні пакети │
│ ├── Вимкніть непотрібні сервіси │
│ └── Використовуйте незмінну інфраструктуру │
│ │
│ ТРИМАЙТЕ ОНОВЛЕНИМ │
│ ├── Регулярні патчі безпеки │
│ ├── Автоматизоване оновлення де можливо │
│ └── Оновлення середовища виконання контейнерів │
│ │
│ ОБМЕЖТЕ ДОСТУП │
│ ├── Вимкніть SSH якщо можливо │
│ ├── Якщо SSH потрібен, лише автентифікація ключем │
│ ├── Використовуйте bastion-хости │
│ └── Аудит всього доступу до вузлів │
│ │
│ УВІМКНІТЬ ФУНКЦІЇ БЕЗПЕКИ │
│ ├── SELinux або AppArmor у режимі впровадження │
│ ├── Профіль seccomp за замовчуванням │
│ └── Зміцнення параметрів ядра │
│ │
└─────────────────────────────────────────────────────────────┘

Мінімальні операційні системи для вузлів

Розділ «Мінімальні операційні системи для вузлів»
ОСОпис
BottlerocketРозроблена AWS, спеціально для контейнерів
Flatcar Container LinuxНаступник CoreOS, мінімальна та незмінна
TalosКерована через API, без SSH, повністю незмінна
Container-Optimized OSМінімальний хост для контейнерів від Google

  • Порт kubelet лише для читання (10255) історично використовувався для налагодження, але розкривав інформацію про поди без автентифікації. Тепер вимкнений за замовчуванням, але варто перевіряти у старих кластерах.

  • Вразливості втечі з контейнера регулярно виявляються. CVE-2019-5736 в runc дозволяв контейнеру перезаписати бінарний файл runc хоста та отримати root-доступ.

  • gVisor було розроблено Google спеціально тому, що їм потрібна була сильніша ізоляція для багатоорендного сервісу Cloud Run.

  • Режим авторизації Node було впроваджено в Kubernetes 1.7 спеціально для обмеження радіусу ураження скомпрометованого вузла.


ПомилкаЧому це шкодитьРішення
Увімкнена анонімна автентифікація kubeletБудь-хто може керувати подами на вузліВимкнути анонімну автентифікацію
Відкритий порт лише для читанняРозкриття інформації про подиВстановити readOnlyPort=0
Не оновлювати вузлиВідомі вразливості можна використатиРегулярний процес оновлення
SSH-ключі розкидані скрізьСкладно відкликати, надмірні привілеїBastion-хост, логування аудиту
Стандартний runtime для ненадійних навантаженьМожлива втеча з контейнераІзольований runtime

  1. Яка роль kubelet у безпеці вузла?

    Відповідь kubelet - це основний агент вузла. Він керує життєвим циклом подів, комунікує з API server та контролює операції контейнерів. Його безпека критична, оскільки він може виконувати команди у будь-якому контейнері на вузлі.
  2. Чому --read-only-port має бути встановлений у 0?

    Відповідь Порт лише для читання (10255) розкриває інформацію про поди та вузол без автентифікації. Його вимкнення (встановлення 0) запобігає розкриттю інформації, яка може допомогти атакуючим у розвідці.
  3. Які механізми Linux забезпечують ізоляцію контейнерів?

    Відповідь Namespaces (ізоляція процесів, мережі, монтування тощо), cgroups (обмеження ресурсів) та модулі безпеки (seccomp, AppArmor, SELinux для контролю системних викликів та доступу).
  4. Що таке ізольований runtime та коли його використовувати?

    Відповідь Ізольовані runtime (gVisor, Kata Containers) забезпечують сильнішу ізоляцію, ніж стандартні. Використовуйте їх для ненадійних навантажень, багатоорендних середовищ або обробки чутливих даних, де ризик втечі з контейнера має бути мінімізований.
  5. Як режим авторизації Node обмежує радіус ураження?

    Відповідь Режим авторизації Node обмежує облікові дані kubelet доступом лише до ресурсів подів, запланованих на цьому вузлі. При компрометації вузла атакуючий не може використати його облікові дані для доступу до секретів або подів на інших вузлах.

Практична вправа: Оцінка безпеки вузла

Розділ «Практична вправа: Оцінка безпеки вузла»

Сценарій: Перегляньте конфігурацію kubelet та визначте проблеми безпеки:

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
anonymous:
enabled: true
webhook:
enabled: false
authorization:
mode: AlwaysAllow
readOnlyPort: 10255
protectKernelDefaults: false
Проблеми безпеки
  1. anonymous.enabled: true - Дозволяє неавтентифікований доступ. Має бути false.
  2. webhook.enabled: false - Вимкнений webhook автентифікації. Має бути true.
  3. authorization.mode: AlwaysAllow - Без перевірки авторизації. Має бути Webhook.
  4. readOnlyPort: 10255 - Увімкнений порт лише для читання. Має бути 0.
  5. protectKernelDefaults: false - Не перевіряє параметри ядра. Має бути true.

Безпека вузлів включає кілька рівнів:

КомпонентКлючові контролі безпеки
kubeletВимкнути анонімну автентифікацію, webhook-авторизація, вимкнути порт для читання
Середовище виконанняОновлювати, seccomp/AppArmor, розглянути ізольовані runtime
ОСМінімальні образи, регулярні патчі, незмінна інфраструктура
ДоступОбмежити SSH, bastion-хости, аудит доступу

Модуль 2.3: Мережева безпека - Плагіни CNI, безпека service mesh та мережеві контролі.