Rootless-режим в Docker

Rootless-режим в Docker

Запуск Docker с правами root создаёт риски для безопасности всей системы и размещённых на VPS сервисов. Rootless-режим позволяет запускать весь стек Docker от имени непривилегированного пользователя, сохраняя функциональность и повышая безопасность. В статье — установка и принципы работы Docker в режиме Rootless.

Введение

Запуск демона Docker с привилегиями root представляет собой риск безопасности для всей системы. Традиционная архитектура Docker предполагает, что он работает от имени суперпользователя, что даёт контейнерам практически неограниченный доступ к ресурсам хостовой операционной системы. Любая уязвимость в коде Docker, ошибка в конфигурации или компрометация одного контейнера может привести к полному захвату контроля над хост-машиной. Злоумышленник, получивший доступ к сокету Docker (/var/run/docker.sock), автоматически получает возможность выполнять произвольные команды на уровне всей системы, создавать новые контейнеры с привилегированным доступом и манипулировать сетевыми настройками.

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

Как работает Rootless-режим

Механизмы пространств имён

В основе Rootless-режима лежат два механизма пространств имён Linux. Пользовательские пространства имён (User namespaces) обеспечивают маппинг идентификаторов пользователей и групп между хост-системой и контейнером. Это позволяет непривилегированному пользователю на хосте (например, с UID 1000) внутри контейнера иметь права root (UID 0) — без реальных привилегий на основной системе. Маппинг осуществляется через файлы /etc/subuid и /etc/subgid, где для каждого пользователя выделяется диапазон доступных ID, например:

user1:100000:65536
user2:165536:65536

Network namespace предоставляет изоляцию сетевого стека, но в Rootless-режиме реализация отличается от традиционной. Поскольку непривилегированный пользователь не может создавать стандартные сетевые интерфейсы (veth, bridge), используется пользовательский сетевой стек.

Ключевые компоненты Rootless

Для работы Rootless-режима нужно несколько специализированных утилит. newuidmap и newgidmap обеспечивают маппинг идентификаторов между пространствами имён, используя заранее выделенные диапазоны из /etc/subuid и /etc/subgid. Эти утилиты имеют setcap-биты, позволяющие непривилегированным пользователям работать с UID/GID маппингом.

slirp4netns, ещё одна обязательная утилита, создаёт пользовательский сетевой стек, эмулирующий TCP/IP функциональность без требований к привилегиям.

fuse-overlayfs предоставляет альтернативу нативному драйверу overlay2, работая полностью в пользовательском пространстве через FUSE (Filesystem in Userspace). Это устраняет необходимость в привилегиях для монтажа файловых систем.

Архитектура традиционного и rootless-демона

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

В Rootless-архитектуре демон работает как пользовательский процесс без привилегий. Сетевые операции перенаправляются через slirp4netns, работа с файловыми системами — через fuse-overlayfs, а управление именами пространств — через newuidmap/newgidmap.

Различия в архитектуре объясняют некоторые ограничения Rootless-режима, включая особенности работы с сетью, производительность и совместимость с определенными функциями Docker

Установка компонентов Rootless на Ubuntu 24.04

Предварительные требования

Перед установкой выполните обновление:

sudo apt update
sudo apt upgrade -y

Установите необходимые зависимости:

sudo apt install uidmap dbus-user-session fuse-overlayfs slirp4netns

Убедитесь, что для вашего пользователя выделены диапазоны UID и GID:

grep ^$(whoami): /etc/subuid
grep ^$(whoami): /etc/subgid

Если записи отсутствуют, добавьте их, указав начальный ID и количество (например, 100000 и 65536):

sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $(whoami)

Убедитесь, что в системе включена поддержка user namespaces (в Ubuntu 24.04 она активирована по умолчанию):

sysctl kernel.unprivileged_userns_clone

Установка Rootless Docker

Установите пакет docker-ce-rootless-extras, который включает в себя скрипт настройки и зависимости:

sudo apt install docker-ce-rootless-extras

После установки пакета, запустите скрипт:

dockerd-rootless-setuptool.sh install

Скрипт выполнит следующие действия:

  • проверит наличие настроенных подчинённых UID/GID в /etc/subuid и /etc/subgid,
  • создаст необходимые директории конфигурации в ~/.local/share/docker,
  • настроит и запустит пользовательский сервис systemd для управления демоном.

Настройка переменных окружения

Для корректной работы в Rootless-режиме нужно настроить переменные окружения. Добавьте следующие строки в ~/.bashrc или ~/.profile:

export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
export PATH=/home/$(whoami)/bin:$PATH

Это настроит DOCKER_HOST для подключения к пользовательскому демону и добавит пути к бинарным файлам Rootless Docker в PATH.

Примените изменения:

source ~/.bashrc

Проверка установки

Убедитесь, что установка прошла успешно, проверив статус демона и конфигурацию:

systemctl --user status docker.service
docker info | grep Rootless
docker version

Вывод команды docker info | grep Rootless должен содержать Rootless: true.

Дополнительная настройка

Для автоматического запуска демона при входе в систему выполните:

systemctl --user enable docker

Убедитесь, что задержка (linger) включена для вашего пользователя:

sudo loginctl enable-linger $(whoami)

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

Ограничения Rootless-режима и их обход

Сетевые ограничения

Одно из основных ограничений Rootless-режима касается работы с сетевыми портами. Процесс в Rootless-режиме не имеет прав для прямого захвата привилегированных портов (ниже 1024). Если контейнеру нужно прослушивать низкие порты, используйте механизм проброса портов — настройте перенаправление с помощью iptables. Например, следующее правило перенаправляет внешний трафик с порта 80 хоста на порт 8080, который уже может прослушивать контейнер:

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

Для перенаправления локального трафика добавьте правило в цепочку OUTPUT:

sudo iptables -t nat -A OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080

Правила iptables сбрасываются после перезагрузки, чтобы сохранить их, используйте пакет netfilter-persistent.

Альтернативным решением является использование утилиты authbind, которая делегирует право на bind к конкретному порту для непривилегированного пользователя. Установите authbind и настройте доступ к нужному порту (например, 80) для вашего пользователя:

sudo apt install authbind
sudo touch /etc/authbind/byport/80
sudo chmod 500 /etc/authbind/byport/80
sudo chown $USER /etc/authbind/byport/80

После этого запуская контейнер, используйте authbind в команде запуска (способ зависит от вашего метода запуска Docker).

Rootless Docker не поддерживает некоторые сетевые драйверы, такие как macvlan и overlay. Вместо них используйте стандартный bridge-драйвер или пользовательские решения на основе технологий туннелирования.

Чтобы ping работал внутри контейнеров также нужна дополнительная настройка:

docker run --cap-add=NET_RAW --rm alpine ping -c 4 example.com

Производительность

Использование slirp4netns может снизить сетевую производительность. Для оптимизации можно использовать следующие параметры:

slirp4netns --enable-seccomp --enable-sandbox --mtu=1500

fuse-overlayfs может быть медленнее нативного overlay2 драйвера. Для критичных к производительности приложений рекомендуется использовать VFS драйвер (как временное решение):

dockerd --storage-driver vfs

Регулярно проверяйте производительность файловой системы:

docker run --rm -it alpine dd if=/dev/zero of=test.bin bs=1M count=100

И сетевую производительность:

docker run --rm --network host nicolaka/netshoot netstat -i

Для продакшен-сред стоит оценить производительность и при необходимости рассмотреть традиционный Docker с дополнительными мерами безопасности (AppArmor, SELinux).

Совместимость

Некоторые флаги docker run несовместимы с Rootless-режимом. Неработающие флаги:

  • --privileged
  • --device /dev/sda
  • --network host

Альтернатива --device /dev/sda для FUSE устройств:

docker run --device /dev/fuse 

Доступ к устройствам ограничен. Для работы с USB и другими устройствами создайте группу для устройства, добавьте пользователя:

sudo groupadd usbusers
sudo usermod -aG usbusers $USER

Настройте права доступа:

sudo chgrp usbusers /dev/bus/usb/*/*
sudo chmod g+rw /dev/bus/usb/*/*

Заключение

Rootless-режим в Docker — это шаг вперёд в сторону безопасного контейнерного окружения. Он устраняет главный риск классической модели — работу демона с правами суперпользователя, что позволяет запускать контейнеры без угрозы для всей системы. Да, Rootless имеет ограничения по производительности, сетевым настройкам и совместимости, однако для большинства сценариев разработки и тестирования он остаётся практичным и надёжным решением. В продакшене такой режим может стать дополнительным уровнем защиты, а при необходимости — сочетаться с традиционным Docker и механизмами усиленной безопасности (AppArmor, SELinux). В итоге Rootless-режим — это баланс между удобством, функциональностью и безопасностью, который стоит рассмотреть каждой команде, работающей с контейнерами.

Читайте в блоге:

Loading spinner
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

Нужен VPS сервер?

Арендуйте мощный VPS сервер для ваших проектов! Быстрая настройка, высокая производительность и надежная поддержка 24/7. Начните прямо сейчас!

Что будем искать? Например,VPS-сервер

Мы в социальных сетях