«Контейнер дал течь»: проверьте безопасность Docker-образа 🐳
Установленные в контейнере Docker пакеты, используемые библиотеки и даже базовый образ – любой компонент может создать уязвимость. Рассказываем, как вовремя найти и устранить течь.
Инструменты анализа Docker: Anchore и Clair
Для поиска уязвимостей в образах Docker есть специальные инструменты: Anchore Engine и Clair.
Anchore Engine –централизованная служба проверки, анализа и сертификации образа. Она сканирует образы, используя данные об уязвимостях (feeds) от вендоров ОС, таких как Red Hat, или Debian. Для non-OS данных используется NVD (National Vulnerability Database), которая включает уязвимости для RPM, Deb, APK, а также Python (PIP), Ruby Gems и т. д.
Clair– статический анализатор, разработанный компанией CoreOS для контейнеров Docker и APPC. Анализатор использует уязвимость метаданных для Red Hat Security Data, NVD, Ubuntu CVE Tracker, Alpine SecDB, Debian Security Bug Tracker и т. д.
Как Anchore, так и
Clair могут быть развёрнуты в Kubernetes или OpenShift, но для простоты настроим всё на локальной машине с помощью docker-compose.
Чтобы настроить Anchore, выполняем следующие действия:
Для Clair выполняем такую последовательность
Проверка Docker-образа на уязвимости с помощью Anchore
Начнём тест Anchore с
базового образа Debian:
Посмотрим, какие
уязвимости были обнаружены:
Сначала мы запускаем
команду image vuln со всеми флагами, чтобы обнаружить уязвимости ОС и пакетов,
присутствующих в образе. Все они незначительны или неизвестны – это хорошо.
Затем мы запускаем команду evaluate check, чтобы проверить, проходит ли образ проверку политики по умолчанию, и, как видим выше, он проходит (Status:
pass). Базовые образы обычно работают без нареканий, поскольку они широко
используются и находятся под большим вниманием.
Но как насчет простого
"Hello World" на Python, построенного с использованием образа Python
3 Debian Buster? Давайте сначала посмотрим на Dockerfile:
Ничего не сообщает о “vulnerable”
или “insecure”. Тогда соберём и проанализируем:
Сначала мы забилдили
образ, используя вышеприведённый debian.Dockerfile и hello.py, затем переместили
его в Docker Hub, откуда он был добавлен в Anchore и проанализирован. Взглянем
на результаты:
Уже не так хорошо. После
переключения на официальный образ Debian Python, появилось более 1000
уязвимостей. После выполнения оценки образа мы видим, что она не удалась (Status:
fail).
Несмотря
на то, что мы использовали официальный и безопасный образ, при создании элементарного
приложения без явных уязвимостей мы все равно получили массу проблем с
безопасностью. Как это исправить?
Поиск идеального образа
Distroless представляет собой набор docker-образов, созданных Google с учетом вопросов
безопасности. Эти образы содержат абсолютный минимум, необходимый для
приложения, а это означает, что нет никаких оболочек, менеджеров пакетов или
других инструментов, которые могли бы увеличить образ. Пусть мы выбрали один из Distroless-образов, посмотрим на новый Dockerfile:
Мало что изменилось по
сравнению с Debian-версией. Мы переключили текущий образ на gcr.io/distroless/python3.
Теперь можем продолжать: сбилдить, запушить и добавить его в Anchore Engine:
Посмотрим, работает ли Distroless менее эффективно, чем Debian-образ:
Можно видеть, что по
сравнению с первым примером здесь только 53 уязвимости и всего 2 уязвимости с
низкой степенью важности. Можно с
уверенностью заключить, что Distroless – лучший выбор, когда речь заходит о
безопасности контейнерных приложений. Однако есть еще несколько штуковин, с которыми
можно поиграться – использовать различные политики оценки:
В приведённой выше
команде перечислены все доступные политики, которые мы можем использовать для
проверки образов. По умолчанию используется anchore_default_bundle, который отлично
работает, но если мы хотим видеть проверку, выполняемую с использованием
другого списка и правил, то можно попробовать anchore_cis_1. 13.0_base:
В примере выше мы рассмотрели
описание политики, запустив policy hub get. Далее мы установили ее и, как
результат – имеем две доступные политики, причем одна из них неактивна. Исправим
это с помощью команды policy activate.
Для получения полного
списка правил в этой политике наберите anchore-cli --json policy hub
get anchore_cis_1.13.0_base.
Пришло время запуска:
Приведённые проблемы/уязвимости
не дают образу нормально пройти оценку политики и должны быть проанализированы.
Одна из них (вторая) вызвана использованием Distroless образа, так что ее можно
игнорировать. Две другие должны быть исправлены. Все это показывает нам,
что выбрать конкретную политику, основанную на ваших требованиях или даже
использовать несколько из них – это хорошая возможность найти как можно больше
уязвимостей.
Типы и уровни
уязвимостей.Не все уязвимости
одинаковы и применимы к нашим приложениям/контейнерам/средам. Поэтому нужно
смотреть не только на их тяжесть, но и на факторы, из которых эта тяжесть
рассчитывается. Это включает в себя вектор атаки, сложность атаки, влияние на
конфиденциальность, влияние на целостность и т. д. Затем эти факторы создают
окончательную оценку серьезности, полученную с помощью калькулятора CVSS. Значения
метрик по тяжести: нет, низкая, средняя, высокая и критическая. Более подробную
информацию о них можно найти на сайте NIST (Национальный институт стандартов и технологий).
Исправление уязвимостей. Уязвимости в
описанном примере легко исправить, но не для всех случаев это так. Когда
речь заходит о проблемах с базовыми образами или встроенными в них пакетами – это ответственность
разработчиков данного софта. Тем не менее, вы должны предотвратить или, по
крайней мере, смягчить возможность использования существующих и будущих
уязвимостей, убрав векторы атаки с помощью того же Distroless, который не имеет
шелла. Кроме того, мы рекомендуем периодически проводить проверку уязвимостей с
помощью конвейеров сборки и развертывания, чтобы как можно скорее выявить
появление уязвимости.
Работа с Clair
Теперь сравним с Anchore работу Clair. Запустим инструмент на наших примера с
образами Debian и Distrolless:
Выглядит довольно похоже на то, что мы получили от Anchore
– много проблем для образа Debian и ничего для Distroless. В выводах двух
сканеров присутствуют одинаковые результаты, но так может быть не всегда. Именно
поэтому мы рекомендуем использовать несколько инструментов сканирования, использующих разные источники уязвимостей метаданных.
Если вы захотите
дополнительно изучить другие инструменты и вопросы безопасности можно обратиться
в Docker Bench for Security.
Заключение
Что касается вопросов безопасности, то всегда
предпочтительнее «подстелить соломку» заранее и стараться избегать уязвимостей
до того как они станут реальной проблемой. Использование описанных инструментов не вызывает трудностей, так что любой сможет сделать их частью ежедневного рабочего
процесса или интегрировать их в свой конвейер сборки и развертывания.
Безопасность создаваемых приложений – это ответственность каждого разработчика, а не только экспертов в области безопасности или
пентестеров.