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

Модуль 1.4: Захист метаданих вузла

Складність: [СЕРЕДНЯ] — критична навичка безпеки, специфічна для хмари.

Час на проходження: 30–35 хвилин.

Передумови: Модуль 1.1 (Мережеві політики), розуміння хмарних провайдерів.


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

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

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

  1. Створювати NetworkPolicies, які блокують доступ Подів до хмарних точок доступу метаданих.
  2. Проводити аудит робочих навантажень кластера на наявність ризиків розкриття сервісу метаданих.
  3. Впроваджувати примусове застосування IMDS v2 та обмеження сервісу метаданих у хмарних провайдерів.
  4. Простежувати шляхи підвищення привілеїв від облікових даних метаданих до доступу до хмарних ресурсів.

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

Ви також повинні вміти пояснити обмеження кожного засобу контролю. Правильна відповідь на цю тему — це не просто «заблокувати 169.254.169.254». Правильна відповідь називає простір імен робочого навантаження, вимогу до примусового застосування на рівні CNI, функцію провайдера, яка зменшує розкриття облікових даних, та команду перевірки, що доводить: обраний Под більше не може дістатися до сервісу метаданих.

Для іспиту CKS це практична навичка, а не тема для зазубрювання хмарних дрібниць. Вас можуть попросити написати політику, але сценарій зазвичай перевіряє, чи розумієте ви, чому політика працює і де вона перестає діяти. Найкращі відповіді поєднують швидке виконання YAML із коротким поясненням примусового застосування, перевірки та обсягу ідентифікації.


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

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

Сервіси метаданих хмарних провайдерів, такі як метадані екземпляра AWS EC2 за адресою 169.254.169.254, розкривають ідентичність вузла, деталі конфігурації та облікові дані ролі IAM. У кластері Kubernetes звичайний прикладний Под часто має маршрут через мережу вузла до цієї link-local точки доступу, якщо ви її не заблокуєте. Це означає, що вебвразливість, дефект SSRF, вихід із оболонки чи вразливий sidecar можуть перетворитися на проблему хмарної ідентичності, замість того щоб залишитися всередині початкового контейнера.

Цей модуль важливий тому, що доступ до метаданих перетинає межі, якими команди часто керують окремо. Інженери Kubernetes мислять у категоріях просторів імен, міток, сервісних акаунтів та безпеки Подів. Хмарні інженери мислять у категоріях профілів екземплярів, керованих ідентичностей, сервісних акаунтів вузлів та дозволів на об’єктне сховище. Зловмисники не зважають на цей поділ; їм потрібен лише один шлях від скомпрометованого робочого навантаження до облікових даних із корисними хмарними дозволами.

Гіпотетичний сценарій: платіжний API дозволяє користувачеві передати URL для імпорту зображення, а обробник переходить за переадресаціями зсередини Пода. Зловмисник спрямовує імпорт на хмарну точку доступу метаданих, отримує тимчасові облікові дані ролі вузла й використовує їх, щоб прочитати внутрішнє сховище (bucket), де зберігаються маніфести розгортання. Помилка в Kubernetes була незначною, але радіус ураження виник через надмірно повноважну ідентичність вузла та відсутню політику вихідного трафіку.

Підхожа ментальна модель — стійка реєстрації в готелі. Гість має просити в стійки лише послуги, призначені для його номера, але точка доступу метаданих радше схожа на залишену без нагляду шухляду з універсальним ключем у коридорі. NetworkPolicy замикає двері коридору для прикладних Подів, функції ідентичності провайдера прибирають непотрібні універсальні ключі з тієї шухляди, а правила брандмауера вузла додають запобіжник на випадок, якщо перший замок відсутній або обійдений.


+--------------------+ HTTP to link-local +----------------------+
| Compromised pod | ------------------------------> | Metadata service |
| app, shell, SSRF | 169.254.169.254 or provider | node identity, |
| vulnerable sidecar | metadata hostname | tokens, config |
+---------+----------+ +----------+-----------+
| |
| stolen temporary credentials |
v v
+--------------------+ +----------------------+
| Cloud APIs | <------------------------------ | IAM / managed |
| storage, queues, | signed requests | identity permissions |
| secrets, registry | | attached to node |
+--------------------+ +----------------------+

Ключова деталь полягає в тому, що 169.254.169.254 не є звичайним призначенням в інтернеті. Це link-local адреса IPv4, і хмарні платформи використовують її так, щоб віртуальна машина могла запитати в локальної платформи факти про саму себе без DNS чи маршрутизованого мережевого шляху. Поду не потрібен публічний доступ до інтернету, щоб спробувати цю адресу. Якщо вузол маршрутизує трафік Подів у бік мережі хоста, запит усе ще може бути достатньо локальним, щоб мати значення.

Звичайна точка входу на рівні застосунку — це SSRF, що означає: зловмисник переконує серверний компонент зробити HTTP-запит, обраний зловмисником. Оболонка контейнера ще простіша, але SSRF — це релевантний для іспиту патерн, оскільки він трапляється у звичайних вебсервісах. Застосунок думає, що завантажує мініатюру, вебхук, пакет чи URL зворотного виклику; зловмисник натомість обирає URL метаданих.

Щойно облікові дані повернуто, зловмисник перестає бути обмеженим дієсловами Kubernetes. Наступним кроком може бути aws s3 ls, виклик API Google Cloud з використанням токена доступу або запит токена керованої ідентичності Azure для Key Vault. Якщо ідентичність вузла має широкі дозволи, компрометація Пода перетворюється на компрометацію хмари навіть тоді, коли RBAC у Kubernetes був жорстким.

Захисний урок полягає в тому, щоб заблокувати шлях, перш ніж покладатися на поведінку застосунку. Розробники можуть виправляти вади SSRF, але платформним командам потрібна базова конфігурація, за якої пропущена помилка валідації не розкриває облікові дані вузла. NetworkPolicy — це засіб контролю Kubernetes, який ви справді можете застосувати в усіх просторах імен робочих навантажень, але він працює лише тоді, коли ваш CNI забезпечує примусове застосування політики вихідного трафіку.

Є ще одна тонкість: розкриття метаданих часто непомітне під час звичайних тестів застосунку. Сервіс може проходити проби готовності, обслуговувати трафік користувачів та проходити перевірки RBAC, водночас залишаючись здатним отримати облікові дані вузла. Саме тому захист метаданих належить до стандартної базової конфігурації простору імен. Не варто чекати, доки конкретна команда застосунку згадає попросити про нього.

Зупиніться та передбачте: Под не має жодних дозволів RBAC у Kubernetes, окрім читання власного ConfigMap. Роль IAM вузла може читати продакшн-сховище об’єктів. Якщо Под може дістатися до метаданих, який набір дозволів має значення після крадіжки облікових даних: роль RBAC Пода чи хмарна роль вузла?


Точки доступу метаданих за провайдерами

Розділ «Точки доступу метаданих за провайдерами»
Хмарний провайдерТочка доступу метаданихШлях, чутливий до облікових данихВажлива поведінка запиту
Вузли AWS EC2 / EKShttp://169.254.169.254/latest/meta-data/iam/security-credentials/IMDSv1 приймає прості HTTP GET-запити, коли увімкнений; IMDSv2 спершу вимагає токен сесії.
Вузли Google Compute Engine / GKEhttp://169.254.169.254 або http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/Запити мають містити Metadata-Flavor: Google; рекурсивне перелічення використовує ?recursive=true.
Вузли Azure VMs / AKShttp://169.254.169.254/metadata/identity/oauth2/tokenЗапити мають містити Metadata: true та параметр запиту api-version.

Усі три провайдери надають знайому link-local адресу 169.254.169.254, але вони не надають точно однаковий API. Ця різниця має значення як під час аналізу атаки, так і під час захисного тестування. Невдала проба без потрібного провайдеру заголовка не доводить, що точка доступу захищена; вона може лише доводити, що запит був неправильно сформований.

В AWS фокус іспиту — це різниця між IMDSv1 та IMDSv2. IMDSv1 дозволяє прямі неавтентифіковані GET-запити до шляхів метаданих, коли екземпляр це допускає. IMDSv2 вимагає, щоб викликач отримав токен за допомогою PUT-запиту до /latest/api/token, а потім надавав цей токен у наступних запитах метаданих із заголовком X-aws-ec2-metadata-token.

Ліміт переходів (hop limit) IMDSv2 — це окремий захист. AWS дозволяє налаштувати кількість мережевих переходів, які може пройти відповідь PUT на токен, із діапазоном налаштувань, задокументованим EC2. Низький ліміт переходів може зробити отримання токена неможливим із мережевого шляху контейнера, але він не замінює політику вихідного трафіку Пода, оскільки Поди з мережею хоста (host-network) та процеси на рівні вузла мають інше мережеве розташування.

У Google Cloud сервер метаданих вимагає заголовок Metadata-Flavor: Google. Шаблони запитів часто використовують ?recursive=true, щоб перелічити вкладені дерева метаданих, і саме тому неохайний захист від SSRF є небезпечним. Якщо зловмисник може додавати заголовки та рядки запиту, API метаданих стає легше перебирати. GKE також має власну поставу метаданих кластера, і сучасні рекомендації спрямовують слухачів до Workload Identity Federation для GKE, а не до покладання лише на застаріле приховування метаданих.

В Azure точка доступу IMDS також використовує 169.254.169.254, але форма запиту відрізняється. Заголовок Metadata: true є обов’язковим, а отримання токена для керованої ідентичності використовує /metadata/identity/oauth2/token із параметрами, такими як api-version та resource. Вимога заголовка зупиняє випадкові запити браузерного стилю, але вона не зупиняє Под, у якому зловмисник може запустити curl.

Саме тому засіб контролю Kubernetes навмисно нудний: заблокувати вихідний трафік до link-local адреси метаданих для прикладних робочих навантажень. Заголовки провайдера та потоки токенів зменшують випадкове розкриття й підвищують зусилля зловмисника. NetworkPolicy усуває маршрут для Подів, яким точка доступу взагалі ніколи не мала б бути потрібна.

Таблиця провайдерів також має змінити те, як ви читаєте логи. Невдалий GET-запит метаданих AWS, запит метаданих GCP із правильним заголовком та URL токена керованої ідентичності Azure — це різні сигнали, але всі вони вказують на той самий намір: робоче навантаження намагається дізнатися про вузол або отримати хмарну ідентичність. Якщо ваша телеметрія середовища виконання чи логи вихідного трафіку показують такі патерни з прикладних просторів імен, розслідуйте їх як поведінку доступу до облікових даних, а не як звичайний вихідний HTTP.


Зупиніться та передбачте: Зловмисник компрометує прикладний Под і виконує curl http://169.254.169.254/latest/meta-data/iam/security-credentials/. Він отримує тимчасові облікові дані AWS із доступом на читання S3. Що він може зробити далі, і який засіб контролю зупинив би перший мережевий запит?

Метод захисту 1: NetworkPolicy

Розділ «Метод захисту 1: NetworkPolicy»

Блокуйте вихідний трафік до IP-адреси метаданих за допомогою NetworkPolicy як вашого першого рівня захисту; на практиці це часто найпростіший спосіб виразити думку «Поди не повинні спілкуватися з секретами площини управління хмари».

Пишучи правило, сприймайте його як звуження площі поверхні вихідного трафіку Пода, а не просто як додавання списку заборон. Політика робить намір явним для кожного робочого навантаження й дає вам версійований, придатний для перегляду засіб контролю безпеки, який можна тестувати та відкочувати.

NetworkPolicy працює, обираючи Поди, а потім дозволяючи лише відповідний трафік для обраного напрямку. У NetworkPolicy API Kubernetes немає портативної дії «заборонити». Заборону ви створюєте, ізолюючи обрані Поди для вихідного трафіку, а потім пишучи правила дозволу, які пропускають призначення, що ви хочете заблокувати. Для захисту метаданих поширений патерн — це 0.0.0.0/0 з except: 169.254.169.254/32.

Поле except виконує важливу роботу. Воно каже «дозволити всі призначення IPv4, охоплені цим CIDR, окрім IP метаданих». Якщо ви натомість напишете лише політику стандартної заборони без відновлення нормального вихідного трафіку, застосунки можуть давати збій із не пов’язаних причин. Якщо ви дозволите 0.0.0.0/0 без винятку, політика документує намір, але все одно дозволяє ризиковану точку доступу.

Головне застереження — це примусове застосування. Kubernetes приймає об’єкти NetworkPolicy навіть тоді, коли встановлений плагін CNI не забезпечує їх примусового застосування. Офіційна документація наголошує, що кластер має використовувати мережевий плагін, який підтримує примусове застосування NetworkPolicy. У відповіді на CKS завжди поєднуйте YAML із пробою під час виконання, бо kubectl get networkpolicy лише доводить, що об’єкт існує.

NetworkPolicy також має межу обсягу, про яку легко забути під час іспитового тиску. Політики — це об’єкти, обмежені простором імен, а podSelector обирає Поди лише всередині простору імен політики. Застосування ідеальної політики до default не захищає production, а застосування її до production не захищає staging. Коли завдання каже «всі простори імен робочих навантажень», повторіть об’єкт або скористайтеся автоматизацією політик вашої платформи, щоб відтиснути ту саму базову конфігурацію всюди.

# Block access to metadata service
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: block-metadata
namespace: production
spec:
podSelector: {} # All pods in namespace
policyTypes:
- Egress
egress:
# Allow all EXCEPT metadata
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32

Читайте цю політику знизу вгору під час іспиту. Обрані Поди — це кожен Под у production. Ізоляцію вихідного трафіку увімкнено, бо policyTypes містить Egress. Єдине правило вихідного трафіку дозволяє призначення в усьому просторі IPv4, окрім одного /32. Оскільки NetworkPolicies є адитивними, інша політика, яка обирає ті самі Поди, могла б випадково знову дозволити метадані, якщо вона містить ширший дозвіл вихідного трафіку. Проводьте аудит ефективного набору політик, а не одного файлу окремо.

Дозвіл DNS разом із блокуванням метаданих

Розділ «Дозвіл DNS разом із блокуванням метаданих»

Багато провалів на іспиті з політикою вихідного трафіку — це самозаподіяні збої DNS. Щойно Под ізольовано для вихідного трафіку, пакети DNS до CoreDNS мають бути дозволені явно, якщо ваше ширше правило вихідного трафіку їх також не охоплює. Написання правила DNS першим робить намір читабельним і дає вам місце, де згодом можна посилити доступ до розв’язання імен.

# More complete: block metadata but allow DNS
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-metadata-allow-dns
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
# Allow DNS
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
# Allow all other traffic except metadata
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32

Показаний тут селектор DNS — це патерн, а не гарантія для кожного кластера. Деякі кластери позначають CoreDNS міткою k8s-app: kube-dns; інші використовують інші мітки або NodeLocal DNSCache. У живому іспитовому середовищі огляньте Поди та мітки в kube-system, перш ніж копіювати селектори. Правильна політика, яка не обирає жодного Пода DNS, усе одно є зламаною політикою.

Робочі навантаження з мережею хоста потребують окремої уваги. Деякі CNI не застосовують звичайну NetworkPolicy Пода до Подів hostNetwork: true так само, як вони застосовують її до звичайної мережі Подів. Це має значення, тому що привілейовані агенти, компоненти CNI, драйвери CSI та демони моніторингу часто працюють із мережею хоста. Сприймайте такі Поди як винятки, що потребують засобів контролю на рівні провайдера, правил брандмауера вузла та ідентичності з найменшими привілеями, а не лише політики простору імен.

З погляду експлуатації, політика метаданих має бути власністю на кшталт будь-якої іншої базової конфігурації безпеки. Покладіть її в Git, протестуйте в одноразовому просторі імен та розгорніть тим самим процесом, що й стандартну заборону, мітки безпеки Подів і політику допуску. Разовий kubectl apply під час інциденту може бути корисним, але тривкий захист виникає з того, що блокування метаданих стає частиною створення простору імен.


Метод захисту 2: iptables на вузлах

Розділ «Метод захисту 2: iptables на вузлах»

Налаштуйте правила iptables на кожному вузлі, щоб заблокувати доступ до метаданих, і сприймайте ці правила як хостовий запобіжник, що ловить трафік, який рівень політик CNI пропускає:

Брандмауеризація вузла — це глибокий захист, а не перший засіб контролю, до якого слід тягнутися у звичайному просторі імен Kubernetes. Її важче аудитувати через API Kubernetes, вона відрізняється залежно від дистрибутива Linux і має пережити заміну вузла. Її цінність у тому, що вона може захищати шляхи поза звичайною політикою Подів, особливо робочі навантаження з мережею хоста, некеровані процеси вузла та аварійні кластери, де CNI ще не забезпечує примусового застосування політики вихідного трафіку.

Terminal window
# Block metadata access from pods (run on each node)
iptables -A OUTPUT -d 169.254.169.254/32 -j REJECT
# Or more specifically, block forwarded pod traffic from a known pod CIDR
iptables -I FORWARD -s 10.244.0.0/16 -d 169.254.169.254/32 -j REJECT
# Make persistent (varies by OS)
iptables-save > /etc/iptables/rules.v4

Різниця між OUTPUT та FORWARD варта того, щоб її знати. OUTPUT контролює трафік, згенерований локальними процесами вузла, тоді як трафік Подів може проходити через ланцюги пересилання або специфічні для CNI ланцюги, перш ніж він залишить простір імен вузла. Якщо ваш CNI використовує eBPF чи nftables замість класичних ланцюгів iptables, точний хук може відрізнятися. Саме тому правила на рівні вузла слід тестувати на фактичній комбінації образу вузла та CNI, а не припускати їх із фрагмента блогу.

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

DaemonSet для правил iptables

Розділ «DaemonSet для правил iptables»

Цей DaemonSet використовує hostNetwork: true та привілеї NET_ADMIN, щоб мати змогу змінювати фактичні правила iptables вузла, а не ізольований мережевий простір імен Пода. Ця різниця має значення, тому що звичайні Поди контролюють лише власний мережевий простір імен, а отже зміна iptables усередині одного Пода автоматично не стає точкою примусового застосування на рівні вузла. Використання DaemonSet — це глибокий захист, коли вам потрібне примусове застосування на рівні хоста, але воно також розширює ваш радіус ураження, тож слід поєднувати його зі суворою безпекою Подів та операційними запобіжниками.

Не сприймайте цей DaemonSet як загальну рекомендацію для продакшну без перегляду. Привілейований DaemonSet, який може змінювати мережу хоста, сам по собі є цінною мішенню. Якщо ви використовуєте цей патерн, закріпіть образ, обмежте, хто може його оновлювати, запускайте його лише у системному просторі імен та зробіть правило вузла ідемпотентним, щоб повторні перезапуски не додавали дублікатів правил.

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: metadata-blocker
namespace: kube-system
spec:
selector:
matchLabels:
app: metadata-blocker
template:
metadata:
labels:
app: metadata-blocker
spec:
hostNetwork: true
containers:
- name: blocker
image: alpine:3.20
command:
- /bin/sh
- -c
- |
apk add iptables
iptables -C FORWARD -d 169.254.169.254/32 -j REJECT 2>/dev/null || \
iptables -I FORWARD -d 169.254.169.254/32 -j REJECT
sleep infinity
securityContext:
privileged: true
capabilities:
add: ["NET_ADMIN"]
tolerations:
- operator: "Exists"

Що сталося б, якби: Ви встановили --http-put-response-hop-limit 1 на ваших екземплярах EC2 з IMDSv2. Под, що працює з hostNetwork: true, намагається дістатися до сервісу метаданих. Чи захищає вас ліміт переходів? Чому так або чому ні?

Метод захисту 3: функції хмарного провайдера

Розділ «Метод захисту 3: функції хмарного провайдера»

AWS IMDSv2 (рекомендовано)

Розділ «AWS IMDSv2 (рекомендовано)»

Instance Metadata Service v2 від AWS вимагає токен сесії, ускладнюючи прямий доступ Пода, тому що викликачі мають отримати токен, перш ніж читання метаданих стане успішним.

Це посилює шлях обміну токенами проти багатьох простих скриптів ексфільтрації, і на практиці змушує зловмисника виконати повнішу послідовність запитів, а не один неавтентифікований зонд метаданих.

IMDSv2 змінює модель загроз, тому що викликачі мають спершу отримати короткоживучий токен, а це означає, що загальних зондів curl уже недостатньо для отримання метаданих. На практиці це допомагає заблокувати багато поширених атак на основі контейнерів, але вам усе одно потрібно міркувати про кількість переходів та робочі навантаження з мережею хоста, перш ніж припускати повний захист.

Важлива для CKS відмінність полягає в тому, що IMDSv2 — це не просто «метадані увімкнені чи вимкнені». Він має щонайменше дві релевантні ручки: чи вимагаються токени і скільки мережевих переходів може пройти відповідь на токен метаданих. Вимога токенів блокує запити одноразового GET у стилі IMDSv1. Суворий ліміт переходів може зупинити отримання токена зі звичайних мереж Подів, але він також може зламати легітимне ПЗ у контейнерних середовищах, якщо робоче навантаження справді потребує метаданих.

Terminal window
# IMDSv2 requires PUT request first to get token
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
# Then use token in subsequent requests
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/

Налаштуйте вузли так, щоб вони вимагали IMDSv2 за допомогою інструментів провайдера, щоб кожен екземпляр дотримувався суворішої поведінки, та перевіряйте налаштування кожної групи вузлів після оновлень, щоб запобігти дрейфу конфігурації, коли шаблони або образи змінюються:

Terminal window
# AWS CLI to enforce IMDSv2 on instance
aws ec2 modify-instance-metadata-options \
--instance-id i-1234567890abcdef0 \
--http-tokens required \
--http-put-response-hop-limit 1

Для EKS поєднуйте IMDSv2 з ізоляцією ідентичності для робочих навантажень. IAM Roles for Service Accounts та EKS Pod Identity обидва дозволяють пов’язати хмарні дозволи з сервісним акаунтом Kubernetes, замість того щоб змушувати Поди позичати профіль екземпляра вузла. Це найчистіше довгострокове виправлення: взагалі не монтуйте IAM вузла у прикладні Поди.

Є нюанс, який відповіді на іспиті часто пропускають. AWS документує, що Поди з hostNetwork: true завжди матимуть доступ до IMDS, хоча SDK мають використовувати облікові дані IRSA чи Pod Identity, коли вони налаштовані. Це означає, що блокування IMDS та ідентичність робочого навантаження доповнюють одне одного. Ідентичність робочого навантаження дає застосунку правильні облікові дані; блокування метаданих не дає тому самому застосунку відкотитися до ширшої ролі вузла.

Режим метаданих робочого навантаження GKE

Розділ «Режим метаданих робочого навантаження GKE»

Якщо робочі навантаження переміщуються між провайдерами, це ваш еквівалент засобів контролю IMDS на GCP: налаштуйте поведінку метаданих на рівні пулу вузлів, щоб робочі навантаження не припускали необмеженого розкриття метаданих за замовчуванням. У багатьох середовищах це починається як зміна «одного прапорця в конфігурації пулу» і стає надійним базовим запобіжником для всіх нових вузлів.

Запитам GCP потрібен заголовок Metadata-Flavor: Google, а рекурсивний запит може перелічити дерево метаданих під /computeMetadata/v1/. Ця вимога заголовка запобігає деяким випадковим читанням, але вона не захищає від контрольованого процесу Пода. Скомпрометований контейнер може додати заголовок так само легко, як він може виконати будь-який інший HTTP-запит.

Terminal window
# Enable the GKE Metadata Server for Workload Identity on the node pool
# (requires Workload Identity enabled on the cluster)
gcloud container node-pools update POOL_NAME \
--cluster=CLUSTER_NAME \
--workload-metadata=GKE_METADATA

Старіший режим --workload-metadata=SECURE реалізовував застаріле приховування метаданих; GKE визнав цей шлях застарілим на користь Workload Identity Federation та режиму сервера GKE_METADATA. Поточну поставу див. у захисті метаданих кластера GKE.

Поточні рекомендації GKE надають перевагу Workload Identity Federation для GKE для доступу застосунків до API Google Cloud. Дизайн ґрунтується на тому самому принципі, що й IRSA: прив’язати хмарний доступ до сервісного акаунта Kubernetes та уникнути розкриття широких облікових даних вузла довільним Подам. Сервісні акаунти вузлів також мають бути з найменшими привілеями, тому що обхід захисту метаданих набагато менш шкідливий, коли ідентичність вузла не може читати чутливі ресурси проєкту.

Instance Metadata Service (IMDS) для Azure

Розділ «Instance Metadata Service (IMDS) для Azure»

Azure вимагає специфічних заголовків, і точка доступу приймає лише виклики, що містять ці маркери безпеки, ось чому прості неавтентифіковані зонди часто зазнають невдачі, навіть коли IP досяжний.

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

Terminal window
# Azure IMDS requires Metadata header; instance probe omits resource=
curl -H "Metadata:true" \
"http://169.254.169.254/metadata/instance?api-version=2021-02-01"

URL токена керованої ідентичності без resource= може повернути HTTP 400, навіть коли IMDS досяжний. Використовуйте цей шлях токена лише тоді, коли вам потрібен реальний тест облікових даних, а не як простий зонд досяжності.

В AKS надавайте перевагу Microsoft Entra Workload ID для прикладних Подів, яким потрібні ресурси Azure. Він використовує токени сервісних акаунтів Kubernetes та федерацію OIDC, щоб робоче навантаження могло обміняти свою спроєктовану ідентичність на облікові дані Azure. Це безпечніше, ніж давати кожному Поду шлях до керованої ідентичності вузла, а потім сподіватися, що помилки застосунку ніколи не дістануться до IMDS.

Між провайдерами патерн послідовний: функції метаданих провайдера зменшують потужність точки доступу, а політика вихідного трафіку Kubernetes зменшує досяжність до неї. Ролі вузла з найменшими привілеями зменшують радіус ураження, якщо обхід усе ж стається. Ідентичність робочого навантаження зменшує саму причину, через яку Подам узагалі торкатися метаданих вузла.

Цей кут зору, орієнтований на ідентичність, є різницею між «заблоковано сьогодні» та «безпечно за дизайном». Якщо Под справді потребує хмарного доступу, дайте йому вузько обмежену ідентичність робочого навантаження та доведіть, що застосунок може використати цей шлях. Якщо він не потребує хмарного доступу, метадані мають бути недосяжними. Якщо єдиний робочий шлях облікових даних — це роль вузла, кластер усе ще залежить від спільної інфраструктурної ідентичності там, де робочі навантаження мали б бути ізольованими.


Тестування доступу до метаданих

Розділ «Тестування доступу до метаданих»

Перевірка, що Под не може дістатися до метаданих

Розділ «Перевірка, що Под не може дістатися до метаданих»

Використовуйте цю перевірку на ранньому етапі вашого процесу валідації, щоб підтвердити, що політика активна для тестового Пода в цільовому просторі імен. Якщо метадані заблоковано, ваш зонд має зазнати невдачі або тайм-ауту; така поведінка — це очікуваний сигнал безпеки, а не помилка платформи.

Завжди запускайте зонд із Пода, обраного політикою. Тестування з вашого ноутбука, з оболонки вузла чи з Пода в іншому просторі імен майже нічого не каже про робоче навантаження, яке ви мали намір захистити. Найкорисніший тест називає простір імен, використовує короткий тайм-аут та виводить явне повідомлення для обох результатів.

Terminal window
# Create test pod
kubectl run test-pod --image=curlimages/curl --rm -i --restart=Never -- \
curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/
# Expected: Connection timeout or refused
# If you see instance metadata, protection isn't working!

Коли ви тестуєте специфічну для провайдера поведінку, використовуйте реальну форму запиту провайдера. На AWS IMDSv2 простий GET може зазнати невдачі, бо потрібен токен, тоді як PUT-запит токена все ще може бути успішним. На GCP та Azure відсутні заголовки можуть створити хибну впевненість. Хороший план валідації має і простий зонд досяжності, і зонд у формі провайдера.

Terminal window
# AWS IMDSv2 token probe: this should fail from ordinary application pods
kubectl run aws-token-probe --image=curlimages/curl --rm -i --restart=Never -- \
curl -sS --connect-timeout 2 -X PUT \
-H "X-aws-ec2-metadata-token-ttl-seconds: 60" \
http://169.254.169.254/latest/api/token
# GCP-shaped probe: this should fail from ordinary application pods
kubectl run gcp-metadata-probe --image=curlimages/curl --rm -i --restart=Never -- \
curl -sS --connect-timeout 2 \
-H "Metadata-Flavor: Google" \
"http://169.254.169.254/computeMetadata/v1/?recursive=true"

У локальному кластері kind зазвичай немає справжнього хмарного сервісу метаданих, тож попередній зонд може й так дати тайм-аут. Це все ще корисно для відпрацювання послідовності команд, але не доводить хмарного примусового застосування. Доказ у kind — це те, що встановлено CNI з примусовим застосуванням NetworkPolicy, політика обирає Под, нормальний вихідний трафік усе ще працює, а зонд метаданих стабільно зазнає невдачі.

Перевірка, що NetworkPolicy застосовано

Розділ «Перевірка, що NetworkPolicy застосовано»

Після запуску зонда під час виконання огляньте об’єкти політик та селектори Подів, щоб ви могли довести обсяг і охоплення. Ключове питання — це не лише чи заблоковано трафік, а чи правильні простори імен та робочі навантаження фактично обрані правилом.

Terminal window
# List network policies
kubectl get networkpolicies -n production
# Describe specific policy
kubectl describe networkpolicy block-metadata -n production
# Check if pod is selected by policy
kubectl get pod test-pod -n production --show-labels

Зробіть ще одну перевірку на випадкові правила повторного дозволу. NetworkPolicies поєднуються адитивно, тож інша політика вихідного трафіку може дозволити трафік, навіть коли ваша політика метаданих виглядає правильною сама по собі. У малих іспитових кластерах kubectl get networkpolicy -A досить швидкий, щоб переглянути вручну. У продакшні експортуйте політики й переглядайте їх за допомогою тестів політик як коду.

Коли тест зазнає невдачі, налагоджуйте пошарово. Спершу підтвердьте, що зондувальний Под перебуває в потрібному просторі імен і має мітки, обрані політикою. Потім підтвердьте, що CNI забезпечує примусове застосування NetworkPolicy. Далі огляньте інші політики, які обирають той самий Под. Нарешті, протестуйте запити у формі провайдера, щоб ви не сприйняли неправильно сформований запит метаданих за заблокований шлях.


Повний приклад безпеки

Розділ «Повний приклад безпеки»

Наступний приклад зводить докупи поведінку політики вихідного трафіку, що використовується у продакшн-патернах: дозволити внутрішню комунікацію сервісів, дозволити DNS та явно виключити метадані з ширшого набору вихідного трафіку. Ця форма корисна, бо вона зберігає повсякденне з’єднання, водночас тримаючи ризиконосну link-local точку доступу недосяжною.

Сприймайте це як базову конфігурацію простору імен для звичайних прикладних робочих навантажень, а не як об’єкт для копіювання-вставлення по всьому кластеру. Системні простори імен можуть потребувати контрольованого доступу до метаданих для початкового завантаження вузла, хмарних контролерів, драйверів CSI чи агентів провайдера. Прикладні простори імен зазвичай ні. Безпечне значення за замовчуванням — застосувати цю форму до просторів імен робочих навантажень і створювати вузькі винятки лише тоді, коли власник може пояснити потребу.

# Apply to every namespace that runs workloads
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-metadata
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
egress:
# Allow DNS resolution
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
# Allow cluster internal communication
- to:
- ipBlock:
cidr: 10.0.0.0/8
# Allow external but block metadata
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32

Уникайте широкого блокування link-local, доки ви не зіставите всіх специфічних для провайдера агентів. Наприклад, EKS Pod Identity використовує іншу link-local точку доступу для агента Pod Identity, а інші CNI чи локальні сервіси вузла можуть використовувати link-local простір для легітимного кластерного водопроводу. Дружня до CKS відповідь — це точний /32 метаданих; ширші діапазони належать до проєктного перегляду, а не до іспитового спринту.

Приклад безпеки все ще потребує роботи з ідентичністю. Якщо роль вузла має дозволи в стилі адміністратора, блокування метаданих знижує розкриття, але не виправляє основний радіус ураження. Використовуйте ролі вузла з найменшими привілеями для kubelet та доповнень вузла, а потім прив’язуйте хмарні дозволи застосунку через IRSA, EKS Pod Identity, Workload Identity Federation для GKE чи Microsoft Entra Workload ID. Так один обхід не успадкує всю хмарну владу вузла.

Для розгортання у продакшні почніть із режиму спостереження в некритичному просторі імен. Створіть одноразовий Под, протестуйте DNS, протестуйте потрібні зовнішні призначення, протестуйте метадані та запишіть очікувані результати. Потім застосуйте ту саму базову конфігурацію до реального простору імен робочих навантажень під час вікна обслуговування або через прогресивну доставку. Блокування метаданих зазвичай має низький ризик для прикладних Подів, але ізоляція вихідного трафіку може виявити приховані залежності, що заслуговують на контрольоване розгортання.

Тримайте обробку винятків нудною та явною. Якщо одне робоче навантаження стверджує, що потребує метаданих, запитайте, який API воно викликає, які облікові дані очікує і чому ідентичність робочого навантаження не може задовольнити ту саму потребу. Більшість винятків зменшується після цієї розмови. Ті, що залишаються, мають бути позначені, мати власника та бути протестованими, бо тепер вони є частиною довіреної обчислювальної бази кластера.


Реальні іспитові сценарії

Розділ «Реальні іспитові сценарії»

Сценарій 1: Блокування доступу до метаданих для простору імен

Розділ «Сценарій 1: Блокування доступу до метаданих для простору імен»

Це патерн, який екзаменатори часто перевіряють: чи можете ви застосувати політику з мінімальним надмірним охопленням і водночас зберегти передбачувану поведінку. Фрагмент навмисно обмежений простором імен, щоб ви відпрацьовували гранулярність площини управління, не торкаючись системних компонентів.

Уважно читайте формулювання завдання. Якщо воно каже «усі Поди в просторі імен production», використовуйте podSelector: {} у тому просторі імен. Якщо воно каже «Поди з міткою tier=frontend», не ізолюйте випадково кожне робоче навантаження. CKS винагороджує точність, бо широкі політики можуть зламати не пов’язані Поди, а вузькі політики можуть залишити вразливий Под відкритим.

Terminal window
# Create NetworkPolicy to block metadata
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: block-cloud-metadata
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32
EOF
# Verify
kubectl get networkpolicy block-cloud-metadata -n production

Сценарій 2: Тестування та перевірка блокування

Розділ «Сценарій 2: Тестування та перевірка блокування»

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

Найшвидша безпечна для іспиту перевірка — це Под curl із коротким тайм-аутом і чітким резервним повідомленням. Не чекайте довгого TCP-тайм-ауту. Не використовуйте робочий прикладний Под, якщо завдання не просить вас уникнути створення тестового Пода. Одноразовий зонд легко прибрати, і він залишає менше стану по собі.

Terminal window
# Create test pod
kubectl run metadata-test --image=curlimages/curl -n production --rm -i --restart=Never -- \
curl -s --connect-timeout 3 http://169.254.169.254/latest/meta-data/ || echo "BLOCKED (expected)"

Сценарій 3: Дозвіл доступу конкретному Поду

Розділ «Сценарій 3: Дозвіл доступу конкретному Поду»

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

Це має бути рідкістю. У сучасних кластерах агент моніторингу, якому потрібні хмарні API, зазвичай має використовувати прив’язку ідентичності робочого навантаження, а не читати сервіс метаданих вузла. Якщо виняток усе ж потрібен, ізолюйте його за простором імен та міткою, вимагайте названого власника та додайте команду перевірки, що доводить: лише обрані Поди можуть дістатися до точки доступу.

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

# Most pods blocked, but monitoring pod needs metadata
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring-metadata
namespace: monitoring
spec:
podSelector:
matchLabels:
app: cloud-monitor
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0 # All traffic including metadata

Політика винятку вище навмисно тупа, щоб ви могли побачити форму. У продакшні поєднуйте її з вужчими портами, ідентичністю робочого навантаження та засобами контролю допуску, що не дають випадковим Подам копіювати мітку app: cloud-monitor. Мітки не є межею безпеки, доки політика допуску не контролює, хто може їх встановлювати.


Зупиніться та передбачте: Ви блокуєте доступ до метаданих для простору імен production за допомогою NetworkPolicy. Але ви не застосовуєте її до kube-system. Чому це може бути навмисним, і який ризик це створює?

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

+------------------------------------------------------------------+
| Metadata protection layers |
+------------------------------------------------------------------+
| 1. Workload identity: give pods their own least-privilege role |
| 2. NetworkPolicy: block app-pod egress to 169.254.169.254/32 |
| 3. Provider posture: require IMDSv2 or provider metadata controls |
| 4. Node firewall: block unexpected host and forwarded paths |
| 5. Pod security: limit hostNetwork, privileged pods, NET_ADMIN |
| 6. Audit: probe after changes and review cloud credential use |
+------------------------------------------------------------------+

Порядок є навмисним. Ідентичність робочого навантаження зменшує залежність від облікових даних вузла, перш ніж ви почнете налаштовувати мережеві шляхи. NetworkPolicy усуває маршрут для звичайних Подів. Засоби контролю провайдера ускладнюють зловживання метаданими, якщо маршрут залишається. Брандмауеризація вузла покриває незручні хостові шляхи. Безпека Подів зменшує кількість робочих навантажень, які можуть обійти звичайну мережу Подів.

Аудит замикає цикл. Шукайте Поди з hostNetwork: true, Поди з NET_ADMIN, привілейовані DaemonSets, простори імен без політики вихідного трафіку та ролі вузла з широким доступом до сховища чи секретів. Кластер може пройти простий тест curl і все одно бути ризикованим, якщо один привілейований агент запускає довільні робочі навантаження користувачів або якщо облікові дані вузла залишаються надмірно повноважними.

Нарешті, стежте за хмарними логами. AWS CloudTrail, журнали аудиту Google Cloud та журнали активності Azure можуть виявити неочікуване використання ідентичностей вузлів. Якщо команди застосунків мають використовувати ідентичність робочого навантаження, раптовий сплеск викликів API ролі вузла з прикладного шляху — це сигнал розслідувати як конфігурацію ідентичності, так і досяжність метаданих.

Політика допуску — це ще один корисний допоміжний рівень. Ви можете обмежити hostNetwork, привілейовані контейнери та NET_ADMIN, щоб команди застосунків не могли випадково створити Поди, які обходять звичайний мережевий шлях. Це не блокує метадані напряму, але зменшує набір робочих навантажень, що потребують спеціального перегляду, і тримає модель NetworkPolicy легшою для осмислення.

Останній рівень — це документація для винятків. Кожен простір імен чи робоче навантаження, що може дістатися до метаданих, має мати власника, причину та план заміни, якщо ідентичність робочого навантаження може усунути потребу. Незадокументовані винятки — це там, де дрейф перетворюється на розкриття: за пів року ніхто не пам’ятає, чому Поду були потрібні облікові дані вузла, але шлях усе ще існує.


  • 169.254.0.0/16 — це link-local. Цей діапазон зарезервовано для локальної мережевої комунікації, а не для маршрутизації в інтернеті. Хмарні провайдери використовують цю властивість для метаданих, бо екземпляр може дістатися до сервісу платформи без залежності від DNS, публічних маршрутів чи керованого клієнтом шлюзу.

  • Об’єкт NetworkPolicy може бути присутнім і все одно нічого не робити. Kubernetes вимагає мережевий плагін, який підтримує примусове застосування NetworkPolicy. Саме тому перевірка має містити зонд під час виконання з обраного Пода, а не лише огляд YAML.

  • Заголовки метаданих — це не авторизація. GCP вимагає Metadata-Flavor: Google, а Azure вимагає Metadata: true, але зловмисник із виконанням коду всередині Пода може додати ці заголовки. Сприймайте заголовки провайдера як засоби контролю форми запиту, а не як заміну ідентичності та мережевої ізоляції.

  • Блокування всього link-local трафіку може бути надто широким. AWS EKS Pod Identity використовує link-local точку доступу, відмінну від IP метаданих EC2. Блокування 169.254.169.254/32 точно націлюється на сервіс метаданих вузла; блокування всього діапазону 169.254.0.0/16 потребує перегляду агентів провайдера.


ПомилкаЧому це поганоКращий підхід
Застосувати політику, але ніколи не тестувати з обраного ПодаОб’єкт може існувати, навіть коли CNI не забезпечує примусового застосування NetworkPolicy або podSelector нічого не збігає.Запустіть зонд curl із коротким тайм-аутом із точного простору імен та міток, охоплених політикою.
Забути DNS після ввімкнення ізоляції вихідного трафікуПоди дають збій із помилками розв’язання імен, і виправлення метаданих звинувачують у не пов’язаних збоях.Додайте явний вихідний трафік TCP і UDP на порт 53 до фактичних цілей CoreDNS чи NodeLocal DNS.
Блокувати kube-system тією самою політикою робочого навантаженняХмарні контролери, драйвери CSI, агенти вузла чи доповнення провайдера можуть легітимно потребувати шляхів на кшталт метаданих.Обмежте базове блокування метаданих прикладними просторами імен і проєктуйте системні винятки окремо.
Припускати, що IMDSv2 робить NetworkPolicy непотрібноюПоди з мережею хоста, процеси вузла, відмінності провайдерів та дрейф конфігурації все одно можуть розкрити шляхи метаданих.Вимагайте IMDSv2, де доступно, і все одно блокуйте вихідний трафік метаданих для звичайних Подів робочих навантажень.
Використовувати 169.254.0.0/16 без перегляду агентів провайдераШирокі блокування link-local можуть зламати EKS Pod Identity, NodeLocal DNS чи інші локальні сервіси вузла.Почніть із 169.254.169.254/32; розширюйте лише після зіставлення легітимних link-local залежностей.
Давати кожному робочому навантаженню хмарні дозволи вузлаОдин SSRF чи вихід з оболонки може успадкувати роль вузла й дістатися до не пов’язаних хмарних ресурсів.Використовуйте IRSA, EKS Pod Identity, Workload Identity Federation для GKE чи Microsoft Entra Workload ID.
Сприймати мітки як безпечну межу виняткуКористувач, який може встановлювати мітки, може скопіювати мітку дозволу метаданих на неавторизований Под.Захищайте мітки винятків політикою допуску та вузьким RBAC для оновлень робочих навантажень.
Тестувати лише простий GET-запитЗасоби контролю провайдера можуть відхилити неправильно сформовані запити, тоді як правильно сформований запит токена все одно працює.Тестуйте AWS token PUT, GCP Metadata-Flavor: Google та шляхи Azure Metadata: true, коли доречно.

  1. Пентестер отримує оболонку в прикладному Поді й виконує curl http://169.254.169.254/latest/meta-data/iam/security-credentials/node-role. Відповідь містить тимчасові облікові дані AWS. Що дало збій і які дві зміни ви зробили б першими?

    Відповідь Под зміг дістатися до сервісу метаданих вузла, а роль вузла мала корисні дозволи. По-перше, застосуйте вихідну NetworkPolicy до простору імен робочого навантаження, яка дозволяє нормальні призначення, окрім `169.254.169.254/32`, а потім перевірте з Подом, обраним політикою. По-друге, увімкніть примусове застосування IMDSv2 на групі вузлів і перенесіть дозволи застосунку на IRSA чи EKS Pod Identity, щоб Под не потребував ролі вузла. Мережеве виправлення блокує маршрут; виправлення ідентичності зменшує радіус ураження.
  2. Колега застосовує політику блокування метаданих до кожного простору імен, включно з kube-system. Хмарний контролер починає давати збій. Чи слід вам прибрати весь захист метаданих, чи створити виняток?

    Відповідь Створіть обмежений виняток або приберіть політику робочого навантаження із системних просторів імен, але збережіть захист метаданих для прикладних просторів імен. Системні компоненти, такі як хмарні контролери, автоскейлери, агенти провайдера та драйвери CSI, можуть мати легітимні залежності від метаданих. Безпечніший дизайн — це політика для конкретного простору імен для робочих навантажень користувачів, засоби контролю провайдера на вузлах, ролі вузла з найменшими привілеями та окремий перегляд для системних компонентів.
  3. Ваші вузли AWS вимагають IMDSv2 та використовують ліміт переходів 1. Рецензент каже, що NetworkPolicies для метаданих є зайвими. Чи правильно це для всіх Подів?

    Відповідь Ні. IMDSv2 зменшує ризик, але це специфічний для AWS засіб контролю провайдера, і він не замінює політику вихідного трафіку Kubernetes. Поди з мережею хоста та процеси вузла мають інше мережеве розташування, а дрейф конфігурації може послабити опції метаданих на майбутніх вузлах. Тримайте NetworkPolicy для звичайних просторів імен робочих навантажень, забезпечуйте примусове застосування IMDSv2 на рівні провайдера та аудитуйте Поди `hostNetwork: true` окремо.
  4. Под GKE не може дістатися до http://169.254.169.254/computeMetadata/v1/ простим GET-запитом. Ваш колега робить висновок, що метадані захищено. Який додатковий тест вам слід запустити?

    Відповідь Запустіть запит у формі провайдера з `Metadata-Flavor: Google` і додайте `?recursive=true`, якщо ви перевіряєте, чи можна перелічити дерева метаданих. Простий GET може зазнати невдачі, бо відсутній потрібний заголовок, а не тому, що мережевий шлях заблоковано. Надійний сигнал — це тайм-аут чи збій з'єднання з обраного Пода, коли запит містить правильний заголовок провайдера.
  5. Ви пишете вихідну NetworkPolicy лише з правилом дозволу DNS. Метадані заблоковано, але застосунок не може дістатися до свого зовнішнього API. Що зробила політика?

    Відповідь Обрані Поди стали ізольованими для вихідного трафіку, і лише трафік DNS збігся з правилом дозволу. NetworkPolicy не починається з «дозволити все, окрім моєї заборони»; вона починає дозволяти лише той трафік, який ви явно описуєте, щойно застосовується ізоляція. Додайте друге правило вихідного трафіку, яке дозволяє потрібні призначення, такі як `0.0.0.0/0` з `except: 169.254.169.254/32`, або вужчий набір CIDR, якщо застосунок має фіксовані призначення.
  6. Команда безпеки блокує 169.254.0.0/16 для кожного Пода. Після міграції на EKS Pod Identity деякі робочі навантаження не можуть отримати облікові дані від агента Pod Identity. Що, найімовірніше, сталося?

    Відповідь Політика була ширшою за точку доступу метаданих EC2. EKS Pod Identity використовує link-local адресу, яка не є `169.254.169.254`, тож суцільне блокування link-local може зламати легітимний водопровід ідентичності провайдера. Використовуйте точний `/32` метаданих для сервісу метаданих вузла, доки ви не зіставите кожну легітимну link-local залежність і не створите явні винятки.
  7. Простір імен робочого навантаження має правильну політику блокування метаданих, але один привілейований DaemonSet із hostNetwork: true усе одно може дістатися до метаданих. Чи зламана NetworkPolicy?

    Відповідь Не обов'язково. Поди з мережею хоста часто перебувають поза звичайним мережевим шляхом Подів, який захищає NetworkPolicy, залежно від CNI та реалізації. Сприймайте той DaemonSet як окреме високоризикове робоче навантаження: приберіть мережу хоста, якщо можливо, прив'яжіть його до ідентичності робочого навантаження з найменшими привілеями, обмежте, хто може його оновлювати, та розгляньте правила брандмауера на рівні вузла для хостових шляхів.

Завдання: Заблокувати доступ до метаданих та перевірити захист на кластері kind v1.35. Сприймайте це як контрольовану вправу: спершу спостерігайте поточну поведінку, потім застосуйте зміни політики, потім запустіть проби після зміни, щоб стан безпеки був відтворюваним для майбутніх аудитів.

  • У вас є доступний кластер Kubernetes v1.35 на kind, і ви можете створювати одноразові простори імен, не впливаючи на жодне спільне середовище.
  • Переконайтеся, що ваш кластер kind забезпечує примусове застосування NetworkPolicy (стандартний kindnet kind v0.24+ це робить; старіші кластери можуть потребувати Calico/Cilium).
  • kubectl вказує на тестовий кластер, а kubectl config current-context показує одноразовий контекст, який ви маєте намір використати.
  • Ви розумієте, що kind не має справжнього хмарного IMDS, тож попередній зонд може зазнати невдачі, бо точка доступу відсутня.

Крок 1: Створіть простір імен робочого навантаження та доведіть, що нормальний вихідний трафік працює

Розділ «Крок 1: Створіть простір імен робочого навантаження та доведіть, що нормальний вихідний трафік працює»
Terminal window
# Setup namespace
kubectl create namespace metadata-test
# External egress should work before protection
kubectl run external-before \
--image=curlimages/curl \
-n metadata-test \
--rm -i --restart=Never -- \
curl -sS --connect-timeout 5 https://kubernetes.io -o /dev/null -w "HTTP %{http_code}\n"
  • Простір імен існує, і ви можете перелічити його за допомогою kubectl get namespace metadata-test, перш ніж створювати будь-яку політику.
  • Зонд зовнішнього вихідного трафіку повертає код статусу HTTP, що доводить: звичайний вихідний трафік працює до ізоляції.

Крок 2: Запустіть зонд метаданих перед застосуванням політики

Розділ «Крок 2: Запустіть зонд метаданих перед застосуванням політики»
Terminal window
# In kind this usually prints METADATA_BLOCKED_OR_ABSENT because there is no cloud IMDS.
# In a real cloud cluster this might return metadata if protection is missing.
kubectl run metadata-before \
--image=curlimages/curl \
-n metadata-test \
--rm -i --restart=Never -- \
sh -c 'curl -sS --connect-timeout 3 http://169.254.169.254/latest/meta-data/ || echo METADATA_BLOCKED_OR_ABSENT'
  • У kind команда завершується, не повертаючи хмарних метаданих, що очікувано, бо реального IMDS локально немає.
  • У реальному хмарному кластері будь-які повернуті метадані сприймаються як знахідка й мають негайно спричинити перегляд політики.

Крок 3: Застосуйте NetworkPolicy, що дозволяє нормальний вихідний трафік, окрім IMDS

Розділ «Крок 3: Застосуйте NetworkPolicy, що дозволяє нормальний вихідний трафік, окрім IMDS»
Terminal window
cat <<'EOF' | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: block-node-metadata
namespace: metadata-test
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32
EOF
  • Політика застосовується без помилок валідації, і kubectl get networkpolicy -n metadata-test перелічує новий об’єкт.
  • Політика використовує 169.254.169.254/32, а не суцільний link-local діапазон, що міг би зламати агентів провайдера.

Крок 4: Перевірте об’єкт політики та обраний простір імен

Розділ «Крок 4: Перевірте об’єкт політики та обраний простір імен»
Terminal window
kubectl get networkpolicy -n metadata-test
kubectl describe networkpolicy block-node-metadata -n metadata-test
kubectl get namespace metadata-test --show-labels
  • block-node-metadata з’являється у просторі імен metadata-test, що підтверджує: об’єкт потрапив у потрібний обсяг.
  • Правило вихідного трафіку показує як дозволи DNS, так і виняток ipBlock, що підтверджує: політика зберігає нормальне розв’язання імен.

Крок 5: Зонд після політики

Розділ «Крок 5: Зонд після політики»
Terminal window
kubectl run metadata-after \
--image=curlimages/curl \
-n metadata-test \
--rm -i --restart=Never -- \
sh -c 'curl -sS --connect-timeout 3 http://169.254.169.254/latest/meta-data/ || echo METADATA_BLOCKED_OR_ABSENT'
kubectl run external-after \
--image=curlimages/curl \
-n metadata-test \
--rm -i --restart=Never -- \
curl -sS --connect-timeout 5 https://kubernetes.io -o /dev/null -w "HTTP %{http_code}\n"
  • Зонд метаданих не повертає метаданих, а результат задокументовано як заблокований політикою або відсутній у kind.
  • Зонд зовнішнього вихідного трафіку все ще повертає код статусу HTTP, доводячи, що політика не створила випадково широкого збою.
  • Якщо метадані успішні після політики, підтвердьте, що ваш CNI забезпечує примусове застосування NetworkPolicy і що жодна інша політика не дозволяє призначення повторно.

Крок 6: Ілюстративна валідація лише для хмари

Розділ «Крок 6: Ілюстративна валідація лише для хмари»

Ці перевірки є ілюстративними, бо kind не надає метаданих AWS, GCP чи Azure. Запускайте їх лише в авторизованому хмарному тестовому кластері, де ви розумієте наслідки.

Terminal window
# AWS IMDSv2 token request: should fail from ordinary application pods
kubectl run aws-imdsv2-after \
--image=curlimages/curl \
-n metadata-test \
--rm -i --restart=Never -- \
sh -c 'curl -sS --connect-timeout 3 -X PUT \
-H "X-aws-ec2-metadata-token-ttl-seconds: 60" \
http://169.254.169.254/latest/api/token || echo AWS_TOKEN_BLOCKED'
# GCP metadata request: should fail from ordinary application pods
kubectl run gcp-metadata-after \
--image=curlimages/curl \
-n metadata-test \
--rm -i --restart=Never -- \
sh -c 'curl -sS --connect-timeout 3 \
-H "Metadata-Flavor: Google" \
"http://169.254.169.254/computeMetadata/v1/?recursive=true" || echo GCP_METADATA_BLOCKED'
  • Запити метаданих у формі хмари зазнають невдачі зі звичайних Подів робочих навантажень, включно із запитами, що використовують потрібні провайдеру заголовки чи метод токена.
  • Будь-який Под, якому легітимно потрібен хмарний доступ, використовує ідентичність робочого навантаження, а не метадані вузла, і прив’язка має найменші привілеї.
Terminal window
# Cleanup
kubectl delete namespace metadata-test

IP метаданих заблоковано або відсутній, зовнішній доступ усе ще працює, а політику забезпечує CNI, що підтримує вихідну NetworkPolicy. Успішний результат — це чіткий сигнал «пройдено/провалено»: точки доступу метаданих недосяжні з тестового робочого навантаження, тоді як загальний вихідний трафік усе ще успішний.


Ризик сервісу метаданих: Точки доступу метаданих можуть витікати облікові дані IAM, ідентичність вузла та контекст конфігурації; коли вони залишені відкритими, вони є прямим мостом від компрометації Пода до дій із хмарними ресурсами. Приклади атак у модулі — це нагадування, що зловживання метаданими слід розглядати як практичний ризик, а не як абстрактну тему хмарного посилення.

Методи захисту: Цей модуль поєднує чотири рівні захисту: обмеження вихідного трафіку NetworkPolicy, примусове застосування IMDS хмарного провайдера, примусове застосування iptables на рівні хоста через нативні для Kubernetes робочі процеси та архітектурні вибори Пода, такі як уникання непотрібних привілеїв hostNetwork.

Найкращі практики: Застосовуйте захист до просторів імен робочих навантажень за замовчуванням, тримайте вихідний трафік DNS явно дозволеним та використовуйте пошарові засоби контролю, щоб провал одного засобу не розкривав метадані. Регулярно запускайте проби валідації після подій дрейфу, бо постава засобів контролю надійна лише тоді, коли її доведено повторюваними перевірками.

Ці пункти безпечні лише тоді, коли вони підкріплені повторюваними перевірками: якщо ви не можете спостерігати поведінку «заблоковано/дозволено» на вимогу, вам слід сприймати засіб контролю як неповний, навіть якщо намір задокументовано.

Поради до іспиту: Зосередьтеся на чистому написанні NetworkPolicies з пам’яті, включно з винятками ipBlock та дозволами DNS, і пам’ятайте, що запобігання атакам на метадані — це ціль глибокого захисту, а не один перемикач.

Найкоротша безпечна відповідь усе одно є пошаровою. Заблокуйте 169.254.169.254/32 для звичайних Подів робочих навантажень, перевірте, що обраний Под не може дістатися до точки доступу, вимагайте посилення метаданих провайдера на вузлах та перенесіть хмарні дозволи застосунку на ідентичність робочого навантаження. Якщо один із цих рівнів відсутній, назвіть залишковий ризик, замість того щоб удавати, ніби кластер повністю захищений.

Коли часу мало, надайте пріоритет засобу контролю, який іспит може спостерегти. Напишіть NetworkPolicy, запустіть зонд та назвіть застереження щодо CNI. Якщо завдання містить конфігурацію провайдера, додайте IMDSv2, поставу метаданих робочого навантаження GKE чи ідентичність робочого навантаження Azure, як вимагається. Якщо завдання просить рекомендацію щодо дизайну, починайте з ідентичності робочого навантаження, бо вона усуває потребу прикладних Подів використовувати метадані вузла взагалі.

Звичка, яку варто зберегти після іспиту, проста: кожен новий простір імен робочого навантаження має відповісти на три питання, перш ніж прибуде продакшн-трафік. Чи можуть звичайні Поди дістатися до метаданих вузла? Яку ідентичність вони використовують для хмарних API? Хто володіє винятком, якщо відповідь навмисно незвичайна у продакшні?


Перевірка для слухача

Розділ «Перевірка для слухача»

NetworkPolicy — це засіб контролю Kubernetes, який ви справді можете застосувати в усіх просторах імен робочих навантажень, але він працює лише тоді, коли ваш CNI забезпечує примусове застосування політики вихідного трафіку.

Використайте це речення як швидкий самотест. Якщо ви можете пояснити, чому обидві половини мають значення, ви розумієте суть цього модуля: Kubernetes приймає об’єкт політики, але справжній захист виникає з примусового застосування плюс зонда з обраного робочого навантаження.


Модуль 1.5: Безпека GUI — Захист Kubernetes Dashboard та вебінтерфейсів.

Цей перехід є навмисним: щойно ви взяли під контроль метадані та вихідний трафік робочих навантажень, ви можете застосувати ту саму дисципліну моделювання загроз до адміністративних поверхонь, зорієнтованих на користувача.

  • Kubernetes Network Policies — Офіційна поведінка NetworkPolicy, включно з вимогою мережевого плагіна з примусовим застосуванням.
  • AWS EC2 instance metadata — Офіційні категорії метаданих EC2, включно з ідентичністю екземпляра та шляхами облікових даних ролі IAM.
  • AWS IMDSv2 session tokens — Офіційний потік отримання та використання токенів IMDSv2.
  • AWS instance metadata options — Офіційні опції метаданих, включно з вимогами до токенів та налаштуваннями ліміту переходів.
  • AWS limiting metadata access — Офіційні рекомендації AWS щодо обмеження доступу до метаданих екземпляра.
  • Amazon EKS IAM roles for service accounts — Офіційні рекомендації IRSA для прив’язки дозволів AWS до сервісних акаунтів Kubernetes.
  • Amazon EKS Pod Identity — Офіційні рекомендації EKS Pod Identity для облікових даних AWS, обмежених робочим навантаженням.
  • Google Compute Engine metadata queries — Офіційна точка доступу метаданих GCP, заголовок та поведінка рекурсивного запиту.
  • GKE cluster metadata protection — Офіційні рекомендації GKE щодо захисту метаданих кластера.
  • Workload Identity Federation for GKE — Офіційні рекомендації щодо ідентичності робочого навантаження GKE.
  • Azure Instance Metadata Service — Офіційна точка доступу IMDS Azure, заголовки та шлях токена керованої ідентичності.
  • AKS workload identity overview — Офіційні рекомендації AKS щодо Microsoft Entra Workload ID.
  • RFC 3927 IPv4 link-local addressing — Авторитетна довідка щодо link-local діапазону 169.254.0.0/16.