🏆 151 курс за 1 подписку: хватит выбирать — бери все и сразу!

Один клик — 151 возможность. Подпишись на OTUS сейчас!
Техномир мчится вперед, а вместе с ними растут и требования к специалистам. OTUS придумал крутую штуку — подписку на 151 курс по всем ключевым направлениям IT!
-
Почему подписка OTUS меняет правила игры:
- Доступ к 151 курсу от практикующих экспертов
- В 3 раза выгоднее, чем покупать каждый курс отдельно
- До 3 курсов одновременно без дополнительных затрат
- Свобода выбора направления — меняй треки когда угодно
Изучай новое, развивайся в своем темпе, меняй направления — подпишись на OTUS и прокачивай скилы по полной!
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576. Erid 2VtzqupFnNL
Инструменты анализа 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, выполняем следующие действия:
mkdir ~/aevolume
cd ~/aevolume
docker pull docker.io/anchore/anchore-engine:latest
docker create --name ae docker.io/anchore/anchore-engine:latest
docker cp ae:/docker-compose.yaml ~/aevolume/docker-compose.yaml
docker rm ae
docker-compose pull
docker-compose up -d
export ANCHORE_CLI_USER=admin
export ANCHORE_CLI_PASS=foobar
docker run --net=host -e ANCHORE_CLI_URL=http://localhost:8228/v1/ -it anchore/engine-cli
Для Clair выполняем такую последовательность
# Download Clair Scanner from https://github.com/arminc/clair-scanner/releases
chmod +x clair-scanner
docker run -p 5432:5432 -d --name db arminc/clair-db:$(date +%F)
docker run -p 6060:6060 --link db:postgres -d --name clair arminc/clair-local-scan:v2.0.6
Проверка Docker-образа на уязвимости с помощью Anchore

Начнём тест Anchore с базового образа Debian:
# inside anchore-cli Docker container
~ $ anchore-cli image add docker.io/library/debian:latest
Image Digest: sha256:121dd2a723be1c8aa8b116684d66157c93c801f2f5107b60287937e88c13ab89
Parent Digest: sha256:a63d0b2ecbd723da612abf0a8bdb594ee78f18f691d7dc652ac305a490c9b71a
Analysis Status: analyzed
Image Type: docker
Analyzed At: 2020-03-07T10:46:20Z
Image ID: 971452c943760ab769134f22db8d3381b09ea000a6c459fbfa3603bb99115f62
Dockerfile Mode: Guessed
Distro: debian
Distro Version: 10
Size: 126607360
Architecture: amd64
Layer Count: 1
Full Tag: docker.io/library/debian:latest
Tag Detected At: 2020-03-07T10:45:48Z
~ $ anchore-cli image wait docker.io/library/debian:latest
Status: analyzing
Waiting 5.0 seconds for next retry.
...
~ $ anchore-cli image list
Full Tag Image Digest Analysis Status
docker.io/library/debian:latest sha256:121dd2a723be1c8aa8b116684d66157c93c801f2f5107b60287937e88c13ab89 analyzed
Посмотрим, какие уязвимости были обнаружены:
~ $ anchore-cli image vuln docker.io/library/debian:latest all
Vulnerability ID Package Severity Fix CVE Refs Vulnerability URL
CVE-2005-2541 tar-1.30+dfsg-6 Negligible None CVE-2005-2541 https://security-tracker.debian.org/tracker/CVE-2005-2541
CVE-2007-5686 login-1:4.5-1.1 Negligible None CVE-2007-5686 https://security-tracker.debian.org/tracker/CVE-2007-5686
...
~ $ anchore-cli evaluate check docker.io/library/debian:latest
Image Digest: sha256:121dd2a723be1c8aa8b116684d66157c93c801f2f5107b60287937e88c13ab89
Full Tag: docker.io/library/debian:latest
Status: pass
Last Eval: 2020-03-14T13:25:24Z
Policy ID: 2c53a13c-1765-11e8-82ef-23527761d060
Сначала мы запускаем
команду image vuln
со всеми флагами, чтобы обнаружить уязвимости ОС и пакетов,
присутствующих в образе. Все они незначительны или неизвестны – это хорошо.
Затем мы запускаем команду evaluate check
, чтобы проверить, проходит ли образ проверку политики по умолчанию, и, как видим выше, он проходит (Status:
pass
). Базовые образы обычно работают без нареканий, поскольку они широко
используются и находятся под большим вниманием.
Но как насчет простого "Hello World" на Python, построенного с использованием образа Python 3 Debian Buster? Давайте сначала посмотрим на Dockerfile:
# debian.Dockerfile
FROM python:3-slim AS build-env
ADD . /app
WORKDIR /app
FROM python:3-buster
COPY --from=build-env /app /app
WORKDIR /app
CMD ["python", "hello.py", "/etc"]
Ничего не сообщает о “vulnerable” или “insecure”. Тогда соберём и проанализируем:
~ $ docker build -f debian.Dockerfile -t martinheinz/debian-python-anchore .
~ $ docker run martinheinz/debian-python-anchore:latest
~ $ docker push martinheinz/debian-python-anchore:latest
# From anchore Docker CLI
~ $ anchore-cli image add martinheinz/debian-python-anchore:latest
~ $ anchore-cli image wait martinheinz/debian-python-anchore:latest
~ $ anchore-cli image list
Full Tag Image Digest Analysis Status
docker.io/library/debian:latest sha256:121dd2a723be1c8aa8b116684d66157c93c801f2f5107b60287937e88c13ab89 analyzed
docker.io/martinheinz/debian-python-anchore:latest sha256:59dff8bdf4af5cd8e9ba0754d25a43a96dfb47b46b771549a0d79d35bc3cc1aa analyzed
Сначала мы забилдили
образ, используя вышеприведённый debian.Dockerfile
и hello.py
, затем переместили
его в Docker Hub, откуда он был добавлен в Anchore и проанализирован. Взглянем
на результаты:
~ $ anchore-cli image vuln docker.io/martinheinz/debian-python-anchore:latest os
Vulnerability ID Package Severity Fix CVE Refs Vulnerability URL
CVE-2007-3476 libwmf-dev-0.2.8.4-14 Low None CVE-2007-3476 https://security-tracker.debian.org/tracker/CVE-2007-3476
CVE-2007-3476 libwmf0.2-7-0.2.8.4-14 Low None CVE-2007-3476 https://security-tracker.debian.org/tracker/CVE-2007-3476
CVE-2007-3477 libwmf-dev-0.2.8.4-14 Low None CVE-2007-3477 https://security-tracker.debian.org/tracker/CVE-2007-3477
CVE-2007-3477 libwmf0.2-7-0.2.8.4-14 Low None CVE-2007-3477 https://security-tracker.debian.org/tracker/CVE-2007-3477
CVE-2016-8660 linux-libc-dev-4.19.98-1 Low None CVE-2016-8660 https://security-tracker.debian.org/tracker/CVE-2016-8660
CVE-2007-3996 libwmf-dev-0.2.8.4-14 Medium None CVE-2007-3996 https://security-tracker.debian.org/tracker/CVE-2007-3996
CVE-2007-3996 libwmf0.2-7-0.2.8.4-14 Medium None CVE-2007-3996 https://security-tracker.debian.org/tracker/CVE-2007-3996
CVE-2009-3546 libwmf-dev-0.2.8.4-14 Medium None CVE-2009-3546 https://security-tracker.debian.org/tracker/CVE-2009-3546
CVE-2009-3546 libwmf0.2-7-0.2.8.4-14 Medium None CVE-2009-3546 https://security-tracker.debian.org/tracker/CVE-2009-3546
...
~ $ anchore-cli image vuln docker.io/martinheinz/debian-python-anchore:latest os | wc -l
1056
~ $ anchore-cli evaluate check docker.io/martinheinz/debian-python-anchore:latest
Image Digest: sha256:59dff8bdf4af5cd8e9ba0754d25a43a96dfb47b46b771549a0d79d35bc3cc1aa
Full Tag: docker.io/martinheinz/debian-python-anchore:latest
Status: fail
Last Eval: 2020-03-07T12:15:00Z
Policy ID: 2c53a13c-1765-11e8-82ef-23527761d060
Уже не так хорошо. После
переключения на официальный образ Debian Python, появилось более 1000
уязвимостей. После выполнения оценки образа мы видим, что она не удалась (Status:
fail
).
Несмотря на то, что мы использовали официальный и безопасный образ, при создании элементарного приложения без явных уязвимостей мы все равно получили массу проблем с безопасностью. Как это исправить?
Поиск идеального образа

Distroless представляет собой набор docker-образов, созданных Google с учетом вопросов безопасности. Эти образы содержат абсолютный минимум, необходимый для приложения, а это означает, что нет никаких оболочек, менеджеров пакетов или других инструментов, которые могли бы увеличить образ. Пусть мы выбрали один из Distroless-образов, посмотрим на новый Dockerfile:
# distroless.Dockerfile
FROM python:3-slim AS build-env
ADD . /app
WORKDIR /app
FROM gcr.io/distroless/python3
COPY --from=build-env /app /app
WORKDIR /app
CMD ["hello.py", "/etc"]
Мало что изменилось по
сравнению с Debian-версией. Мы переключили текущий образ на gcr.io/distroless/python3
.
Теперь можем продолжать: сбилдить, запушить и добавить его в Anchore Engine:
docker build -f distroless.Dockerfile -t martinheinz/distroless-python-anchore .
docker run martinheinz/distroless-python-anchore:latest
docker push martinheinz/distroless-python-anchore:latest
# From anchore Docker CLI
anchore-cli image add martinheinz/distroless-python-anchore:latest
Посмотрим, работает ли Distroless менее эффективно, чем Debian-образ:
~ $ anchore-cli image vuln docker.io/martinheinz/distroless-python-anchore:latest os
Vulnerability ID Package Severity Fix CVE Refs Vulnerability URL
CVE-2019-16935 libpython3.5-minimal-3.5.3-1+deb9u1 Low None CVE-2019-16935 https://security-tracker.debian.org/tracker/CVE-2019-16935
CVE-2019-16935 python3.5-minimal-3.5.3-1+deb9u1 Low None CVE-2019-16935 https://security-tracker.debian.org/tracker/CVE-2019-16935
...
~ $ anchore-cli image vuln docker.io/martinheinz/distroless-python-anchore:latest os | wc -l
53
~ $ anchore-cli evaluate check docker.io/martinheinz/distroless-python-anchore:latest
Image Digest: sha256:29b5288e934dc724377f2ff187e8a0664246c95b0e70bd9a13f6874628dc8662
Full Tag: docker.io/martinheinz/distroless-python-anchore:latest
Status: pass
Last Eval: 2020-03-07T12:15:20Z
Policy ID: 2c53a13c-1765-11e8-82ef-23527761d060
Можно видеть, что по сравнению с первым примером здесь только 53 уязвимости и всего 2 уязвимости с низкой степенью важности. Можно с уверенностью заключить, что Distroless – лучший выбор, когда речь заходит о безопасности контейнерных приложений. Однако есть еще несколько штуковин, с которыми можно поиграться – использовать различные политики оценки:
~ $ anchore-cli policy hub list
Name Description
anchore_security_only Single policy, single whitelist bundle for performing
security checks, including example blacklist known malicious
packages by name.
anchore_default_bundle Default policy bundle that comes installed with vanilla
anchore-engine deployments. Mixture of light vulnerability
checks, dockerfiles checks, and warning triggers for common
best practices.
anchore_cis_1.13.0_base Docker CIS 1.13.0 image content checks, from section 4 and
5. NOTE: some parameters (generally are named 'example...')
must be modified as they require site-specific settings
В приведённой выше
команде перечислены все доступные политики, которые мы можем использовать для
проверки образов. По умолчанию используется anchore_default_bundle
, который отлично
работает, но если мы хотим видеть проверку, выполняемую с использованием
другого списка и правил, то можно попробовать anchore_cis_1. 13.0_base
:
~ $ anchore-cli policy hub get anchore_cis_1.13.0_base
Policy Bundle ID: anchore_cis_1.13.0_base
Name: anchore_cis_1.13.0_base
Description: Docker CIS 1.13.0 image content checks, from section 4 and 5. NOTE: some parameters (generally are named 'example...') must be modified as they require site-specific settings
Policy Name: CIS File Checks
Policy Description: Docker CIS section 4.8 and 4.10 checks.
Policy Name: CIS Dockerfile Checks
Policy Description: Docker CIS section 4.1, 4.2, 4.6, 4.7, 4.9 and 5.8 checks.
Policy Name: CIS Software Checks
Policy Description: Docker CIS section 4.3 and 4.4 checks.
Whitelist Name: RHEL SUID Files
Whitelist Description: Example whitelist with triggerIds of files that are expected to have SUID/SGID, for rhel-based images
Whitelist Name: DEB SUID Files
Whitelist Description: Example whitelist with triggerIds of files that are expected to have SUID/SGID, for debian-based images
Mapping Name: default
Mapping Rule: */*:*
Mapping Policies: CIS Software Checks,CIS Dockerfile Checks,CIS File Checks
Mapping Whitelists: DEB SUID Files,RHEL SUID Files
~ $ anchore-cli policy hub install anchore_cis_1.13.0_base
Policy ID: anchore_cis_1.13.0_base
Active: False
Source: local
Created: 2020-03-07T12:20:46Z
Updated: 2020-03-07T12:20:46Z
~ $ anchore-cli policy list
Policy ID Active Created Updated
2c53a13c-1765-11e8-82ef-23527761d060 True 2020-02-17T11:10:20Z 2020-02-17T11:10:20Z
anchore_cis_1.13.0_base False 2020-03-07T12:20:46Z 2020-03-07T12:20:46Z
~ $ anchore-cli policy activate anchore_cis_1.13.0_base
Success: anchore_cis_1.13.0_base activated
В примере выше мы рассмотрели
описание политики, запустив policy hub get
. Далее мы установили ее и, как
результат – имеем две доступные политики, причем одна из них неактивна. Исправим
это с помощью команды policy activate
.
Для получения полного
списка правил в этой политике наберите anchore-cli --json policy hub
get anchore_cis_1.13.0_base
.
Пришло время запуска:
~ $ anchore-cli evaluate check docker.io/martinheinz/distroless-python-anchore:latest --detail
...
dockerfile instruction Dockerfile directive 'HEALTHCHECK' not found, matching condition 'not_exists' check stop
dockerfile instruction Dockerfile directive 'FROM' check 'not_in' matched against 'example_trusted_base1,example_trusted_base2' for line 'scratch' stop
dockerfile effective_user User root found as effective user, which is explicity not allowed list stop
...
Приведённые проблемы/уязвимости не дают образу нормально пройти оценку политики и должны быть проанализированы. Одна из них (вторая) вызвана использованием Distroless образа, так что ее можно игнорировать. Две другие должны быть исправлены. Все это показывает нам, что выбрать конкретную политику, основанную на ваших требованиях или даже использовать несколько из них – это хорошая возможность найти как можно больше уязвимостей.
Типы и уровни уязвимостей. Не все уязвимости одинаковы и применимы к нашим приложениям/контейнерам/средам. Поэтому нужно смотреть не только на их тяжесть, но и на факторы, из которых эта тяжесть рассчитывается. Это включает в себя вектор атаки, сложность атаки, влияние на конфиденциальность, влияние на целостность и т. д. Затем эти факторы создают окончательную оценку серьезности, полученную с помощью калькулятора CVSS. Значения метрик по тяжести: нет, низкая, средняя, высокая и критическая. Более подробную информацию о них можно найти на сайте NIST (Национальный институт стандартов и технологий).
Исправление уязвимостей. Уязвимости в описанном примере легко исправить, но не для всех случаев это так. Когда речь заходит о проблемах с базовыми образами или встроенными в них пакетами – это ответственность разработчиков данного софта. Тем не менее, вы должны предотвратить или, по крайней мере, смягчить возможность использования существующих и будущих уязвимостей, убрав векторы атаки с помощью того же Distroless, который не имеет шелла. Кроме того, мы рекомендуем периодически проводить проверку уязвимостей с помощью конвейеров сборки и развертывания, чтобы как можно скорее выявить появление уязвимости.
Работа с Clair
Теперь сравним с Anchore работу Clair. Запустим инструмент на наших примера с образами Debian и Distrolless:
# Run setup steps from beginning of article...
~ $ clair-scanner --ip 192.168.1.56 martinheinz/debian-python-anchore:latest
2020/03/07 17:54:11 [INFO] ▶ Start clair-scanner
2020/03/07 17:54:18 [INFO] ▶ Server listening on port 9279
2020/03/07 17:54:18 [INFO] ▶ Analyzing 55db4dd701c0a4eea04ba231e74bd04d6c1cdbd86cf8084e988648aa7cf5af9b
2020/03/07 17:54:18 [INFO] ▶ Analyzing 1938b02d46a5b801035965c5680d11c513a679e0ad4a560276df9a8ececa0bed
2020/03/07 17:54:18 [INFO] ▶ Analyzing 90bd3e8e4e9f1dd7624ecdd1ee35c36072e582a2cd5c606f290d2b3cb4a1559c
2020/03/07 17:54:18 [INFO] ▶ Analyzing ced4f27972d40674b72da7b1a51b63a8396bbca3a4fca86dffa8031228ab88cb
2020/03/07 17:54:18 [INFO] ▶ Analyzing 7abae7ca0ef88724a59f51748b1658136bdbb1eae246550478f5939484358d94
2020/03/07 17:54:18 [INFO] ▶ Analyzing 62547b912c7f2d5d69eaca3cd5ad1cb053c39886cb7276b0cb753b3824c32358
2020/03/07 17:54:18 [INFO] ▶ Analyzing cb7076fa495a6c437ac374b1b67a62075b94db45400c10e8849b5db75ffbce21
2020/03/07 17:54:18 [INFO] ▶ Analyzing a3ffe04a8073815ecfa94620efbbccf412b85ca80b6550c029617eed51c5edb6
2020/03/07 17:54:18 [INFO] ▶ Analyzing 715fd7b0b1161fa57f74a843f4525f1ab7035c9a8051a6559c91ff360e44f20f
2020/03/07 17:54:18 [INFO] ▶ Analyzing 20519035fc6a7d347a1540a633c461ac321dc8db7cb8c163283c1d802097697b
2020/03/07 17:54:18 [WARN] ▶ Image [martinheinz/debian-python-anchore:latest] contains 356 total vulnerabilities
2020/03/07 17:54:18 [ERRO] ▶ Image [martinheinz/debian-python-anchore:latest] contains 356 unapproved vulnerabilities
... List of vulnerabilities follows
~ $ clair-scanner --ip 192.168.1.56 martinheinz/distroless-python-anchore:latest
2020/03/07 17:56:08 [INFO] ▶ Start clair-scanner
2020/03/07 17:56:09 [INFO] ▶ Server listening on port 9279
2020/03/07 17:56:09 [INFO] ▶ Analyzing 51756e4adf1ad2b5a00c36dcc9e799a69d72462d60e6f88c87f96eed832b8a2a
2020/03/07 17:56:09 [INFO] ▶ Analyzing 49905beb7372788afbefede92af761383ad2bac7f8d21b2f2d6fb165afff48e8
2020/03/07 17:56:09 [INFO] ▶ Analyzing 3d9fd80998dc9ea371366e1ef54046fbe86e6e360d17ece650ea8a3ea5023c63
2020/03/07 17:56:09 [INFO] ▶ Analyzing 83b671756e1e2cc132505e55c87c5c5b1da185665f9bb875d771568959dc05a2
2020/03/07 17:56:09 [INFO] ▶ Analyzing b80190979f279448d479a3ed0450f6d2912662e12edd1fe477a2b74d0568e1f0
Выглядит довольно похоже на то, что мы получили от Anchore – много проблем для образа Debian и ничего для Distroless. В выводах двух сканеров присутствуют одинаковые результаты, но так может быть не всегда. Именно поэтому мы рекомендуем использовать несколько инструментов сканирования, использующих разные источники уязвимостей метаданных.
Если вы захотите дополнительно изучить другие инструменты и вопросы безопасности можно обратиться в Docker Bench for Security.
Заключение
Что касается вопросов безопасности, то всегда предпочтительнее «подстелить соломку» заранее и стараться избегать уязвимостей до того как они станут реальной проблемой. Использование описанных инструментов не вызывает трудностей, так что любой сможет сделать их частью ежедневного рабочего процесса или интегрировать их в свой конвейер сборки и развертывания.
Безопасность создаваемых приложений – это ответственность каждого разработчика, а не только экспертов в области безопасности или пентестеров.
Библиотека программиста регулярно публикует материалы по Docker:
Комментарии