Заметки о Kubernetes Security и DevSecOps

DevSecOps для самых маленьких: 5\n. Микросегментация: как построить стены внутри базы

19 сентября 2026 г., 5 минуты

В Minecraft есть крипер. Пока он снаружи, забор работает отлично. Но если крипер уже внутри, а у тебя одна большая комната, деваться особо некуда. Микросегментация — это внутренние стены между комнатами. Смысл не в том, чтобы запретить всё подряд, а в том, чтобы каждый сервис общался только с теми, кто ему действительно нужен.

Представь приложение из трёх частей: фронтенд принимает запросы, бэкенд обрабатывает, база хранит данные. Если фронтенд взломают, зачем ему вообще возможность подключаться к базе напрямую? Микросегментация не починит уязвимость фронтенда, но уменьшит число направлений, куда может пойти атакующий.

Почему периметра мало и дефолт не спасает
Фаервол на границе защищает внешние точки входа, но не внутренние соединения. Если атакующий попал на один сервер, дальше он ходит по разрешённым маршрутам.

В Kubernetes по умолчанию любой под может обратиться к любому другому: пока не применена NetworkPolicy, трафик разрешён. Поды при этом живут недолго, их IP-адреса меняются, поэтому правила строят не по IP, а по меткам (labels) подов и пространств имён.

  • Правила игры у NetworkPolicy. Нужен подходящий CNI. NetworkPolicy применяет сетевой плагин. Если он политики не поддерживает, объект создастся, а трафик фильтроваться не будет. Kubernetes принимает YAML без ошибок в любом случае.
  • Политики складываются. Если к поду применено несколько политик, разрешено всё, что разрешает хотя бы одна
  • Ingress и egress — отдельные режимы изоляции. Запрет входящего не запрещает исходящий. Чтобы соединение прошло, нужно разрешение с обеих сторон: egress у источника и ingress у получателя.
  • Уровни L3/L4. Стандартная политика видит IP, порты и метки, но не содержимое запроса. Правила на уровне L7 (например, по HTTP-методу) нужны отдельные возможности, такие как у Cilium.

С чего начать: default deny
Начни с политики, которая изолирует все поды namespace, и потом разрешай только нужное:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: shop
spec:
  podSelector: {}
  policyTypes: [Ingress, Egress]


Не включай её сразу в production: можно отрезать DNS, внешние API, сбор метрик и очереди. Приложение при этом упадёт не сразу, а на следующем запросе или фоновой задаче. Первым делом верни DNS:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: shop
spec:
  podSelector: {}
  policyTypes: [Egress]
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - {protocol: UDP, port: 53}
        - {protocol: TCP, port: 53}


Проверь метку у своего DNS-сервиса: в большинстве кластеров это k8s-app: kube-dns, но не во всех. Теперь разреши сценарий «фронтенд → бэкенд»: у фронтенда egress, у бэкенда ingress.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: frontend-to-backend-egress
  namespace: shop
spec:
  podSelector:
    matchLabels: {app: frontend}
  policyTypes: [Egress]
  egress:
    - to:
        - podSelector:
            matchLabels: {app: backend}
      ports:
        - {protocol: TCP, port: 8080}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-from-frontend-ingress
  namespace: shop
spec:
  podSelector:
    matchLabels: {app: backend}
  policyTypes: [Ingress]
  ingress:
    - from:
        - podSelector:
            matchLabels: {app: frontend}
      ports:
        - {protocol: TCP, port: 8080}


Так же описываются «бэкенд → база» (порт базы, например 5432). Прямого пути «фронтенд → база» нет, и это правильно.

Что сегментировать в первую очередь
Базы данных: только тем, кому нужно, а не всему namespace. Админки и внутренние панели: сетевой доступ ограничь, а аутентификацию проверь отдельно. Очереди и кеши (Redis, RabbitMQ, Kafka): сетевое разрешение не заменяет их собственную аутентификацию. Исходящий трафик: egress не менее важен, чем ingress; выясни, какие адреса и порты приложение использует на самом деле. Имей в виду, что стандартная NetworkPolicy не умеет разрешать доступ по DNS-имени. Для FQDN-правил нужны возможности конкретного CNI.

Инструменты

  • NetworkPolicy — стандартная отправная точка, если твой CNI её поддерживает.
  • Cilium — eBPF, расширенные политики, L7-правила для поддерживаемых протоколов, Hubble показывает сетевые потоки. L7 и видимость нужно включать отдельно.
  • Calico — поддерживает NetworkPolicy и собственные расширения.
  • Istio — service mesh: mTLS и политики авторизации между сервисами. Работает на другом уровне и дополняет NetworkPolicy, а не заменяет её.
    KubeArmor — политики для процессов и файлов, а не сеть. Дополняет микросегментацию, но не заменяет.
  • Российские: Deckhouse Kubernetes Platform и Luntry. Сверь, какие функции входят в твою редакцию (управление NetworkPolicy, построение правил, наблюдаемость).

План: от наблюдения к проверке
1. Проверь, что твой CNI применяет NetworkPolicy. 2. Выбери тестовый namespace с понятными зависимостями. 3. Собери карту соединений: Hubble, документация приложений, тесты. Отсутствие трафика за период наблюдения не доказывает, что связь не нужна: бывают фоновые задачи и cron. 4. Включи default deny и верни DNS. 5. Добавляй разрешения по одному сценарию. 6. Проверь запреты: из пода фронтенда попробуй достучаться до базы, соединение должно оборваться по таймауту. 7. Расширяй на другие приложения, документируй исключения и пересматривай политики при появлении новых сервисов.
Микросегментация не гарантирует, что крипер никогда не взорвётся. Но она не даёт одному взрыву разрушить весь дом. Начни с одного namespace, составь карту зависимостей, включи изоляцию и открывай только необходимое.

Напоминаю, что статьи мы обсуждаем в Telegram-канале. Недушный ИнфоБез.

Social Media
Telegram
Powered by BS5 Simply Blog and Bludit
Navigation