Поиск по сайту:

Привилегированный и root в Docker: в чем разница?


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

Что вообще означает «корень»?

Разница между пользователем внутри контейнера и пользователем вне контейнера сводится к тому, как Docker работает внутри. В основе технологии Docker лежат пространства имен Linux, обеспечивающие изоляцию на уровне ядра.

Основная концепция довольно проста. С точки зрения хоста контейнер Docker может хранить свои данные в /var/lib/docker/container/, но, поскольку контейнер находится в отдельном пространстве имен «Mount», он представлен как / , и контейнер не имеет значения. Существует несколько типов пространств имен, таких как пространство имен процесса и IPC, пространство имен сети и пространство имен пользователя. Docker использует их все, чтобы заставить контейнеры работать.

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

Это по-прежнему оставляет его открытым для теоретических атак с повышением привилегий, поэтому многие люди предпочтут переназначить пользователя контейнера root с помощью флага --user, чтобы он работал как менее привилегированным пользователем на хост-компьютере и отказом в любом виде root-доступа. Передайте ему произвольный идентификатор пользователя, и Docker сопоставит root (ID 0) внутри контейнера с указанным идентификатором пользователя:

docker run -it --user 4000 ubuntu sh

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

Privileged разрешает побег из контейнера

Привилегированное бывает разным. Это специальный флаг, который вы можете установить во время выполнения, чтобы позволить контейнеру Docker освободиться от своих пространств имен и получить прямой доступ ко всей системе. Как правило, это очень плохая идея, так как это позволяет вредоносному коду из контейнера делать неприятные вещи, например перезаписывать .ssh/authorized_keys хоста или удалять разделы диска.

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

Как установить и использовать Jenkins для создания конвейера CI/CD

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

docker run -it --privileged ubuntu sh

Та же функциональность доступна для Kubernetes с использованием securityContext:

spec:
containers:
 - name: nginx
   image: nginx
   securityContext:
     privileged: true