Введение

Контейнеры LXC могут быть двух типов:

  • Привилегированные контейнеры
  • Непривилегированные контейнеры

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

Вторые были добавлены в LXC 1.0 (февраль 2014) и требуют относительно свежее ядро (3.13 и выше). Положительная сторона в том, что мы считаем такие контейнеры безопасными для root так что пока вы отслеживаете все проблемы безопасности ядра, такие контейнеры безопасны.

Так как привилегированные контейнеры считаются небезопасными, мы обычно не считаем новые эксплоиты выхода из контейнера проблемами безопасности, достойными CVE и быстрого исправления. Мы тем не менее пытаемся уменьшить эти проблемы защищая хост от случайного повреждения.

Привилегированные контейнеры

Привилегированным контейнером считается любой контейнер в котором uid 0 соотносится с uid 0 хоста. В таких контейнерах, защита хоста и предотвращение выхода целиком производится через Мандатное управление доступом (apparmor, selinux), фильтры seccomp, ограничение привилегий и пространства имен.

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

Позиция upstream LXC в том, что такие контейнеры не являются и не могут быть безопасными для root.

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

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

Непривилегированные контейнеры

Непривилегированные контейнеры безопасны как задумано. uid 0 контейнера соответствует непривилегированному пользователю снаружи контейнера и имеет расширенные права только на свои ресурсы.

С таким контейнером, использование SELinux, AppArmor, Seccomp и capabilities для защиты не является необходимым. LXC будет по прежнему использовать их для добавления дополнительного уровня защиты который может быть полезным в случае проблемы безопасности ядра, но защита обеспечивается не только ими.

Для обеспечения работы непривилегированных контейнеров, LXC взаимодействует с 3 частями кода setuid:

  • lxc-user-nic (setuid helper для создания пары veth и моста на хосте)
  • newuidmap (из пакета shadow, задает связку uid)
  • newgidmap (из пакета shadow, задает связку gid)

Все остальное запущено под своими собственными пользователями или под uid вашего пользователя.

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

LXC upstream счастлив помочь отследить такую проблему безопасности и находится на связи с сообществом ядра Linux для разрешения их быстро как только возможно.

Потенциальные DoS атаки

LXC не пытается предотвратить DoS атаки по умолчанию. При запуске множества недоверенных контейнеров или при разрешении недоверенным пользователям запуска контейнеров, следует держать в уме несколько вещей и обновлять свои настройки соответственно:

Ограничения Cgroup

LXC наследует ограничения cgroup от своего родителя, на моем дистрибутиве Linux, реальных ограничений не установлено. В результате, пользователь в контейнере может довольно легко DoS запуском fork бомбы, использовав всю системную память или создавая сетевые интерфейсы пока у ядра не кончится память.

Это можно предотвратить задав необходимые элементы конфигурации lxc.cgroup (память, cpu и pids) или удостоверившись что родительский пользователь помещен в надлежащим образом настроенную cgroups во время входа.

Пользовательские ограничения

Как и с cgroups, родительские ограничения наследуются так что непривилегированные контейнеры не могут иметь ulimits установленным на значения выше чем их родительские.

Тем не менее есть одна вещь которую стоит держать в уме, ulimits как и предполагает их имя, связаны с uid на уровне ядра. Это глобальный uid ядра, не uid внутри пространства имен пользователя.

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

Для предотвращения этого, недоверенные пользователи или контейнеры должны иметь абсолютно разные связи id (в идеале из 65536 uids и gids каждый).

Общие сетевые мосты

LXC устанавливает базовую level 2 связь для своих контейнеров. Для удобства он также предоставляет один мост по умолчанию для системы.

Так как контейнер подключенный к мосту может передавать любой level 2 трафик какой захочет, он может успешно совершать MAC или IP spoofing на мосту.

При запуске недоверенных контейнеров или при разрешении недоверенным пользователям запуска контейнеров, следует в идеале создавать один мост на пользователя или на группу недоверенных контейнеров и настраивать /etc/lxc/lxc-usernet чтобы такие пользователи могли использовать только выделенные мосты.

Сообщение о проблемах безопасности

Для уверенности в том что проблемы безопасности могут быть исправлены так быстро как возможно и одновременно во всех дистрибутивах Linux, о проблемах должно быть сообщено либо:

  • По электронной почте одновременно serge.hallyn (at) ubuntu (dot) com И stgraber (at) ubuntu (dot) com
  • Открытием приватного сообщения о проблемах безопасности на https://launchpad.net/ubuntu/+source/lxc/+filebug

Затем мы подтвердим проблему безопасности, подоспеем с исправлениями всех поддерживаемых релизов, предоставим вам эти патчи для тестирования и затем получим CVE, также как скоординированную дату выпуска для вас и сообщества дистрибутивов Linux.