Модуль 3.4: Мережева безпека хоста
Складність:
[MEDIUM]- Мережеве адміністрування з фокусом на безпекуЧас на виконання: 35-40 хвилин
Передумови: Модуль 3.3 (Зміцнення ядра), базові знання мережевих технологій
Що ви зможете робити
Розділ «Що ви зможете робити»Після завершення цього модуля ви зможете:
- Налаштувати брандмауери на рівні хоста (iptables/nftables) для захисту портів вузлів Kubernetes
- Аудитувати відкриті сервіси та порти вузлів на наявність непотрібної поверхні атаки
- Реалізувати мережеву сегментацію між площиною управління, робочими вузлами та зовнішніми мережами
- Діагностувати проблеми мережевої безпеки хоста, що обходять NetworkPolicies на рівні контейнерів
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»Хоча NetworkPolicy Kubernetes контролюють трафік між Pod, мережева безпека на рівні хоста захищає самі вузли. Відкриті порти, відкриті сервіси та нефільтрований трафік на рівні хоста можуть повністю обійти ізоляцію контейнерів.
CKS очікує, що ви розумієте як контейнерну, так і хостову мережеву безпеку.
Поверхня мережевої атаки хоста
Розділ «Поверхня мережевої атаки хоста»┌─────────────────────────────────────────────────────────────┐│ ПОВЕРХНЯ МЕРЕЖЕВОЇ АТАКИ ХОСТА │├─────────────────────────────────────────────────────────────┤│ ││ Інтернет / Зовнішня мережа ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────┐ ││ │ ХОСТ (вузол Kubernetes) │ ││ │ │ ││ │ Відкриті сервіси: │ ││ │ ├── :22 SSH (управління) │ ││ │ ├── :6443 API-сервер (площина управління) │ ││ │ ├── :10250 API Kubelet │ ││ │ ├── :10255 Kubelet тільки для читання │ ││ │ │ (повинен бути вимкнений!) │ ││ │ ├── :2379 etcd (площина управління) │ ││ │ └── :30000-32767 Сервіси NodePort │ ││ │ │ ││ │ Pod з hostNetwork: true │ ││ │ └── Має доступ до ВСІХ мережевих інтерфейсів хоста│ ││ │ │ ││ └─────────────────────────────────────────────────────┘ ││ ││ ⚠️ Кожен відкритий порт — потенційна точка входу ││ ⚠️ Pod з hostNetwork обходять ізоляцію CNI ││ │└─────────────────────────────────────────────────────────────┘Необхідні порти Kubernetes
Розділ «Необхідні порти Kubernetes»┌─────────────────────────────────────────────────────────────┐│ НЕОБХІДНІ ПОРТИ KUBERNETES │├─────────────────────────────────────────────────────────────┤│ ││ Площина управління: ││ ───────────────────────────────────────────────────────── ││ 6443 - API-сервер Kubernetes (HTTPS) ││ 2379 - etcd клієнт (тільки від API-сервера) ││ 2380 - etcd peer (тільки між вузлами etcd) ││ 10250 - API Kubelet (автентифікований) ││ 10259 - kube-scheduler (HTTPS, localhost) ││ 10257 - kube-controller-manager (HTTPS, localhost) ││ ││ Робочі вузли: ││ ───────────────────────────────────────────────────────── ││ 10250 - API Kubelet (автентифікований) ││ 30000-32767 - Сервіси NodePort (якщо використовуються) ││ ││ Повинні бути ВИМКНЕНІ: ││ ───────────────────────────────────────────────────────── ││ 10255 - Порт тільки для читання Kubelet ││ (без автентифікації!) ││ 8080 - Небезпечний порт API-сервера (застарілий) ││ │└─────────────────────────────────────────────────────────────┘Перевірка відкритих портів
Розділ «Перевірка відкритих портів»# Список всіх портів, що слухаютьss -tlnp
# Список всіх портів з назвами процесівsudo netstat -tlnp
# Перевірити конкретні порти Kubernetesss -tlnp | grep -E '6443|10250|2379'
# Перевірити наявність небезпечних портівss -tlnp | grep -E '10255|8080'
# Використання nmap з зовнішнього хостаnmap -p 6443,10250,10255,2379 <node-ip>Конфігурація брандмауера
Розділ «Конфігурація брандмауера»Використання iptables
Розділ «Використання iptables»# Дозволити SSHiptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Дозволити API Kubernetes (з конкретних мереж)iptables -A INPUT -p tcp --dport 6443 -s 10.0.0.0/8 -j ACCEPT
# Дозволити API kubelet (з площини управління)iptables -A INPUT -p tcp --dport 10250 -s 10.0.0.10/32 -j ACCEPT
# Дозволити діапазон NodePort (при потребі)iptables -A INPUT -p tcp --dport 30000:32767 -j ACCEPT
# Заблокувати все іншеiptables -A INPUT -p tcp --dport 6443 -j DROPiptables -A INPUT -p tcp --dport 10250 -j DROP
# Зберегти правилаiptables-save > /etc/iptables/rules.v4Використання UFW (Ubuntu)
Розділ «Використання UFW (Ubuntu)»# Увімкнити UFWsudo ufw enable
# Дозволити SSHsudo ufw allow ssh
# Дозволити API Kubernetes з внутрішньої мережіsudo ufw allow from 10.0.0.0/8 to any port 6443
# Дозволити kubelet з площини управлінняsudo ufw allow from 10.0.0.10 to any port 10250
# Перевірити статусsudo ufw status verboseВикористання firewalld (RHEL/CentOS)
Розділ «Використання firewalld (RHEL/CentOS)»# Дозволити API Kubernetessudo firewall-cmd --permanent --add-port=6443/tcp
# Дозволити kubeletsudo firewall-cmd --permanent --add-port=10250/tcp
# Перезавантажитиsudo firewall-cmd --reload
# Перевірити відкриті портиsudo firewall-cmd --list-portsВимкнення небезпечних портів
Розділ «Вимкнення небезпечних портів»Порт тільки для читання Kubelet
Розділ «Порт тільки для читання Kubelet»readOnlyPort: 0 # Вимкнути порт тільки для читання (10255)
# Перезапустити kubeletsudo systemctl restart kubelet
# Перевіритиss -tlnp | grep 10255 # Не повинно повернути нічогоПеревірка небезпечного порту API-сервера
Розділ «Перевірка небезпечного порту API-сервера»# Небезпечний порт (8080) видалено в Kubernetes 1.24+# Для старших версій переконайтеся, що він вимкнений:# --insecure-port=0 у прапорцях API-сервера
# Перевірити відсутність небезпечного портуss -tlnp | grep 8080Pod з hostNetwork
Розділ «Pod з hostNetwork»Ризик
Розділ «Ризик»# hostNetwork: true обходить CNIapiVersion: v1kind: Podmetadata: name: host-network-podspec: hostNetwork: true # Pod використовує мережевий простір імен вузла! containers: - name: app image: nginx
# Цей Pod може:# - Прив'язуватися до будь-якого порту на хості# - Бачити весь мережевий трафік# - Отримувати доступ до сервісів localhost# - Обходити NetworkPolicyОбмеження hostNetwork
Розділ «Обмеження hostNetwork»# Використовувати Pod Security Admission для блокуванняapiVersion: v1kind: Namespacemetadata: name: secure-ns labels: pod-security.kubernetes.io/enforce: restricted # 'restricted' блокує hostNetwork: trueКонтрольний список мережевого зміцнення
Розділ «Контрольний список мережевого зміцнення»┌─────────────────────────────────────────────────────────────┐│ КОНТРОЛЬНИЙ СПИСОК МЕРЕЖЕВОЇ БЕЗПЕКИ │├─────────────────────────────────────────────────────────────┤│ ││ □ Вимкнути порт тільки для читання kubelet (10255) ││ readOnlyPort: 0 у конфігурації kubelet ││ ││ □ Обмежити доступ до API-сервера ││ Правила брандмауера для обмеження IP-адрес джерел ││ ││ □ Заблокувати hostNetwork для звичайних навантажень ││ Використовувати Pod Security Admission ││ ││ □ Обмежити відкритість NodePort ││ Використовувати LoadBalancer або Ingress натомість ││ ││ □ etcd доступний тільки від API-сервера ││ Правила брандмауера для 2379/2380 ││ ││ □ Використовувати шифрування при передачі ││ TLS для всіх компонентів ││ ││ □ Регулярне сканування портів ││ Аудит на наявність несподіваних відкритих портів ││ │└─────────────────────────────────────────────────────────────┘Мережеві налаштування Sysctl
Розділ «Мережеві налаштування Sysctl»# Вимкнути ICMP-перенаправлення (запобігання MITM)net.ipv4.conf.all.accept_redirects = 0net.ipv4.conf.default.accept_redirects = 0net.ipv4.conf.all.send_redirects = 0net.ipv6.conf.all.accept_redirects = 0
# Вимкнути маршрутизацію від джерелаnet.ipv4.conf.all.accept_source_route = 0net.ipv6.conf.all.accept_source_route = 0
# Увімкнути SYN cookies (захист від SYN-флуду)net.ipv4.tcp_syncookies = 1
# Журналювати марсіанські пакетиnet.ipv4.conf.all.log_martians = 1
# Ігнорувати broadcast ICMPnet.ipv4.icmp_echo_ignore_broadcasts = 1
# Ігнорувати помилкові повідомлення ICMPnet.ipv4.icmp_ignore_bogus_error_responses = 1
# Застосуватиsudo sysctl -p /etc/sysctl.d/99-network-security.confРеальні сценарії іспиту
Розділ «Реальні сценарії іспиту»Сценарій 1: Вимкнення порту тільки для читання Kubelet
Розділ «Сценарій 1: Вимкнення порту тільки для читання Kubelet»# Перевірити, чи відкритий порт 10255ss -tlnp | grep 10255
# Відредагувати конфігурацію kubeletsudo vi /var/lib/kubelet/config.yaml
# Додати або змінити:# readOnlyPort: 0
# Перезапустити kubeletsudo systemctl restart kubelet
# Перевіритиss -tlnp | grep 10255 # Повинно бути порожнімСценарій 2: Аудит відкритих портів
Розділ «Сценарій 2: Аудит відкритих портів»# Список всіх портів, що слухаютьss -tlnp
# Порівняти з очікуваними портамиecho "Очікувані: 22, 6443, 10250, 10256 (kube-proxy)"echo "Неочікувані порти слід розслідувати"
# Перевірити наявність небезпечних портівss -tlnp | grep -E ':10255|:8080'Сценарій 3: Налаштування брандмауера
Розділ «Сценарій 3: Налаштування брандмауера»# Заблокувати зовнішній доступ до kubeletsudo iptables -A INPUT -p tcp --dport 10250 ! -s 10.0.0.0/8 -j DROP
# Дозволити тільки площині управління доступ до kubeletsudo iptables -I INPUT -p tcp --dport 10250 -s 10.0.0.10 -j ACCEPT
# Перевіритиsudo iptables -L INPUT -n | grep 10250Захист мережевого доступу до etcd
Розділ «Захист мережевого доступу до etcd»# etcd повинен приймати з'єднання тільки від API-сервера# На вузлі etcd:sudo iptables -A INPUT -p tcp --dport 2379 -s <api-server-ip> -j ACCEPTsudo iptables -A INPUT -p tcp --dport 2379 -j DROP
# Для peer-трафіку etcd (багатовузловий etcd)sudo iptables -A INPUT -p tcp --dport 2380 -s <etcd-node-1-ip> -j ACCEPTsudo iptables -A INPUT -p tcp --dport 2380 -s <etcd-node-2-ip> -j ACCEPTsudo iptables -A INPUT -p tcp --dport 2380 -j DROPЧи знали ви?
Розділ «Чи знали ви?»-
Порт тільки для читання kubelet (10255) надає інформацію про Pod без автентифікації. Він був корисним для налагодження, але є ризиком безпеки. Сучасний Kubernetes використовує автентифіковані точки доступу метрик.
-
Хмарні провайдери часто керують правилами брандмауера через Security Groups (AWS), Firewall Rules (GCP) або Network Security Groups (Azure). Вони доповнюють брандмауери на рівні хоста.
-
Сервіси NodePort відкриваються на всіх вузлах, навіть якщо Pod працює лише на одному. Це збільшує поверхню атаки. Використовуйте LoadBalancer або Ingress для обмеження відкритості.
-
Плагіни CNI забезпечують ізоляцію мережі Pod, але Pod з hostNetwork повністю обходять це, працюючи безпосередньо в мережевому стеку хоста.
Поширені помилки
Розділ «Поширені помилки»| Помилка | Чому це шкодить | Рішення |
|---|---|---|
| Залишити 10255 відкритим | Витік інформації без автентифікації | Встановити readOnlyPort: 0 |
| Без брандмауера хоста | Всі порти відкриті | Налаштувати iptables/ufw |
| Використання NodePort публічно | Кожен вузол — точка входу | Використовуйте LoadBalancer/Ingress |
| Дозвіл hostNetwork | Обхід ізоляції мережі | Блокувати з PSA |
| etcd відкритий для кластера | Дані можуть бути викрадені | Обмежити до API-сервера |
Тест
Розділ «Тест»-
Що таке порт тільки для читання kubelet і чому його слід вимкнути?
Відповідь
Порт 10255 надає інформацію про Pod без автентифікації. Зловмисники можуть перелічити Pod, контейнери та їхні конфігурації. Вимкніть за допомогою `readOnlyPort: 0` у конфігурації kubelet. -
Які Pod обходять NetworkPolicy Kubernetes?
Відповідь
Pod з `hostNetwork: true` обходять NetworkPolicy, оскільки вони використовують мережевий простір імен хоста безпосередньо замість мережі Pod, керованої CNI. -
Які порти використовує etcd і хто повинен мати до них доступ?
Відповідь
Порт 2379 для клієнтських з'єднань (тільки API-сервер повинен мати доступ) та 2380 для peer-з'єднань (тільки інші вузли etcd). Обидва повинні бути захищені брандмауером. -
Як перевірити, що небезпечні порти вимкнені?
Відповідь
Використовуйте `ss -tlnp | grep -E '10255|8080'`, щоб перевірити, чи слухають ці порти. Порожній вивід означає, що вони вимкнені.
Практична вправа
Розділ «Практична вправа»Завдання: Аудит та захист мережевої конфігурації вузла.
# Крок 1: Перевірити всі відкриті портиecho "=== Відкриті порти ==="ss -tlnp
# Крок 2: Перевірити наявність небезпечних портівecho "=== Перевірка небезпечних портів ==="ss -tlnp | grep -E ':10255|:8080' && echo "ПОПЕРЕДЖЕННЯ: Відкриті небезпечні порти!" || echo "OK: Небезпечних портів немає"
# Крок 3: Перевірити конфігурацію порту тільки для читання kubeletecho "=== Конфігурація Kubelet ==="grep -i readOnlyPort /var/lib/kubelet/config.yaml 2>/dev/null || echo "Перевірте на реальному вузлі"
# Крок 4: Перевірити мережеві налаштування sysctlecho "=== Мережеві налаштування безпеки Sysctl ==="sysctl net.ipv4.conf.all.accept_redirectssysctl net.ipv4.conf.all.send_redirectssysctl net.ipv4.tcp_syncookies
# Крок 5: Список поточних правил брандмауера (якщо є)echo "=== Правила брандмауера ==="sudo iptables -L INPUT -n --line-numbers 2>/dev/null | head -20 || echo "Перевірте iptables на реальному вузлі"
# Крок 6: Перевірити наявність Pod з hostNetworkecho "=== Pod з hostNetwork ==="kubectl get pods -A -o json | jq -r '.items[] | select(.spec.hostNetwork==true) | "\(.metadata.namespace)/\(.metadata.name)"'
# Критерії успіху:# - Немає відкритих небезпечних портів# - readOnlyPort: 0 у конфігурації kubelet# - Мінімум Pod, що використовують hostNetworkКритерії успіху: Виявити проблеми безпеки та знати, як їх усунути.
Підсумок
Розділ «Підсумок»Необхідні порти:
- 6443: API-сервер
- 10250: Kubelet (автентифікований)
- 2379/2380: etcd (обмежений)
Вимкнути ці порти:
- 10255: Kubelet тільки для читання
- 8080: Небезпечний порт API
Стратегія брандмауера:
- Дозволяти тільки необхідні порти
- Обмежувати IP-адреси джерел
- Блокувати hostNetwork для навантажень
Поради для іспиту:
- Знайте, як перевірити відкриті порти
- Вмійте вимкнути порт тільки для читання kubelet
- Розумійте ризики hostNetwork
Частина 3 завершена!
Розділ «Частина 3 завершена!»Ви закінчили Зміцнення системи (15% CKS). Тепер ви розумієте:
- Профілі AppArmor для контейнерів
- Фільтрацію системних викликів Seccomp
- Зміцнення ядра Linux та ОС
- Мережеву безпеку хоста
Наступна частина: Частина 4: Мінімізація вразливостей мікросервісів — Контексти безпеки, Pod Security та управління секретами.