DevGang
Авторизоваться

Докер без рут привилегий 

В этой статье мы обсудим, как запустить Docker без привилегий root, чтобы лучше управлять безопасностью в ваших контейнерах.

Docker с root правами

Docker запускает свои контейнеры как root. Но нужен ли вашему рабочему контейнеру root права? Ответ: редко. Тем не менее, ваши контейнеры по умолчанию продолжают работать от имени пользователя root. Это может иметь серьезные проблемы с безопасностью. Процесс, который выполняется внутри контейнера от имени пользователя root, фактически является процессом, выполняющимся от имени пользователя root на самом хосте. Это дает возможность злонамеренной попытке получить неограниченный доступ к самому хосту.

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

$ kubectl run -i --tty hello-world --image=hello-world --restart=Never -- sh
/ # ps aux
PID   USER     TIME  COMMAND
  1   root     0:10  sh

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

Добавление пользователя без прав root в Dockerfile

Создайте пользователя с таким количеством разрешений, которое требуется рабочей нагрузкой внутри контейнера. Вы можете создать пользователя с помощью команды RUN в Dockerfile самого изображения контейнера.

RUN groupadd --gid 5000 newuser \
    && useradd --home-dir /home/newuser --create-home --uid 5000 \
        --gid 5000 --shell /bin/sh --skel /dev/null newuser

Выше строка кода создает пользователя, newuser,  вместе с домашним каталогом. Теперь просто добавьте пользователя в свой Dockerfile, как в следующем примере:

FROM ubuntu:18.04
COPY . /myapp
RUN make /myapp
...
USER newuser
CMD python /myapp/hello.py

Начиная со строки 5, каждая команда запускается от имени пользователя newuser, а не от имени пользователя root. Просто, не правда ли?

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

Эти сторонние образы Docker по умолчанию будут работать от имени пользователя root, если мы не будем с ними что-то делать. Если вы используете изображение из не очень популярного источника, то оно может даже быть встроено с помощью вредоносной команды, которая может поставить под угрозу безопасность вашего кластера.

К нам приходят на помощь контекст безопасности Kubernetes и политики безопасности pod.

Используйте Pod Security Context

Вы можете использовать контекст безопасности модуля, чтобы ограничить выполнение модуля конкретным пользователем без полномочий root. Чтобы указать эти параметры безопасности для модуля, добавьте поле securityContext в спецификации модуля.

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  securityContext:
    runAsUser: 5000
    runAsGroup: 5000
  volumes:
  - name: my-vol
    emptyDir: {}
  containers:
  - name: my-container
    image: hello-world
    command: ["sh", "-c", "sleep 10 m"]
    volumeMounts:
    - name: my-vol
      mountPath: /data/hello
    securityContext:
      allowPrivilegeEscalation: false

В приведенной выше спецификации runAsUser указывает, что любой контейнер внутри модуля будет работать  только с идентификатором пользователя 5000. Это пользователь, которого мы создали специально как непривилегированного. runAsGroup определяет идентификатор группы всех процессов. Если мы не упомянем об этом, то идентификатор группы будет root (0).

Теперь вы можете создать этот модуль и проверить процессы, запущенные внутри контейнера:

$ kubectl apply -f my-pod.yaml
$ kubectl exec -it my-pod – sh
ps
PID   USER     TIME  COMMAND
  1   5000     0:00  sleep 10 m
  6   5000     0:00  sh

Как вы можете видеть выше, PID 1 запускается как userID 5000, а не как root.

Использовать политику безопасности Kubernetes Pod

Kubernetes Pod Политика безопасности определяет условия, с которыми модуль должен работать; в противном случае он не будет подготовлен в кластере. Другими словами, если эти условия не будут выполнены, Kubernetes будет препятствовать запуску pod.

Пример PodSecurityPolicy приведен ниже: 

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: my-psp
spec:
  privileged: false
  #Required to prevent escalations to root.
  allowPrivilegeEscalation: false
  allowedCapabilities:
  - '*'
  volumes:
  - 'nfs'
  hostNetwork: true
  hostPorts:
  - min: 8000
    max: 8000
  hostIPC: true
  hostPID: true
  runAsUser:
    #Require the container to run without root.
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'RunAsAny'
  supplementalGroups:
    rule: 'RunAsAny'
  fsGroup:
    rule: 'RunAsAny'

Эта политика безопасности обеспечивает следующее:

  1. Запретить запуск контейнера в привилегированном режиме.
  2. Ограничить контейнер, которому нужен рут.
  3. Ограничьте контейнер, который обращается к другим файлам, кроме тома NFS.
  4. Разрешить только контейнерам доступ к хост-порту 100.

Активировать политику:

$ kubectl create -f my-psp.yaml

Проверьте политику:

$ kubectl get psp
NAME    PRIV   RUNASUSER         FSGROUP   SELINUX   VOLUMES
My-psp  false  MustRunAsNonRoot  RunAsAny  RunAsAny  [nfs]

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

$ kubectl run --image=my-root-container

Политика безопасности модуля запрещает запуск и выдает сообщение об ошибке:

$ kubectl get pods
NAME         READY    STATUS     
my-root-pod  0/1      container has runAsNonRoot and image will run as root

Вывод

В этой статье я выделил риск, связанный с запуском контейнера Docker с настройками по умолчанию для пользователя root. Я также предложил несколько способов преодолеть этот риск.

  1. Если вы запускаете пользовательский образ, создайте нового непривилегированного пользователя и укажите его в своем Dockerfile.
  2. Если вы используете сторонние изображения, вы можете установить контекст безопасности на уровне контейнера.
  3. Еще один способ - создать политику безопасности pod, которая не позволит ни одному контейнеру работать с привилегиями root.

Источник:

#Docker
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

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

Попробовать

Оплатив хостинг 25$ в подарок вы получите 100$ на счет

Получить