Блог

Достижение истинной многопользовательской изоляции в Docker

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

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

Контейнеры Docker используют общее ядро хоста, что может быть проблемой безопасности в многопользовательских средах, где арендаторы не доверяют друг другу. В этой статье объясняются пробелы в изоляции в стандартных настройках Docker и предоставляются конкретные шаги для усиления изоляции с помощью пространств имен Linux, cgroups, пользовательских пространств имен, seccomp, AppArmor и аппаратной визуализации. Вы узнаете, как настроить демоны Docker для каждого арендатора, использовать инструменты песочницы, такие как gVisor или Firecracker, для более надежной изоляции, а также оркестрировать с помощью Kubernetes для многопользовательской работы. Мы также рассмотрим выбор подходящего поставщика инфраструктуры, предлагающего виртуализацию на основе KVM для дополнительного уровня разделения. В итоге у вас будет план для безопасного запуска многопользовательских рабочих нагрузок с Docker.

При размещении нескольких арендаторов на одном хосте Docker стандартной изоляции контейнеров, основанной на пространствах имен Linux и cgroups, часто недостаточно. Побег из контейнера одного арендатора может скомпрометировать весь хост и все остальные контейнеры. Эта проблема особенно остра в общем хостинге, SaaS-платформах или любых сценариях, где недоверенный код работает вместе с вашим. Хорошая новость: вы можете комбинировать несколько методов изоляции, чтобы создать защищенную многопользовательскую среду. Это руководство проведет вас через шесть практических шагов, от низко висящих фруктов, таких как пользовательские пространства имен, до продвинутых мер, таких как изолированные среды выполнения и выбор инфраструктуры.

Понимание изоляции Docker по умолчанию

Docker использует пространства имен Linux для изоляции процессов, сети, файловой системы и других ресурсов. Cgroups ограничивают CPU, память и ввод-вывод. Но они используют одно ядро — уязвимость в ядре может затронуть все контейнеры. Для истинной многопользовательской работы, особенно с недоверенными арендаторами, нужна эшелонированная защита. Как обсуждалось в Проектирование многопользовательской архитектуры Docker: выбор правильного уровня изоляции, уровни изоляции варьируются от слабых (только пространства имен) до сильных (аппаратная визуализация). Давайте начнем с самого слабого.

Шаг 1: Включение пользовательских пространств имен

По умолчанию root внутри контейнера соответствует root на хосте. Побег из контейнера дает полный доступ к хосту. Пользовательские пространства имен переназначают root контейнера на непривилегированного пользователя снаружи. Включите глобально с dockerd --userns-remap=default или для каждого контейнера с --userns=host. Этот простой шаг устраняет многие атаки повышения привилегий. Протестируйте свои приложения: некоторые, требующие привилегий уровня хоста (например, монтирование файловых систем), могут сломаться. Для сайтов Drupal или WordPress это обычно безопасно.

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

Seccomp ограничивает системные вызовы, которые может совершать контейнер. Docker поставляется с профилем seccomp по умолчанию, который блокирует опасные системные вызовы, такие как mount и reboot. Для многопользовательской работы ужесточите его: блокируйте редкие системные вызовы, используемые инструментами побега. Аналогично, AppArmor может ограничивать процессы контейнера. Создайте пользовательский профиль AppArmor, запрещающий запись в интерфейсы ядра и ограничивающий пути файлов. Оба устанавливаются с помощью флагов --security-opt. Комбинируйте их для многоуровневой защиты.

Шаг 3: Использование демонов Docker для каждого арендатора

Запуск одного демона Docker для всех арендаторов рискован — любой побег из контейнера может получить доступ к сокету демона. Изолируйте демонов для каждого арендатора с помощью Docker-in-Docker (DinD) или удаленных конечных точек демона. Например, запустите демона Docker внутри контейнера с --privileged (но это ослабляет изоляцию). Лучший подход: запускать отдельные демоны на отдельных виртуальных машинах или использовать экспериментальную функцию --group Docker с пользовательскими пространствами имен. Для оркестрации изоляция на основе пространств имен Kubernetes более практична, как описано в Защита от побега из контейнера: практическое руководство по изоляции Docker для многопользовательского хостинга.

Шаг 4: Рассмотрите изолированные среды выполнения

Когда само ядро Linux не заслуживает доверия, используйте изолированную среду выполнения, которая добавляет легкий слой виртуальной машины. gVisor (runsc) перехватывает системные вызовы и реализует собственное ядро, а Firecracker использует микровиртуальные машины с аппаратной визуализацией. Оба интегрируются с Docker через среды выполнения containerd. Например, добавьте "runtimes": {"runsc": {}} в конфигурацию демона Docker и запускайте контейнеры с --runtime=runsc. Накладные расходы по производительности составляют 5–15%, но изоляция значительно прочнее. Идеально для высокозащищенных многопользовательских установок.

Шаг 5: Оркестрация с Kubernetes и политиками безопасности

Kubernetes предоставляет встроенную многопользовательскую работу через пространства имен, стандарты безопасности Pod и политики сети. Определите пространства имен для каждого арендатора с квотами ресурсов и применяйте ограниченные контексты безопасности Pod (отключите все возможности, корневая файловая система только для чтения). Контроллеры допуска, такие как OPA/Gatekeeper, могут блокировать неправильные конфигурации. Если вы управляете многими арендаторами, Kubernetes автоматизирует обеспечение изоляции. Для оркестрации производственного масштаба обратитесь к Beyond Docker Compose: оркестрация контейнеризованных приложений, готовых к производству.

Шаг 6: Выбор правильного хостинг-провайдера

Гипервизор вашего поставщика инфраструктуры имеет значение. Docker на общем хостинге (OpenVZ) дает слабую изоляцию — один арендатор может видеть процессы других. Предпочитайте провайдеров, использующих KVM или VMware, которые обеспечивают разделение на уровне оборудования. Провайдеры, такие как DigitalOcean, Kamatera или AWS, предлагают VPS на базе KVM с выделенными ресурсами. Для bare-metal убедитесь, что виртуализация на уровне BIOS включена для вложенных контейнеров. Провайдер, который изолирует арендаторов на уровне гипервизора, дополняет изоляцию контейнеров. Как подробно описано в Освоение изоляции Docker для безопасного и эффективного веб-хостинга, хостовая ОС также должна быть защищена с минимальной поверхностью атаки.

Предостережения и компромиссы

Каждый дополнительный слой добавляет сложность и затраты производительности. Пользовательские пространства имен могут нарушить работу томов, монтируемых хостом. Профили Seccomp требуют настройки для каждого приложения. Изолированные среды выполнения, такие как gVisor, не поддерживают все системные вызовы — ваше приложение может не работать. Демоны Docker для каждого арендатора увеличивают накладные расходы памяти. Выбирайте уровень изоляции, соответствующий вашей модели угроз: для доверенных арендаторов может быть достаточно пространств имен по умолчанию; для публичного SaaS инвестируйте в изолированные среды выполнения и политики Kubernetes. Тщательно тестируйте перед запуском в производство.

Заключение

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

Sources (5)