Лучшие практики безопасности Kubernetes за 5 шагов

Коллеги из Palark рассказали о том, что несмотря на популярность DevSecOps и разговоры о нем, проблемы безопасности редко решаются правильно.
В результате нам приходится разбираться с последствиями плохой конфигурации безопасности. Что же делать?

Это перевод статьи Palark.

Ландшафт безопасности

Предприятия всех размеров — крупные, малые и средние — используют Kubernetes в качестве отраслевого стандарта. Отчет Dynatrace «Kubernetes in the wild report 2023» демонстрирует ежегодный прирост числа кластеров Kubernetes в облаке на 127% и на 27% для локальных кластеров. Также сообщается, что 48% организаций ожидают значительного (50-100%) или резкого (100%+) роста количества своих кластеров K8s.


Кажется, что чем больше кластеров, тем лучше, поскольку Kubernetes предназначен для решения проблем, с которыми мы все сталкиваемся. Это действительно оптимизирует операции, ускоряет доставку, повышает ежедневную скорость развертывания и т. д. Но что может пойти не так?

Обзор стандартов безопасности

Одним из самых известных является Kubernetes CIS Benchmark и содержит конкретные инструкции о том, как обеспечить безопасность кластера K8s — вплоть до того, какие флаги установить для сервера API. Вот что он проверяет в настройках Kubernetes:


  • Компоненты плоскости управления:
  1. Файлы конфигурации узла;
  2. Плоскость управления;
  3. API-сервер;
  4. Диспетчер контроллеров;
  5. Планировщик и т.д.;
  • Конфигурация плоскости управления:
  1. Аутентификация и авторизация;
  2. Ведение журнала и аудит;
  • Рабочие узлы:
  1. Файлы конфигурации рабочего узла;
  2. Конфигурация Kubelet;
  • Политики: RBAC, сервисные учетные записи, стандарты безопасности Pod и сетевые политики.

Существует множество других стандартов как коммерческих, так и некоммерческих организаций. Они дополняются всевозможными таблицами данных и контрольными списками от компаний, разрабатывающих ПО, связанное с безопасностью Kubernetes.


Модель 4С подсказывает:


  1. Начните с кода, чтобы защитить используемые приложения и библиотеки;
  2. Просканируйте контейнеры на уязвимости, проконтролируйте и защитите среду исполнения;
  3. Ограничьте доступ к плоскости управления Kubernetes и узлам кластера;
  4. Настройте безопасный доступ к облачным API и инфраструктуре.

Излишне говорить, что в случае, если злоумышленник получит доступ к облачному API, уже не имеет значения, какие уровни защиты ниже, т.е. насколько безопасен код в контейнере. Злоумышленник просто удалит виртуальные машины, сманипулирует данными на дисках и так далее.

Пять шагов к безопасности Kubernetes

  1. Правильная настройка кластеров Kubernetes;
  2. Сканирование образа;
  3. Сетевая безопасность;
  4. Контроль запущенных приложений;
  5. Аудит и регистрация событий.

Шаг №1: Правильная конфигурация кластера Kubernetes

  1. Начните с запуска эталонного теста CIS и проверьте, соответствуют ли настройки узла и уровня управления тем, которые указаны в стандарте. Kube-bench и Kubescape идеально подходят для этого. Все, что вам нужно сделать, это запустить один из них, изучить результаты теста и исправить все проблемы, о которых сообщается в предупреждениях.
  2. Если возможно, рекомендуется ограничить сетевой доступ к API Kubernetes, настроить белые списки, разрешить доступ только через VPN и т. д.
  3. Каждый пользователь, который обращается к Kubernetes API, должен быть идентифицирован. Это важно для последующих проверок и понимания, кто что сделал; он также пригодится для грануляции RBAC.
  4. Каждому пользователю должны быть предоставлены только те RBAC, которые ему необходимы. Предположим, что какой-то оператор в кластере получает список всех модулей. В этом случае ему не нужно позволять видеть все секреты, а тем более редактировать их.

Все это кажется достаточно простым. Тем не менее, есть реальный живой пример для рассмотрения.


Сотрудник Palark развернул кластеры Kubernetes у нескольких облачных провайдеров и провел тест CIS. Ошибок и предупреждений практически не было. Протестировал только рабочие узлы, поскольку не все провайдеры предлагают доступ к узлам плоскости управления. Затем он посмотрел, как реализован доступ к только что развернутому кластеру.


Изучив kubeconfig, он обнаружил, что группа system:masters использовалась. Хотя в первом пункте контрольного списка безопасности Kubernetes четко указано, что после развертывания кластера никто не должен проходить в нем аутентификацию как system:masters. Если злоумышленник получит доступ к этому kubeconfig, все ЦС в кластере придется переоформить, потому что без этого отозвать доступ у группы system:masters невозможно.


Как видите, даже облачные провайдеры могут нарушать правила безопасности, поэтому вам всегда следует помнить о них.

Шаг № 2: Сканирование образа

Пришло время подумать, какое программное обеспечение мы собираемся запускать в кластере и как обеспечить его безопасность. Очевидное решение — сканировать образы контейнеров, которые мы используем.


Вы можете сделать это на разных этапах, например:


  • Сканировать их на этапе конвейера CI/CD,
  • Настроить сканирование реестра по расписанию,
  • Просканировать все образы, используемые в кластере Kubernetes.

Есть много инструментов для этого: например, Trivy от Aqua Security и Grype от Anchore.


После сканирования проанализируйте его результаты:


  1. Обязательно ищите критические проблемы и предупреждения, а также исследуйте найденные уязвимости. Оценивайте проблему рационально: даже если мы нашли критическую уязвимость, это не значит, что она на самом деле такая.
  2. Используйте базовые образы. Если у вас есть золотой образ и вы нашли в нем CVE, можете начать с простой замены образа контейнера и перезапуска конвейера CI/CD.
  3. Избегайте добавления ненужных зависимостей. Например, инструменты отладки всех видов никогда не должны попадать в рабочие образы.
  4. Для компилируемых языков необходимо собрать артефакт, скомпилировать в нем бинарник, скопировать его в золотой образ, а затем запустить его в продакшене.

Помните: чем больше количество избыточных зависимостей, тем выше риск наличия у них CVE.

Шаг № 3: Безопасность сети

  • CNI в кластере должен поддерживать сетевые политики;
  • Политики входа и выхода должны быть настроены для всех компонентов кластера;
  • Установите «запретить все» в качестве политики по умолчанию и вручную разрешите всё необходимое.

Случай из реальной жизни. Клиент просит провести аудит настройки Kubernetes. Выглядит все нормально: K8s запущен, везде используются сертификаты, а разработчики имеют доступ только к пространству имен stage.


Однако это многопользовательский кластер. Разработчики ограничены stage, но на самом деле они могут попасть оттуда буквально куда угодно (например, добраться до производственных баз данных), так какотсутствует сегментация и изоляция сети. Что можно с этим сделать?


Например, использовать Cilium. Он имеет визуальный редактор, который позволяет настроить правильную политику всего за несколько кликов. Эта политика позволит разработчику работать только в пределах своего пространства имен и получать доступ к DNS Kubernetes. Вот как может выглядеть созданная политика исходящего трафика:


egress:
   - toEndpoints:
       - matchLabels:
           io.kubernetes.pod.namespace: kube-system
           k8s-app: kube-dns
     toPorts:
       - ports:
           - port: "53"
             protocol: UDP
         rules:
           dns:
             - matchPattern: "*"
   - toEndpoints:
       - {}

В этом случае разработчик может получить доступ к базе данных только в среде stage.

  • Не стоит надеяться, что все, что развернуто в частной среде, по умолчанию защищено. Мы должны следить за этими вещами и понимать, кто куда идет и что делает.
  • Подход «политики как код» также важен. Подобно подходу «инфраструктура как код» (IaC), это означает, что политики безопасности хранятся в репозитории Git и развертываются вместе с приложением.
  • Наконец, вы должны внедрить все эти вещи в самом начале. При внедрении нового компонента необходимо сразу наметить его сетевые взаимодействия и обозначить политики. Для установки политик в уже работающую инфраструктуру требуется гораздо больше усилий.

Шаг №4: Контроль запущенных приложений

Когда мы рассмотрели сетевую безопасность, необходимо обсудить концепцию среды выполнения — хоста, на котором запускаются контейнеры.


В Kubernetes запросы проходят по довольно длинной цепочке. Одна из его особенностей — Admission Controller, которая проверяет объекты, созданные в кластере. В Kubernetes 1.23 есть Pod Security Admission, который отвечает требованиям безопасности. Также есть стандарты безопасности подов, которые запрещают запуск подов от имени пользователя root, использование хост-сети и так далее. Если этих политик недостаточно, вы можете использовать один из вариантов:


Когда стандартов безопасности Pod недостаточно, можно организовать CRD OperationPolicy. Он работает поверх ресурсов Gatekeeper. Вот как выглядит его конфигурация:


apiVersion: deckhouse.io/v1alpha1
kind: OperationPolicy
metadata:
  name: common
spec:
  policies:
    allowedRepos:
      - myregistry.example.com
    requiredResources:
      limits:
        - memory
      requests:
        - cpu
        - memory
    disallowedImageTags:
      - latest
    requiredProbes:
      - livenessProbe
      - readinessProbe
    maxRevisionHistoryLimit: 3
    imagePullPolicy: Always
    priorityClassNames:
    - production-high
    checkHostNetworkDNSPolicy: true
    checkContainerDuplicates: true
  match:
    namespaceSelector:
      labelSelector:
        matchLabels:
         operation-policy.deckhouse.io/enabled: "true"

В нем вы можете обозначить передовые методы безопасности:


  1. Разрешены только trusted registries. Разработчикам не разрешается использовать образы Docker Hub для определенных пространств имен;
  2. Ресурсы pod (запросы, лимиты) должны быть указаны;
  3. Probes должны быть указаны;
  4. Применяется ограничение revision history limit;
  5. Требуется использование priorityClasses;
  6. Тег latest запрещен.

Определение политик безопасности приложений является обязательным. Больше контроля означает меньшую вероятность возникновения ошибки и раскрытия уязвимости.

Шаг № 5: Аудит и регистрация событий

Теперь, когда приложение запущено и работает, вам нужно посмотреть, что происходит в Kubernetes и системе в целом. Речь идет именно об аудите событий.


В Kubernetes есть встроенный аккуратный аудит «из коробки» — аудит Kubernetes API, который легко настроить. Журналы собираются и возвращаются в систему регистрации для дальнейшего анализа. Ниже приведен пример базовой политики сбора запросов, отправляемых модулям:


apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
 - RequestReceived
rules:
 - level: RequestResponse
   resources:
   - group: ""
     resources: ["pods"]

Эта политика приведет к тому, что журнал будет выглядеть следующим образом:


{
 "kind": "Event",
 "apiVersion": "audit.k8s.io/v1",
 "level": "RequestResponse",
 "auditID": "28eff2fc-2e81-41c1-980b-35d446480e77",
 "stage": "ResponseComplete",
 "requestURI": "/api/v1/namespaces/default/pods/nginx-6799fc88d8-5p7x5",
 "verb": "delete",
 "user": {
   "username": "system:serviceaccount:d8-service-accounts:gitlab-runner-deploy",
   "uid": "fd5a6209-c893-4b77-adf7-90500ecd2723",
   "groups": [
     "system:serviceaccounts",
     "system:serviceaccounts:d8-service-accounts",
     "system:authenticated"
   ]
 },
...

Недостаточно просто собирать такие события. Вы должны проанализировать их. Предположим, учетная запись службы удалила какой-то модуль или создала ресурс в продашкене. В этом случае это, вероятно, часть процесса развертывания. Однако, если бы это был обычный пользователь, было бы неплохо получать уведомления о его действиях.


Также необходимо регистрировать события в хост-ОС и в среде выполнения. Например, команда crictl exec может быть проигнорирована аудитом API Kubernetes, и мы можем не знать, что кто-то вошел в модуль. Кроме того, важно знать, какие процессы выполняются внутри контейнеров.


В можете использовать Falco. Он делает следующее:

  • разбирает системные вызовы на хосте;
  • извлекает журнал аудита из Kubernetes API через серверную часть веб-перехватчика;
  • проверяет поток событий по настроенным правилам;
  • отправляет оповещения, если правила нарушены.

Однако недостаточно просто генерировать метрики. Администратор кластера должен быть уведомлен, если в кластере происходит какая-либо подозрительная активность. Так как все метрики отправляются в Prometheus, для них нужно создать правило:


apiVersion: deckhouse.io/v1
kind: CustomPrometheusRules
metadata:
 name: runtime-audit-pod-exec
spec:
 groups:
 - name: runtime-audit-pod-exec
   rules:
   - alert: RuntimeAuditPodExecAlerts
     annotations:
       description: |
         There are suspicious attach/exec operations.
         Check your events journal for more details.
       summary: Falco detected a security incident
     expr: |
       sum(rate(falco_events{rule="Attach/Exec Pod"}[5m])) > 0

Falco полезен для решения реальных инцидентов, в том числе не связанных с безопасностью. Например, вы можете использовать его для поиска неисправного оператора в кластере, который незаконно удалил некоторые модули.


Наконец, одним из наиболее важных компонентов аудита и ведения журналов является реагирование на угрозы.

Заключение

Обеспечение безопасности — это итеративный процесс. Всегда есть возможности для улучшения, поскольку в Kubernetes есть много других важных аспектов безопасности, которые администраторы (и не только инженеры DevSecOps!) должны учитывать:


  • Аутентификация и авторизация;
  • Аудит RBAC;
  • Управление секретами;
  • Безопасность цепочки поставок:
  • Предотвращение запуска образов с уязвимостями;
  • Запуск только подписанных образов и использование cosign;
  • Автоматическое создание политик с использованием режима обучения;
  • Автоматические ответы на события аудита.
Ответим на все вопросы по переносу, сборке и развертыванию.
Kubernetes для Enterprise