Облачная платформаEvolution

Анализ опасных ролей кластера Managed Kubernetes в Container Security


С помощью этого руководства вы создадите в кластере Managed Kubernetes потенциально опасную роль. Затем проанализируете результаты сканирования роли в Container Security и выясните, как она может быть эксплуатирована злоумышленниками. Далее получите рекомендации по модификации таких ролей, следуя принципу минимальных привилегий. Это поможет предотвратить потенциальные угрозы и укрепить безопасность вашего кластера Managed Kubernetes.

Вы будете использовать следующие сервисы:

  • Managed Kubernetes — сервис управления кластерами Kubernetes на вычислительных ресурсах облака.

  • Container Security — сервис управления безопасностью контейнеров.

Шаги:

Перед началом работы

Если вы уже зарегистрированы, войдите под своей учетной записью.

1. Разверните необходимые ресурсы в облаке

  1. Создайте кластер Managed Kubernetes со следующими параметрами:

    • Количество мастер-узлов — 1.

    • Гарантированная доля vCPU, % — 30.

    • CPU, шт. — 2.

    • RAM, ГБ — 4.

    Остальные параметры оставьте по умолчанию.

    • Гарантированная доля vCPU, % — 30.

    • CPU, шт. — 2.

    • RAM, ГБ — 4.

    • Объем хранилища, ГБ — 40.

    • Количество узлов — 3.

  2. Выберите способ публикации плагина в интернет — LoadBalancer.

  3. Чтобы проверить подключение к кластеру, выполните:

    kubectl get node

    Если отобразится список узлов, подключение настроено.

2. Создайте ClusterRole

На этом шаге мы создадим кластерную роль nodeproxy, которая позволяет выполнять действия get и create только для ресурсов nodes/proxy.

  1. Сохраните манифест в файле cloudru-cluster-role.yaml:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
    name: nodeproxy
    rules:
    - apiGroups: [""]
    resources: ["nodes/proxy"]
    verbs: ["get"]
  2. Выполните команду:

    kubectl apply -f cloudru-cluster-role.yaml

3. Создайте ServiceAccount

На этом шаге мы создадим сервисный аккаунт с именем nodeproxy в пространстве имен default.

  1. Сохраните манифест в файле cloudru-service-account.yaml:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
    name: nodeproxy
    namespace: default
  2. Выполните команду:

    kubectl apply -f cloudru-service-account.yaml

4. Создайте ClusterRoleBinding

На этом шаге мы выполним привязку роли, которая позволит сервисной учетной записи nodeproxy в пространстве имен default использовать разрешения, определенные в кластерной роли.

  1. Сохраните манифест в файле cloudru-cluster-role-binding.yaml:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
    name: nodeproxybinding
    roleRef:
    apiGroup: rbac.authorization.k8s.io
    kind: ClusterRole
    name: nodeproxy
    subjects:
    - kind: ServiceAccount
    name: nodeproxy
    namespace: default
  2. Выполните команду:

    kubectl apply -f cloudru-cluster-role-binding.yaml

5. Проверьте доступ с использованием ServiceAccount

  1. Создайте токен для сервисной учетной записи:

    kubectl create token nodeproxy
  2. Чтобы проверить доступ с использованием токена, выполните:

    kubectl proxy -h --token <token>

    Примерный результат:

    Create a proxy server or application-level gateway between localhost and the Kubernetes API server.
    Examples:
    # To proxy all of the Kubernetes API and nothing else, use:
    kubectl proxy --api-prefix=/
    # To proxy only part of the Kubernetes API and also some static files:
    kubectl proxy --www=/my/files --www-prefix=/static/ --api-prefix=/api/
    ...
  3. Попробуйте получить список подов с использованием сгенерированного токена:

    kubectl get pods -A --token <token>

    Результат:

    is forbidden: User "system:serviceaccount:default:nodeproxy" cannot get resource "pods" in API group ""

    Ошибка возникает из-за отсутствия разрешения на доступ к Pods.

    ClusterRole не включает никаких правил для ресурса Pods. Поэтому попытка вызвать команду kubectl get pods с этой сервисной учетной записью приводит к отказу в доступе. Команда пытается получить список всех подов (get действие на ресурсе pods), но для этого необходимы соответствующие разрешения.

    Таким образом, созданная роль выглядит безопасной. Но на самом деле эта роль может быть использована для проведения атак.

6. Посмотрите отчет об опасных ролях в Container Security

На шаге 2 была создана потенциально опасная роль, поэтому она отобразится в отчете Container Security. Чтобы посмотреть отчет:

  1. Перейдите в панель управления Container Security.

  2. В левом меню выберите Анализ RBAC → Опасные роли.

  3. В списке найдите отчет nodeproxy, используя поисковую строку.

    Для роли nodeproxy обнаружен один риск.

    Для перехода к описанию найденного риска нажмите на название отчета nodeproxy.

    Чтобы получить подробную информацию о риске, нажмите KSV047. Ознакомьтесь с описанием риска и сообщением сканера.

7. Проанализируйте роль

На странице отчета nodeproxy перейдите на вкладку Разрешения.

Разрешения роли

Ниже описаны основные разрешения роли nodeproxy.

Параметр

Значение

Описание

Действия

get, create

Доступ пользователя с ролью nodeproxy к получению информации и созданию указанных типов ресурсов

API-группы

""

Роль позволяет доступ к основной API-группе кластера

Типы ресурсов

nodes/proxy

Роль разрешает выполнять указанные действия с nodes/proxy

В чем опасность

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

Маппинг авторизации kubelet в Kubernetes объясняет, почему предоставление прав к nodes/proxy представляет особый риск. Многие пути kubelet четко соответствуют подресурсам, таким как nodes/metrics, nodes/stats, nodes/log. Все остальное часто относится к более общей категории: nodes/proxy. То есть nodes/proxy выступает в роли «универсального решения», которое нежелательно предоставлять сервисным аккаунтам из-за слишком широкого доступа.

Многие агенты мониторинга и телеметрии запрашивают широкий доступ к узлам, поэтому именно стеки мониторинга становятся вектором атаки.

Вот как может выглядеть сценарий эксплуатации:

  1. Злоумышленник располагает ВМ с сетевым доступом к узлу Kubernetes nodes/proxy. ВМ, например, с IP 10.0.0.23, находится в той же сети или имеет маршруты к рабочему узлу, например с IP 10.0.0.22.

  2. Злоумышленнику известен валидный Bearer-токен, который предполагает доступ к API Kubelet, необходимый для выполнения запросов от имени авторизованного пользователя.

    Чтобы получить доступ к информации о подах, работающих на узлах, выполняется HTTP-запрос к Kubelet API, который возвращает список всех подов, запущенных на рабочем узле. Этот запрос предполагает использование токена для аутентификации.

    Для ранних версий Kubernetes через Kubelet API доступна возможность удаленного выполнения команды (RCE) в контейнере, находящемся в поде. Это осуществляется с помощью отправки POST-запроса с указанием команды, которую требуется выполнить на целевом контейнере.

    В более новых версиях Kubernetes выполнение команд через Kubelet API изменилось из-за обновлений API, но возможность RCE все еще сохраняется.

8. Ограничьте создание роли для nodes/proxy

Нельзя повлиять на внутренние механизмы kubelet, но можно предотвратить распространенную ошибку: создание ролей, которые предоставляют права доступа nodes/proxy в широком смысле.

Настройте политику, которая блокирует создание роли для nodes/proxy:


  1. В панели управления Container Security перейдите в раздел Контроль допуска → Политики допуска и нажмите Рекомендуемые политики.

  2. Найдите политику restrict-clusterrole-nodesproxy и нажмите на ее название.

  3. Нажмите Добавить политику.

Теперь при попытке создания роли с nodes/proxy она будет заблокирована.

9. Модифицируйте роль nodeproxy

В зависимости от потребностей конкретизируйте ресурс, для которого доступна эта роль. Например, если роль используется только для мониторинга, замените nodes/proxy на nodes/metrics.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nodeproxy
rules:
- apiGroups: [""]
resources: ["nodes/metrics"]
verbs: ["get"]

Что еще можно сделать:

  1. Ограничьте роль так, чтобы она имела доступ только к тем узлам, где это необходимо.

  2. Используйте Role вместо ClusterRole для ограничения доступа к определенным пространствам имен.

  3. Привяжите роль nodeproxy к определенным сервисным аккаунтам, которые предназначены исключительно для узкоспециализированных задач. Это уменьшит риск использования этой роли не по назначению.

  4. Включите аудит-логирование в кластере для отслеживания всех действий, осуществляемых через эту роль. Это поможет быстро выявить и отреагировать на подозрительную активность.

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

  6. Обеспечьте актуальность всех компонентов кластера Kubernetes, чтобы избежать использования устаревших и уязвимых версий.

Результат

В практической работе вы научились анализировать с помощью отчетов Container Security потенциально опасные роли, созданные в кластере Managed Kubernetes, а также получили рекомендации по модификации таких ролей.