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

Kubernetes RBAC-харденинг: убираем wildcard-биндинги и включаем audit-log

После очередного отчёта об утечках через незащищённый kube-apiserver прошлись по всем кластерам: убрали wildcard-биндинги, включили audit-log, ограничили NodePort.

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

Рост числа инцидентов с открытыми Kubernetes API вывел тему RBAC-харденинга на первый план

Новый год начался с очередного разбора полётов - на этот раз не у нас, но где-то очень близко по профилю инфраструктуры. В сети снова всплыл отчёт об утечках через открытый kube-apiserver: кто-то поднял кластер, не закрыл 6443, и кто-то другой этим воспользовался. Мы решили не ждать, пока это коснётся нас напрямую, и устроили собственный внеплановый аудит.

Спойлер: нашли что поправить.

Что искали

Точкой отсчёта взяли три вопроса: кто может делать * на *, кто слышит всё что происходит в кластере, и через какие порты снаружи вообще торчит что не должно.

Wildcard ClusterRoleBinding. Первый же kubectl get clusterrolebindings -o json | jq показал несколько биндингов с resources: ["*"] и verbs: ["*"] - часть из них появилась во время первоначальной настройки как «временное, разберёмся потом», и, конечно, так и осталась. Сервис-аккаунты CI-пайплайна с правами cluster-admin - это не архитектура, это авария в ожидании повода.

Отсутствие audit-log. В нескольких кластерах --audit-log-path не был выставлен вообще. То есть, если кто-то и делал kubectl exec в продакшн-поды ночью - мы бы об этом не узнали. Это неприятное осознание.

NodePort-диапазон по умолчанию. Стандартный диапазон 30000-32767 - широкий, и несколько сервисов висело на портах, которые снаружи ничем не были прикрыты, потому что правила файрвола описывались руками и не всегда синхронизировались с тем, что реально поднималось в кластере.

Что сделали

Начали с инвентаризации прав. Прошли по каждому ClusterRole и Role, выписали все биндинги с wildcard-ами и разобрали каждый: нужен ли он, кому, с каким реальным scope. Большинство оказались либо избыточными, либо переназначаемыми с конкретным набором ресурсов и глаголов. Там где пайплайну нужен был только get и list на ConfigMap в конкретном namespace - он и получил именно это.

Параллельно включили audit-log на всех контрол-плейнах. Конфигурацию policy написали в два уровня:

  • None для /healthz, /readyz, /livez и всего что от system-компонентов - иначе логи затапливает мусором.
  • RequestResponse для всего что касается секретов, configmap-ов, exec и attach - именно это интересно при разборе инцидента.

Audit-лог пишем на диск и забираем fluentd в централизованный ELK. Retention - 90 дней, хватит для разбора.

NodePort-диапазон сузили через --service-node-port-range на kube-apiserver. Конкретный диапазон - дело договорённостей с сетевиками, но сам факт его ограничения резко упрощает жизнь при написании правил файрвола: теперь правила статичны и не зависят от того, какой случайный порт выбрал Kubernetes.

Что оказалось неожиданным

Audit-log на загруженном кластере пишет заметно больше, чем кажется. Первые сутки мы немного недооценили объём и поймали предупреждение о месте на диске. Пришлось сразу аккуратнее выставить rotation и размер файла. Ничего критичного, но приятного мало.

Ещё один момент: несколько разработчиков работали с namespace-ами через kubectl, используя куберовые дефолтные сервис-аккаунты - которые, как выяснилось, имели чуть больше прав, чем надо. После урезания прав пара скриптов сломалась. Это был честный разговор о том, что «работает» и «правильно» - не одно и то же.

Ссылка на проведённую работу - аудит безопасности инфраструктуры.

Итог

Кластеры стали прозрачнее и жёстче одновременно. Wildcard-ов в биндингах не осталось, audit включён, NodePort-диапазон ограничен. Это не финальная точка - впереди ещё работа с Network Policy и проверка того, что admission controller настроен разумно. Но то, что было совсем открыто - закрыто.

Если у вас в кластере есть биндинг с verbs: ["*"] на resources: ["*"] и вы не можете с ходу объяснить зачем - это сигнал. Не завтра, сейчас.

Контакт

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

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