Блог

Укрепление контейнеров Docker для мультитенантного хостинга: пошаговое руководство по изоляции

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

Краткое содержание

Запуск мультитенантной платформы хостинга Docker требует герметичной изоляции контейнеров, чтобы предотвратить вмешательство арендаторов друг в друга или побег на хост. Это руководство предоставляет конкретный, пошаговый процесс укрепления, который вы можете применить сегодня. Вы узнаете, как настроить пользователей без root, отключить ненужные возможности Linux, монтировать файловые системы только для чтения, применять ограничения ресурсов через cgroups, сегментировать сети и применять профили seccomp или AppArmor. Мы также рассмотрим, когда дополнять контейнеры виртуальными машинами для максимальной безопасности. В конце у вас будет контрольный список для систематического устранения типичных векторов побега из контейнеров и поддержания истинной изоляции вашей мультитенантной инфраструктуры.

Реальная проблема с мультитенантными контейнерами

Контейнеры Docker используют общее ядро хоста, и если изоляция настроена неправильно, один арендатор теоретически может получить доступ к данным другого, загрузить весь ЦП или даже вырваться на хост. Как поставщик хостинга, вам нужны герметичные границы без ущерба для производительности контейнеров. Многие команды начинают с настроек Docker по умолчанию, которые предназначены для разработки, а не для производственной мультитенантности. Хорошая новость: с помощью систематического контрольного списка укрепления вы можете заблокировать каждый контейнер до уровня изоляции, близкого к ВМ, сохраняя при этом скорость Docker.

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

Шаг 1: Запуск контейнеров от имени пользователя без root

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

FROM ubuntu:22.04
RUN useradd -m appuser
USER appuser

Предостережение: Некоторые процессы (например, привязка к портам < 1024) требуют root. В таких случаях используйте флаг --cap-add, чтобы предоставить только необходимую возможность, например --cap-add=NET_BIND_SERVICE, и все равно запускайте процесс от имени пользователя без root.

Для получения дополнительной информации о базовой изоляции см. наше руководство по достижению истинной мультитенантной изоляции в Docker.

Шаг 2: Отключите все возможности Linux и добавьте только то, что нужно

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

docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE my-app

Типичные возможности, которых следует избегать: SYS_ADMIN (побег из контейнера), NET_RAW (перехват пакетов), SYS_PTRACE (отладка процессов). Используйте docker run с --security-opt no-new-privileges, чтобы предотвратить повышение привилегий через setuid-бинарники.

Шаг 3: Монтирование корневой файловой системы только для чтения

Злоумышленники часто записывают вредоносные скрипты в файловую систему контейнера. Сделав корневую файловую систему только для чтения, вы предотвращаете это:

docker run --read-only --tmpfs /tmp:rw,noexec,nosuid,size=64m my-app

--tmpfs создает временную монтируемую область для записи для каталогов, таких как /tmp и /var/run. Флаг noexec предотвращает выполнение из этой точки монтирования. Этот подход заставляет злоумышленников маневрировать через каталоги, доступные для записи, которые вы можете отслеживать.

Шаг 4: Ограничение ресурсов с помощью cgroups

Неограниченные контейнеры могут выполнять атаки типа «отказ в обслуживании», истощая память или ЦП хоста. Используйте ограничения времени выполнения Docker:

docker run --memory=512m --memory-swap=512m --cpus=0.5 --pids-limit=100 my-app
  • --memory и --memory-swap устанавливают жесткие лимиты (без подкачки).
  • --cpus ограничивает ЦП.
  • --pids-limit предотвращает fork-бомбы, ограничивая количество процессов.

Предостережение: Ограничения ресурсов применяются cgroups, но они не предотвращают кражу данных по сети. Комбинируйте с изоляцией сети (следующий шаг).

Шаг 5: Сегментация сетей с помощью пользовательских сетей Docker

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

docker network create tenant-alpha --internal
docker run --network tenant-alpha my-app

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

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

Шаг 6: Применение профилей Seccomp и AppArmor

Seccomp фильтрует системные вызовы, а AppArmor (или SELinux) применяет обязательный контроль доступа. Docker предоставляет профиль seccomp по умолчанию, который блокирует опасные системные вызовы, такие как clone с определенными флагами. Для более строгой изоляции создайте собственный профиль:

docker run --security-opt seccomp=./custom.json --security-opt apparmor=docker-default my-app

Вы можете сгенерировать базовый профиль с помощью docker run --rm -it --security-opt seccomp=unconfined my-app strace -c -S time, а затем сократить его. Предостережение: Чрезмерно строгие профили могут нарушить легитимную функциональность. Тщательно тестируйте в промежуточной среде.

Шаг 7: Рассмотрите гибридную изоляцию с виртуальными машинами

Если ваши арендаторы требуют абсолютной изоляции (например, регулируемая отрасль), запускайте контейнеры внутри легковесной ВМ. Такие инструменты, как Sysbox или Kata Containers, обеспечивают аппаратное разделение без ущерба для скорости контейнеров. Этот подход используется Docker Enhanced Container Isolation (ECI). Хотя накладные расходы выше, чем у голых контейнеров, они намного ниже, чем у полных ВМ на рабочую нагрузку.

Для получения дополнительной информации о выборе подходящего уровня изоляции прочитайте проектирование мультитенантной архитектуры Docker.

Собираем всё вместе: контрольный список по укреплению

  1. Создавайте контейнеры с пользователем без root.
  2. Отключите все возможности, добавьте только необходимые.
  3. Монтируйте файловую систему только для чтения с временными точками монтирования для записи.
  4. Установите лимиты памяти, ЦП и PID.
  5. Создавайте изолированные сети Docker для каждого арендатора.
  6. Применяйте пользовательские профили seccomp и AppArmor.
  7. Оцените гибридные контейнеры ВМ для задач с высокими требованиями к безопасности.

Заключение

Укрепление контейнеров — это не разовая задача, а постоянная дисциплина. Шаги выше формируют базовый уровень безопасности для мультитенантного хостинга. Помните, что ни одна отдельная мера не гарантирует безопасность; ключевым является эшелонированная защита. Начните с основ: пользователи без root и отключенные возможности. Затем добавьте ограничения ресурсов и сегментацию сети. Для самых чувствительных рабочих нагрузок комбинируйте контейнеры с ВМ. С этим руководством вы сможете уверенно развертывать мультитенантные среды Docker, которые одновременно эффективны и безопасны.

Sources (5)