Docker-образ — это набор слоёв с операционной системой, библиотеками и вашим приложением, и в каждом из них могут оказаться пакеты с известными уязвимостями. Trivy сопоставляет содержимое образа с базой уязвимостей и показывает, какие пакеты затронуты и в какой версии проблема исправлена. Ниже — установка, запуск, чтение отчёта и встраивание проверки в сборку.
Что проверяет Trivy
Trivy умеет анализировать образы контейнеров, каталоги с проектом, файлы конфигурации и репозитории. Он определяет пакеты операционной системы и зависимости приложения: npm, Composer, pip и другие. Важно понимать границу: сканер находит только уже опубликованные уязвимости, уязвимости собственного кода и неизвестные дыры он не покажет.
| Режим | Команда | Что проверяется |
|---|---|---|
| Образ | trivy image | Пакеты ОС и зависимости внутри образа |
| Файловая система | trivy fs | Каталог проекта, lock-файлы, секреты |
| Конфигурация | trivy config | Dockerfile, Compose, манифесты |
Установка
Trivy можно установить пакетом из репозитория проекта (инструкции для вашего дистрибутива есть в документации Trivy) либо запустить прямо из контейнера, ничего не устанавливая на сервер. Во втором случае сокет Docker передаётся внутрь, чтобы сканер видел локальные образы. При первом запуске он скачивает базу уязвимостей и хранит её в кэше, поэтому первый запуск дольше следующих.
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image nginx:latest
trivy --version
Сканирование образа и файловой системы
Для образа достаточно указать его имя. Без фильтров отчёт получается длинным, поэтому на практике ограничивают уровень серьёзности и скрывают уязвимости, для которых исправление ещё не выпущено: по ним вы всё равно ничего не сделаете. Результат можно сохранить в JSON для дальнейшей обработки.
trivy image myapp:1
trivy image --severity HIGH,CRITICAL myapp:1
trivy image --severity HIGH,CRITICAL --ignore-unfixed myapp:1
trivy image --format json -o result.json myapp:1
Для проекта на диске используйте режим fs: он читает файлы зависимостей и находит проблемные версии библиотек ещё до сборки образа. Режим config проверяет сами Dockerfile и манифесты на небезопасные настройки.
trivy fs .
trivy fs --scanners vuln,secret,misconfig .
trivy config .
Как читать отчёт
В таблице отчёта указаны пакет, идентификатор CVE, установленная версия, версия с исправлением и серьёзность. Уровни серьёзности: UNKNOWN, LOW, MEDIUM, HIGH и CRITICAL. Пустое поле с исправлением значит, что поставщик пакета его ещё не выпустил. Не каждая найденная уязвимость достижима в вашей конфигурации: пакет может быть в образе, но не запускаться. Решение о срочности принимайте, оценив реальную доступность из сети.
- Сначала разбирайте CRITICAL и HIGH с доступным исправлением.
- Если исправления нет, проверьте, используется ли пакет, и по возможности уберите его из образа.
- Заведите файл .trivyignore для осознанных исключений и записывайте причину в комментарии.
- Пересматривайте исключения регулярно: ситуация и база уязвимостей меняются.
Игнор-лист и встраивание в сборку
Файл .trivyignore содержит по одному идентификатору на строку, строки с решёткой — комментарии. Идентификаторы в примере условные, подставьте реальные из своего отчёта. Для автоматической проверки используйте код возврата: параметр --exit-code 1 заставляет Trivy завершиться ошибкой, если найдены уязвимости выбранной серьёзности, и сборка в CI остановится.
# .trivyignore
# CVE-YYYY-NNNNN not reachable from the network, review later
CVE-YYYY-NNNNNdocker build --pull --no-cache -t myapp:2 .
trivy image --exit-code 1 --severity CRITICAL myapp:2
echo $?
Уязвимость в базовом образе и пересборка
Большинство найденных проблем лежит не в вашем коде, а в базовом образе из строки FROM: в пакетах ОС и системных библиотеках. Вы не можете исправить их внутри работающего контейнера, потому что образ неизменяем. Лечение одно: получить обновлённый базовый образ и пересобрать свой. Параметр --pull заставляет Docker скачать свежую версию базового образа, а --no-cache не даёт использовать старые слои. Конкретный пример пересборки разобран в статье PHP в Docker: как закрыть PHP2Shell пересборкой образа.
Просканированные образы удобно хранить и проверять повторно в собственном хранилище: об этом написано в материале Приватный Docker Registry на собственном сервере. Если вы только знакомитесь с понятиями, начните со статьи Образ Docker и контейнер: в чём разница.
Частые вопросы
Чем Trivy отличается от docker scan?
Trivy — самостоятельный сканер с открытым кодом, он работает без привязки к конкретной версии Docker, умеет проверять образы, каталоги и конфигурации и легко встраивается в CI. Он пригоден и для серверов без графического клиента: достаточно командной строки и доступа к базе уязвимостей при обновлении.
Почему в свежем образе всё равно есть уязвимости?
База уязвимостей пополняется ежедневно, а образ фиксирует состояние пакетов на момент сборки. Новая запись в базе может появиться уже на следующий день, даже если вы ничего не меняли. Поэтому образы нужно проверять регулярно, а не один раз перед выкладкой.
Нужно ли исправлять каждую найденную уязвимость?
Нет, начинать нужно с критичных и тех, для которых уже есть исправление. Часть записей относится к пакетам, которые не запускаются или недоступны из сети. Такие случаи разумно вносить в .trivyignore с пояснением и пересматривать позже, не оставляя без внимания навсегда.
Как исправить уязвимость в базовом образе?
Обновите базовый образ и пересоберите свой: docker build с параметром --pull скачает свежую версию, а --no-cache отключит устаревшие слои. Затем повторите сканирование и перезапустите контейнеры из нового образа. Обновление пакетов внутри уже запущенного контейнера не сохраняется и не заменяет пересборку.