🐳 Как средства Docker защищают контейнерные среды |

🐳 Как средства Docker защищают контейнерные среды

Обзоры

Docker активно использует возможности ядра Linux.

Одними из основных аспектов, которые контейнеры используют из ядра Linux, являются пространства имен и cgroups.

В этой статье представлен обзор различных примитивов безопасности docker, которые можно использовать при работе с контейнерами docker.

Мы обсудим пространства имен, cgroups, возможности, профили seccomp и профили apparmor.

Продолжение статьи:

🐳 Как защитить Docker в производственной среде?

Пространства имен

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

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

Аналогично, давайте рассмотрим другой сценарий, в котором есть 3 веб-сервера Apache, запущенные в 3 разных контейнерах.

Все три контейнера должны будут запустить серверы Apache на порту 80.

Кроме того, хост-машина также должна иметь возможность использовать порт 80 для другой службы.

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

Пространства имен – это функция ядра Linux, которая разделяет ресурсы ядра таким образом, что один набор процессов видит один набор ресурсов, а другой набор процессов – другой набор ресурсов.

Таким образом, Docker использует пространства имен для обеспечения такой изоляции контейнеров от хоста.

Команда lsns на хосте Docker показывает список пространств имен, используемых Docker.

lsns
NS TYPE   NPROCS   PID USER   COMMAND
4026531835 cgroup     73  1516 docker /lib/systemd/systemd --user
4026531836 pid        73  1516 docker /lib/systemd/systemd --user
4026531837 user       73  1516 docker /lib/systemd/systemd --user
4026531838 uts        73  1516 docker /lib/systemd/systemd --user
4026531839 ipc        73  1516 docker /lib/systemd/systemd --user
4026531840 mnt        73  1516 docker /lib/systemd/systemd --user
4026531992 net        73  1516 docker /lib/systemd/systemd --user

Как видно из предыдущего вывода, движок docker использует 6 различных пространств имен, а именно:

  • Пространство имен PID для изоляции процессов.
  • Пространство имен USER для изоляции привилегий пользователей.
  • Пространство имен UTS для изоляции идентификаторов ядра и версий.
  • Пространство имен IPC для управления доступом к ресурсам IPC.
  • Пространство имен MNT для управления точками монтирования файловой системы.
  • Пространство имен NET для управления сетевыми интерфейсами.

Cgroups

Группы управления (cgroups) – это функция ядра Linux, которая позволяет ограничить доступ процессов и контейнеров к системным ресурсам, таким как CPU, RAM, IOPS и сеть.

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

Записи Cgroup на машине Ubuntu можно найти в следующем месте.

/sys/fs/cgroup/

В этой директории есть несколько каталогов для различных ресурсов, таких как CPU, память и PID.

Список каталогов приведен в следующей выдержке.

ls /sys/fs/cgroup/ blkio  cpu  cpuacct  cpu,cpuacct  cpuset  devices  freezer  hugetlb  memory  net_cls  net_cls,net_prio  net_prio  perf_event  pids  rdma  systemd  unified

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

Это выглядит следующим образом.

cat /sys/fs/cgroup/pids/docker/b80255b4f42f0603eff01be1472fe9e561e1ee2f7a584f57fcf4ed30ca5e4156/pids.max
max

Как мы заметили в предыдущем отрывке, файл pids.max содержит значение max для определенного контейнера, чей идентификатор начинается с b80255.

Этим можно управлять при запуске контейнера.

Следующий пример показывает, как число пидов может быть ограничено определенным числом, которое в данном случае равно 6.

docker run -itd --pids-limit 6 alpine

Проверка записи cgroup этого нового контейнера показывает следующее.

  $ cat /sys/fs/cgroup/pids/docker/abfccb1e25e9dc57698800e53ca277f51c7cc0632734a2cf17a27cd10f14d620/pids.max
6

Как мы можем заметить, количество для этого контейнера теперь ограничено 6.

Аналогичным образом мы можем контролировать и другие ресурсы, такие как CPU, память и IOPS.

Capabilities

Root-пользователи в Linux особенные, они обладают сверхспособностями.

Это означает, что root-пользователи имеют больше привилегий, чем обычные пользователи в среде Linux.

Если разбить все эти сверхспособности на отдельные единицы, они станут Capabilities (возможностями).

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

Разбивка этих возможностей на части позволяет нам контролировать то, что может делать пользователь root.

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

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

Мы можем использовать команды Docker для добавления или удаления возможностей.

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

casph --print

Если контейнер запускается с использованием флага –privileged, все возможности будут назначены контейнеру.

🐳 Как и зачем запускать Docker внутри Docker

Docker позволяет нам отбрасывать или добавлять определенные возможности к контейнеру.

В следующем примере показано, как можно отказаться от определенной возможности.

  $ docker run -it --cap-drop CHOWN alpine sh

Как мы можем заметить, возможность CHOWN удалена из контейнера.

В следующем примере показано, как можно удалить все возможности и добавить определенную возможность.

  $ docker run -it --cap-drop ALL --cap-add chown alpine sh

Как мы можем заметить, добавлена возможность 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 по умолчанию.

docker run --rm -it --security-opt seccomp=unconfined alpine sh

Мы можем убедиться, что больше не работаем с профилем seccomp по умолчанию, выполнив команду unshare, которая запускает процесс оболочки в новом пространстве имен.

Это выглядит следующим образом.

  $ docker run --rm -it --security-opt seccomp=unconfined alpine sh
/ # unshare --map-root-user --user
456dee225040:/# whoami
root
456dee225040:/#

К сведению, мы не можем выполнить команду unshare, когда загружен профиль seccomp по умолчанию.

При попытке выполнить команду это выглядит следующим образом.

  $ docker run --rm -it alpine sh
/ # unshare --map-root-user --user
unshare: unshare(0x10000000): Operation not permitted
/ #

AppArmor

AppArmor (Application Armor) – это модуль безопасности Linux, который защищает операционную систему и ее приложения от угроз безопасности.

AppArmor не создан для Docker, это инструмент безопасности Linux.

Поскольку Docker использует ядро Linux, AppArmor можно использовать и с контейнерами Docker.

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

Чтобы использовать его в Docker, нам нужно связать профиль безопасности AppArmor с каждым контейнером.

Таким образом, когда мы запускаем контейнер, мы должны предоставить ему пользовательский профиль AppArmor, и Docker ожидает, что политика AppArmor будет загружена и применена.

Docker поставляется с профилем по умолчанию для контейнеров под названием docker-default.

Следующая команда может быть использована для загрузки профиля AppArmor при запуске контейнера.

  $ docker run -itd --security-opt apparmor=apparmor-profile alpine

🐧 AppArmor и SELinux: Всестороннее сравнение

Заключение

В этой статье мы рассмотрели, как docker использует различные возможности ядра Linux, включая пространства имен, cgroups и capabilities.

Мы обсудили, как можно добавлять или удалять возможности при создании контейнера.

Кроме того, мы обсудили, как можно использовать профили AppArmor и seccomp для повышения общей безопасности контейнеров.

см. также:

 

Пожалуйста, не спамьте и никого не оскорбляйте. Это поле для комментариев, а не спамбокс. Рекламные ссылки не индексируются!
Добавить комментарий