ADG Оставить заявку
Блог Информационная безопасность 4 мин чтения

Kubernetes NetworkPolicy с Calico: неделя проектирования, зато east-west трафик под контролем

Внедрили Calico NetworkPolicy в кластере клиента. Первый блок правил проектировали неделю - зато теперь любой Pod общается только с явно разрешёнными соседями.

Контекст момента

Calico 3.x и Cilium 1.0 - production-ready CNI с NetworkPolicy для микросегментации в Kubernetes

После того как мы разобрались с RBAC и PodSecurityPolicy в кластере того же клиента, следующим пунктом в плане аудита стояла сетевая сегментация. Технически всё работало: поды деплоились, сервисы отвечали. Но с точки зрения безопасности картина была классической - flat network, любой под мог инициировать соединение к любому другому поду в кластере. East-west трафик ничем не ограничен.

Это не экзотическая угроза. Если что-то компрометируется - frontend-под, воркер очереди, что угодно - у атакующего появляется плацдарм внутри кластера с прямым доступом к базам данных, внутренним API, системным компонентам. Никаких дополнительных барьеров.

Клиент использовал Calico как CNI - это нам повезло, потому что Calico поддерживает Kubernetes NetworkPolicy нативно и добавляет сверху собственные GlobalNetworkPolicy с расширенными возможностями. Flannel, для сравнения, NetworkPolicy не умеет вообще - нужен отдельный агент типа Canal.

Почему неделя на первый блок правил

Написать NetworkPolicy технически несложно. Сложно ответить на вопрос «кому что реально нужно», не сломав при этом продакшн.

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

Параллельно развернули Calico и включили логирование дропнутых пакетов - в режиме Log перед Deny, чтобы сначала понаблюдать, не блокируя. Это дало реальную картину трафика за несколько дней. Обнаружилось несколько соединений, о которых никто не подозревал: один под периодически ходил к etcd напрямую (это был мониторинговый агент, который никто не перенастраивал после переезда), несколько подов стучались наружу за обновлениями без какой-либо проксировки.

Ещё два дня - собственно проектирование политик. Мы пошли от принципа default-deny: сначала запрещаем всё, потом явно разрешаем нужное. Это единственный подход, который даёт реальную сегментацию - если идти от «разрешить всё, запретить лишнее», рано или поздно что-то лишнее просочится.

Структура правил получилась такой:

  • Default-deny для всех namespace-ов приложений. Один манифест, который создаётся в каждом namespace-е при его создании.
  • Явные Allow по меткам. Frontend -> backend только по порту приложения. Backend -> postgres только по 5432. Воркеры -> Redis только по 6379. И так далее.
  • Отдельные политики для мониторинга. Prometheus должен скрейпить metrics-порты у всего что торчит - это законный широкий доступ, но изолированный в отдельную политику, которую легко найти и проверить.
  • Egress на DNS. Забыть про kube-dns в egress-правилах - значит сломать резолвинг имён. Это одна из самых частых ошибок при первом внедрении NetworkPolicy.

Последний день первой недели - тестирование. Включили политики в staging, прогнали дымовые тесты, нашли две ошибки (один сервис ходил к другому по нестандартному порту, который не попал в правила) и поправили.

Calico vs Cilium: как выбирали

Параллельно с этим проектом мы смотрели на Cilium 1.0, который вышел в апреле этого года. Cilium работает на eBPF - это принципиально другая архитектура по сравнению с iptables-подходом Calico.

У Cilium есть одна очень привлекательная вещь: политики можно писать на уровне HTTP, то есть разрешать не «трафик на порт 8080», а «GET /api/v1/health» - и блокировать всё остальное. Это L7-фильтрация прямо в CNI, без service mesh.

Но для этого клиента мы остановились на Calico по нескольким причинам. Calico 3.x - зрелый продукт, активно используется в продакшне, хорошо документирован и с iptables-бэкендом ведёт себя предсказуемо. Cilium 1.0 - первый релиз с таким номером, мы понимали что eBPF-путь перспективный, но для клиента с продакшн-нагрузкой брать только что вышедший 1.0 - это риск, который надо обосновать. Не обосновали.

Ещё один момент: ядро клиентских серверов было достаточно старое, eBPF-фичи на нём работали с ограничениями. Calico с iptables завелся без проблем.

Что получилось

После внедрения: любой под общается только с теми, кому явно разрешено в NetworkPolicy. Попытки соединения от не разрешённых источников логируются и видны в Calico Felix. Это не замена мониторингу - но это честный барьер, который атакующий внутри кластера не обойдёт без шума.

Операционная нагрузка выросла: при добавлении нового сервиса нужно писать NetworkPolicy-манифесты. Клиент поначалу воспринял это как неудобство - мы объяснили что это и есть цена сегментации. Удобнее не значит безопаснее.

Один практический вывод, который стоит зафиксировать: NetworkPolicy в Kubernetes описывает что разрешено, но не объясняет почему. Через полгода никто не помнит зачем именно такая политика написана. Комментарии в манифестах и запись топологии в документацию - не опциональны, а часть самой политики безопасности.

О том как мы строим аудит сетевой безопасности Kubernetes-кластеров - в описании аудита информационной безопасности.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.