Модуль 3.6: Основи безпеки (теорія)
- Складність:
[QUICK]— лише основи - Час на проходження: 35–40 хвилин
- Передумови: Модулі 3.1–3.5 (Хмарно-нативна архітектура)
- Цільова версія Kubernetes: Kubernetes 1.35+
Результати навчання
Розділ «Результати навчання»Після завершення цього модуля ви зможете застосовувати трибар’єрну модель безпеки до реалістичних оглядів дизайну Kubernetes та сортування інцидентів:
- Діагностувати збої ідентифікації та доступу, простежуючи автентифікацію, авторизацію, контроль допуску, суб’єкти RBAC, ролі та прив’язки.
- Спроєктувати модель ServiceAccount і RoleBinding із найменшими привілеями для робочого навантаження в межах простору імен.
- Оцінити ризик довіри до образу, порівнюючи змінні теги, незмінні дайджести, результати сканування та сигнали походження.
- Впровадити рішення щодо стримування під час виконання, обираючи відповідні Pod Security Standards та NetworkPolicies.
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»Найпоширеніші вторгнення в Kubernetes — це не кінематографічні історії про вразливості нульового дня з власними ланцюжками експлойтів. Це звичайні відкриті площини управління: адміністративний дашборд, доступний з інтернету; API kubelet без автентифікації; залишений відкритим порт etcd під час поспішної міграції. Класичний приклад 2018 року у великій автомобільній компанії задокументовано в модулі безпеки GUI для CKS — щойно зловмисники дісталися дашборда, їм не знадобився складний експлойт; вони використали кластер для запуску майнінгових навантажень і приховали активність, тримаючи споживання ресурсів достатньо низьким, щоб уникнути очевидних сигналів тривоги. Kubernetes може бути потужним і добре спроєктованим, але все одно зазнати поразки через один-єдиний відсутній контроль доступу.
Той самий патерн з’являється в багатьох інцидентах Kubernetes, тому що кластери будуються з кількох рішень щодо безпеки, які виглядають нешкідливими поодинці. Стандартний ServiceAccount здається зручним, доки кожен Под не успадкує токен, який йому не потрібен. Широка ClusterRoleBinding здається швидким способом розблокувати розгортання, доки скомпрометоване CI-завдання не зможе читати Secret’и по всьому кластеру. Знайомий тег образу здається стабільним, доки тег не зміститься, і робоче навантаження вже не відповідатиме програмному забезпеченню, що пройшло перевірку. Основи безпеки не є базовими через те, що вони прості; вони є базовими через те, що кожен контроль вищого рівня залежить від них.
Цей модуль будує ментальну модель, що лежить в основі безпеки Kubernetes, а не перетворює вас на кандидата CKS за один урок. Ви потренуєтеся читати дизайн кластера так, як оператор читає план будівлі: хто може увійти, що вони можуть принести з собою і якої шкоди вони можуть завдати, коли щось піде не так. Мета — не запам’ятати кожне поле в кожній політиці. Мета — діагностувати, до якого бар’єра належить збій, порівняти доступні контролі та зробити обґрунтоване перше покращення, перш ніж система стане складнішою.
У цьому курсі для kubectl використовується аліас k. Якщо ви виконуєте кроки в лабораторії, визначте його у вашій оболонці:
alias k=kubectlТри бар’єри: аналогія з безпекою будівлі
Розділ «Три бар’єри: аналогія з безпекою будівлі»Безпеку Kubernetes легше осмислити, коли ви перестаєте сприймати її як одну величезну функцію під назвою «безпека» і починаєте розглядати її як послідовність бар’єрів. Безпечна офісна будівля не покладається на одного охоронця, який вирішує всі проблеми. Вона перевіряє ідентичність біля дверей, оглядає те, що люди вносять усередину, і все одно обмежує те, до чого може дістатися відвідувач, якщо він пройшов повз вестибюль. Кластер Kubernetes потребує такої ж багаторівневої позиції, тому що жоден окремий контроль не може відповісти на кожне запитання.
ТРИ БАР'ЄРИ БЕЗПЕКИ
ВИ ──► БАР'ЄР 1 ──► БАР'ЄР 2 ──► БАР'ЄР 3 ──► ВСЕРЕДИНІ Перепустка Огляд сумки Ремінь безпеки
┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │ БАР'ЄР 1: │ │ БАР'ЄР 2: │ │ БАР'ЄР 3: │ │ ПЕРЕПУСТКА │ │ ОГЛЯД СУМКИ │ │ РЕМІНЬ БЕЗПЕКИ │ │ │ │ │ │ │ │ "Хто ви?" │ │ "Що ви │ │ "Що ви можете │ │ "До чого ви │ │ вносите?" │ │ робити, коли │ │ маєте доступ?" │ │ │ │ ви всередині?" │ │ │ │ │ │ │ │ K8s: API Auth │ │ K8s: довіра до │ │ K8s: Pod │ │ та RBAC │ │ образу, скани, │ │ Security, │ │ │ │ походження │ │ NetworkPolicy │ └────────────────┘ └────────────────┘ └────────────────┘Бар’єр 1 — це ідентичність та доступ. Kubernetes спершу має знати, хто робить запит, а потім має вирішити, чи може ця ідентичність виконати запитувану дію над запитуваним ресурсом. Саме тут поєднуються автентифікація, авторизація, контроль допуску та RBAC. Коли цей бар’єр дає збій, кластер часто надає особі, інструменту чи робочому навантаженню більше доступу до API, ніж їм потрібно, що перетворює невеликий витік облікових даних на широку проблему площини управління.
Бар’єр 2 — це довіра до образу. Образ контейнера — це пакет програмного забезпечення, який Kubernetes запускатиме, але Kubernetes автоматично не знає, чи цей пакет походить із надійної збірки, чи містить відомі вразливі бібліотеки, чи все ще відповідає образу, який пройшов тестування минулого тижня. Аналогія з оглядом сумки корисна, тому що ризик потрапляє всередину до того, як робоче навантаження запуститься. Щойно скомпрометований образ допускається до кластера, Pod Security та NetworkPolicy можуть зменшити шкоду, але вони не можуть зробити програмне забезпечення надійним заднім числом.
Бар’єр 3 — це стримування під час виконання. Навіть добре автентифіковані користувачі можуть розгортати вразливі застосунки, і навіть добре відскановані образи можуть містити невідомі дефекти. Контролі під час виконання припускають, що зрештою щось зазнає збою, і запитують, скільки залишається радіуса ураження. Pod Security Standards обмежують небезпечні інтеграції з Linux і хостом, тоді як NetworkPolicies зменшують здатність одного скомпрометованого Пода сканувати чи викликати кожен внутрішній сервіс. Глибокоешелонований захист означає, що кожен бар’єр цінний сам по собі та сильніший, коли присутні два інші.
Зупиніться та спрогнозуйте: уявіть робоче навантаження, яке використовує виділений ServiceAccount, образ, прив’язаний за дайджестом, і специфікацію Пода, яка встановлює privileged: true. Який бар’єр сильний, який слабкий і який інцидент усе ще міг би статися, якщо застосунок експлуатують? Запишіть свою відповідь, перш ніж продовжити, бо ця звичка віднесення знахідки до конкретного бар’єра — найпростіший спосіб уникнути розпливчастих розмов про безпеку.
Бар’єр 1: Ідентичність, запити до API та RBAC
Розділ «Бар’єр 1: Ідентичність, запити до API та RBAC»Кожне змістовне обговорення безпеки Kubernetes зрештою повертається до API-сервера. Користувачі створюють Деплойменти через нього, контролери узгоджують бажаний стан через нього, Поди можуть звертатися до нього через токени ServiceAccount, а плагіни допуску перевіряють об’єкти, перш ніж вони будуть збережені. Це означає, що перше питання безпеки кластера — не «Який контейнер запущено?», а «Яка ідентичність просить API-сервер щось зробити?». Якщо ви можете точно відповісти на це питання, багато контролів безпеки Kubernetes стає легше порівнювати.
Життєвий цикл запиту до API Kubernetes має три основні етапи. Автентифікація запитує, хто є викликачем, зазвичай через клієнтський сертифікат, токен-носій, вебхук або зовнішнього провайдера ідентичності, такого як OIDC. Авторизація запитує, чи може цей автентифікований викликач виконати дієслово, таке як get, create чи delete, над ресурсом, таким як Поди, Secret’и чи Деплойменти. Контроль допуску запускається після авторизації та перевіряє об’єкт, який створюється або змінюється, що дозволяє кластеру відхилити ризикований Под навіть тоді, коли користувач загалом має право створювати Поди.
Ця відмінність важлива, тому що кожен збій потребує іншого виправлення. Якщо розробник отримує помилку автентифікації, надання RoleBinding не допоможе, бо Kubernetes усе ще не довіряє ідентичності. Якщо розробник автентифікований, але отримує відповідь «заборонено», ймовірна проблема — авторизація, а не допуск. Якщо розробник може створювати звичайні Поди, але API відхиляє той, що використовує hostNetwork: true, RBAC може працювати точно так, як налаштовано, тоді як допуск блокує небезпечне навантаження. Хороша діагностика починається з називання рівня, який сказав «ні».
Наведена далі діаграма RBAC з оригінального уроку варта збереження, бо вона вловлює всю взаємозалежність авторизації на одній картинці. Суб’єкт — це «хто», роль — це «що може робити», а прив’язка — це клей, що з’єднує ці двоє. Частина, яку новачки в Kubernetes часто пропускають, — це область дії: Role та RoleBinding живуть у просторі імен, тоді як ClusterRole та ClusterRoleBinding можуть застосовуватися в межах усього кластера. Вибір ширшого об’єкта через те, що це зручно, — один із найшвидших способів зробити майбутній інцидент більшим, ніж він мав бути.
RBAC FLOW
SUBJECT BINDING ROLE RESOURCE (who) (glue) (permissions) (what)
┌──────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │ User │ │ │ │ Role │ │ Pods │ │ Group │───►│ RoleBinding │───►│ (namespace) │───►│ Secrets │ │ Service │ │ or Cluster │ │ or Cluster │ │ ConfigMaps│ │ Account │ │ RoleBinding │ │ Role (global)│ │ Deploys │ └──────────┘ └──────────────┘ └──────────────┘ └──────────┘
"Who" "connects" "can do what" "to which who to what things"ServiceAccount’и заслуговують на особливу увагу, тому що вони є ідентичностями робочих навантажень. Інженер-людина зазвичай автентифікується через kubeconfig, але Под, якому потрібно звернутися до API-сервера, використовує токен ServiceAccount. Kubernetes створює default ServiceAccount у кожному просторі імен, і Поди використовують його, доки специфікація Пода не назве інший ServiceAccount. Така стандартна поведінка зручна для лабораторії та ризикована у виробничому середовищі, бо вона робить ідентичність неявною. Безпечніший дизайн називає виділений ServiceAccount для кожного робочого навантаження та надає йому лише ті дієслова й ресурси, які робочому навантаженню справді потрібні.
Цей мінімальний приклад Role і RoleBinding надає доступ лише для читання до ConfigMap’ів та Secret’ів в одному просторі імен, а потім прикріплює ці дозволи до ServiceAccount на ім’я app. YAML навмисно невеликий, бо мета — побачити форму взаємозв’язку, а не скопіювати виробничу політику. Зверніть увагу, що роль перелічує дієслова явно, а не використовує символ підстановки, і зверніть увагу, що RoleBinding посилається на Role, а не на ClusterRole. Ці деталі нудні в найкращому з можливих сенсів: вони тримають поверхню авторизації вузькою.
# Minimal Role + Binding example (namespace-scoped)kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata: name: read-configrules:- apiGroups: [""] resources: ["configmaps","secrets"] verbs: ["get","list"]---kind: RoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata: name: bind-read-configsubjects:- kind: ServiceAccount name: approleRef: kind: Role name: read-config apiGroup: rbac.authorization.k8s.ioВи можете перевірити рішення RBAC, не вгадуючи, поставивши API-серверу те саме питання авторизації, на яке він відповідав би під час запиту. У реальному кластері k auth can-i — одна з найбезпечніших перших команд, тому що вона нічого не змінює; вона просто запитує, чи може суб’єкт виконати дієслово над ресурсом. Наведений нижче приклад не замінює перегляд YAML, але він дає оператору швидкий спосіб підтвердити, чи поводиться політика так, як стверджує дизайн.
k auth can-i get secrets --as=system:serviceaccount:default:appk auth can-i delete pods --as=system:serviceaccount:default:appПринцип найменших привілеїв легко сформулювати та важко практикувати, бо інженерні команди природно оптимізують швидкість під тиском постачання. Конвеєр, який може робити все, розблоковуватиме кожен реліз, аж до того дня, коли його токен витече. Група розробників із правами на весь кластер уникатиме звернень до служби підтримки, аж до того дня, коли хтось видалить ресурси за межами свого простору імен. Найменші привілеї змушують поставити інше питання: який найменший набір дій усе ще дозволяє цій ідентичності виконувати свою роботу, і як ми помітимо, коли ця робота зміниться?
Перш ніж запускати це в реальному кластері, який результат ви очікуєте? Якщо ServiceAccount має лише Role, показану вище, він повинен мати змогу читати Secret’и у своєму просторі імен, але не повинен мати змоги видаляти Поди. Якщо ваш прогноз і вивід команди не збігаються, не розширюйте політику одразу. Спершу перевірте простір імен, ім’я суб’єкта, область дії прив’язки та чи не надає інша прив’язка дозволів, про існування яких ви забули.
Гіпотетичний сценарій: платформенна команда виявляє, що внутрішній інструмент розгортання має cluster-admin, бо ранньому прототипу потрібно було створювати простори імен, і ніхто не переглянув цю прив’язку. За кілька місяців інструмент лише оновлював Деплойменти у двох просторах імен, але стара прив’язка залишилася. Коли команда змоделювала скомпрометований токен конвеєра, токен міг читати Secret’и, патчити вебхуки допуску та видаляти робочі навантаження по всьому кластеру. Виправлення не було екзотичним: винести створення просторів імен в окремий контрольований адміністративний робочий процес, надати конвеєру Role у межах простору імен для оновлень розгортань та регулярно проводити аудит решти ClusterRoleBinding.
Бар’єр 2: Довіра до образу, теги, сканування та походження
Розділ «Бар’єр 2: Довіра до образу, теги, сканування та походження»Kubernetes планує контейнери, але він не доводить магічним чином, що образ контейнера — саме той, який ваша команда мала намір запустити. Посилання на образ виглядає як невеликий рядок у маніфесті, проте цей рядок з’єднує ваш кластер із реєстром, конвеєром збірки, базовою операційною системою, залежностями застосунку та історією патчів. Якщо ви ставитеся до цього рядка недбало, ви передаєте частину свого рішення щодо безпеки тому, хто чи що може змінити посилання в реєстрі.
Теги — це перша пастка, бо вони виглядають стабільними, поводячись при цьому як вказівники. Тег на кшталт nginx:1.25 чи myapp:production можна перемістити на інший образ після вашої перевірки. Така мінливість корисна під час розробки, бо люди легше запам’ятовують назви, ніж хеші, але вона послаблює відтворюваність у виробничому середовищі. Два Поди, створені з одного маніфесту в різний час, можуть завантажити різний вміст образу, якщо тег зміниться, а локальний кеш вузла ще не має старого образу.
TAG (mutable -- can change) nginx:1.25
DIGEST (immutable -- content-addressed) nginx@sha256:6a5db2a1c89e0deaf...
If a single byte changes, the digest changes.Tags can be re-pointed. Digests cannot be faked.Дайджест образу — це ідентифікатор, адресований за вмістом, що означає, що посилання змінюється, коли змінюється вміст образу. Прив’язка виробничих робочих навантажень за дайджестом дає тим, хто реагує на інциденти, та інженерам релізів точну відповідь на питання «що запущено?». Це також створює реальний компроміс щодо обслуговування. Прив’язка за дайджестом не завантажить автоматично пропатчений образ лише тому, що тег змістився, тому організації потрібна автоматизація, яка оновлює дайджести, запускає тести та відкриває придатні для перегляду зміни. Безпека покращується, коли незмінність та автоматизація оновлень ідуть пліч-о-пліч.
Сканування образу відповідає на інше питання: які відомі вразливості чи ризиковані пакети існують усередині цього образу? Сканери зазвичай перевіряють шари образу, ідентифікують пакети та мовні залежності й порівнюють версії з даними про вразливості. Результат — не магічна позначка «безпечний» чи «небезпечний». Це доказ для прийняття рішення. Критична вразливість у невикористовуваному пакеті все одно може потребувати очищення, тоді як віддалено експлуатована вада в робочому шляху застосунку може заблокувати реліз, доки базовий образ або залежність не буде пропатчено.
Походження запитує, звідки взявся образ і чи можна довіряти процесу збірки. Інструменти підпису, такі як Sigstore cosign, можуть прикріплювати криптографічні підписи та атестації до образів, дозволяючи політиці кластера чи процесу релізу вимагати, щоб образи походили з відомого конвеєра. На рівні KCNA вам не потрібно запам’ятовувати кожну команду підпису. Вам потрібна концепція: сканування каже вам, що всередині, тоді як походження каже вам, хто його зібрав і чи відповідає шлях збірки вашій політиці довіри.
Бар’єр огляду сумки особливо важливий, бо маніфести Kubernetes часто рухаються швидше, ніж огляд безпеки. Команда може скопіювати публічний образ у прототип, а потім просунути той самий маніфест у staging та production, бо «він спрацював». Інша команда може покладатися на змінний внутрішній тег, бо її система розгортання була побудована до того, як прив’язка за дайджестом стала поширеною. Жодна команда не є недбалою в моральному сенсі; вони відчувають звичайний тиск постачання. Дизайн безпеки має зробити безпечніший шлях достатньо зручним, щоб швидкість не завжди перемагала його.
Який підхід ви б обрали тут і чому? Для виробничого платіжного API порівняйте три варіанти: публічний образ за тегом, внутрішній образ за тегом після сканування або внутрішній образ за дайджестом із перевіркою підпису. Останній варіант має більше операційного механізму, але він дає вам чіткіший ланцюжок від джерела до виконання. Для одноразового локального демо цей додатковий механізм може бути зайвим; для чутливого сервісу це різниця між сподіванням і перевіркою.
Ось перевірений спосіб оцінити посилання на образ під час огляду. По-перше, запитайте, чи походить образ із реєстру, якому довіряє ваша організація. По-друге, запитайте, чи є посилання незмінним для виробничого середовища. По-третє, запитайте, чи відбулося сканування на вразливості достатньо близько до розгортання, щоб дані були корисними. По-четверте, запитайте, чи можна простежити образ назад до контрольованого конвеєра збірки. Якщо відповідь на будь-яке з цих питань — «припускаємо, що так», ви знайшли прогалину, яку треба закрити.
Реалістичний ракурс реагування на інциденти показує, чому це важливо. Припустімо, команда повідомляє, що Под перезапустився і тепер поводиться інакше, але Деплоймент усе ще каже myapp:production. Без дайджеста вам доведеться перевіряти кеші вузлів, історію реєстру, логи CI та час розгортання, щоб реконструювати, які саме байти були запущені. З дайджестом сам маніфест записує точний вміст. Це не вирішує інцидент, але прибирає цілий клас невизначеності, доки всі вже перебувають під тиском.
Бар’єр 3: Безпека Подів та сегментація мережі
Розділ «Бар’єр 3: Безпека Подів та сегментація мережі»Стримування під час виконання починається з незручного припущення: одне з ваших робочих навантажень зрештою буде вразливим, неправильно налаштованим або обманом змушеним зробити те, чого не повинно. Тому безпечний кластер намагається зменшити дозволи та досяжність кожного робочого навантаження до того, як станеться компрометація. Pod Security Standards зосереджуються на тому, що Под може зробити з межею вузла та ядра. NetworkPolicies зосереджуються на тому, чого Под може досягти через мережу. Разом вони перетворюють один експлуатований застосунок із проблеми масштабу всього кластера на менше розслідування.
Багато образів контейнерів запускаються від імені root усередині контейнера, якщо автор образу чи специфікація Пода не вказують інакше. Root усередині контейнера не є автоматично root на вузлі, але він стає набагато небезпечнішим у поєднанні з монтуваннями hostPath, додатковими можливостями Linux, привілейованим режимом, мережею хоста, доступом до PID хоста чи файловими системами хоста з правом запису. Kubernetes дає вам словник, щоб заборонити ці комбінації, перш ніж вони досягнуть вузла. Важливий урок полягає в тому, що безпека під час виконання — це не один прапорець; це набір рішень, які зменшують корисність експлойта.
Мережа хоста небезпечна зі схожих причин. Под, що використовує hostNetwork: true, ділить мережевий простір імен вузла, що дозволяє йому прив’язувати порти на вузлі та взаємодіяти з трафіком у спосіб, який звичайна мережа Подів не дозволила б. Деякі компоненти інфраструктури справді потребують доступу на рівні хоста, особливо мережеві агенти та системне програмне забезпечення рівня вузла. Більшість застосункових робочих навантажень — ні. Коли звичайний вебзастосунок просить мережу хоста, правильна перша реакція — не «звісно»; це «яку саме можливість рівня вузла ви намагаєтеся використати?».
Kubernetes визначає три Pod Security Standards як іменовані рівні політики. Ці рівні забезпечуються вбудованим контролером Pod Security Admission, коли простори імен позначено для поведінки enforce (примус), audit (аудит) чи warn (попередження). Мітки pod-security.kubernetes.io/enforce, warn та audit можна встановлювати незалежно — наприклад, warn: restricted виводить порушення, не блокуючи робочі навантаження, доки команда виправляє образи, а потім enforce: restricted застосовується, щойно сумісність доведено.
| Рівень | Що дозволяє | Сценарій використання |
|---|---|---|
| Privileged | Усе. Без обмежень. | Інфраструктура системного рівня (CNI, драйвери сховищ) |
| Baseline | Блокує найнебезпечніші налаштування (hostNetwork, привілейовані контейнери, hostPath), залишаючись широко сумісним | Робочі навантаження загального призначення з мінімальними змінами |
| Restricted | Вимагає запуску не від імені root, відкидає всі можливості (дозволено лише повернення NET_BIND_SERVICE), seccomp RuntimeDefault, обмежені типи томів, без підвищення привілеїв | Чутливі до безпеки та посилені робочі навантаження |
Baseline часто є практичним першим кроком для змішаного застосункового середовища, бо він блокує найочевидніші «постріли собі в ногу», не змушуючи негайно перезбирати кожен наявний образ. Restricted — кращий орієнтир для чутливих робочих навантажень, нових сервісів та команд, які контролюють свої Dockerfile. Компромісом є тертя для розробників. Застосунок, який записує тимчасові файли у свою кореневу файлову систему чи припускає, що може прив’язувати привілейовані порти, може зазнати збою під Restricted, доки команда не скоригує образ та конфігурацію виконання. Це тертя не є причиною уникати Restricted; це причина свідомо спланувати міграцію.
NetworkPolicies стосуються іншого стандартного стану. У Kubernetes Поди зазвичай можуть спілкуватися з іншими Подами, якщо політика не виокремлює їх та не обмежує трафік. Така відкрита мережа є дружньою для ранньої розробки та небезпечною для виробничого середовища. Скомпрометований фронтенд-Под не повинен автоматично діставатися бази даних, бекенду метрик та внутрішнього адміністративного інструменту лише через те, що вони ділять кластер. NetworkPolicies дозволяють вам описати дозволений трафік за мітками Подів, мітками просторів імен, портами та напрямком.
WITHOUT NetworkPolicy WITH NetworkPolicy
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ Web │────►│ DB │ │ Web │────►│ DB │ └─────┘ └─────┘ └─────┘ └─────┘ │ X │ │ (blocked) ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ Log │────►│ DB │ │ Log │ │ DB │ └─────┘ └─────┘ └─────┘ └─────┘
Everyone can reach Only Web can reach everything reach DBПозиція «заборонено за замовчуванням» (default-deny) — це поширений безпечний патерн. Спершу ви створюєте політику, яка виокремлює Поди та забороняє вхідний (ingress) чи вихідний (egress) трафік за замовчуванням, а потім додаєте вузькі дозвільні політики для трафіку, який застосунку справді потрібен. Ця модель відчувається повільнішою першого разу, бо командам доводиться називати залежності, які раніше були неявними. Це водночас і перевага. Перелік залежностей стає придатним для перегляду, тестування та значно легшим для осмислення під час інциденту.
Зупиніться та подумайте: за замовчуванням кожен Под у багатьох кластерах Kubernetes може спілкуватися з кожним іншим Подом. Якщо зловмисник компрометує один Под у просторі імен frontend, до яких ресурсів він міг би дістатися без наявних NetworkPolicies? Хороша відповідь включає бази даних, адміністративні дашборди, внутрішні API та, можливо, API-сервер Kubernetes, якщо Под також має корисний токен ServiceAccount.
Наведений нижче приклад показує просту політику заборони вхідного трафіку за замовчуванням. Вона навмисно невелика, щоб ви могли зосередитися на ідеї: виокремити Поди в поточному просторі імен та не дозволяти жодних правил вхідного трафіку. У реальному застосунку ви б додали другу політику, яка дозволяє трафік від фронтенд-Подів за допомогою міток namespaceSelector та podSelector на конкретних портах, яких потребує сервіс. Поведінка NetworkPolicy залежить від плагіна CNI, який її реалізує — перевірте підтримку у вибраному вами мережевому рівні, перш ніж покладатися на політики у виробничому середовищі. Calico, Cilium та інші CNI реалізують NetworkPolicy, але стандартний kubenet чи деякі конфігурації керованих кластерів можуть не застосовувати правила, доки ви не ввімкнете сумісний CNI.
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-deny-ingress namespace: backendspec: podSelector: {} policyTypes: - IngressПрактична історія стримування часто починається з невеликої помилки в застосунку. Уявіть, що фронтенд-сервіс має ваду підробки запиту на стороні сервера (SSRF), яка дозволяє зловмиснику робити вихідні HTTP-виклики зсередини Пода. Без NetworkPolicies зловмисник може сканувати DNS-імена кластера, викликати внутрішні сервіси та шукати кінцеві точки метаданих чи адміністративні інструменти. З обмеженнями вихідного трафіку та політиками вхідного трафіку для простору імен та сама помилка все ще може бути серйозною, але карта зловмисника менша. Основи безпеки рідко роблять інциденти неможливими; вони роблять інциденти менш руйнівними.
Патерни та антипатерни
Розділ «Патерни та антипатерни»Патерни безпеки корисні лише тоді, коли вони прив’язані до причини, чому вони працюють. «Використовуйте найменші привілеї» — це гасло, доки команда не може описати ідентичність, ресурс, дієслово та простір імен, де потрібен дозвіл. «Скануйте образи» — розпливчасто, доки процес релізу не визначить, які вразливості блокують розгортання і хто відповідає за усунення. Наведені нижче патерни навмисно операційні, тому що безпека Kubernetes найчастіше зазнає невдачі в проміжку між хорошим принципом та відтворюваним робочим процесом.
| Патерн | Коли використовувати | Чому це працює | Аспект масштабування |
|---|---|---|---|
| Виділені ServiceAccount’и робочих навантажень | Будь-яке робоче навантаження, що звертається до API Kubernetes або працює в чутливому просторі імен | Це дає кожному робочому навантаженню окрему ідентичність та запобігає випадковому успадкуванню від default | Автоматизуйте створення ServiceAccount та Role у шаблонах, щоб команди не копіювали широкі прив’язки |
| Спочатку RBAC у межах простору імен | Простори імен застосунків, що належать командам, та CI-завдання, що розгортають у відомі простори імен | Це обмежує скомпрометовані облікові дані ділянкою, де насправді відбувається робота | Використовуйте окремі адміністративні робочі процеси для ресурсів масштабу кластера замість того, щоб дозволяти кожному конвеєру керувати ними |
| Образи, прив’язані за дайджестом, з автоматизованими оновленнями | Виробничі робочі навантаження та регульовані середовища | Це робить запущений образ відтворюваним, водночас дозволяючи переглянуті оновлення патчів | Використовуйте автоматизацію залежностей для оновлення дайджестів, запуску тестів та відкриття придатних для перегляду змін |
| Baseline всюди, Restricted там, де готові | Змішані кластери як зі старими, так і з новими застосунками | Це негайно блокує найнебезпечніші налаштування Подів, водночас створюючи шлях до сильнішого посилення | Використовуйте Pod Security Admission у режимі warn чи audit, перш ніж широко застосовувати Restricted |
| Заборона за замовчуванням плюс вузькі дозвільні політики | Простори імен, що містять бази даних, черги, площини управління чи адміністративні інструменти | Це перетворює неявну мережеву досяжність на явні залежності застосунку | Ретельно підтримуйте мітки, бо якість NetworkPolicy залежить від точних селекторів |
Антипатерни зазвичай починаються як скорочення шляху. Небезпечна частина не в тому, що команда робить один виняток під час надзвичайної ситуації; небезпечна частина в тому, що цей виняток стає невидимою інфраструктурою. Однотижнева прив’язка cluster-admin живе рік. Тимчасовий тег :latest стає механізмом виробничого релізу. Привілейований Под, доданий для усунення несправностей, стає частиною постійного розгортання. Виправлення — це не лише технічне очищення, а й звичка володіння: кожен виняток потребує причини, відповідального та дати перегляду.
| Антипатерн | Чому команди в це впадають | Краща альтернатива |
|---|---|---|
Прив’язка розробників чи конвеєрів до cluster-admin | Це негайно розблоковує кожну помилку дозволів та уникає вивчення області дії RBAC | Створюйте Role у межах простору імен для рутинної роботи та зберігайте cluster-admin для контрольованого аварійного доступу |
Використання default ServiceAccount’ів усюди | Специфікації Подів коротші, і ранні демо працюють без додаткового YAML | Називайте ServiceAccount’и, специфічні для робочого навантаження, та вимикайте монтування токена для Подів, що не звертаються до API |
| Довіра до тегів образів як до доказу релізу | Теги читабельні та відповідають людським назвам релізів | Записуйте назви релізів окремо та розгортайте незмінні дайджести в маніфестах |
| Примус Restricted до тестування застосунків | Орієнтир безпеки правильний, але старі образи не були для нього зібрані | Спершу запустіть режим warn чи audit, виправте образи, потім застосуйте Restricted за простором імен |
| Створення NetworkPolicies без дисципліни щодо міток | Політики начебто існують, але селектори збігаються із занадто великим чи занадто малим | Ставтеся до міток як до частини контракту безпеки та переглядайте їх разом із політикою |
Найефективніші команди поєднують патерни. Простір імен, який використовує виділені ServiceAccount’и, але не має NetworkPolicies, усе одно залишає скомпрометований застосунок вільним досліджувати мережу. Робоче навантаження, прив’язане за дайджестом, але запущене як привілейоване, усе одно перетворює ваду застосунку на проблему рівня вузла. Мережева політика заборони за замовчуванням із широким токеном ServiceAccount усе одно залишає API-сервер цінною ціллю. Трибар’єрна модель запобігає хибному відчуттю комфорту, бо вона змушує вас перевіряти ідентичність, ланцюг постачання та стримування під час виконання окремо.
Фреймворк прийняття рішень
Розділ «Фреймворк прийняття рішень»Коли ви переглядаєте робоче навантаження Kubernetes, починайте з питання, яке створює найбільший безпосередній радіус ураження: яку ідентичність використовує це робоче навантаження і що ця ідентичність може робити? Якщо Поду не потрібен API Kubernetes, вимкніть автоматичне монтування токена або переконайтеся, що ServiceAccount не має значущих дозволів. Якщо ж API йому потрібен, напишіть Role так, ніби вам доведеться пояснювати кожне дієслово тому, хто розслідує інцидент. Таке формулювання перетворює verbs: ["*"] зі зручності на непояснений ризик.
Далі перегляньте посилання на образ та докази збірки. Для простору імен розробки читабельний тег із внутрішнього реєстру може бути прийнятним, якщо простір імен має обмежений доступ, а робоче навантаження є одноразовим. Для виробничого середовища надавайте перевагу образу, прив’язаному за дайджестом, із надійного конвеєра збірки з результатами сканування та походженням. Рішення — не «теги завжди зло»; рішення полягає в тому, чи може середовище терпіти неоднозначність, яку вносять теги. Чутливі середовища зазвичай не можуть.
Потім перегляньте стримування під час виконання. Якщо робоче навантаження просить привілейований режим, мережу хоста, hostPath, PID хоста чи додаткові можливості, вимагайте конкретної технічної причини. Компонентам інфраструктури іноді потрібні ці повноваження, але звичайним застосунковим сервісам — рідко. Обирайте Baseline, коли вам швидко потрібна широка сумісність, та обирайте Restricted, коли застосунок може працювати не від імені root із вужчою файловою системою та моделлю можливостей. Використовуйте режими warn чи audit, щоб дізнатися, що зламається, перш ніж застосовувати суворіший рівень у межах простору імен.
Нарешті, перегляньте мережеву досяжність як карту залежностей застосунку. Запитайте, які Поди мають ініціювати трафік, які Поди мають його отримувати і які порти потрібні. Якщо команда не може відповісти, це не причина залишати мережу відкритою назавжди; це завдання з виявлення. Почніть із чутливих просторів імен, таких як бази даних, черги, бекенди спостережуваності та внутрішні адміністративні інструменти. Політика заборони за замовчуванням там приносить негайну цінність, бо ці цілі привабливі під час горизонтального переміщення.
| Питання огляду | Безпечніший стандарт | Використовуйте ширший варіант лише коли | Які докази вимагати |
|---|---|---|---|
| Який ServiceAccount має використовувати Под? | Виділений ServiceAccount із вузькою Role | Робоче навантаження справді потребує спільної ідентичності в контрольованому наборі Подів | Правила Role, область дії прив’язки та перевірки k auth can-i |
| Як має бути вказано образ? | Внутрішній образ, прив’язаний за дайджестом | Робоче навантаження — це одноразове демо розробки | Власність реєстру, результат сканування та автоматизація оновлень |
| Який рівень Pod Security підходить? | Baseline для сумісності, Restricted для чутливих сервісів | Под — це інфраструктура рівня вузла із задокументованою потребою | Мітки простору імен, вивід попереджень та відповідальний за виняток |
| Який мережевий трафік дозволено? | Заборона за замовчуванням плюс явні дозвільні правила | Простір імен тимчасовий та ізольований від чутливих цілей | Карта залежностей, мітки, порти та підтримка NetworkPolicy у CNI |
Цей фреймворк навмисно достатньо невеликий, щоб використовувати його під час огляду дизайну. Якщо запропоноване робоче навантаження проходить усі чотири рядки, воно не стає автоматично безпечним, але воно подолало поширені на рівні KCNA режими збою. Якщо воно провалює один рядок, трибар’єрна модель підказує вам, де зосередитися. Якщо воно провалює кілька рядків одразу, не приймайте одне широке виправлення на кшталт «ми будемо це моніторити». Моніторинг допомагає виявити проблему, але він не замінює межі ідентичності, довіру до образу чи стримування під час виконання.
Поєднання бар’єрів в оглядах
Розділ «Поєднання бар’єрів в оглядах»Хороший огляд безпеки Kubernetes звучить менше як судовий процес і більше як дисциплінований прохід системою. Почніть із читання маніфесту робочого навантаження та називання ідентичності. Якщо Под використовує default, запитайте, чи має ця ідентичність будь-які RoleBinding, чи є необхідним монтування токена і чи ділить інше робоче навантаження той самий простір імен. Потім прочитайте посилання на образ та запитайте, чи є точні байти відтворюваними. Лише після цього вам слід перевіряти привілейовані налаштування, інтеграцію з хостом та мережеву досяжність. Такий порядок корисний, бо він іде шляхом від дозволу API до постачання програмного забезпечення та радіуса ураження під час виконання.
Одна практична техніка огляду — написати одне речення на кожен бар’єр, перш ніж пропонувати будь-яке виправлення. Наприклад: «Ризик перепустки: Под аналітики використовує стандартний ServiceAccount простору імен, і ця ідентичність може переглядати Secret’и». «Ризик огляду сумки: образ використовує змінний тег релізу без дайджеста в маніфесті». «Ризик ременя безпеки: Под просить привілейований режим, а простір імен не має примусу Pod Security Admission». Ці речення змушують того, хто проводить огляд, бути конкретним. Вони також запобігають поширеній помилці, коли команда реагує на кожну знахідку одним і тим самим загальним контролем, таким як сканування, моніторинг чи документація.
Три бар’єри також допомагають вам встановити пріоритет усунення. Привілейований Под із токеном cluster-admin є терміновим, бо Бар’єр 1 та Бар’єр 3 дають збій разом, роблячи правдоподібним як зловживання API, так і зловживання рівнем вузла після компрометації. Образ, прив’язаний за дайджестом, що має одну вразливість середньої серйозності в невикористовуваному пакеті, усе одно може потребувати патча, але це інший рівень надзвичайності, якщо RBAC та стримування під час виконання сильні. Пріоритет — це не лише позначки серйозності зі сканера. Пріоритет — це поєднання експлуатованості, привілеїв, досяжності та здатності переходити від однієї межі до іншої.
Під час реагування на інциденти та сама модель стає інструментом для запитань. Щодо ідентичності запитайте, який токен ServiceAccount було змонтовано, які виклики API було зроблено і чи показують журнали аудиту заборонені спроби чи успішні читання чутливих ресурсів. Щодо довіри до образу запитайте, який дайджест було запущено, коли його зібрано, чи змінилося посилання в реєстрі і чи був конвеєр збірки частиною підозрюваної компрометації. Щодо стримування під час виконання запитайте, чи мав Под доступ до хоста, чи запускався він від імені root, яких просторів імен він міг досягти і які шляхи вихідного трафіку були відкриті. Ці запитання достатньо конкретні, щоб різні команди розслідували паралельно.
Ця модель також корисна під час навчання застосункових команд, бо вона уникає перетворення безпеки платформи на список непояснених заборон. Замість того щоб казати «ви не можете використовувати hostPath», поясніть, що hostPath перетинає межу ременя безпеки, надаючи контейнеру доступ до файлів вузла, яких звичайний код застосунку не повинен торкатися. Замість того щоб казати «ми вимагаємо дайджести», поясніть, що теги — це вказівники, а дайджести — це докази точного вмісту. Замість того щоб казати «вам потрібен інший ServiceAccount», поясніть, що спільна ідентичність унеможливлює надання одному робочому навантаженню дозволу без надання його кожному Поду, який ділить цей акаунт.
Є один останній компроміс, який варто тримати на оці: контролі, невидимі для розробників, легше прийняти, але контролі, які ніколи не розуміють, легше обійти. Шаблони просторів імен, політики допуску та автоматизація розгортання мають надавати безпечні стандарти, бо ніхто не хоче, щоб кожна команда власноруч створювала YAML безпеки з нуля. Водночас інженери повинні розуміти причину стандартів достатньо добре, щоб розпізнавати винятки. Знання безпеки на рівні KCNA — це словник для таких розмов. Він дозволяє новачку поставити правильне запитання, перш ніж кластер накопичить роки прихованого ризику.
Коли ви не впевнені, з чого почати, оберіть одне робоче навантаження та простежте його від початку до кінця. Назвіть ServiceAccount, перелічіть RoleBinding’и, перевірте посилання на образ, з’ясуйте, чи примушує простір імен рівень Pod Security, та визначте, які NetworkPolicies виокремлюють цей Под. Такий невеликий огляд корисніший за широку обіцянку безпеки, бо він дає конкретні докази. Він може виявити, що робоче навантаження вже досить добре стримане, або може виявити, що три незв’язані команди кожна припускала, що інша команда володіє тією самою межею. Будь-який результат є дієвим.
Основи безпеки також стають легшими, коли ви відокремлюєте запобігання від відновлення. RBAC, походження образу, Pod Security та NetworkPolicy — це запобіжні контролі, бо вони зменшують те, що може статися до початку інциденту. Журнали аудиту, історія реєстру, записи сканування та записи розгортань підтримують відновлення, бо вони допомагають реконструювати, що сталося, після появи підозри. Зрілий кластер потребує обох, але вони відповідають на різні питання. Якщо дизайн покладається лише на докази для відновлення, зловмисник може вже мати забагато простору для маневру. Якщо дизайн покладається лише на запобігання, команді може бути важко довести, що насправді сталося під час реальної події.
Іспит KCNA не проситиме вас побудувати повну корпоративну платформу безпеки, але він очікує, що ви розпізнаватимете ці взаємозв’язки. Secret, відкритий через надто широкий RBAC, — це проблема ідентичності та авторизації, навіть якщо образ ідеально відсканований. Змінний тег у виробничому середовищі — це проблема довіри до образу, навіть якщо Под працює не від імені root. База даних, доступна з кожного простору імен, — це проблема стримування під час виконання, навіть якщо застосункова команда використовує виділений ServiceAccount. Навичка полягає в тому, щоб точно класифікувати ризик, а потім обрати контроль, який змінює умову, замість того щоб просто звучати по-безпековому.
Ця звичка класифікації цінна за межами іспитів, бо вона покращує те, як команди спілкуються під тиском. Розпливчастий звіт на кшталт «кластер небезпечний» не дає оператору, з чого почати. Точний звіт на кшталт «цей простір імен не має NetworkPolicy, а база даних приймає трафік від незв’язаних Подів» вказує безпосередньо на придатну до тестування зміну. Чітка мова скорочує шлях від занепокоєння до усунення.
Чи знали ви?
Розділ «Чи знали ви?»- RBAC у Kubernetes став стабільним у Kubernetes 1.8, замінивши старіші патерни авторизації для більшості кластерів та зробивши зміни політики можливими через звичайні об’єкти API замість статичних файлів.
- Стандартний ServiceAccount існує в кожному просторі імен, і Поди використовують його, доки не названо інший ServiceAccount, тому неявна ідентичність робочого навантаження є реальною загрозою безпеці.
- Pod Security Policy було видалено в Kubernetes 1.25, і вбудований контролер Pod Security Admission тепер є стандартним нативним способом примусу Pod Security Standards.
- Один Под із
privileged: trueта доступом до хоста може підірвати ізоляцію вузла, тому політики Restricted відхиляють небезпечні налаштування простору імен хоста та можливостей.
Типові помилки
Розділ «Типові помилки»| Помилка | Чому це трапляється | Як це виправити |
|---|---|---|
Використання default ServiceAccount для всіх робочих навантажень | Команди пропускають проєктування ідентичності, бо Поди працюють без додаткового YAML, а потім кожне робоче навантаження успадковує будь-які дозволи, що їх має стандартна ідентичність | Створіть виділений ServiceAccount для кожного робочого навантаження та прив’яжіть лише ту Role у межах простору імен, яка йому потрібна |
Надання cluster-admin конвеєрам CI/CD | Широкі дозволи швидко розблоковують релізи, особливо коли конвеєр керує більш ніж одним типом ресурсів | Відокремте налаштування масштабу кластера від рутинного розгортання та надайте конвеєру явні дієслова на явних ресурсах |
Посилання на образи за тегом (:latest чи :v2) | Теги читабельні та зручні, тому команди помилково вважають їх незмінним доказом релізу | Використовуйте дайджести (@sha256:...) для виробничих розгортань та автоматизуйте переглянуті оновлення дайджестів |
| Запуск контейнерів від імені root | Базові образи часто стандартно запускаються від root, і застосункові команди можуть не помічати цього, доки не почнеться посилення | Збирайте образи, що працюють від імені користувача не-root, та встановлюйте runAsNonRoot: true, де це доречно |
| Відсутність NetworkPolicies у жодному просторі імен | Ранні кластери надають пріоритет зв’язності, і відкритий стандарт зберігається після появи виробничих даних | Застосуйте політику заборони вхідного трафіку за замовчуванням для кожного чутливого простору імен, потім дозволяйте конкретний трафік |
Використання символів підстановки в правилах RBAC (verbs: ["*"]) | Символи підстановки простіші, ніж з’ясування точних дієслів API, які потрібні інструменту | Перелічуйте кожне дієслово явно, наприклад get, list, watch, create та update |
| Примус Restricted без проходу для міграції | Команда обирає правильний орієнтир, але пропускає виявлення сумісності для наявних робочих навантажень | Спершу запустіть Pod Security Admission у режимі warn чи audit, виправте образи, потім примушуйте за простором імен |
Перевірка знань
Розділ «Перевірка знань»Питання 1: Ваша компанія використовує `myapp:production` як тег образу для всіх розгортань. Розробник пушить нову збірку в той самий тег. Який ризик безпеки це створює і як би ви його усунули?
Змінні теги означають, що вміст образу може змінитися без зміни посилання. Розгортання, що використовує myapp:production, може завантажити інший образ на кожному вузлі чи після перезапуску, потенційно запускаючи неперевірений або скомпрометований код. Це також ламає відтворюваність, бо ті, хто реагують на інциденти, не можуть визначити, який саме образ запущено, лише з маніфесту. Виправлення — посилатися на виробничі образи за їхнім адресованим за вмістом дайджестом та використовувати автоматизацію для оновлення цього дайджеста через перегляд, коли схвалено нову збірку.
Питання 2: Стажер розгорнув Под із `privileged: true`. Які ризики це створює і який контроль під час виконання має це вловити?
Привілейований контейнер отримує широкий доступ до можливостей Linux та операцій рівня хоста, яких звичайні застосункові Поди потребувати не повинні. Якщо зловмисник компрометує застосунок, привілейований режим може перетворити цю ваду застосунку на компрометацію вузла чи втечу з контейнера. Pod Security Admission, що примушує Baseline чи Restricted, має відхилити це для звичайних робочих навантажень, тоді як процес огляду має вимагати конкретної інфраструктурної причини для будь-якого винятку. Усунення полягає в тому, щоб прибрати привілейований режим та скоригувати застосунок для роботи в межах безпечнішого Pod Security Standard.
Питання 3: Команда створює одну ClusterRole з `resources: ["*"]` та `verbs: ["*"]`, а потім прив'язує її до всіх розробників через ClusterRoleBinding. Чому це проблема?
Це надає кожному розробнику повну адміністративну досяжність на ресурсах та просторах імен, включно зі здатністю читати Secret’и, видаляти робочі навантаження, змінювати RBAC та, можливо, ескалувати далі. Проблема не лише в тому, що дозволи широкі; вона в тому, що радіус ураження одного скомпрометованого облікового запису стає масштабу всього кластера. Кращий дизайн починається з Role у межах простору імен для рутинної роботи та резервує дозволи масштабу кластера для меншого операційного робочого процесу. Команда має перевірити нову політику за допомогою перевірок k auth can-i, перш ніж видаляти стару прив’язку.
Питання 4: Ваш кластер не має налаштованих NetworkPolicies. Под у просторі імен `frontend` скомпрометовано. Чого може досягти зловмисник?
Без NetworkPolicies мережа Kubernetes зазвичай достатньо відкрита, щоб зловмисник міг спробувати з’єднання з Подами в інших просторах імен, включно з бекенд-базами даних, внутрішніми API та інструментами моніторингу. Якщо Под також має корисний токен ServiceAccount, API-сервер Kubernetes може стати ще однією ціллю. Пом’якшення — створити політики заборони за замовчуванням у чутливих просторах імен, а потім додати вузькі дозвільні правила для потрібних потоків застосунку. Це не виправляє початкову компрометацію, але зменшує горизонтальне переміщення.
Питання 5: Аудит безпеки виявляє, що багато Подів у просторі імен `analytics` використовують `default` ServiceAccount, і цей ServiceAccount прив'язаний до ClusterRole, що надає `get` та `list` на Secret'ах у межах усього кластера через ClusterRoleBinding на ім'я `default-secret-reader`. Який радіус ураження і як би ви це усунули?
Радіус ураження серйозний, бо компрометація будь-якого Пода в analytics, що монтує цей токен, може відкрити Secret’и по всьому кластеру, а не лише в межах простору імен. Кожен простір імен має свій власний default ServiceAccount, але ClusterRoleBinding застосовується в межах усього кластера незалежно від того, у якому просторі імен живе суб’єкт. Негайне виправлення — прибрати чи звузити ClusterRoleBinding, щоб стандартний ServiceAccount більше не успадковував доступ до Secret’ів масштабу кластера. Тривале виправлення — створити виділені ServiceAccount’и для робочих навантажень, що потребують API, та не встановлювати значущих дозволів для тих, що не потребують. Для Подів, які ніколи не звертаються до API, вимкнення автоматичного монтування токена ще більше зменшує цінність компрометації.
Питання 6: Розробник успішно автентифікується та має Role RBAC, що дозволяє йому створювати Поди, але API-сервер відхиляє Под, що використовує `hostNetwork: true`. Порівняйте автентифікацію, авторизацію та контроль допуску в цьому сценарії. Який рівень заблокував запит?
Автентифікація вдалася, бо API-сервер розпізнав ідентичність розробника. Авторизація також вдалася, бо RBAC дозволив цій ідентичності створювати об’єкти Pod. Контроль допуску заблокував запит після перевірки вмісту специфікації Пода та виявлення налаштування, що порушило політику. Саме тому RBAC та допуск є взаємодоповнюючими: RBAC вирішує, чи можете ви отримати доступ до кінцевої точки, тоді як допуск вирішує, чи є цей конкретний об’єкт прийнятним.
Питання 7: Команда прив'язує образи за дайджестом, але розгортає кожне робоче навантаження з тим самим високопривілейованим ServiceAccount. Який бар'єр сильний, який слабкий і що їм слід виправити першочергово?
Бар’єр довіри до образу сильніший, бо прив’язка за дайджестом покращує відтворюваність та зменшує неоднозначність щодо запущеного програмного забезпечення. Бар’єр ідентичності слабкий, бо спільний високопривілейований ServiceAccount дає кожному робочому навантаженню однакову широку досяжність до API. Першим виправленням має бути розділення ідентичностей робочих навантажень та прив’язка Role у межах простору імен із явними дієсловами та ресурсами. Прив’язку за дайджестом слід зберегти, але вона не може компенсувати небезпечну ідентичність API.
Практична вправа
Розділ «Практична вправа»Ця вправа — це аудит дизайну безпеки, а не лабораторія зі зміни кластера. Це навмисно для теоретичного модуля KCNA: ви тренуєтеся класифікувати знахідки, обирати контролі та пояснювати причину кожного виправлення. Якщо у вас є одноразовий кластер Kubernetes 1.35+, ви можете виконати перевірки k auth can-i лише для читання з розділу про RBAC, але основну роботу тут можна виконати лише зі сценаріїв.
Розв’язаний приклад: застосування трьох бар’єрів
Розділ «Розв’язаний приклад: застосування трьох бар’єрів»Перш ніж спробувати вправу нижче, оцініть одну конфігурацію за допомогою фреймворку «Три бар’єри». Розробник надає фрагмент для нового внутрішнього інструмента аналітики: він використовує image: internal-registry/analytics:v2, називає serviceAccountName: default та встановлює securityContext: { privileged: true }. Цей єдиний фрагмент перетинає всі три бар’єри, бо посилання на образ змінне, ідентичність робочого навантаження неявна, а налаштування виконання небезпечне для звичайного застосунку.
Усунення також слід розділити за бар’єрами. Для Бар’єра 1 створіть виділений ServiceAccount analytics-sa з RBAC найменших привілеїв замість покладання на default. Для Бар’єра 2 розв’яжіть образ до незмінного дайджеста та переконайтеся, що образ відскановано в конвеєрі збірки чи релізу. Для Бар’єра 3 приберіть привілейований режим та позначте простір імен для Baseline чи Restricted Pod Security Admission після тестування сумісності. Це звичка, яку ви виробляєте: класифікувати знахідку, а потім обрати контроль, який насправді усуває цей клас ризику.
Ваша черга
Розділ «Ваша черга»Перегляньте наведені нижче сценарії. Для кожного визначте, який із трьох бар’єрів він переважно порушує, та запропонуйте конкретне виправлення конфігурації для його захисту. Деякі сценарії мають вторинний ризик, але оберіть спочатку основний бар’єр, щоб ваше усунення залишалося сфокусованим.
| # | Сценарій | Порушений бар’єр | Запропоноване виправлення |
|---|---|---|---|
| 1 | Розгортання вебзастосунку монтує кореневу файлову систему вузла за допомогою hostPath: /. | ? | ? |
| 2 | Конвеєр CI/CD використовує ServiceAccount, прив’язаний до ClusterRole з verbs: ["*"]. | ? | ? |
| 3 | Розгортання завантажує nginx:latest безпосередньо з Docker Hub для виробничого застосунку. | ? | ? |
| 4 | Усі Поди в просторі імен backend можуть вільно отримувати трафік від просторів імен frontend та testing. | ? | ? |
- Класифікуйте кожен сценарій як Перепустку, Огляд сумки чи Ремінь безпеки.
- Напишіть один конкретний контроль Kubernetes чи зміну маніфесту, що зменшила б ризик.
- Поясніть, чому ваше запропоноване виправлення усуває обраний вами бар’єр, а не інший.
- Визначте, яку знахідку ви б усунули першочергово під час огляду виробничого інциденту.
- Порівняйте свої відповіді з розв’язком та перегляньте будь-яку відповідь, що покладається на розпливчасту пораду.
Запропонований розв'язок
| # | Порушений бар’єр | Запропоноване виправлення |
|---|---|---|
| 1 | Ремінь безпеки (Бар’єр 3) | Приберіть монтування hostPath. Примусьте Baseline чи Restricted Pod Security Standard у просторі імен, щоб заблокувати доступ до файлової системи хоста, зменшуючи радіус ураження рівня хоста. |
| 2 | Перепустка (Бар’єр 1) | Приберіть дієслова-символи підстановки. Створіть Role у межах простору імен, що явно перелічує лише точні дієслова (наприклад, create, update, get) та ресурси (наприклад, deployments, services), які конвеєру насправді потрібні. |
| 3 | Огляд сумки (Бар’єр 2) | Змініть nginx:latest на конкретний дайджест образу (nginx@sha256:...). Переконайтеся, що образ завантажується з надійного, відсканованого внутрішнього реєстру, а не безпосередньо з Docker Hub. |
| 4 | Ремінь безпеки (Бар’єр 3) | Впровадьте NetworkPolicy заборони за замовчуванням у просторі імен backend. Потім створіть конкретну NetworkPolicy з namespaceSelector та podSelector, що дозволяє вхідний трафік лише від простору імен frontend на порт 443. |
Критерії успіху
Розділ «Критерії успіху»- Ви можете пояснити, чому автентифікація, авторизація та контроль допуску є окремими етапами безпеки API.
- Ви можете прочитати RoleBinding та визначити суб’єкт, посилання на роль та область дії простору імен.
- Ви можете обґрунтувати прив’язку за дайджестом, не вдаючи, що вона усуває потребу в автоматизації патчів.
- Ви можете обрати між Baseline та Restricted Pod Security Standards для реалістичного робочого навантаження.
- Ви можете описати, як політика заборони за замовчуванням NetworkPolicy зменшує горизонтальне переміщення.
Джерела
Розділ «Джерела»- Документація Kubernetes: Authentication
- Документація Kubernetes: Authorization
- Документація Kubernetes: Using RBAC Authorization
- Документація Kubernetes: Service Accounts
- Документація Kubernetes: Admission Controllers
- Документація Kubernetes: Pod Security Standards
- Документація Kubernetes: Pod Security Admission
- Документація Kubernetes: Network Policies
- Документація Kubernetes: Images
- Документація Kubernetes: Secrets
- Документація Kubernetes: Security Checklist
- Документація Sigstore cosign
Наступний модуль
Розділ «Наступний модуль»Перейдіть до Модуля 3.7: Спільнота та співпраця, щоб дізнатися, як управління відкритим кодом, SIG’и та екосистема CNCF формують розробку Kubernetes, бо технічні рішення щодо безпеки також формуються людьми та проєктними структурами, що підтримують хмарно-нативне програмне забезпечення.