Безопасность хостовой системы
Одно из самых важных вопросов безопасности Docker - это обеспечение безопасности хост-машин, особенно ядра операционной системы. Поскольку в уже скомпрометированной системе изоляция и другие механизмы безопасности контейнеров, которые мы могли бы использовать, не смогут помочь. Это связано с тем, что Docker спроектирован таким образом, что все запущенные контейнеры используют ядро хост-системы. Поэтому в качестве хоста должен быть использован обновленный дистрибутив Linux без известных уязвимостей и признаков заражения вредоносным ПО.
Классическим примером такой уязвимости является «выход за пределы контейнера» (container breakout) в Docker. Эта уязвимость описывает ситуацию, когда программе, запущенной внутри контейнера, удается преодолеть механизмы изоляции и обрести привилегии суперпользователя (root) или получить доступ к важной информации, хранящейся на хост-машине. Один из типичных примеров такой уязвимости - уязвимость Dirty COW (CVE-2016-5195).
Для обеспечения защиты от подобных ситуаций применяется стратегия ограничения привилегий, выдаваемых контейнеру по умолчанию. Например, если демон Docker запущен с привилегиями суперпользователя (root), для него создается пользовательское пространство имен (user-level namespace) с минимальными привилегиями.
Как видно, безопасность хост-машины является фундаментальным вопросом для обеспечения безопасности Docker. Применение соответствующих мер, таких как использование обновленного дистрибутива Linux без известных уязвимостей, а также стратегий ограничения привилегий, позволяет снизить риски и обеспечить безопасность контейнеров.
Исчерпание ресурсов, или DDoS на контейнер
Если сравнивать контейнеры с виртуальными машинами, то первые более легковесны. Даже на старом и слабом железе можно запустить много контейнеров. Однако ошибки в конфигурации демонов, сетевого стека, недостатки проектирования архитектуры и атаки хакеров могут приводить к состояниям типа «отказ в обслуживании» (Denial of Service).
К примеру, некий контейнер или целый пул контейнеров может пожрать все процессорное время хоста и просадить его производительность. Аналогичная ситуация может сложиться и с сетевыми интерфейсами, когда количество генерируемых пакетов превысит нормальную пропускную способность сети. Но выход тут, в принципе, довольно прост: должным образом настроить лимиты ресурсов для контейнера.
Скомпрометированные образы для Docker
Docker является open source-программным обеспечением, распространяемым бесплатно. Оно предоставляет публичный доступ к образам, с помощью которых можно создавать контейнеры. Но данная свобода также открывает возможности для злоумышленников, которые могут использовать фишинг и другие методы социальной инженерии, чтобы манипулировать действиями пользователей, загружая предварительно скомпрометированные образы с вредоносными программами или задними дверями.
Например, в апреле этого года возникла новость о том, как неизвестные злоумышленники получили доступ к базе данных крупнейшей библиотеки образов для контейнеров Docker Hub. В результате этого инцидента были скомпрометированы личные данные пользователей, хеши паролей, а также токены для репозиториев на GitHub и Bitbucket, которые используются для автоматизированных сборок Docker. Также стоит вспомнить новость из лета 2018 года, когда семнадцать образов контейнеров, содержащих опасные backdoor программы, были удалены из официального реестра Docker Hub. Позднее эксперты обнаружили, что через эти образы на серверы пользователей проникал скрытый майнинг-софт и были установлены обратные шеллы.
Таким образом, необходимо аккуратно подойти к выбору и загрузке образов Docker, а также регулярно обновлять их для минимизации рисков и обеспечения безопасности своих систем.
Использование достоверных образов
Начнем, пожалуй, с банальной для репозиториев Docker проблемы — достоверности образа. Чтобы избежать проблем с фейковыми образами, используй приватные (private) или строго доверенные репозитории (trusted repositories) вроде Docker Hub. В отличие от других репозиториев, образы, которые там хранятся, всегда сканирует и просматривает специальный робот безопасности Docker’s Security Scanning Service.
Верифицируем образы через сервис Docker Content Trust
Еще один полезный и доступный всем инструмент, которым стоит воспользоваться, — Docker Content Trust. Это новая функция, доступная с версии Docker Engine 1.8. Она позволяет верифицировать владельца образа. Таким образом этот сервис защищает тебя от фейков и подделок, атак повторного воспроизведения и компрометации ключей.
Проверка хоста и контейнера с помощью Docker Bench Security
Docker Bench for Security — это скрипт, который проверяет десятки распространенных рекомендаций по развертыванию контейнеров Docker в рабочей среде. Все тесты автоматизированы и основаны на тесте CIS Docker Community Edition Benchmark v1.1.0.
https://github.com/docker/docker-bench-security — Гитхаб проекта
https://hub.docker.com/r/docker/docker-bench-security — Документация
Инструмент основывается на рекомендациях из документа The CIS Docker 1.13 Benchmark (PDF) и применяется в следующих областях:
Использование нативных опций безопасности на хостовых ОС
Для усиления безопасности можно использовать штатные инструменты Linux: AppArmor, SELinux, grsecurity и Seccomp.
AppArmor
AppArmor — эффективная и простая в использовании система безопасности приложений Linux. AppArmor активно защищает операционную систему и приложения от внешних или внутренних угроз, даже атак нулевого дня, обеспечивая хорошее поведение и предотвращая использование как известных, так и неизвестных недостатков приложений.
AppArmor дополняет модель Discretionary Access Control (DAC) — традиционной системы безопасности Unix, обеспечивая обязательный контроль доступа (MAC). Он включен в основное ядро Linux начиная с версии 2.6.36, а его разработка поддерживается Canonical с 2009 года.
SELinux
Security Enhanced Linux представляет собой набор правил и механизмов доступа, основанный на моделях мандатного и ролевого доступа, для защиты систем Linux от потенциальных угроз и исправления недостатков Discretionary Access Control (DAC) — традиционной системы безопасности Unix. Проект зародился в недрах Агентства Национальной Безопасности США, непосредственно разработкой занимались, в основном, подрядчики Secure Computing Corporation и MITRE, а также ряд исследовательских лабораторий.
grsecurity
Grsecurity — это обширное усовершенствование безопасности ядра Linux, которое защищает от широкого спектра угроз безопасности посредством интеллектуального контроля доступа, предотвращения эксплойтов на основе повреждения памяти и множества других мер по усилению защиты системы, которые обычно не требуют настройки.
Seccomp
Seccomp (сокращение от secure computing) — механизм ядра Linuх, позволяющий процессам определять системные вызовы, которые они будут использовать. Если злоумышленник получит возможность выполнить произвольный код, seccomp не даст ему использовать системные вызовы, которые не были заранее объявлены.
Seccomp — разработка Google. Он используется, в частности, в браузере Google Chrome для запуска плагинов.
Ограничения Docker Engine
Вспомним, что Docker Engine — это своего рода API, который прослушивает все входящие запросы и взаимодействует с базовым ядром хоста. Docker Engine поддерживает связь на трех сокетах: unix
, tcp
и fd
.
Безопасное состояние по умолчанию — это прослушивание сокета unix
.
Выставляем ограничение на привилегии выполнения
Чтобы максимально уменьшить площадь потенциальной атаки, подумай над следующими вопросами:
Для настройки ограничений будем использовать команды --cap-drop and
и --cap-add
.
Предположим, приложению абсолютно не требуется изменять системные процессы или биндить привилегированные порты, но при этом нужно загружать и выгружать модули ядра.
docker run \\
--cap-drop SETPCAP \\
--cap-drop NET_BIND_SERVICE \\
--cap-add SYS_MODULE \\
-ti busybox /bin/sh
Для обеспечения безопасности сетевого взаимодействия можно настроить правила iptables, реализованные в Docker. Например, указать диапазон IP-адресов для источника пакетов, чтобы ограничить трафик на контейнер. Это поможет предотвратить обращение глубоко изолированного контейнера во внешнюю сеть.
Ограничиваем потребление системных ресурсов
Чтобы откалибровать пул ресурсов, выделяемых для контейнера (CPU, RAM, SWAP, I/O), нужно задать пороговые значения следующими флагами:
-m
, --memory
— установить лимит выделения оперативной памяти (hard);--memory-reservation
— установить мягкий лимит памяти (soft);--kernel-memory
— установить лимит памяти ядра (kernel OS);--cpus
— ограничить количество используемых CPU;--device-read-bps
— ограничить пропускную способность чтения для конкретного устройства.Легитимность использования образов для развертывания контейнеров — один из ключевых критериев безопасности.