Аудит безопасности Kubernetes-кластера снижает вероятность компрометации узлов, утечки секретов и несанкционированного доступа. Этот процесс проверяет пять ключевых областей: управление доступом через RBAC, безопасность подов, сетевые политики, хранение секретов и настройки kubelet. Для каждого шага вы получите готовые команды kubectl и конкретные рекомендации по устранению найденных проблем.
Проверку стоит проводить регулярно, минимум раз в квартал, и после любых значительных изменений в конфигурации кластера. Аудит не разовая акция, а непрерывный цикл: проверка, исправление, повторная проверка. Если вы уже настраивали журналирование событий, этот материал дополнит вашу практику. Если нет, начните с команд ниже, они дадут быстрый срез текущего состояния безопасности.
Для комплексной проверки всей IT-инфраструктуры, включая Docker и Nginx, используйте готовый план аудита безопасности за 1 день. Он содержит чек-листы в CSV/Markdown и шаблон отчета.
Шаг 1: Аудит управления доступом (RBAC)
RBAC определяет, кто и какие действия может выполнять в кластере. Избыточные права у сервисных аккаунтов или пользователей открывают путь для горизонтального перемещения атакующего. Начните с инвентаризации всех ролей и привязок.
Выполните команды для получения полного списка объектов RBAC:
kubectl get roles --all-namespaces
kubectl get clusterroles
kubectl get rolebindings --all-namespaces
kubectl get clusterrolebindingsОбратите внимание на привязки, которые ссылаются на роли с широкими правами. Особенно опасны wildcard-разрешения в rules, например, resources: ["*"] или verbs: ["*"]. Такие правила дают полный доступ ко всем объектам указанного типа.
Поиск субъектов с правами cluster-admin
Роль cluster-admin предоставляет неограниченные права на все ресурсы во всех неймспейсах. Найдите всех пользователей, группы и сервисные аккаунты, которым она назначена:
kubectl get clusterrolebindings -o json | jq -r '.items[] | select(.roleRef.name == "cluster-admin") | .subjects[]? | "\(.kind) \t \(.name) \t \(.namespace // "-")"'Если вывод содержит сервисные аккаунты из продакшн-неймспейсов, это повод для немедленного пересмотра прав. Минимизируйте количество субъектов с cluster-admin: в идеале это только администраторы кластера и системные компоненты.
Проверка использования ролей и привязок
Неиспользуемые роли и привязки создают шум и увеличивают поверхность атаки. Определите, какие RoleBinding и ClusterRoleBinding ссылаются на несуществующие роли или субъектов:
kubectl get rolebindings --all-namespaces -o json | jq -r '.items[] | select(.subjects == null or .subjects == []) | "\(.metadata.namespace)/\(.metadata.name)"'Удалите привязки без субъектов и роли, на которые нет ссылок. Для автоматизации проверки RBAC используйте инструменты вроде kubeaudit или Polaris, они находят избыточные права по готовым правилам.
Подробный разбор создания ролей и привязок с YAML-манифестами вы найдете в практическом руководстве по RBAC в Kubernetes.
Шаг 2: Проверка безопасности подов
Настройки securityContext в подах определяют, какие привилегии получают контейнеры. Привилегированный контейнер имеет доступ ко всем устройствам хоста и может скомпрометировать узел. Проверьте, какие поды запущены с повышенными правами.
Команда для поиска привилегированных контейнеров:
kubectl get pods --all-namespaces -o json | jq -r '.items[] | select(.spec.containers[]?.securityContext?.privileged == true) | "\(.metadata.namespace)/\(.metadata.name)"'Если вывод не пуст, для каждого найденного пода задайте вопрос: действительно ли контейнеру нужен доступ к устройствам хоста? В большинстве случаев привилегированный режим заменяется точечной выдачей capabilities.
Поиск привилегированных контейнеров
Проверьте также init-контейнеры и ephemeral-контейнеры, они часто упускаются из виду:
kubectl get pods --all-namespaces -o json | jq -r '.items[] | select(.spec.initContainers[]?.securityContext?.privileged == true) | "\(.metadata.namespace)/\(.metadata.name) (init)"'Рекомендация: установите политику безопасности на уровне кластера через Pod Security Admission или Kyverno, чтобы запретить создание привилегированных подов. Это предотвратит появление новых проблем.
Проверка capabilities и других ограничений
Capabilities дают контейнеру отдельные привилегии ядра Linux. Опасные capabilities: SYS_ADMIN, NET_ADMIN, SYS_PTRACE, CAP_SYS_MODULE. Проверьте, какие capabilities выданы контейнерам:
kubectl get pods --all-namespaces -o json | jq -r '.items[] | .spec.containers[]? | select(.securityContext?.capabilities?.add != null) | "\(.name): \(.securityContext.capabilities.add | join(","))"'Минимальный набор capabilities для большинства приложений пуст. Если контейнер не работает без SYS_ADMIN, это сигнал пересмотреть архитектуру приложения, а не выдавать права.
Дополнительно проверьте, что контейнеры запускаются от непривилегированного пользователя и с read-only корневой файловой системой:
kubectl get pods --all-namespaces -o json | jq -r '.items[] | .spec.containers[]? | select(.securityContext?.runAsNonRoot != true or .securityContext?.readOnlyRootFilesystem != true) | "\(.name): runAsNonRoot=\(.securityContext?.runAsNonRoot) readOnlyRootFilesystem=\(.securityContext?.readOnlyRootFilesystem)"'Внедрите seccomp-профили и AppArmor для ограничения системных вызовов. Это снижает риск эксплуатации уязвимостей ядра из контейнера.
Шаг 3: Анализ сетевых политик
Сетевые политики контролируют трафик между подами. Отсутствие политик означает, что любой под может обращаться к любому другому поду в кластере. Это критично для сервисов с базами данных или внутренними API.
Проверьте наличие сетевых политик во всех неймспейсах:
kubectl get networkpolicies --all-namespacesНеймспейсы без политик открыты для всего трафика внутри кластера. Создайте default deny политику для каждого такого неймспейса.
Проверка наличия сетевых политик в неймспейсах
Команда для вывода неймспейсов без NetworkPolicy:
comm -23 <(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | sort) <(kubectl get networkpolicies --all-namespaces -o jsonpath='{.items[*].metadata.namespace}' | tr ' ' '\n' | sort -u)Для каждого неймспейса из вывода создайте базовую запрещающую политику:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: <namespace>
spec:
podSelector: {}
policyTypes:
- Ingress
- EgressПосле этого точечно открывайте только необходимые соединения.
Анализ правил сетевых политик
Просмотрите детали существующих политик и проверьте, не разрешают ли они слишком много:
kubectl get networkpolicies --all-namespaces -o yaml | grep -E "podSelector|namespaceSelector|ports" -A 3Обращайте внимание на podSelector: {}, который выбирает все поды в неймспейсе. Такая политика в сочетании с открытыми портами фактически отменяет изоляцию. Сужайте селекторы до конкретных подов по labels.
Для контроля сетевых потоков и обнаружения аномалий используйте Cilium Hubble, как описано в руководстве по безопасному мониторингу Kubernetes.
Шаг 4: Аудит хранения секретов
Секреты Kubernetes хранят пароли, токены и ключи. По умолчанию они хранятся в etcd в base64-кодированном виде, что не является шифрованием. Любой, кто получит доступ к etcd, прочитает все секреты.
Проверьте, сколько секретов в кластере и в каких неймспейсах они находятся:
kubectl get secrets --all-namespacesОбратите внимание на секреты типа Opaque в неймспейсах приложений. Если их много, это повод для инвентаризации и переноса во внешнее хранилище.
Проверка шифрования секретов в etcd
Проверьте, включено ли шифрование секретов на уровне kube-apiserver. Выполните на control-plane узле:
ps aux | grep kube-apiserver | grep encryption-provider-configЕсли флаг --encryption-provider-config отсутствует, секреты хранятся в незашифрованном виде. Включите шифрование, создав EncryptionConfiguration и указав его в конфигурации kube-apiserver. Для Kubernetes 1.28+ используйте провайдер aescbc или kms.
Поиск секретов в переменных окружения
Секреты, смонтированные как тома, обновляются автоматически и не попадают в вывод env. Секреты в переменных окружения остаются в памяти процесса и могут быть прочитаны через /proc. Найдите поды, использующие секреты через env:
kubectl get pods --all-namespaces -o json | jq -r '.items[] | select(.spec.containers[]?.env[]?.valueFrom?.secretKeyRef != null or .spec.containers[]?.envFrom[]?.secretRef != null) | "\(.metadata.namespace)/\(.metadata.name)"'Рекомендация: переведите секреты на volume mounts. Для критичных данных используйте внешние системы управления секретами: HashiCorp Vault, Sealed Secrets или External Secrets Operator.
Шаг 5: Проверка настроек kubelet
Kubelet работает на каждом узле и управляет подами. Его API предоставляет доступ к логам, метрикам и командам выполнения. Небезопасная конфигурация kubelet открывает путь к компрометации узла.
Проверьте аргументы запуска kubelet на узле:
ps aux | grep kubelet | tr ' ' '\n' | grep -E "anonymous-auth|authorization-mode|read-only-port"Или проверьте конфигурационный файл /var/lib/kubelet/config.yaml, если kubelet использует его.
Проверка анонимного доступа к kubelet
Анонимный доступ позволяет любому без аутентификации обращаться к API kubelet. Проверьте флаг:
ps aux | grep kubelet | grep -o 'anonymous-auth=[a-z]*'Если значение true или флаг отсутствует, анонимный доступ разрешен. Установите --anonymous-auth=false в конфигурации kubelet. Это критичное исправление, внедрите его в первую очередь.
Проверка режима авторизации kubelet
Режим авторизации определяет, как kubelet проверяет права запрашивающего. Проверьте:
ps aux | grep kubelet | grep -o 'authorization-mode=[a-zA-Z]*'Рекомендуемый режим Webhook. Он интегрирует kubelet с RBAC кластера и позволяет точно настраивать права через роли. Режим AlwaysAllow разрешает все запросы и должен быть заменен немедленно.
Дополнительно отключите read-only порт 10255, если он не используется системами мониторинга. Этот порт предоставляет метрики без аутентификации.
Заключение: регулярный аудит и автоматизация
Пять шагов аудита: RBAC, поды, сетевые политики, секреты и kubelet. Выполняйте их последовательно, фиксируйте найденные проблемы и устраняйте по приоритету. Критичные исправления: отключение анонимного доступа к kubelet, включение шифрования секретов, удаление привилегированных контейнеров.
Автоматизируйте проверки с помощью инструментов: kube-bench для CIS Benchmarks, kubeaudit для аудита манифестов, Polaris для проверки конфигураций. Встройте их в CI/CD пайплайн, чтобы каждая деплой-операция проходила проверку безопасности.
Для настройки журналирования событий аудита в kube-apiserver используйте готовые YAML-конфигурации и политики аудита. Логи аудита дополнят ручные проверки и обеспечат непрерывный контроль.
Внедрите чек-лист в рабочий процесс. Проводите аудит ежеквартально и после каждого значительного изменения кластера. Безопасность Kubernetes требует постоянного внимания, а не разовых акций.