Модуль 2.3: Мережева безпека
Складність:
[СЕРЕДНЯ]— основні знанняЧас на проходження: 35–40 хвилин
Передумови: Модуль 2.2: Безпека вузла
Цей модуль спирається на поведінку Kubernetes 1.35+ і використовує короткий псевдонім команди k замість kubectl. Якщо ви виконуєте приклади в лабораторному кластері, визначте псевдонім один раз у своїй оболонці командою alias k=kubectl, а потім послідовно вживайте коротшу форму, щоб команди збігалися з уроком.
Що ви зможете робити
Розділ «Що ви зможете робити»Після завершення цього модуля ви зможете застосовувати ці результати під час проєктних оглядів, лабораторної перевірки та розмов про реагування на інциденти, що стосуються мережевої відкритості Kubernetes:
- Оцінювати пласку мережеву модель Kubernetes та її наслідки для безпеки щодо латерального переміщення
- Проєктувати покриття NetworkPolicy, яке ізолює простори імен, робочі навантаження, вхідні та вихідні шляхи трафіку
- Діагностувати прогалини у застосуванні політик CNI, перш ніж покладатися на політику як на засіб контролю
- Впроваджувати mTLS сервісної мережі та ідентичність робочого навантаження як доповнення до політики рівнів L3 та L4
- Порівнювати мережеву політику, шифрування CNI та авторизацію сервісної мережі під час вибору дизайну з ешелонованим захистом
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»На початку 2018 року велика автомобільна компанія повідомила, що зловмисники зловжили відкритим дашбордом Kubernetes, щоб запустити навантаження з майнінгу криптовалюти у своєму хмарному акаунті. Публічні повідомлення зосередилися на видимій помилці, але глибший урок стосувався меж довіри: щойно зловмисник дістався керівної поверхні кластера, слабка сегментація перетворила єдиний плацдарм на значно ширший радіус ураження. Прямою ціною стала не лише марна витрата обчислювальних ресурсів; це був час на реагування на інцидент, відволікання інженерів, робота з ротації секретів та незручне запитання, яке кожна команда безпеки ставить після локалізації загрози: до чого ще могло дістатися те навантаження, поки воно працювало?
Kubernetes робить розподілені системи на вигляд охайними, бо Под може звернутися до імені сервісу, не переймаючись тим, на якому вузлі розташований ендпоінт. Ця зручність є навмисною, і саме вона є однією з причин операційної масштабованості платформи. Ціна для безпеки так само навмисна: типова мережа відкрита, доки ви не додасте засоби контролю, а простори імен є радше організаційними мітками, ніж пакетними фільтрами. Скомпрометований фронтенд, налагоджувальний контейнер, залишений із надто широкими правами, або вразливий внутрішній API можуть стати шляхом до баз даних, брокерів повідомлень, сервісів метаданих та ендпоінтів, суміжних із площиною управління, якщо в кластері немає продуманої мережевої політики.
Цей модуль навчає мережевої безпеки як інженерної задачі проєктування, а не як купи фрагментів YAML. Ви почнете з типової пласкої моделі, а потім додасте NetworkPolicy у спосіб, який робить залежності трафіку видимими, а не загадковими. Ви перевірите, чи насправді CNI застосовує політики, які ви пишете, бо об’єкт політики без площини даних, що його застосовує, — це лише документація. Нарешті, ви порівняєте мережеву політику з mTLS та авторизацією сервісної мережі, щоб вирішити, коли достатньо простої сегментації, а коли в дизайні має бути шифрування з урахуванням ідентичності.
Оцінка пласкої мережевої моделі
Розділ «Оцінка пласкої мережевої моделі»Мережа Kubernetes починається з корисної обіцянки: кожен Под отримує IP-адресу, кожен Под зазвичай може звернутися до будь-якого іншого Пода без трансляції мережевих адрес, а сервіси надають стабільні віртуальні імена для ендпоінтів, що змінюються. Ця модель усуває чимало прикладної рутини. Розробникам не потрібно жорстко прописувати адреси вузлів, балансувальники навантаження можуть спрямовувати трафік до Подів між вузлами, а поступові розгортання можуть міняти ендпоінти без зміни конфігурації клієнта. Модель є операційно елегантною, бо трактує кластер як єдину маршрутизовану тканину.
Проблема безпеки в тому, що зручність маршрутизації — це не те саме, що авторизація. Типово Под у просторі імен розробки може спробувати відкрити TCP-з’єднання до Пода у виробничому просторі імен, і сам Kubernetes не заблокує цей пакет лише через те, що простори імен різні. Якщо застосунок-отримувач приймає з’єднання, мережа кластера виконала свою типову роботу. Саме тому імена просторів імен, імена сервісів та мітки не є засобами контролю безпеки, доки компонент, що застосовує політики, не використає їх у рішенні про політику.
┌─────────────────────────────────────────────────────────────┐│ DEFAULT KUBERNETES NETWORKING │├─────────────────────────────────────────────────────────────┤│ ││ BY DEFAULT: ││ • All pods can communicate with all other pods ││ • No network isolation between namespaces ││ • Any pod can reach any service ││ • Pods can reach external networks ││ ││ ┌─────────────────────────────────────────────────────┐ ││ │ ALL PODS ←──────────────→ ALL PODS │ ││ │ │ ││ │ Pod A ───→ Pod B ───→ Pod C ───→ Pod D │ ││ │ ↑ │ │ ││ │ └─────────────────────────────────┘ │ ││ │ │ ││ │ No restrictions, full mesh connectivity │ ││ └─────────────────────────────────────────────────────┘ ││ ││ THIS IS DANGEROUS: ││ • Compromised pod can scan entire cluster ││ • Lateral movement is trivial ││ • No defense in depth ││ │└─────────────────────────────────────────────────────────────┘Уявіть пласку мережу як офісну будівлю, де в кожній кімнаті є двері, але на жодних дверях немає замків. Планування ефективне, і люди можуть швидко пересуватися, проте відвідувач, який зайшов до однієї кімнати, може посмикати кожну іншу ручку. Kubernetes чудово маркує кімнати, але самі лише мітки їх не замикають. NetworkPolicy — це система, яка починає перетворювати мітки на контрольовані двері, а ідентичність сервісної мережі може згодом вирішувати, чи справді людина за дверима є тим, ким себе видає.
Практичний огляд безпеки починається із запитання, які комунікації є бізнес-вимогами, а які — лише звичками. Фронтенд-Подам може бути потрібно звертатися до бекенд-Подів на порту 8080, бекенд-Подам — до бази даних на 5432, а кожному рівню — до DNS. Це зовсім інше твердження, ніж «усі Поди можуть звертатися до всіх Подів». Перше твердження можна переглянути, протестувати та відстежувати; друге — це порожній чек для будь-якого скомпрометованого навантаження.
Зупиніться та спрогнозуйте: якщо в кластері взагалі немає об’єктів NetworkPolicy, що, на вашу думку, станеться, коли тимчасовий діагностичний Под у default спробує під’єднатися до сервісу бази даних у production? Важлива деталь — не те, чи прийме база даних логін. Сам мережевий шлях відкритий, доки інший засіб контролю поза Kubernetes його не заблокує, тож спроба з’єднання досягає мережевого ендпоінта призначення.
Наслідком є латеральне переміщення. Зловмисникам рідко потрібні всі облікові дані кластера першого ж дня; їм потрібен шлях від першого слабкого навантаження до чогось ціннішого. Под із вразливим вебфреймворком може дозволити їм виконувати команди, сканувати DNS-імена сервісів, пробувати поширені порти та виявляти внутрішні системи, які ніколи не призначалися для виходу в інтернет. Пласка мережа перетворює цю фазу сканування на загальнокластерну вправу, якщо сегментацію ще не впроваджено.
Kubernetes не вважає цю відкритість вадою, бо багато кластерів запускають компоненти платформи, оператори, виявлення сервісів, системи допуску та агенти спостережуваності, яким справді потрібна комунікація між навантаженнями. Позиція типової заборони зламала б багато наївних інсталяцій. Тому платформа надає вам примітиви й очікує, що оператор кластера обере модель політики, придатну для середовища. Для безпекового міркування рівня KCSA ця відмінність має значення: Kubernetes надає механізми, тоді як ваша архітектура постачає безпековий намір.
Патерн, що повторюється на багатьох внутрішніх платформах: команда додає новий сервіс звітності, який читає з черги повідомлень і пише до аналітичної бази даних. Під час тижня запуску інженер розгортає налагоджувальний Под із менеджером пакетів та інструментами оболонки, щоб оглянути чергу. Через місяці цей патерн образу Пода копіюють до іншого простору імен, де він зберігає широкий мережевий доступ. У подіях Kubernetes ніщо не виглядає тривожним, але кластер тихо унормував навантаження, здатне зондувати значно більше, ніж йому потрібно.
Безпечніша звичка — визначати контракти трафіку, поки застосунок ще малий. Якщо простір імен містить триярусний застосунок, запишіть, який ярус ініціює кожне з’єднання, який порт потрібен, чи потрібен DNS і чи легітимний зовнішній вихідний трафік. Цей контракт стає вашим переліком NetworkPolicy. Він також стає планом тестування: якщо несподіваний Под може дістатися бази даних, дизайн відхилився від контракту.
Ще одна корисна звичка огляду — відокремлювати досяжність від дозволу. Досяжність запитує, чи можуть пакети прибути до сокета. Дозвіл запитує, чи має сервіс-отримувач приймати того, хто викликає, і цю дію. Мережева політика Kubernetes здебільшого допомагає з досяжністю, тоді як автентифікація застосунку та авторизація мережі допомагають із дозволом. Якщо ви злиєте ці ідеї докупи, ви можете надмірно довіритися одному рівню. Невдалий логін до бази даних не доводить сегментацію, а мережевий тайм-аут не доводить, що застосунок має правильну авторизацію.
Для команд платформи пласка модель також створює комунікаційний виклик. Прикладні команди часто припускають, що простір імен на ім’я prod природно захищеніший за простір імен на ім’я dev, бо багато інструментів подають простори імен як надійні організаційні контейнери. Старший рецензент має зробити неявну модель явною: простори імен групують об’єкти API, RBAC може обмежувати, хто змінює ці об’єкти, квоти ресурсів можуть обмежувати споживання, а NetworkPolicy може обмежувати трафік. Кожну межу потрібно налаштовувати окремо, і кожна межа потребує власного тесту.
Діагностика застосування політик CNI
Розділ «Діагностика застосування політик CNI»NetworkPolicy є частиною API Kubernetes, але сервер API сам по собі не виконує фільтрацію пакетів. Фактичне застосування належить реалізації мережі кластера, яку зазвичай називають плагіном Container Network Interface. Цю відмінність легко проґавити, бо об’єкт політики може бути прийнятий, збережений і показаний командою k get networkpolicy, навіть коли площина даних його ігнорує. Засіб контролю безпеки, який можна створити, але не застосувати, — це один із найнебезпечніших режимів відмови, бо дашборди світяться зеленим, тоді як трафік лишається відкритим.
┌─────────────────────────────────────────────────────────────┐│ CNI PLUGIN RESPONSIBILITIES │├─────────────────────────────────────────────────────────────┤│ ││ BASIC NETWORKING ││ • Assign IP addresses to pods ││ • Enable pod-to-pod communication ││ • Route traffic between nodes ││ ││ SECURITY FEATURES (varies by plugin) ││ • Network policy enforcement ││ • Encryption in transit ││ • Egress controls ││ • Observability and logging ││ ││ COMMON CNI PLUGINS ││ ┌──────────────┬────────────────────────────────────┐ ││ │ Plugin │ Network Policy Support │ ││ ├──────────────┼────────────────────────────────────┤ ││ │ Calico │ Full (plus extensions) │ ││ │ Cilium │ Full (plus extensions) │ ││ │ Weave Net ⚠️ │ Full (effectively unmaintained │ ││ │ │ since Weaveworks shut down 2024) │ ││ │ Flannel │ None (basic networking only) │ ││ │ AWS VPC CNI │ Via network policy features/add-on │ ││ └──────────────┴────────────────────────────────────┘ ││ ││ WARNING: Some CNIs provide connectivity but not policy. ││ Choose a CNI that supports your security requirements. ││ │└─────────────────────────────────────────────────────────────┘Плагін CNI найкраще розуміти як частину кластера, яка під’єднує мережеві інтерфейси Подів, призначає маршрути та програмує правила, що вирішують, чи рухатимуться пакети. Деякі плагіни зосереджені на базовій зв’язності, деякі додають застосування політик, а деякі додають шифрування, ідентичність, спостережуваність або засоби контролю на основі eBPF. Специфікація NetworkPolicy в Kubernetes описує переносний намір, але кожна реалізація сама обирає, як перекласти цей намір на правила iptables, програми eBPF, хмарні засоби контролю безпеки чи інший механізм площини даних.
Перш ніж покладатися на політику, перевірте і спроможність, і поведінку. Спроможність означає, що документація плагіна стверджує підтримку NetworkPolicy для режиму кластера, який ви використовуєте. Поведінка означає, що реальний пакет, який має бути заблокований, у вашому кластері справді блокується. Це різні перевірки. Версії керованого Kubernetes, хмарні розширення та прапорці конфігурації CNI можуть змінювати те, що застосовується, тож огляд політики має включати «живий» негативний тест, а не лише читання маніфестів.
alias k=kubectlk get pods -n kube-system -o widek get networkpolicy -Ak api-resources | grep -i networkpolicyЦі команди повідомляють, що встановлено і які політики існують, але вони не доводять застосування. Ресурс API може існувати, бо Kubernetes підтримує цей тип об’єкта, тоді як CNI все одно може на нього не реагувати. Корисний лабораторний тест створює два Поди, застосовує політику заборони до одного простору імен, а потім намагається встановити з’єднання, яке має зазнати невдачі. Якщо з’єднання все ще працює після того, як політика обрала Под призначення, кластер не застосовує засіб контролю, який ви, на вашу думку, розгорнули.
k create namespace netsec-labk -n netsec-lab run web --image=nginx:1.27 --labels=app=web --port=80k -n netsec-lab run probe --image=curlimages/curl:8.10.1 --restart=Never -- sleep 3600k -n netsec-lab expose pod web --port=80k -n netsec-lab exec probe -- curl -sS --max-time 3 http://webПерше з’єднання має спрацювати у типово відкритому просторі імен, бо жодна політика не обирає Под web. Цей базовий рівень важливий, бо доводить, що ваш тест має сенс; ви показали, що сервіс, DNS та ендпоінт справні, перш ніж застосувати заборону. Тести безпеки, які пропускають базовий рівень, часто хибно тлумачать сторонні відмови DNS, відмови завантаження образу чи неправильне налаштування сервісу як успіх політики.
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: deny-web-ingress namespace: netsec-labspec: podSelector: matchLabels: app: web policyTypes: - Ingressk apply -f deny-web-ingress.yamlk -n netsec-lab exec probe -- curl -sS --max-time 3 http://webПісля застосування політики заборони з’єднання має завершитися тайм-аутом або зазнати невдачі, бо обраний Под не має дозволених джерел вхідного трафіку. Якщо воно все ще успішне, не починайте з налагодження YAML. Запитайте, чи застосовує CNI NetworkPolicy, чи збігається простір імен політики з простором імен Пода, чи збігаються обрані мітки з Подом призначення, і чи дозволяє цей трафік інша політика. Такий порядок запобігає поширеній помилці огляду: шліфуванню синтаксису політики, тоді як справжня проблема — площина даних, що не застосовує політику.
Перш ніж це запускати, який вивід ви очікуєте від другого curl і яке спостереження довело б, що ваш CNI не застосовує NetworkPolicy? Відмова з боку застосунку — це не те саме, що мережева заборона, а помилка пошуку DNS — це не те саме, що ізоляція вхідного трафіку. Ви шукаєте зміну зі стану «досяжний» на «недосяжний» після того, як політика обрала Под.
Вибір CNI також впливає на операційну видимість. Calico та Cilium можуть розкривати рішення про політики, журнали потоків або інструменти трасування політик залежно від конфігурації. Ці можливості допомагають, коли заборона спрацьовує надто добре і застосунок ламається після розгортання. Простий плагін без видимості політик усе ще може бути прийнятним для невеликого нечутливого кластера, але цей компроміс має бути явним. У регульованих або мультикомандних середовищах здатність довести, яка політика дозволила чи заборонила потік, часто стає частиною самого засобу контролю безпеки.
Важливий екзаменаційний момент полягає в тому, що NetworkPolicy має дві половини: намір Kubernetes та застосування з боку CNI. Маніфест виражає намір у переносному API. Плагін перетворює цей намір на реальну обробку пакетів. Проєктний огляд, який перевіряє лише одну половину, є неповним, а виробниче розгортання, що пропускає негативний тест зв’язності, може лишити команду в переконанні, що вона має сегментацію, тоді як кластер усе ще поводиться як пласка мережа.
Покриття політиками слід вимірювати з перспективи робочого навантаження, а не за кількістю об’єктів. Десять об’єктів NetworkPolicy усе ще можуть лишити критичний Под необраним, тоді як дві сфокусовані політики можуть ефективно ізолювати невеликий простір імен. Під час огляду перелічіть Поди, що обробляють чутливі дані, перевірте, які політики обирають їх для вхідного та вихідного трафіку, а потім протестуйте один заборонений шлях для кожного чутливого ярусу. Це перетворює покриття з розпливчастого твердження на доказ: обрані Поди, обрані напрямки, дозволені джерела, дозволені призначення та зафіксовані заборони.
Діагностуючи невдалу заборону, не піддавайтеся спокусі трактувати CNI як чорну скриньку. CNI є частиною межі безпеки, тож його версія, режим та конфігурація належать до огляду. Керовані пропозиції іноді вмикають політику через розширення, а самокеровані кластери можуть запускати плагін, який підтримує політику лише після встановлення певних компонентів. Зафіксуйте цю залежність у документації платформи. Інакше майбутні оновлення кластера, зміни образу вузла та міграції розширень можуть прибрати чи змінити застосування без жодної зміни прикладного маніфесту.
Проєктування покриття NetworkPolicy
Розділ «Проєктування покриття NetworkPolicy»NetworkPolicy використовує селектори, щоб вирішувати, які Поди ізольовано і який трафік дозволено. Найважливіше правило — адитивна поведінка: якщо жодна політика не обирає Под для напрямку, цей напрямок лишається відкритим; щойно хоча б одна політика обирає Под для цього напрямку, дозволяється лише трафік, дозволений об’єднанням політик, що збігаються. Це означає, що проєктування політики менше схоже на написання одного файлу фаєрвола й більше — на побудову набору невеликих дозволів, які накопичуються в задуманий контракт трафіку.
┌─────────────────────────────────────────────────────────────┐│ NETWORK POLICY CONCEPT │├─────────────────────────────────────────────────────────────┤│ ││ Network policies are ADDITIVE: ││ • No policy = allow all traffic ││ • Policy exists = default deny for selected pods ││ • Multiple policies = union of allowed traffic ││ ││ POLICY COMPONENTS: ││ ││ podSelector: Which pods this policy applies to ││ policyTypes: [Ingress, Egress] or both ││ ingress: Rules for incoming traffic ││ egress: Rules for outgoing traffic ││ ││ SELECTOR OPTIONS: ││ • podSelector - Match by pod labels ││ • namespaceSelector - Match by namespace labels ││ • ipBlock - Match by CIDR range ││ • ports - Match by port/protocol ││ │└─────────────────────────────────────────────────────────────┘Найпростіша безпечна відправна точка — типова заборона для простору імен, а далі явні дозволи для потрібних шляхів. Політика типової заборони з podSelector: {} обирає кожен Под у цьому просторі імен. Якщо вона перелічує Ingress і не має правил вхідного трафіку, обрані Поди не отримують жодного вхідного трафіку, окрім дозволеного іншою політикою. Якщо вона перелічує Egress і не має правил вихідного трафіку, обрані Поди не можуть ініціювати вихідний трафік, окрім дозволеного іншою політикою. Відсутність правил і є забороною; присутність іншої політики постачає дозвіл.
# Default deny all ingress in namespaceapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-deny-ingress namespace: productionspec: podSelector: {} # Selects all pods in namespace policyTypes: - Ingress # No ingress rules = deny all ingress# Default deny all egress in namespaceapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-deny-egress namespace: productionspec: podSelector: {} policyTypes: - Egress # No egress rules = deny all egressТипова заборона потужна, бо перетворює невідомий трафік на видиму поломку під час контрольованого тестування, а не на невидиму відкритість під час інциденту. Компроміс у тому, що застосунки часто залежать від більшої кількості потоків, ніж пам’ятають розробники. DNS, збір метрик, перевірки справності, вебхуки допуску, об’єктне сховище, репозиторії пакетів та сервіси ліцензування — усе це може стати випадковими залежностями. Тому зріле розгортання використовує інвентаризацію, поетапні простори імен та цільові зонди, а не застосовує широку заборону вихідного трафіку до завантаженого виробничого простору імен без репетиції.
Щойно базовий рівень на місці, дозвольте найменший осмислений шлях. Правило «фронтенд до бекенду» має обирати бекенд як призначення, називати селектор фронтенду як джерело й обмежувати порт. Цей напрямок важливий. Правила вхідного трафіку пишуть із перспективи обраного Пода призначення, а не Пода-ініціатора. Інженери часто читають назву політики й припускають, що вона обирає клієнта; spec.podSelector — це призначення для вхідного трафіку та джерело для вихідного.
# Allow frontend to communicate with backendapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-frontend-to-backend namespace: productionspec: podSelector: matchLabels: app: backend policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: frontend ports: - protocol: TCP port: 8080Ця політика не надає фронтенду загального доступу до простору імен. Вона надає трафік від Подів із міткою app: frontend до Подів із міткою app: backend на TCP 8080 і лише як вхідний трафік до обраних бекенд-Подів. Якщо бекенд-Подам також потрібна ізоляція вихідного трафіку, ви маєте написати політику вихідного трафіку окремо. Це розділення не є надмірністю; це спосіб, у який Kubernetes дозволяє вам незалежно контролювати вхідні та вихідні шляхи.
Ізоляція простору імен — наступний шар проєктування. Багато організацій використовують простори імен для команд, етапів, орендарів чи меж застосунків, а потім припускають, що ці межі передбачають мережеве розділення. Це не так. Межа простору імен стає мережевою ізоляцією лише тоді, коли політика обирає Поди й обмежує джерела тим самим простором імен або схваленими мітками простору імен. Політика нижче дозволяє трафік лише від Подів у тому ж просторі імен, бо podSelector без namespaceSelector збігається з Подами у просторі імен самої політики.
┌─────────────────────────────────────────────────────────────┐│ NAMESPACE ISOLATION PATTERN │├─────────────────────────────────────────────────────────────┤│ ││ BEFORE (Default - No Isolation): ││ ┌────────────────┐ ┌────────────────┐ ││ │ namespace: dev │←──→│ namespace: prod│ ││ │ Pod A ←────────┼────┼───→ Pod B │ ││ └────────────────┘ └────────────────┘ ││ All namespaces can communicate ││ ││ AFTER (Namespace Isolation): ││ ┌────────────────┐ ┌────────────────┐ ││ │ namespace: dev │ ✗ │ namespace: prod│ ││ │ Pod A ─────────┼────┼───X Pod B │ ││ └────────────────┘ └────────────────┘ ││ Cross-namespace traffic blocked ││ │└─────────────────────────────────────────────────────────────┘# Only allow traffic from same namespaceapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-same-namespace namespace: productionspec: podSelector: {} policyTypes: - Ingress ingress: - from: - podSelector: {} # Any pod in same namespaceПатерн «той самий простір імен» корисний для швидкого стримування, але це не повний дизайн застосунку. Виробничому простору імен може законно бути потрібний вхідний трафік від спільного простору імен контролера інгресу, метрики з простору імен спостережуваності або виклики з простору імен пакетної обробки. Коли таке трапляється, використовуйте мітки простору імен свідомо. Промаркуйте схвалений простір імен-джерело, зіставте цю мітку в політиці й задокументуйте, хто володіє міткою, щоб випадкове редагування простору імен не стало обходом авторизації.
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-ingress-controller namespace: productionspec: podSelector: matchLabels: app: frontend policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: platform.kubedojo.io/ingress: "true" podSelector: matchLabels: app.kubernetes.io/name: ingress-nginx ports: - protocol: TCP port: 8080Ізоляція бази даних заслуговує на особливу увагу, бо бази даних схильні зберігати ті дані, яких зловмисник насправді хоче. База даних не має бути досяжною з фронтенд-Подів, налагоджувальних Подів, cron-завдань чи довільних навантажень, що ділять простір імен. Вона має приймати трафік від ролі бекенду на порту бази даних і мати вихідний трафік лише тоді, коли реплікація, резервне копіювання або зовнішнє сховище справді цього потребують. Форма політики нижче зберігає вихідний патерн «бекенд до бази даних», водночас роблячи призначення явним.
# Only allow backend pods to reach databaseapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: database-access namespace: productionspec: podSelector: matchLabels: app: database policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: role: backend ports: - protocol: TCP port: 5432Політика вихідного трафіку — це місце, де багато добрих намірів ламають застосунки. Найпоширеніша помилка — забути про DNS. Щойно політика вихідного трафіку обирає Под, Под більше не може надсилати пакети до CoreDNS, доки політика не дозволить UDP, а часто й TCP, порту 53 до DNS-Подів. Деякі кластери маркують CoreDNS як k8s-app: kube-dns; інші використовують інші мітки, особливо в керованих сервісах чи посилених інсталяціях. Не копіюйте політику DNS наосліп. Огляньте фактичні мітки в kube-system, перш ніж покладатися на приклад.
k -n kube-system get pods --show-labels | grep -E 'coredns|kube-dns'k -n production get pods --show-labelsk -n production describe networkpolicy database-accessЯкий підхід ви б тут обрали і чому: одну широку політику вихідного трафіку, яка дозволяє всім Подам діставатися DNS та інтернету, чи політики вихідного трафіку для конкретних ярусів, які дозволяють лише ті призначення, що потрібні кожному ярусу? Широке правило швидше розгорнути, але воно лишає відкритими шляхи для ексфільтрації. Вихідний трафік для конкретних ярусів потребує більшої роботи з інвентаризації, проте дає вам придатну для огляду карту того, які навантаження можуть надсилати дані й куди.
Розгорнутий приклад: триярусний застосунок має tier=frontend, tier=backend і tier=database. Фронтенд отримує трафік від контролера інгресу, викликає бекенд на 8080 і потребує DNS. Бекенд викликає базу даних на 5432, надсилає метрики до простору імен спостережуваності та потребує DNS. База даних приймає лише трафік бекенду й надсилає трафік резервного копіювання до відомого CIDR об’єктного сховища. Ці твердження і є дизайном; YAML — лише його кодування. Якщо дизайн не можна викласти цією простою мовою, політика не готова.
NetworkPolicy має обмеження, які не варто від себе приховувати. Стандартні політики обмежені простором імен, тож немає єдиного вбудованого об’єкта типової заборони на рівні всього кластера. Політики зазвичай працюють на рівнях L3 та L4, тож зіставляють блоки IP, селектори, порти та протоколи, а не HTTP-шляхи чи ідентичності користувачів. Вони не шифрують трафік. Вони також значною мірою залежать від міток, а отже керування мітками є частиною мережевої безпеки. Якщо розробник може додати role=backend до будь-якого Пода без огляду, політика на основі селекторів може дозволити більше, ніж задумано.
Існує другий підступ із селекторами щодо поєднань namespaceSelector та podSelector. У межах одного запису from селектор простору імен і селектор Пода поєднуються так, що мають збігтися обидва: Поди з обраними мітками всередині просторів імен з обраними мітками. В окремих записах from вони є альтернативами. Ця відмінність може несподівано розширити доступ. Коли політика перетинає межі просторів імен, повільно читайте відступи й перекладайте правило простою мовою, перш ніж його схвалити.
Політики вхідного та вихідного трафіку також мають належати команді, яка розуміє граф залежностей застосунку, а не лише центральній команді безпеки. Центральні команди можуть надавати шаблони, запобіжники та стандарти огляду, але супровідники застосунку знають, коли бекенд починає звертатися до нового кешу, черги чи зовнішнього API. Найкраща операційна модель — спільна: команда платформи визначає безпечні типові налаштування та конвенції міток, тоді як власники сервісів оновлюють політику паралельно із залежностями сервісу. Це тримає політику достатньо близько до застосунку, щоб вона лишалася точною.
Впровадження mTLS та ідентичності робочого навантаження
Розділ «Впровадження mTLS та ідентичності робочого навантаження»NetworkPolicy вирішує, які мережеві шляхи мають існувати, але вона не доводить ідентичності застосунку всередині Пода і сама по собі не шифрує прикладний трафік. Якщо пакет дозволено від фронтенду до бекенду на порту 8080, CNI пересилає цей пакет згідно з політикою. Корисне навантаження все ще може бути у відкритому тексті, а бекенду все ще може бути потрібен окремий спосіб дізнатися, чи є той, хто викликає, автентичним фронтенд-навантаженням. Саме цю прогалину покликаний закрити mTLS сервісної мережі.
┌─────────────────────────────────────────────────────────────┐│ SERVICE MESH ARCHITECTURE │├─────────────────────────────────────────────────────────────┤│ ││ WITHOUT SERVICE MESH: ││ ┌─────────┐ ┌─────────┐ ││ │ Pod A │ ─── HTTP/TCP ───→ │ Pod B │ ││ │ (app) │ │ (app) │ ││ └─────────┘ └─────────┘ ││ Unencrypted, no identity ││ ││ WITH SERVICE MESH: ││ ┌─────────────────┐ ┌─────────────────┐ ││ │ Pod A │ │ Pod B │ ││ │ ┌─────┐┌─────┐│ │┌─────┐┌─────┐ │ ││ │ │ app ││proxy│├── mTLS ───→│proxy ││ app │ │ ││ │ └─────┘└─────┘│ │└─────┘└─────┘ │ ││ └─────────────────┘ └─────────────────┘ ││ Encrypted, identity-based, observable ││ │└─────────────────────────────────────────────────────────────┘Сервісна мережа зазвичай вставляє проксі поруч із кожним прикладним контейнером або використовує площину даних у режимі ambient, щоб перехоплювати трафік навантаження. Мережа видає сертифікати навантаженням, ротує їх і використовує взаємний TLS, щоб обидві сторони автентифікували одна одну. Застосунок може локально й далі спілкуватися через HTTP чи gRPC, тоді як мережа опікується шифруванням та ідентичністю між навантаженнями. Цей дизайн привабливий, бо централізує складну безпекову проблему, але він також додає рухомі частини, режими відмови та операційні накладні витрати.
┌─────────────────────────────────────────────────────────────┐│ mTLS EXPLAINED │├─────────────────────────────────────────────────────────────┤│ ││ REGULAR TLS (one-way) ││ Client ──────→ Server ││ • Client verifies server identity ││ • Server doesn't verify client ││ • Like HTTPS to a website ││ ││ MUTUAL TLS (two-way) ││ Client ←─────→ Server ││ • Client verifies server identity ││ • Server verifies client identity ││ • Both parties authenticated ││ ││ IN KUBERNETES: ││ • Service mesh handles mTLS automatically ││ • Each pod gets a certificate ││ • Certificates rotated automatically ││ • Zero Trust networking achieved ││ │└─────────────────────────────────────────────────────────────┘Взаємний TLS — це більше, ніж шифрування. Він дає серверу криптографічну підставу довіряти, що той, хто викликає, — це конкретна ідентичність навантаження, а не просто якийсь Под із мережевим доступом. У добре налаштованій мережі авторизація може казати, що frontend може викликати backend на вузькому наборі маршрутів, тоді як налагоджувальний Под у тому ж просторі імен — ні. NetworkPolicy усе ще може дозволяти чи забороняти TCP-шлях, але мережа може ухвалити багатше рішення після того, як з’єднання досягне проксі.
| Можливість | Опис |
|---|---|
| mTLS | Автоматичне шифрування між сервісами |
| Ідентичність | Криптографічна ідентичність для кожного навантаження |
| Авторизація | Дрібнозернисті політики доступу |
| Спостережуваність | Метрики трафіку, трасування |
| Контроль трафіку | Обмеження частоти, повторні спроби, тайм-аути |
Ці можливості потужні, але вони не мають вести до мислення «мережа вирішує все». Сервісна мережа зазвичай захищає трафік, що бере участь у мережі. Вона може не покривати Поди з мережею хоста, локальні агенти вузла, трафік, що оминає sidecar-и, чи компоненти, виключені з ін’єкції. NetworkPolicy лишається корисною, бо обмежує шляхи пакетів ще до того, як буде оцінено політику прикладного рівня. Ешелонований захист означає, що мережа й CNI безпечно «не погоджуються»: якщо будь-який рівень забороняє несподіваний шлях, шлях відмовляє.
┌─────────────────────────────────────────────────────────────┐│ WHY ENCRYPT INTERNAL TRAFFIC? │├─────────────────────────────────────────────────────────────┤│ ││ "But it's inside my network, why encrypt?" ││ ││ THREAT: Network eavesdropping ││ • Compromised node can sniff traffic ││ • Network devices could be compromised ││ • Cloud provider could theoretically observe ││ ││ THREAT: Man-in-the-middle attacks ││ • Without mTLS, pods can impersonate others ││ • No verification of "who is talking to who" ││ ││ COMPLIANCE: ││ • Many regulations require encryption in transit ││ • PCI-DSS, HIPAA, SOC2 often require it ││ ││ ZERO TRUST: ││ • Assume the network is compromised ││ • Encrypt everything, verify everything ││ │└─────────────────────────────────────────────────────────────┘Поширений виробничий патерн — почати з NetworkPolicy для грубої ізоляції й додати mTLS сервісної мережі для чутливих викликів між сервісами. Наприклад, простір імен платежів може забороняти весь вхідний трафік, окрім як від шлюзів інгресу та схвалених бекенд-просторів імен, а потім вимагати mTLS усередині простору імен і застосовувати ідентичності сервісів на рівні мережі. Якщо скомпрометований Под опиняється в сусідньому просторі імен, CNI блокує більшість шляхів. Якщо він досягає дозволеного порту через помилкову мітку чи схвалений шлюз, мережа все одно вимагає правильної ідентичності.
| Мережа | Опис |
|---|---|
| Istio | Повнофункціональна, складна, широко поширена |
| Linkerd | Легка, проста, швидка |
| Cilium | CNI на основі eBPF із опційними можливостями мережі |
| Consul Connect | Сервісна мережа від HashiCorp |
Вибір серед варіантів мереж — це не лише порівняння можливостей. Istio пропонує розлогі засоби керування трафіком та поверхні політик, що може бути цінним для великих команд платформи, але обтяжливим для малих. Linkerd наголошує на простоті та автоматичному mTLS, що може зменшити операційне тертя. Cilium може поєднувати політику CNI, спостережуваність на eBPF та можливості шифрування в одній екосистемі. Consul Connect може пасувати організаціям, які вже вклалися у виявлення сервісів HashiCorp. Правильний вибір залежить від того, хто його експлуатуватиме під час інцидентів, оновлень та ротацій сертифікатів.
Зупиніться та спрогнозуйте: NetworkPolicy дозволяє frontend діставатися backend, а мережа вимагає mTLS для backend. Що станеться, якщо Под без ідентичності в мережі спробує викликати backend зі схваленого простору імен-джерела? Пакет може пройти правило CNI, якщо селектори збігаються, але проксі мережі має відхилити з’єднання, бо однорангова сторона не може завершити обов’язкове рукостискання ідентичності. У цьому й полягає сенс багаторівневих засобів контролю.
Обсяг шифрування теж заслуговує на точне формулювання. Деякі плагіни CNI можуть шифрувати трафік Подів між вузлами за допомогою таких механізмів, як WireGuard чи IPsec. Це захищає трафік «на дроті» між вузлами, але може не надавати ідентичності на рівні навантаження чи авторизації з урахуванням HTTP. mTLS сервісної мережі надає ідентичність навантаження й може підтримувати політику рівня L7, але лише для трафіку на шляху мережі. Обидва підходи можуть бути слушними. Плутанина починається, коли команди кажуть «зашифровано», не називаючи, що саме зашифровано, де зберігаються ключі та яку ідентичність автентифіковано.
Операційний тягар реальний. Сертифікати мережі мають надійно ротуватися, sidecar-и чи компоненти режиму ambient мають оновлюватися, розгортання політик потребують поетапної перевірки, а системи спостережуваності мають розрізняти мережеві заборони та прикладні заборони. Зламана площина управління мережі може вплинути на розгортання чи поведінку трафіку, навіть коли прикладний код не змінювався. Це не робить сервісну мережу поганою ідеєю; це означає, що mTLS слід впроваджувати з власниками, раннбуками та планами відкату, а не як галочку після зауваження аудиту.
Коли мережу впроваджують після NetworkPolicy, ретельно сплануйте шлях міграції. Почніть зі спостереження за трафіком і ввімкнення дозвільних режимів mTLS там, де мережа це підтримує, а потім переводьте чутливі простори імен до суворих режимів, щойно кожне навантаження зареєстровано й протестовано. Якщо суворий mTLS увімкнути до того, як усі клієнти матимуть sidecar-и чи сумісні ідентичності, відмови можуть виглядати як випадкові збої застосунку. Спокійна міграція трактує ідентичність як розгортання із залежностями, перевірками справності та критеріями відкату, а не як перемикач, клацнутий по всьому кластеру.
Найменування ідентичностей теж має значення. Ідентичності навантажень мають відображатися на сервісні акаунти, простори імен та володіння розгортанням у спосіб, придатний для аудиту людьми. Якщо кожен сервіс працює під широким типовим сервісним акаунтом, mTLS доводить лише те, що «якесь навантаження в цьому просторі імен» з’єдналося, чого може бути недостатньо для чутливих API. Поєднуйте ідентичність мережі з гігієною сервісних акаунтів із попередніх модулів безпеки. Мережева безпека стає міцнішою, коли ідентичність навантаження, RBAC, мітки та політика описують одну й ту саму архітектуру.
Порівняння засобів контролю в дизайні з ешелонованим захистом
Розділ «Порівняння засобів контролю в дизайні з ешелонованим захистом»Рішення щодо мережевої безпеки стають простішими, коли ви відокремлюєте запитання, на які відповідає кожен засіб контролю. NetworkPolicy запитує: «Чи дозволено цьому джерелу відкрити цей мережевий шлях до цього призначення й порту?» Шифрування CNI запитує: «Чи може спостерігач у мережі прочитати пакети між вузлами чи ендпоінтами?» mTLS сервісної мережі запитує: «Чи можуть обидва навантаження довести свої ідентичності й встановити зашифровану сесію?» Авторизація мережі запитує: «Чи дозволено цьому автентифікованому виклику виконати цю дію прикладного рівня?» Ці засоби контролю перетинаються, але вони не тотожні.
| Засіб контролю | Найкращий у чому | Головна сліпа зона | Типовий власник |
|---|---|---|---|
| NetworkPolicy | Сегментація просторів імен і Подів за селектором, CIDR, портом та протоколом | Без вбудованого шифрування чи усвідомлення запитів рівня L7 | Команда мережі платформи |
| Шифрування CNI | Захист трафіку Подів «на дроті» між вузлами чи ендпоінтами площини даних | Може не надавати ідентичності навантаження чи авторизації HTTP | Команда мережі платформи |
| mTLS сервісної мережі | Ідентичність навантаження, ротація сертифікатів та зашифровані сесії між сервісами | Захищає лише трафік, що бере участь у шляху мережі | Команда платформи чи сервісної мережі |
| Авторизація мережі | Політика рівня методу, шляху, принципала та сервісу | Залежить від коректної реєстрації в мережі та застосування проксі | Команда прикладної платформи |
| Автентифікація застосунку | Бізнес-авторизація та рішення з урахуванням користувача | Не може замінити мережеву сегментацію після компрометації | Прикладна команда |
Практична послідовність проєктування зазвичай іде від грубого до тонкого. По-перше, оберіть CNI, який застосовує політику, і застосуйте базові рівні типової заборони до чутливих просторів імен. По-друге, дозвольте відомі шляхи сервісів із вузькими селекторами та портами. По-третє, додайте засоби контролю вихідного трафіку для навантажень, що обробляють чутливі дані чи облікові дані. По-четверте, впровадьте mTLS там, де відкритий трафік, видавання себе за чуже навантаження чи вимоги відповідності виправдовують складність. По-п’яте, додайте авторизацію рівня L7 для API, чий ризик не можна охопити номером порту.
Послідовність має лишатися придатною до тестування. Для кожного важливого шляху напишіть позитивний тест і негативний тест. Позитивний тест доводить, що застосунок усе ще може виконувати свою роботу. Негативний тест доводить, що несхвалений Под, простір імен чи ідентичність не можуть зробити те саме. Без обох сторін ви маєте або крихкий безпековий дизайн, що ламає виробництво, або комфортний дизайн, що дозволяє той шлях зловмисника, який ви мали намір закрити.
Гіпотетичний сценарій: команда платформи фінансових сервісів якось розгорнула політики заборони вихідного трафіку до простору імен, що містив внутрішні API. Зміна пройшла огляд маніфестів, бо кожен шлях «бекенд до бази даних» було представлено, але після розгортання частота помилок у виробництві зросла. Відсутньою залежністю була не база даних; це був ендпоінт інтроспекції токенів, який використовувався під час автентифікації, та резервний шлях DNS через TCP, що спрацьовував на великих відповідях. Виправленням було не відмовитися від політики вихідного трафіку. Виправленням стало додати виявлення залежностей, поетапне тіньове тестування та явні винятки, які переглядали як код.
Саме тому проєктування мережевої політики належить до звичайних робочих процесів доставки. Мітки мають бути частиною конвенцій розгортання, зміни політик слід переглядати поряд зі змінами застосунку, а нові залежності сервісів мають оновлювати контракт трафіку. Репозиторій політик, якого ніхто не торкається після початкового розгортання, швидко застаріває. Кластер і далі прийматиме розгортання, імена сервісів і далі розв’язуватимуться, а мережа поступово розходитиметься з безпековою моделлю, якщо огляд політики не трактувати як живу практику.
Останній пункт порівняння — поведінка при відмові. Відмови NetworkPolicy часто з’являються як тайм-аути, відмови mTLS мережі можуть з’являтися як помилки рукостискання TLS чи відповіді, заборонені проксі, а відмови авторизації застосунку можуть з’являтися як відповіді HTTP 403 чи специфічні для домену повідомлення про помилку. Хороші раннбуки навчають тих, хто реагує, розрізняти ці рівні. Без такої дисципліни команди можуть послабити не той засіб контролю під час збою. Найшвидше відновлення не завжди є найбезпечнішим; правильна мета — визначити, який рівень заблокував який запит і чи відповідало блокування задуманій політиці.
Для підготовки до KCSA вправляйтеся викладати стек засобів контролю простою мовою. Сильна відповідь звучить так: «CNI застосовує NetworkPolicy, щоб обмежити досяжність Подів, політика вихідного трафіку обмежує шляхи ексфільтрації, шифрування CNI чи мережі захищає трафік у дорозі, а mTLS сервісної мережі дає навантаженням криптографічну ідентичність для чутливих викликів сервісів». Це пояснення корисніше за перелік назв продуктів, бо прив’язує кожен механізм до загрози, яку він адресує.
Патерни та антипатерни
Розділ «Патерни та антипатерни»Патерни в мережевій безпеці Kubernetes корисні, бо кодують операційні уроки, які легко забути під тиском доставки. Хороший патерн має казати вам, коли його використовувати, чому він працює і як він масштабується, коли кластер набирає більше просторів імен та команд. Таблиця нижче віддає перевагу патернам, які можна протестувати звичайними ресурсами Kubernetes і вдосконалити пізніше за допомогою можливостей, специфічних для CNI чи мережі.
| Патерн | Коли використовувати | Чому працює | Міркування щодо масштабування |
|---|---|---|---|
| Типова заборона для простору імен | Будь-який простір імен із виробничими, регульованими чи мультикомандними навантаженнями | Перетворює неявну досяжність на явні дозволи | Застосовуйте з шаблонами чи політикою-як-кодом, щоб нові простори імен починали ізольованими |
| Правила дозволу «ярус-до-ярусу» | Застосунки з чіткими ярусами фронтенду, бекенду та даних | Зіставляє трафік з архітектурою застосунку, а не з довільними іменами Подів | Вимагайте стабільних міток і володіння змінами міток |
| DNS як явна залежність | Будь-який простір імен з ізоляцією вихідного трафіку | Запобігає тихим відмовам виявлення сервісів після заборони вихідного трафіку | Перевіряйте фактичні мітки CoreDNS у кожному кластері, перш ніж копіювати приклади |
| Негативні тести зв’язності | Кожне суттєве розгортання політики | Доводить, що заборонений трафік справді заборонений з боку CNI | Автоматизуйте зонди в CI чи передвиробничих просторах імен |
| mTLS мережі для чутливих API | Сервіси, що несуть облікові дані, платіжні дані, персональні дані чи привілейовані керівні дії | Додає шифрування та ідентичність навантаження понад мережеву досяжність | Призначте власника для сертифікатів, оновлень та налагодження політик |
Антипатерни зазвичай з’являються, бо команди намагаються зменшити тертя. Вони розгортають широке правило дозволу, щоб зупинити збій, дають міткам дрейфувати, бо реліз терміновий, чи припускають, що ім’я простору імен несе більше сенсу, ніж насправді. Ці зрізані кути здаються розумними в моменті, але вони прибирають слід доказів, потрібний команді безпеки під час інциденту.
| Антипатерн | Що йде не так | Краща альтернатива |
|---|---|---|
| Об’єкти політики на CNI, що не застосовує | API приймає маніфести, тоді як пакети лишаються необмеженими | Доведіть застосування «живими» тестами заборони, перш ніж заявляти про покриття |
| Один гігантський виняток «дозволити весь вихідний трафік» | Скомпрометовані Поди можуть ексфільтрувати дані до довільних призначень | Пишіть правила вихідного трафіку для конкретних ярусів і переглядайте зовнішні залежності |
| Довіра самим лише межам просторів імен | Трафік між просторами імен лишається типово відкритим | Додайте політики ізоляції просторів імен зі схваленими мітками просторів імен |
| Розповзання міток без володіння | Будь-яке навантаження може випадково збігтися з привілейованими правилами дозволу | Визначте конвенції міток і переглядайте чутливі для безпеки мітки |
| Сегментація лише через мережу | Трафік поза мережею чи в обхід неї може лишатися досяжним | Тримайте NetworkPolicy як грубу мережеву межу |
Здорова модель поведінки нудна: запишіть задумані потоки, закодуйте їх вузько, протестуйте дозволені й заборонені випадки та переглядайте контракт, коли застосунок змінюється. Kubernetes дає вам динамічну інфраструктуру, а це означає, що вчора правильна політика може стати неповною завтра. Трактуйте набір політик як архітектуру застосунку, а не як одноразовий безпековий артефакт.
Каркас прийняття рішень
Розділ «Каркас прийняття рішень»Використовуйте цей каркас, коли потрібно вирішити, який засіб контролю мережевої безпеки належить до дизайну. Починайте із загрози, а не з інструмента. Якщо ризик — широке латеральне переміщення між Подами, NetworkPolicy є першим засобом контролю для оцінки. Якщо ризик — видимість пакетів на вузлі чи в нижчій мережі, центральним стає шифрування. Якщо ризик — видавання себе за чуже навантаження чи авторизація прикладного рівня, можуть знадобитися ідентичність і політика сервісної мережі.
┌─────────────────────────────────────────────────────────────┐│ NETWORK SECURITY DECISION FLOW │├─────────────────────────────────────────────────────────────┤│ ││ 1. Do pods need unrestricted namespace-wide reachability? ││ ├─ No → Apply namespace default deny ││ └─ Yes → Document why and add monitoring ││ ││ 2. Do specific tiers need specific ports only? ││ ├─ Yes → Add tier-to-tier NetworkPolicies ││ └─ No → Revisit application dependency map ││ ││ 3. Could sensitive data cross a node or network boundary? ││ ├─ Yes → Evaluate CNI encryption or service mesh mTLS ││ └─ No → Confirm with data classification ││ ││ 4. Must the receiver verify workload identity? ││ ├─ Yes → Require mTLS and identity-aware authorization ││ └─ No → NetworkPolicy may be enough for this path ││ ││ 5. Do you need HTTP method, path, or principal rules? ││ ├─ Yes → Add mesh or application-layer authorization ││ └─ No → Keep Layer 3/4 policy simple and testable ││ │└─────────────────────────────────────────────────────────────┘| Ситуація | Основний засіб контролю | Додати за потреби | Обґрунтування |
|---|---|---|---|
| Новий виробничий простір імен | Типова заборона NetworkPolicy | Шаблони просторів імен та зонди CI | Запобігає тихій типово відкритій вразливості від першого розгортання |
| Триярусний внутрішній застосунок | Політика вхідного й вихідного трафіку для конкретних ярусів | mTLS мережі для чутливих викликів бекенду | Кодує очікувані шляхи застосунку й обмежує латеральне переміщення |
| Трафік сервісу в зоні PCI | NetworkPolicy плюс mTLS | Авторизація рівня L7 для API | Сегментація контролює досяжність, тоді як mTLS захищає конфіденційність та ідентичність |
| Кластер із CNI лише для базової зв’язності | Заміна CNI чи розширення політики | Тести політики після міграції | NetworkPolicy не може захистити трафік без площини даних, що її застосовує |
| Змішані навантаження в мережі й поза нею | Базовий рівень NetworkPolicy | Авторизація мережі для зареєстрованих сервісів | Груба політика покриває шляхи в обхід, тоді як мережа опікується викликами з урахуванням ідентичності |
Каркас прийняття рішень також допомагає під час аудитів. Замість того щоб казати «ми використовуємо Cilium» чи «ми встановили Istio», опишіть ризик і засіб контролю, що його адресує. Для латерального переміщення покажіть типову заборону й негативні тести зв’язності. Для шифрування покажіть режим mTLS чи конфігурацію шифрування CNI та спосіб це перевірити. Для ідентичності покажіть, які ідентичності навантажень дозволено. Аудитори й ті, хто реагує на інциденти, потребують доказів, а не назв продуктів.
Чи знали ви?
Розділ «Чи знали ви?»-
NetworkPolicy стала стабільною в Kubernetes 1.8, тобто основний API існує вже багато років, але застосування все одно залежить від плагіна CNI в кластері.
-
Мережеві політики обмежені простором імен, тож стандартна NetworkPolicy Kubernetes не може створити один об’єкт типової заборони на рівні всього кластера одразу для кожного простору імен.
-
mTLS автентифікує обидві сторони з’єднання, на відміну від звичайного одностороннього TLS, де клієнт перевіряє сервер, але сервер може не перевіряти сертифікат клієнта.
-
CNI на основі eBPF, як-от Cilium, можуть застосовувати політику в площині даних ядра Linux, що уможливлює дизайни політик, спостережуваності та балансування навантаження, відмінні від традиційних підходів із інтенсивним використанням iptables.
Типові помилки
Розділ «Типові помилки»| Помилка | Чому вона трапляється | Як її виправити |
|---|---|---|
| Створення NetworkPolicy на CNI, який її не застосовує | Сервер API приймає об’єкт, тож маніфест виглядає успішним в оглядах | Підтвердьте підтримку CNI й запустіть негативний тест зв’язності, перш ніж заявляти, що засіб контролю працює |
| Забути про DNS після ізоляції вихідного трафіку | DNS здається інфраструктурною рутиною, а не залежністю застосунку | Дозвольте UDP і TCP 53 до фактичних DNS-Подів, обраних за мітками у вашому кластері |
| Написати політику вхідного трафіку, але припускати, що вихідний теж контрольовано | Інженери читають назву політики як повний контракт трафіку | Визначайте вхідний і вихідний трафік окремо, потім тестуйте кожен напрямок зондами |
| Зіставляти привілейований доступ із недбалими мітками | Мітки легко додати під час розгортань, і вони можуть дрейфувати з часом | Трактуйте чутливі для безпеки мітки як власні поля API й переглядайте зміни в них |
| Дозволяти весь вихідний трафік, щоб уникнути ризику запуску | Команди бояться зламати приховані залежності під час розгортання | Виявіть залежності в staging, потім дозвольте названі призначення та порти за ярусами |
| Припускати, що сервісна мережа замінює NetworkPolicy | Політика мережі може не покривати трафік поза мережею, з мережею хоста чи в обхід | Тримайте NetworkPolicy як грубу мережеву межу й використовуйте ідентичність мережі понад нею |
| Копіювати приклади namespaceSelector без керування мітками просторів імен | Мітка простору імен може стати рішенням про авторизацію без володіння | Обмежте, хто може встановлювати чутливі для безпеки мітки просторів імен, і регулярно їх перевіряйте |
| Трактувати шифрування як ідентичність | Зашифрований трафік усе ще може надходити від неправильного навантаження, якщо ідентичність однорангової сторони не перевірено | Використовуйте mTLS чи інший автентифікований механізм ідентичності, коли отримувачі мають довіряти тим, хто викликає |
Тест
Розділ «Тест»Питання 1: Ваша команда розгортає виробничий простір імен без об'єктів NetworkPolicy, і тимчасовий Под у `default` може під'єднатися до сервісу виробничої бази даних. Що ви перевірите й зміните найперше?
Почніть з усвідомлення, що це очікувана типова поведінка Kubernetes, а не доказ того, що сервіс бази даних налаштовано неправильно. Перевірте, чи застосовує CNI кластера NetworkPolicy, потім додайте базовий рівень типової заборони для простору імен і явні правила вхідного трафіку до бази даних від ролі бекенду. Перша безпечна зміна — це не широка заборона, наосліп скопійована у виробництво; це протестований дизайн політики, що включає потрібні потоки, як-от доступ бекенду та DNS. Ця відповідь відображається на пласку мережеву модель, бо проблема — це латеральна досяжність, створена типово відкритою мережею Подів.
Питання 2: Бекенд-Под обрано двома політиками вхідного трафіку. Одна дозволяє `app=frontend` на порту 8080, а інша дозволяє `app=monitoring` на порту 9090. Фронтенд-Под пробує порт 9090. Чи дозволено трафік?
Трафік заборонено, бо NetworkPolicy дозволяє об’єднання повних дозволених правил, а не змішану комбінацію джерел і портів. Об’єднання тут — це фронтенд на 8080 або моніторинг на 9090. Фронтенд на 9090 не задовольняє жоден дозволений шлях. Саме тому огляди політик мають читати кожне правило як кортеж «джерело-і-порт», а не як окремі купи дозволених міток та дозволених портів.
Питання 3: Керівник із безпеки виявляє, що маніфести NetworkPolicy існують, але тест заборони все одно дозволяє трафік до обраного Пода. Яка діагностика має передувати редагуванню селекторів?
Переконайтеся, що плагін CNI підтримує й увімкнув застосування NetworkPolicy у цьому режимі кластера. Kubernetes може зберігати об’єкти NetworkPolicy навіть тоді, коли площина даних їх не застосовує, тож успішний k apply не є доказом захисту. Після підтвердження спроможності огляньте розташування простору імен, мітки Подів, селектори політик та будь-які додаткові політики, що можуть дозволяти потік. Такий порядок запобігає марнуванню часу на зміни YAML, коли рівень застосування відсутній.
Питання 4: Ваш платіжний бекенд має довести, що ті, хто викликає, є схваленими навантаженнями, і має шифрувати трафік між Подами. NetworkPolicy уже обмежує порт. Що слід додати?
Додайте автентифіковане навантаженням шифрування, як-от mTLS сервісної мережі, а потім використовуйте авторизацію з урахуванням ідентичності для платіжного бекенду. NetworkPolicy обмежує досяжність на рівнях L3 та L4, але вона не автентифікує ідентичність застосунку всередині Пода-викликача й не шифрує корисне навантаження сама по собі. mTLS дозволяє обом сторонам перевіряти ідентичність однорангової сторони, шифруючи сесію. Тримайте NetworkPolicy на місці, бо вона все одно обмежує, які мережеві шляхи можуть дістатися захищеного мережею сервісу.
Питання 5: Розгортання політики вихідного трафіку ламає розв'язання імен сервісів для Подів, які в іншому випадку мають коректні правила дозволу застосунку. Що, ймовірно, було проґавлено?
Політика, ймовірно, забула про вихідний DNS до CoreDNS чи kube-dns. Щойно політика вихідного трафіку обирає Под, вихідний DNS заборонено, доки його явно не дозволено, і виявлення сервісів зазнає невдачі ще до того, як застосунок зможе дістатися задуманого призначення. Виправлення — оглянути мітки DNS-Подів у kube-system і дозволити UDP та TCP 53 до цих Подів. Це слід тестувати як частину кожного розгортання політики вихідного трафіку, бо DNS — це прихована залежність майже в кожному застосунку Kubernetes.
Питання 6: Колега каже, що Istio AuthorizationPolicy робить NetworkPolicy Kubernetes надлишковою. Як ви відповісте на проєктному огляді?
Вони є взаємодоповнювальними засобами контролю. NetworkPolicy обмежує мережеву досяжність до того, як трафік досягне проксі сервісу, тоді як авторизація Istio може ухвалювати рішення з урахуванням ідентичності чи запиту після mTLS та обробки проксі. Політика мережі може не захищати навантаження поза мережею чи шляхи в обхід, а NetworkPolicy сама по собі не може виражати методи HTTP чи принципалів навантаження. Сильний дизайн використовує NetworkPolicy для грубої сегментації й політику мережі для автентифікованої авторизації на рівні сервісу там, де ризик це виправдовує.
Питання 7: Команда платформи хоче одну стандартну політику для всіх нових просторів імен. Який мінімальний доказ їм слід вимагати, перш ніж назвати патерн безпечним?
Вони мають вимагати доказ того, що CNI застосовує політику, базовий рівень типової заборони, явні шаблони дозволу для DNS та схваленого трафіку платформи, а також позитивні й негативні тести зв’язності. Політика також має визначати володіння мітками, бо мітки просторів імен і Подів можуть стати вхідними даними для авторизації. Стандартний шаблон цінний лише тоді, коли його поєднано з перевіркою в реальних кластерах. Інакше організація може масштабувати хибне відчуття сегментації на кожен новий простір імен.
Практична вправа: проєктування мережевої політики
Розділ «Практична вправа: проєктування мережевої політики»У цій вправі ви спроєктуєте й протестуєте політики для триярусного застосунку в лабораторному просторі імен. Мета — не запам’ятати ідеальний файл YAML; вона полягає у вправлянні в перетворенні вимог трафіку на селектори, порти, напрямки та перевірки. Використовуйте одноразовий кластер, де ваш CNI підтримує NetworkPolicy, бо негативні тести є частиною уроку.
Сценарій: спроєктуйте мережеві політики для триярусного застосунку, де кожен ярус має окрему мітку, вузький набір потрібних з’єднань і чітке очікування огляду, що довільний трафік «Под-до-Пода» має зазнавати невдачі.
- Фронтенд-Поди (мітка:
tier=frontend) - Бекенд-Поди (мітка:
tier=backend) - Поди бази даних (мітка:
tier=database)
Вимоги нижче описують задуманий контракт трафіку простою мовою, перш ніж ви закодуєте його як політику Kubernetes:
- Фронтенд може отримувати трафік звідусіль
- Бекенд може отримувати трафік лише від фронтенду
- База даних може отримувати трафік лише від бекенду
- Жоден Под не повинен мати необмеженого вихідного трафіку
Налаштування
Розділ «Налаштування»Створіть простір імен і три прості Поди. У реальному кластері ви б використали Deployment’и, але Поди тримають лабораторію достатньо малою для прямого огляду. Команди нижче припускають, що ви вже створили псевдонім k, описаний на початку модуля.
k create namespace appk -n app run frontend --image=nginx:1.27 --labels=tier=frontend --port=80k -n app run backend --image=nginx:1.27 --labels=tier=backend --port=8080k -n app run database --image=postgres:17 --labels=tier=database --env=POSTGRES_PASSWORD=example-only --port=5432k -n app run probe --image=curlimages/curl:8.10.1 --restart=Never -- sleep 3600k -n app get pods --show-labelsЗавдання
Розділ «Завдання»- Підтвердьте, що ваш CNI застосовує NetworkPolicy, виконавши один досяжний базовий тест і один заборонений тест.
- Створіть політику типової заборони, яка обирає кожен Под у просторі імен
appдля вхідного й вихідного трафіку. - Дозвольте вхідний трафік до фронтенду звідусіль, тримаючи бекенд і базу даних захищеними від довільних джерел.
- Дозвольте вихідний трафік фронтенду до бекенду на 8080 і вихідний трафік бекенду до бази даних на 5432.
- Додайте правила вихідного DNS, використовуючи фактичні мітки CoreDNS чи kube-dns з вашого кластера.
- Задокументуйте один позитивний і один негативний тест для кожного ярусу, щоб рецензенти могли перевірити дизайн.
Розв'язання
# 1. Default deny all ingress and egressapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-deny-all namespace: appspec: podSelector: {} policyTypes: - Ingress - Egress---# 2. Allow ingress to frontend from anywhereapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: frontend-ingress namespace: appspec: podSelector: matchLabels: tier: frontend policyTypes: - Ingress ingress: - {} # Allow from anywhere---# 3. Allow frontend to reach backendapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: backend-from-frontend namespace: appspec: podSelector: matchLabels: tier: backend policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: tier: frontend ports: - port: 8080---# 4. Allow backend to reach databaseapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: database-from-backend namespace: appspec: podSelector: matchLabels: tier: database policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: tier: backend ports: - port: 5432---# 5. Allow frontend egress to backendapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: frontend-egress namespace: appspec: podSelector: matchLabels: tier: frontend policyTypes: - Egress egress: - to: - podSelector: matchLabels: tier: backend ports: - port: 8080 - to: # Allow DNS (kube-system only) - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports: - port: 53 protocol: UDP - port: 53 protocol: TCP # add if your cluster requires TCP 53 for DNS---# 6. Allow backend egress to databaseapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: backend-egress namespace: appspec: podSelector: matchLabels: tier: backend policyTypes: - Egress egress: - to: - podSelector: matchLabels: tier: database ports: - port: 5432 - to: # Allow DNS (kube-system only) - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports: - port: 53 protocol: UDP - port: 53 protocol: TCP # add if your cluster requires TCP 53 for DNSРозв’язання зберігає основний триярусний дизайн, але вам слід адаптувати селектори DNS до свого кластера. Деякі кластери маркують DNS-Поди інакше, а деякі вимагають TCP 53 на додачу до UDP 53. Вам також слід додавати вихідний трафік бази даних лише тоді, коли базі даних справді потрібні резервне копіювання, реплікація чи зовнішні сервіси.
Критерії успіху
Розділ «Критерії успіху»- Простір імен
appмає політику типової заборони, яка обирає всі Поди для вхідного й вихідного трафіку. - Вхідний трафік до фронтенду працює зі схваленого джерела, а вхідний трафік до бекенду від довільного зонд-Пода зазнає невдачі.
- Бекенд може дістатися бази даних на 5432, а фронтенд не може дістатися бази даних напряму.
- Розв’язання DNS усе ще працює для ярусів, яким потрібне виявлення сервісів.
-
k describe networkpolicy -n appпоказує селектори та порти, що збігаються із задокументованим контрактом трафіку.
Операційний підсумок
Розділ «Операційний підсумок»Мережева безпека в Kubernetes потребує активного налаштування. Типова тканина спроєктована для зв’язності, а не для ізоляції, тож безпечна позиція походить від політик, міток, можливостей площини даних та систем ідентичності, які ви додаєте навколо неї. Тримайте цю підсумкову таблицю поруч під час оглядів, бо вона відокремлює головні концепції, які команди часто змішують докупи.
| Концепція | Ключові пункти |
|---|---|
| Типова поведінка | Усі Поди можуть діставатися всіх Подів — впровадьте типову заборону |
| Плагіни CNI | Оберіть той, що підтримує мережеві політики (Calico, Cilium) |
| Мережеві політики | Адитивні, обмежені простором імен, потребують явних дозволів |
| Сервісна мережа | Надає mTLS, ідентичність та дрібнозернисту авторизацію |
| mTLS | Шифрує трафік ТА перевіряє обидві сторони |
Ключові патерни лишаються простими, навіть коли базова реалізація складна. Почніть із типової заборони, дозвольте лише потрібний трафік, розгляньте засоби контролю вихідного трафіку для навантажень, що несуть дані, використовуйте mTLS для чутливих комунікацій і перевірте, що ваш CNI підтримує семантику політик, від якої ви залежите. Найкращі дизайни — не найдовші файли YAML; це дизайни, чий задуманий трафік можна пояснити, протестувати й захистити під час інциденту.
Джерела
Розділ «Джерела»- Kubernetes: Network Policies
- Kubernetes: Cluster Networking
- Kubernetes: Services, Load Balancing, and Networking
- Kubernetes: Declare Network Policy
- CNI Specification
- Calico: Kubernetes Default Deny Policy
- Cilium: Kubernetes Network Policy
- Cilium: Transparent Encryption
- Istio: Security
- Linkerd: Automatic mTLS
- Amazon EKS: Network Policy
Наступний модуль
Розділ «Наступний модуль»Модуль 2.4: PKI та сертифікати — Далі ви пов’яжете мережеву ідентичність із машинерією сертифікатів, на яку Kubernetes покладається для довіреної комунікації площини управління та робочих навантажень.