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

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

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

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

Ограничение доступа из внешней сети

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

Независимо от того, в какой сети используется кластер Kubernetes — частной или публичной — рекомендуется назначить строгие правила для фаервола. Kubernetes открывает ряд важных сервисов типа API и хранилища etcd, которые содержат конфиденциальную информацию, поэтому нужно оставить открытыми на фаерволе только те порты, которые нужны для функционирования кластера.  Если кластер запускается в облаке, то проще всего воспользоваться облачным фаерволом. Для управления кластером необходимо открыть на фаерволе 6443/TCP-порт Kubernetes API. Какие ещё нужно открыть порты, зависит  от того, каким приложениям в кластере нужно открыть доступ извне.

Кроме того, для доступа к нодам кластера по SSH предпочтительно использовать SSH-бастион, который представляет собой защищенный SSH-шлюз с публичным доступом. В этом случае ноды кластера Kubernetes будут закрыты от внешней сети и смогут принимать только тот трафик, который поступает с SSH-бастиона.

Управление квотами

В одном кластере Kubernetes сосуществуют десятки и сотни процессов, запущенных от имени пользователей с различными правами доступа. При отсутствии ограничений для контейнеров на использование физических ресурсов один или несколько контейнеров могут использовать бóльшую часть доступных ресурсов CPU и RAM. В лучшем случае это может привести к снижению производительности кластера, в худшем — к полной остановке функционирования системы, когда кластер просто перестаёт отвечать на запросы. Поэтому важно адекватно оценивать количество ресурсов, необходимое для каждого приложения, и устанавливать соответствующие ограничения на контейнеры при создании деплоймента (spec->containers->resources->limits) либо на неймспейс через объект ResourceQuota.

Подробности об управлении квотами можно узнать в официальной документации Kubernetes.

Управление доступом

Корректное управление доступом к кластеру Kubernetes включает настройку аутентификации и разграничение доступа для каждого пользователя в кластере.

Kubernetes поддерживает несколько методов аутентификации, в том числе базовую аутентификацию по имени и паролю, а также анонимный режим, в котором запросы без аутентификационных данных всё же получают доступ с ограниченными правами к ресурсам кластера. Оба метода весьма небезопасны, однако анонимный режим включен по умолчанию, поэтому стоит отключить его на этапе запуска API-сервера, используя флаг  —anonymous-auth=false

Вместо этого рекомендуется использовать аутентификацию пользователей по сертификатам, используя флаг —client-ca-file=%CERTFILE при запуске api-сервера. Для большей безопасности Kubernetes также позволяет использовать интеграцию со сторонними протоколами аутентификации, например LDAP, Kerberos и т.д.

Что касается авторизации, рекомендуется использовать управление доступом на основе ролей (RBAC) при запуске api-server, используя флаг —-authorization-mode=RBAC. RBAC стабилен начиная с Kubernetes 1.8.

В RBAC  права пользователей на действия с объектами внутри кластера Kubernetes выдаются через объекты Role и RoleBinding.

Объект Role описывает права доступа к объектам. Например, следующая роль example-role позволяет осуществлять действия get, watch, list с объектами pod внутри неймспейса mynamespace:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: mynamespace
  name: example-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
>

Объект RoleBinding выдает права, указанные в объекте Role, пользователю. Например, после применения нижеприведенного RoleBinging пользователь example-user получит права, прописанные в созданной ранее роли example-role:

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: example-rolebinding
  namespace: mynamespace
subjects:
- kind: User
  name: example-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: example-role
  apiGroup: rbac.authorization.k8s.io

Подробнее с RBAC можно ознакомиться в официальной документации Kubernetes.

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

Ограничение привилегий в контейнерах

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

Для этого рекомендуется принять следующие меры:

  • Не запускайте приложения внутри контейнеров от имени пользователя с правами root. Это очевидная мера, но ей часто пренебрегают. Большинство приложений на Docker Hub запускается от имени root, поскольку так удобнее разработчикам. Тем не менее такой подход приводит к нарушению безопасности, поскольку root-процесс внутри контейнера является root-процессом и на самой ноде.
  • Не выдавайте контейнерам привилегии без необходимости. Если запустить контейнер в привилегированном режиме, он получит доступ к ресурсам хоста. Например, приложения в таком контейнере могут читать и менять данные на хосте, менять сетевые настройки хоста и выполнять много других потенциально опасных действий.
Kubernetes как сервис с сертификацией CNCF
Беспроблемная доставка ваших приложений
Перейти

Для ограничения привилегий контейнеров в Kubernetes используются ресурсы PodSecurityContext и PodSecurityPolicy.

PodSecurityContext описывает привилегии, которые присваиваются процессам внутри контейнера. Среди них могут быть указаны пользователь и группа, от которых будут запускаться все процессы в контейнере, группа файловой системы, запрет на запуск от суперпользователя, а также запрет на эскалацию привилегий, разрешенные типы Persistent Volumes, параметры изоляции и многое другое.

PodSecurityPolicy — это политики контекста безопасности. Они позволяют определить, с какими параметрами безопасности могут быть запущены поды. Например, в нижеприведенном файле конфигурации PodSecurityPolicy указаны следующие политики в отношении подов:

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  fsGroup:
    rule: RunAsAny
privileged: false #эта строка запрещает запуск 
привилегированных подов runAsUser:
   rule: MustRunAsNonRoot #здесь запрещен запуск
с правами пользователя
root
supplementalGroups:
    rule: RunAsAny #разрешен запуск от любой группы Linux
volumes: #список Volumes, в которые разрешено
монтирование подов
  - 'epmtyDir'
  - 'secret'
  - 'downwardAPI'
  - 'configMap'
  - 'persistentVolumeClaim'
  - 'projected'
  hostPID: false
  hostIPC: false
  hostNetwork: false

PodSecurityContext необходимо привязать к ролям через RoleBinding. Так можно настроить детальные политики для запуска подов от имени различных пользователей.

Подробнее в официальной документации Kubernetes: о PodSecurityContext и PodSecurityPolicy.

Источники образов

Технология контейнеризации позволяет легко скачивать и запускать образы приложений, подготовленные огромным сообществом разработчиков open source-приложений. Кроме очевидного преимущества, у такого подхода есть и недостаток: высокий риск запустить небезопасное приложение.  Контейнеры с вредоносным ПО могут получить доступ к процессам, запущенным в других контейнерах или на самой машине, и парализовать работу кластера.

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

Мониторинг инфраструктуры и аудит

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

Для автоматизации мониторинга, логирования и аудита существуют готовые решения.

Мониторинг и логирование

  • ELK (ElasticSearch, Logstash и Kibana)универсальное решение, обладающее почти неограниченными возможностями для мониторинга как приложений, так и базовой инфраструктуры.
  • Datadog: прост в установке, удобный UI. Для кластеров, состоящих менее чем из 5 нод действует бесплатный тариф.

ELK можно установить и сконфигурировать самостоятельно или получить настроенное решение «из коробки» в виде облачного сервиса.
Читать больше об инструментах мониторинга кластеров.

ПО для аудита безопасности

  • Clair: сканер уязвимостей, разработанный CoreOS специально для контейнеров.
  • Kube-bench: инструмент от Aquasec, который проводит проверку кластера на соответствие CIS benchmarks для Kubernetes.
  • OpenSCAP: набор автоматизированных инструментов для оценки конфигурации кластера и поиска известных уязвимостей в ПО в соответствии с протоколом SCAP. Решение имеет специальный модуль для работы с контейнерами.

Заключение

Мы рассмотрели базовые меры, которые позволят обеспечить безопасность кластера Kubernetes. Помните, что невозможно раз и навсегда «настроить безопасность» — вместе с новыми релизами компонентов появляются новые потенциальные уязвимости, поэтому не забывайте регулярно проводить аудит системы и при необходимости обновлять политики кластера.

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