Docker активно использует возможности ядра Linux.
Одними из основных аспектов, которые контейнеры используют из ядра Linux, являются пространства имен и cgroups.
В этой статье представлен обзор различных примитивов безопасности docker, которые можно использовать при работе с контейнерами docker.
Мы обсудим пространства имен, cgroups, возможности, профили seccomp и профили apparmor.
Продолжение статьи:
🐳 Как защитить Docker в производственной среде?
Пространства имен
Одной из основных проблем при использовании контейнеров является изоляция между контейнерами и хостом, а также изоляция между различными контейнерами.
Представьте, что мы запускаем два контейнера с разными наборами функций, и нет необходимости, чтобы каждый процесс контейнера знал, что запущено в другом контейнере.
Аналогично, давайте рассмотрим другой сценарий, в котором есть 3 веб-сервера Apache, запущенные в 3 разных контейнерах.
Все три контейнера должны будут запустить серверы Apache на порту 80.
Кроме того, хост-машина также должна иметь возможность использовать порт 80 для другой службы.
Эти проблемы решаются в контейнерах с помощью функции ядра Linux, называемой пространствами имен.
Пространства имен – это функция ядра Linux, которая разделяет ресурсы ядра таким образом, что один набор процессов видит один набор ресурсов, а другой набор процессов – другой набор ресурсов.
Таким образом, Docker использует пространства имен для обеспечения такой изоляции контейнеров от хоста.
Команда lsns на хосте Docker показывает список пространств имен, используемых Docker.
Как видно из предыдущего вывода, движок docker использует 6 различных пространств имен, а именно:
- Пространство имен PID для изоляции процессов.
- Пространство имен USER для изоляции привилегий пользователей.
- Пространство имен UTS для изоляции идентификаторов ядра и версий.
- Пространство имен IPC для управления доступом к ресурсам IPC.
- Пространство имен MNT для управления точками монтирования файловой системы.
- Пространство имен NET для управления сетевыми интерфейсами.
Cgroups
Группы управления (cgroups) – это функция ядра Linux, которая позволяет ограничить доступ процессов и контейнеров к системным ресурсам, таким как CPU, RAM, IOPS и сеть.
Cgroup ограничивает приложение определенным набором ресурсов, что позволяет движку Docker распределять доступные аппаратные ресурсы между контейнерами и по желанию применять лимиты и ограничения.
Записи Cgroup на машине Ubuntu можно найти в следующем месте.
/sys/fs/cgroup/
В этой директории есть несколько каталогов для различных ресурсов, таких как CPU, память и PID.
Список каталогов приведен в следующей выдержке.
При запуске контейнеров docker на хосте для каждого контейнера будет создана запись в некоторых из этих каталогов с информацией о подключенных ресурсах.
Это выглядит следующим образом.
Как мы заметили в предыдущем отрывке, файл pids.max содержит значение max для определенного контейнера, чей идентификатор начинается с b80255.
Этим можно управлять при запуске контейнера.
Следующий пример показывает, как число пидов может быть ограничено определенным числом, которое в данном случае равно 6.
Проверка записи cgroup этого нового контейнера показывает следующее.
Как мы можем заметить, количество для этого контейнера теперь ограничено 6.
Аналогичным образом мы можем контролировать и другие ресурсы, такие как CPU, память и IOPS.
Capabilities
Root-пользователи в Linux особенные, они обладают сверхспособностями.
Это означает, что root-пользователи имеют больше привилегий, чем обычные пользователи в среде Linux.
Если разбить все эти сверхспособности на отдельные единицы, они станут Capabilities (возможностями).
Почти все супервозможности, связанные с пользователем root, разбиты на отдельные.
Разбивка этих возможностей на части позволяет нам контролировать то, что может делать пользователь root.
Это означает, что мы можем сделать пользователя root менее влиятельным, а также предоставить больше полномочий стандартному пользователю на гранулярном уровне.
По умолчанию Docker отбрасывает все возможности, кроме тех, которые необходимы, используя подход “белого списка”.
Мы можем использовать команды Docker для добавления или удаления возможностей.
Следующая команда может быть использована для получения списка стандартного набора возможностей контейнера alpine.
Если контейнер запускается с использованием флага –privileged, все возможности будут назначены контейнеру.
🐳 Как и зачем запускать Docker внутри Docker
Docker позволяет нам отбрасывать или добавлять определенные возможности к контейнеру.
В следующем примере показано, как можно отказаться от определенной возможности.
Как мы можем заметить, возможность CHOWN удалена из контейнера.
В следующем примере показано, как можно удалить все возможности и добавить определенную возможность.
Как мы можем заметить, добавлена возможность CHOWN, а все остальные возможности удалены из контейнера.
Так мы можем использовать возможности для детального контроля над привилегиями, которыми могут обладать рутовые учетные записи.
Seccomp
Seccomp – это функция ядра Linux, которую мы можем использовать для ограничения действий, доступных внутри контейнера.
При запуске нового контейнера Docker мы можем переопределить стандартный профиль seccomp на профиль по нашему выбору, как показано ниже.
{ "defaultAction": "SCMP_ACT_ALLOW", "architectures": [ "SCMP_ARCH_X86_64", "SCMP_ARCH_X86", "SCMP_ARCH_X32" ], "syscalls": [ { "name": "chmod", "action": "SCMP_ACT_ERRNO", "args": [] } ] }
Предшествующий профиль seccomp является незащищенным, разрешающим по умолчанию все вызовы систем из контейнера, кроме chmod, который явно заблокирован.
Следующая команда показывает, как можно запустить контейнер docker без загрузки профиля seccomp по умолчанию.
Мы можем убедиться, что больше не работаем с профилем seccomp по умолчанию, выполнив команду unshare, которая запускает процесс оболочки в новом пространстве имен.
Это выглядит следующим образом.
К сведению, мы не можем выполнить команду unshare, когда загружен профиль seccomp по умолчанию.
При попытке выполнить команду это выглядит следующим образом.
AppArmor
AppArmor (Application Armor) – это модуль безопасности Linux, который защищает операционную систему и ее приложения от угроз безопасности.
AppArmor не создан для Docker, это инструмент безопасности Linux.
Поскольку Docker использует ядро Linux, AppArmor можно использовать и с контейнерами Docker.
Профили AppArmor применяются к путям файловой системы, чтобы наложить ограничения на доступ к файлам.
Чтобы использовать его в Docker, нам нужно связать профиль безопасности AppArmor с каждым контейнером.
Таким образом, когда мы запускаем контейнер, мы должны предоставить ему пользовательский профиль AppArmor, и Docker ожидает, что политика AppArmor будет загружена и применена.
Docker поставляется с профилем по умолчанию для контейнеров под названием docker-default.
Следующая команда может быть использована для загрузки профиля AppArmor при запуске контейнера.
🐧 AppArmor и SELinux: Всестороннее сравнение
Заключение
В этой статье мы рассмотрели, как docker использует различные возможности ядра Linux, включая пространства имен, cgroups и capabilities.
Мы обсудили, как можно добавлять или удалять возможности при создании контейнера.
Кроме того, мы обсудили, как можно использовать профили AppArmor и seccomp для повышения общей безопасности контейнеров.
- ☸️ Изучаем Kubernetes: 5 лучших практик безопасности
- ☸️ Как узнать, что находится в образах контейнеров
- ☸️ Vesta: Анализ конфигурации кластеров Docker и Kubernetes и анализ уязвимостей
- 🐳 Как опросить сокет Docker с помощью curl
- 🐳 Как минимизировать, оптимизировать и защитить контейнеры Docker с помощью DockerSlim
- 🐳 Как запускать удаленные команды Docker с помощью SSH