company_banner

Безопасность для Docker-контейнеров

Автор оригинала: Rain
  • Перевод
Прим. перев.: Тема безопасности Docker, пожалуй, одна из вечных в современном мире IT. Поэтому без лишних объяснений представляем перевод очередной подборки соответствующих рекомендаций. Если вы уже интересовались этим вопросом, многие из них будут вам знакомы. А саму подборку мы дополнили списком из полезных утилит и несколькими ресурсами для дальнейшего изучения вопроса.



Предлагаю вниманию руководство по обеспечению безопасности Docker'а. Обратная связь приветствуется, так как это скорее сборник отрывков с разных ресурсов, и не все они были подвергнуты доскональной проверке. Рекомендации разделены на три категории:

  1. Необходимые меры внутри операционной системы хоста при работе с Docker'ом;
  2. Инструкции, относящиеся к файлу конфигурации сборки и созданию контейнеров;
  3. Инструменты для безопасности, которые могут интегрироваться со специфическими функциями Docker Enterprise.

Базой для руководства стали различные ресурсы, многие из которых приведены ниже. Его нельзя назвать исчерпывающим, однако оно охватывает все основы. Дополнительную информацию можно найти в описании к тестам CIS (ссылка приведена в конце этого руководства), а также в документации к Docker'у.

Docker Security Benchmark


Docker Bench for Security автоматически проверяет ваш Docker на соответствие наиболее распространенным лучшим практикам. Скрипт выступает неплохим эвристическим тестом безопасности, однако его не стоит рассматривать как инструмент комплексного анализа.

ОС хоста


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

Правила аудита


Создавайте и используйте правила аудита для файлов, связанных с Docker'ом, с помощью auditctl. Например, можно добавить -w /usr/bin/dockerd -k docker к /etc/audit.rules и перезапустить сервис аудита.

Режим FIPS


Включение режима FIPS заставляет криптографические инструменты переключиться на алгоритмы, внесенные в FIPS (американские Federal Information Processing Standards — прим. перев.), соответствуя, таким образом, федеральным и отраслевым нормам и требованиям. Если ОС хоста поддерживает режим FIPS, его можно включить, выполнив следующие команды:

sed -i 's/GRUB_CMDLINE_LINUX="/GRUB_CMDLINE_LINUX="fips=1 /g' /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg && reboot

Также необходимо включить FIPS в Docker Engine:

mkdir -p /etc/systemd/system/docker.service.d 2>&1; echo -e "[Service]\n Environment=\"DOCKER_FIPS=1\"" > /etc/systemd/system/docker.service.d/fips-module.conf; systemctl daemon-reload; systemctl restart docker

Для получения дополнительной информации см. в документации Docker и Red Hat.

Docker Secrets


Конфиденциальные данные должны храниться как секреты. Запустить соответствующий сервис можно с помощью команды docker service create:

docker service create --label com.docker.ucp.access.label=/prod --name nginx --publish 443 --secret source=orcabank_prod_mobile.ca.pem.v1,target=ca.pem nginx

Подробности см. в документации.

Файл конфигурации Docker'а


Следующие настройки можно добавить в файл конфигурации /etc/docker/daemon.json:

  • "icc":false — отключает обмен данными между контейнерами, чтобы избежать ненужной утечки информации.
  • log-level: "info" — захватывает все логи кроме отладочных.
  • {
      "log-driver": "syslog",
      "log-opts": {
        "syslog-address": "udp://1.2.3.4:1111"
      }
    }

    — подключает удаленное ведение логов, пересылает их по указанному адресу. Работает только в том случае, если запущен демон syslog. В качестве опций принимаются TCP и UDP. Также возможно подключение для каждого конкретного контейнера. Для этого устанавливается специальный флаг при запуске Docker'а (--log-opt syslog-address=ADDRESS).
  • "userns-remap": "Your_User" — предотвращает поднятие привилегий (privilege escalation), изолируя пространство имен под конкретного пользователя.

Безопасность транспортного уровня


Возможность подключения к демону Docker'а (если удаленный доступ необходим) должна быть только у пользователей с доступом к учетным данным TLS-клиента.

Плагины авторизации


Определитесь с тем, каким пользователям какие команды разрешено выполнять, и создайте соответствующий плагин авторизации для Docker'а. Затем запустите демон Docker'а и добавьте в него плагин:

dockerd --authorization-plugin=PLUGIN_ID

Чтобы больше узнать о создании авторизационных плагинов, см. в документации.

Параметры демона


Демон Docker'а работает с набором параметров по умолчанию.

  • --live-restore — этот параметр помогает сократить время простоя контейнеров при выключении или перезагрузке системы. Становится проще их патчить или обновлять с минимальным простоем;
  • --userland-proxy=false — когда доступны или используются hairpin NAT'ы, прокси в пользовательском пространстве становится избыточной службой, которая только увеличивает число возможных векторов атаки;
  • --no-new-privileges — предотвращает получение дополнительных привилегий контейнерами при помощи suid или sguid;
  • --seccomp-profile /path/to/profile — если у вас есть собственный профиль seccomp, можно его применить с помощью этого флага. Узнать больше о Seccomp и Docker можно здесь.

Конфигурация контейнеров и файлов сборки


Создание пользователя


Убедитесь, что для контейнера создан пользователь и запускайте его под этим пользователем (НЕ запускайте контейнер под рутом).

Удаленный доступ


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

Изолируйте пространство имен пользователя


Особенно важно убедиться, что пространство имен пользователя в Docker'е изолировано, поскольку по умолчанию оно используется совместно с пространством имен хоста. В некоторых случаях этим можно воспользоваться для поднятия привилегий или даже для выхода за пределы контейнера. Изолировать пользовательское пространство имен можно путем редактирования файла конфигурации (как описывается выше в разделе «Файл конфигурации Docker'а»). Дополнительное упоминание этой проблемы здесь вызвано ее важностью.

Healthcheck'и


Healthcheck (проверка работоспособности) — мощный инструмент, позволяющий проверять целостность контейнера. Настраивается он в Dockerfile с помощью инструкции HEALTHCHECK. Healthcheck'и позволяют убедиться, что контейнер работает должным образом. В приведенном ниже примере проверка работоспособности завершается 0, если сервер работает, и 1, если он «упал»:

HEALTHCHECK CMD curl --fail http://localhost || exit 1

SELinux


Если SELinux поддерживается операционной системой хоста, создайте или импортируйте политику SELinux и запускайте Docker в режиме демона с включенным SELinux:

docker daemon --selinux-enable

В этом случае Docker-контейнеры можно запускать с параметрами безопасности, например:

docker run --interactive --tty --security-opt label=level:TopSecret centos /bin/bash

Сетевые интерфейсы


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

docker run --detach --publish 10.2.3.4:49153:80 nginx

Кэшированные версии образов


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

Сетевой мост


Сетевая модель по умолчанию, docker0, уязвима перед атаками типа ARP-spoofing и MAC-flooding. Чтобы решить эту проблему, создайте сетевой мост в соответствии со своими спецификациями, как описано здесь.

Предупреждение о сокете Docker'а


Никогда не пробрасывайте сокет Docker'а внутрь контейнера. Иначе у контейнера появится возможность выполнять команды Docker'а и, следовательно, связываться с операционной системой хоста и контролировать её. Не делайте этого.

Конфигурирование Docker Enterprise


Docker Trust


Docker Trust позволяет генерировать ключи, с помощью которых можно проверять криптографическую целостность образов. Ключи Docker Trust можно использовать для подписи образов Docker приватными ключами, что проверяются публичными ключами на Notary Server. Дополнительная информация — здесь. Включение Docker Trust в Enterprise Engine подробно описано в этом разделе документации.

Сканирование уязвимостей


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

Прим. перев.: Существуют и Open Source-сканеры уязвимостей в Docker-образах, примеры которых см. в конце материала.

Интеграция LDAP и UCP


Universal Control Plane можно интегрировать с LDAP. Результатом станет упрощенная система аутентификации, позволяющая избежать ненужного дублирования. Подробнее об этом можно почитать в статье Integrate with an LDAP directory.

Другие материалы


Дополнительную информацию о лучших практиках в области обеспечения безопасности Docker'а можно найти на docs.docker.com. Также рекомендуем загрузить тесты Center for Internet Security для Docker.

Бонус от переводчика


В качестве логичного дополнения к этой статье публикуем список из 10 популярных Open Source-утилит для обеспечения безопасности в Docker. Он был заимствован из другой статьи (за авторством Bill Doerrfeld из Doerrfeld.io).

NB: Подробнее о многих из упомянутых здесь проектах читайте также в статье «33+ инструмента для безопасности Kubernetes».

  1. Docker Bench for Security — уже упомянутый в самом начале статьи скрипт, проверяющий контейнеры Docker на соответствие распространённым практикам обеспечения безопасности.

  2. Clair — наверное, самая популярная утилита для статического анализа уязвимостей в контейнере. Использует для этого многочисленные базы уязвимостей CVE (включая трекеры ведущих Linux-дистрибутивов, таких как Red Hat, Debian, Ubuntu). Предлагает API для разработчиков и простую возможность по расширению функций (через добавление «драйверов»). Применяется в популярном публичном реестре образов контейнере (аналоге Docker Hub) — Quay.io.
  3. Cilium — решение для обеспечения сетевой безопасности на уровне ядра, основанное на технологии фильтрации сетевых пакетов BPF.
  4. Anchore — утилита для анализа содержимого образов на наличие уязвимостей в безопасности по базе CVE. Кроме того, она позволяет применять пользовательские политики (на основе разных данных включая белые/черные списки, содержимое файлов и т.п.) для оценки безопасности контейнеров.
  5. OpenSCAP Workbench — целая экосистема для создания и поддержания политик безопасности на разных платформах. Для проверки контейнеров предлагает утилиту oscap-docker.
  6. Dagda — утилита для сканирования Docker-контейнеров на наличие уязвимостей, троянов, вирусов и malware. В базы CVE включены проверки по зависимостям от OWASP, база Red Hat Oval, репозиторий эксплоитов Exploit Database.
  7. Notary — фреймворк для подписывания Docker-образов, изначально созданный в Docker Inc (и затем переданный на развитие в CNCF). Его использование позволяет делегировать роли и распределять ответственности по конетйнерам, а также верифицировать криптографическую целостность образов.
  8. Grafaes — API для метаданных, призванный предназначенный для управления внутренними политиками безопасности. Как пример, он позволяет улучшить работу сканеров безопасности контейнеров. Shopify использует этот API для управления метаданными по своим 500 тысячам образов.
  9. Sysdig Falco — утилита для Kubernetes, следящая за поведением системы: активностью в контейнерах, на хостах, в сети. Позволяет настраивать непрерывные проверки в инфраструктуре, обнаружение аномалий и отправку алертов по любым системным вызовам Linux.
  10. Banyanops Collector — ещё один инструмент для статического анализа образов Docker-контейнеров. Позволяет «заглядывать» в файлы образа, собирая необходимые данные, применяя нужные политики и т.п.

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

Для желающих ещё детальнее погрузиться в эту тему в прошлом году вышла книга «Docker Security: Quick Reference», фрагменты которой свободно доступны здесь.

Наконец, для практического знакомства с некоторыми аспектами безопасности Docker: профилями Seccomp и использованием capabilities Linux-ядра в контейнерах — можно пройти соответствующие лабораторные работы на ресурсе Play with Docker* — см. секцию «Security».



* Про сам этот ресурс мы рассказывали два года назад, а в ноябре 2018-го с ним случилась очень занимательная (с точки зрения безопасности) история. Если вкратце, то специалистам из CyberArk Software Ltd. удалось его взломать: добиться возможности выполнять команды за пределами контейнеров, т.е. на хост-системе. Прекрасная иллюстрация проблемы безопасности в Docker, не так ли? Обо всех деталях случившегося читайте здесь.

P.S. от переводчика


Читайте также в нашем блоге:

  • +37
  • 11,1k
  • 7
Флант
697,15
Специалисты по DevOps и Kubernetes
Поддержать автора
Поделиться публикацией

Комментарии 7

    0

    Перевод отличный, но интересно узнать ваше мнение. Собственное. Потому что многие вещи, описанные в статье… ну, спорные…
    Например, live-restore. Отличный способ себе пострелять по ногам, когда радикально меняются настройки докер демона (я не проверял, но есть подозрение, что та же смена storage driver + liverestore все сломает).


    Еще есть как минимум два сценария использования докера — на машине разработчика в режиме разработки и на тестовых/промышленных средах. А вот для последних рекомендации актуальны. Вряд ли кто-то будет бридж на машине разработчика спуфить )

      0
      Да, есть довольно странные или спорные моменты, но куда без них? :)

      По вашему примеру с live-restore. Предполагаю, что да — эта проблема имеет место быть, НО! в реальности часто ли вам приходится менять те же storage driver? Почему нельзя мигрировать контейнеры на новые ноды с новым storage driver и потом на старых нодах провести работы. Если вы собираетесь делать такие вещи и знаете, что вы выставили live-restore.
        0

        Потому что, очевидно, нет понятия миграции контейнеров. Они же иммутабельные и созданы, чтобы умирать. Это раз.
        Два — это подразумевает кластерное решение вроде кубернетеса. А там свой процесс. И более того — свои особенности. И докИр там не нужен.
        Я уж не говорю о том, что есть вероятность, что не все контейнеры управляются оркнстратором типа кубернетеса. Например, ранчер любит системные компоненты вроде кьюьлета запускать в докере вне куба. А не в системди сервисе.
        Три — мне показалось, или это так и есть, но автор рассматривал безопасность именно standalone docker нод

      +1
      Никогда не запускайте сокет Docker'а внутри контейнера.

      — гугл транслейт, ты ли это?
        0
        Спасибо, поправили.
        +1
        Конфиденциальные данные должны храниться как секреты. Запустить соответствующий сервис можно с помощью команды docker service create

        я ошибаюсь или docker service доступен только если хост в режиме Swarm? Т.е. «просто так» этого не сделать. Может стоит указывать такое в тексте?

        Healthcheck (проверка работоспособности) — мощный инструмент, позволяющий проверять целостность контейнера.

        мне кажется, к теме безопасности (равно как и целостности контейнера) это не относится. Вызов какого-то скрипта (утилиты) Healthcheck это лишь проверка «работает ли процесс внутри контейнера должным образом». И то — если такая возможность представляется самим процессом. Как это повышает безопасность?

        Я бы еще добавил пункт о том, что пользователь хоста, имеющий доступ к сокету Докера (или иным способом имеющий возможность управлять контейнерами) по сути имеет полный доступ к хосту.
        Как пример — включение в группу docker (без включения возможности sudo) позволяет прокинуть в контейнер корень ФС и изнутри контейнера спокойно «что-то запрещенное почитать\исправить».

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

      Самое читаемое