Настройка сканирования Docker-образов через Grype/Syft

Уязвимости в базовых слоях образов нередко доживают до самого релиза и всплывают уже в рабочей среде. Мы настраиваем сканирование Docker-образов через Grype под ключ: разбираем реестр, встраиваем проверку в конвейер сборки, задаём пороги блокировок. Доля непроверенных образов сокращается в разы.
Часто задаваемые вопросы

Сканирование образов через Grype: где теряются уязвимости

Анализ образа идёт по слоям, и базовый слой почти всегда зафиксирован на момент сборки. Syft снимает инвентарь — перечень пакетов операционной системы и зависимостей приложения с их версиями. По этому перечню Grype сопоставляет версии с базами уязвимостей и отдаёт находки с оценкой критичности и указанием слоя, из которого они приехали.

Разрыв возникает между сборкой и пересборкой. Приложение обновляется каждый релиз, а системные библиотеки в базовом слое остаются неизменными месяцами. Уязвимость уже опубликована, база обновлена, но в образе живёт прежняя версия пакета — и проверка контейнеров при выкладке её не показывает, если запускается по факту готового образа, а не на этапе сборки.

Вторая точка потерь — фильтры. Отсечение по уровню критичности или отключение проверки устаревшего базового слоя убирает шум, но одновременно прячет самый частый класс находок: высокое влияние при низкой формальной оценке.

Третья — формат результата. Плоский список удобен для чтения и бесполезен для управления: не видно, повторяется ли находка из релиза в релиз и закрылась ли она после обновления. Инвентарь состава привязывает каждую запись к конкретному пакету и слою, поэтому понятно, что именно нужно обновить.

Разбираем этот путь по шагам: снятие инвентаря, настройка порогов, автоматическая пересборка базовых слоёв — и показываем, где именно уязвимости в образах теряются.

Что даёт регулярное сканирование Docker-образов

Автоматическое сканирование на этапе сборки превращает безопасность контейнеров из ручной проверки перед релизом в штатный шаг конвейера. Инструмент разбирает слои образа, сверяет пакеты и их версии с базами уязвимостей и отдаёт находки до того, как образ попал в реестр. Ниже — три эффекта, которые видны уже через два-три релиза.

Окно уязвимости сжимается до одного цикла сборки

Пока образ лежит в реестре и не пересобирается, уязвимость в нём живёт месяцами: о находке узнают на очередном аудите или после разбора инцидента. При сканировании при сборке и по расписанию срок от публикации уязвимости до её закрытия в рабочем окружении падает с недель до одного-двух циклов — обычно в пределах суток.

Ручная приёмка релиза уходит

Политика по уровням критичности («критичные — стоп сборки, высокие — предупреждение и запись в отчёт») даёт формальный вердикт вместо просмотра списка глазами. Релиз либо проходит, либо падает с указанием конкретного пакета и слоя — приёмка перестаёт быть узким местом и не зависит от того, кто сегодня на дежурстве.

Единый список находок по всем реестрам

Сканирование всех репозиториев одной конфигурацией даёт единый формат отчёта и единый порог. Видно, пришла уязвимость из базового слоя или из зависимостей приложения: понятно, кто правит — команда сопровождения базовых образов или разработчик. Контроль базовых слоёв становится регулярным, а не разовым.

Мы настраиваем Grype вместе с формированием перечня компонентов образа — по нему находки можно перепроверять и сравнивать между релизами.

Подходы к сканированию образов: сравнение вариантов

Один режим проверки почти всегда оставляет дыру. Проверка на сборке ничего не знает о том, что уже неделями работает в кластере, а регулярный обход развёрнутых образов не остановит выкладку уязвимой сборки. Причина в асимметрии: образ собирается один раз, а база известных уязвимостей обновляется ежедневно — вчерашний чистый образ сегодня содержит проблемы.

Ниже — четыре режима, между которыми реально выбирают, и границы применимости каждого.

Режим сканирования Когда подходит Ограничения
На этапе сборки, блокирующий Новые сервисы и активная разработка; нужно не пустить уязвимость дальше конвейера Ловит только то, что известно на момент сборки; ложные срабатывания тормозят релизы, если порог строгий
Перед выкладкой, по манифесту Регулярные релизы в несколько сред; нужен контроль на входе в продакшн Требует доступа к реестру и прав на остановку выкладки; не покрывает образы, выложенные в обход конвейера
Периодический обход развёрнутых образов Уже работающий контур, долгоживущие сервисы, требования комплаенса Не предотвращает — только фиксирует; нужен разбор находок и план обновления
Проверка по сохранённому перечню компонентов Закрытые контуры без доступа к образам; разбор инцидента задним числом Перечень нужно формировать заранее и хранить вместе с релизом

На практике режимы не конкурируют, а дополняют друг друга: блокирующая проверка на сборке отсекает явный брак, периодическая — поднимает то, что стало уязвимым после выкладки, а сохранённый перечень компонентов позволяет за минуты ответить на вопрос «где ещё встречается эта библиотека», когда по ней выходит критичное уведомление. Grype и Syft работают с одним и тем же перечнем компонентов, поэтому все режимы опираются на единый источник правды, а не на три несогласованных отчёта.

Внедрение Grype в конвейер сборки образов: этапы работ

Сканирование образов встраиваем в конвейер сборки, а не запускаем отдельным заданием по расписанию: проверка происходит до публикации образа в реестр, иначе дефект уже в продакшене. Syft собирает состав пакетов по слоям, Grype сопоставляет его с базами уязвимостей, а сборка получает код возврата, по которому решается — пропускать образ дальше или останавливать. Порядок работ выстроен так, чтобы к моменту включения блокировок команда понимала каждое срабатывание.

  1. Инвентаризация образов. Собираем перечень сервисов, базовых слоёв и внешних зависимостей — без него пороги блокировок ставятся наугад и останавливают сборку на первом же изменении.
  2. Схема интеграции. Определяем точку вызова в конвейере (после сборки, до публикации), способ хранения отчётов и локального зеркала баз уязвимостей, поведение на узлах без доступа во внешнюю сеть.
  3. Настройка Grype. Задаём набор источников уязвимостей, форматы вывода — читаемый для логов, машиночитаемый для разбора, — и исключения для заведомо неприменимых срабатываний со сроком пересмотра.
  4. Пороги блокировок и политики безопасности. Уровни критичности разделяем: сборка падает на уязвимостях с доступным исправлением и высоким риском, остальное уходит в отчёт и в очередь на устранение. Пороги калибруем по реальному составу образов, чтобы не получить стену ложных остановок.
  5. Проверка на боевых сборках. Прогоняем на действующих сервисах: замеряем время добавленного шага, долю срабатываний и стоимость поддержки баз в закрытом контуре.
  6. Передача регламентов. Отдаём описание политик, инструкцию по разбору срабатываний и порядок действий при остановленной сборке — команда меняет пороги и исключения самостоятельно.

После передачи ведём сопровождение: обновление баз, пересмотр исключений и правка порогов по мере изменения состава сервисов.

Политики сканирования, регламенты и пороги блокировок

Сканирование без регламента быстро превращается в фон: отчёты формируются, находки копятся, а решения по ним принимаются каждый раз заново. К моменту включения Grype в конвейер команда получает пакет артефактов, где у каждого правила есть владелец, срок и понятный способ оспорить — иначе первая же блокировка сборки учит инженеров обходить проверку, а не исправлять причину.

  • Конфигурация сканирования: файл политики с порогами по уровням критичности, перечнем проверяемых слоёв и режимом работы для каждой ветки — где достаточно предупреждения, а где сборка останавливается.
  • Матрица приоритетов: какие находки закрываются в ближайшем релизе, какие уходят в плановый порядок, а какие допустимо принять как известный риск.
  • Список исключений уязвимостей: каждая запись с обоснованием, ответственным и датой пересмотра — исключение перестаёт быть вечным и возвращается в работу автоматически.
  • Регламент реагирования: кто получает уведомление, за какое время подтверждает находку, как выпускается исправленный образ и при каких условиях блокировка снимается.
  • Документация по сканированию: где хранится состав образа, снятый Syft, как воспроизвести проверку локально теми же правилами и как читать отчёт при разборе инцидента.
  • Отчётность по образам: сводка по репозиториям и тегам — доля образов без критичных находок, динамика по неделям, перечень просроченных исключений.
  • Порядок ревизии: плановый пересмотр порогов и исключений, а также внеплановый — после смены базового образа или появления исправления у поставщика компонента.
  • Роли и точка эскалации: кто владеет политикой и кто принимает решение, когда находка конфликтует со сроком выпуска.

Такой пакет остаётся у команды, а не у подрядчика: проверку можно перезапустить, пороги — обосновать, а любое исключение — снять одной правкой конфигурации.

Кейс: сократили долю непроверенных образов в разы

До работ образы собирались вручную, а сканирование запускалось от случая к случаю — обычно перед крупным релизом. Реестр при этом рос быстрее, чем кто-либо успевал смотреть его содержимое, и находки всплывали уже в эксплуатации: по факту инцидента или обращения.

Что было до внедрения

Замер базовой картины дал конкретные цифры: под регулярной проверкой находилась примерно десятая часть образов, остальные жили в реестре без контроля. Время реакции на новую уязвимость в используемом пакете измерялось неделями, а определить, в каком именно образе сидит проблемная библиотека, можно было только ручным разбором.

Что изменили

В конвейер сборки добавили два шага. Syft разбирает образ на перечень пакетов с версиями, Grype сверяет этот перечень с базами уязвимостей и отдаёт находки с уровнем критичности. Отчёт стал обязательным артефактом: без него образ не попадает в реестр, а критичные находки блокируют продвижение в среду эксплуатации. Отдельно прогнали накопившийся реестр — старые находки разобрали по приоритету, а не «когда-нибудь».

Что стало

Доля непроверенных образов сократилась до единиц процентов — вне контроля остаются только локальные сборки, которые не покидают машины разработчиков. Время реакции на критичную находку сжалось до часов: она приходит вместе с результатом сборки, а не после инцидента в эксплуатации. Метрики безопасности снимаются автоматически, и рост реестра больше не означает рост слепой зоны.

Чем сканирование слоёв отличается от проверки файловой системы?

Образ — это не монолитный слепок, а стек слоёв: каждый добавляет или перекрывает файлы предыдущего. Сканирование слоёв читает манифест и собранный перечень пакетов, поэтому видит, какой менеджер пакетов поставил компонент, в каком слое он появился и что притянуло его транзитивной зависимостью. Ответ приходит с происхождением, а не только с номером версии.

Проверка файловой системы контейнера работает с тем, что реально смонтировано и доступно процессу: распакованные бинарники, библиотеки, файлы, положенные копированием в обход менеджера пакетов. Зато родословной она не знает — по находке не видно, из какого слоя она пришла и обновлялась ли позже.

Разница подходов видна на двух классах ошибок. Проверка по слоям покажет компонент из нижнего слоя, даже если верхний его заменил или удалил, — в отчёте всплывает уже несуществующая версия. Файловая система маркеры удаления не учитывает и описывает финальное состояние, но пропускает всё, что не дожило до рабочего контейнера.

Поэтому охват собирают из двух источников: перечень пакетов формируется по слоям на этапе сборки, а готовая файловая система проверяется после — как страховка от ручных копирований и распаковок. Grype сопоставляет находки с базой уязвимостей, но полнота отчёта зависит от того, чем собран перечень и по какому источнику — образ целиком, директория или отдельный слой. Мы настраиваем оба режима и разводим находки, чтобы отчёт не тонул в ложных срабатываниях.

Технические ограничения и вопросы по сканированию образов

Сканирование образа встраивается в сборку и сразу поднимает четыре инженерных вопроса: сколько времени оно добавляет, что делать с уязвимостями без исправления, как отсекать ложные срабатывания и нужна ли пересборка после обновления баз. Ниже — как мы отвечаем на каждый.

Замедлит ли сканирование сборку?

Syft разбирает слои образа и составляет перечень пакетов, Grype сверяет его с базой уязвимостей. Основное время уходит на чтение слоёв, а не на поиск, поэтому проверка идёт параллельно с остальными шагами и на типовом образе не меняет общее время выпуска.

Что делать с уязвимостями, для которых нет исправления?

Часть находок — в пакетах, где поставщик ещё не выпустил обновление, и установкой новой версии их не закрыть. Такие случаи не блокируют выпуск: правила настраиваются по уровням опасности, а неисправимое уходит в список принятого риска с датой пересмотра.

Как отсекать ложные срабатывания?

Ложное срабатывание возникает, когда совпадение идёт по имени пакета, а не по фактически собранному коду. Лечится исключениями с обоснованием и привязкой к номеру уязвимости — правило живёт в репозитории, его видно на review и можно отозвать.

Нужна ли пересборка при обновлении баз?

Нет. База уязвимостей хранится отдельно от образа: повторное сканирование уже собранных тегов даёт свежую картину без выпуска новых версий. Пересборка требуется только при смене базового образа или самих правил.

Обсудим задачу: сканирование ваших образов и пороги блокировок

Чтобы оценка задачи опиралась на вашу схему сборки, а не на усреднённые цифры, разбор начинаем с того, как образы появляются и живут у вас. Пришлите файлы сборки, выгрузку манифестов из реестра, перечень базовых образов и порядок выпуска релизов — по ним видно, на каком шаге сканирование Grype и Syft встраивается, не останавливая выпуск.

После разбора вы получаете:

  • карту текущего потока: от коммита до публикации образа в реестре и дальше до стенда;
  • перечень базовых образов и слоёв с оценкой уязвимостей по каждому;
  • предложенные пороги блокировок по уровням критичности и правило их пересмотра;
  • схему подавления ложных срабатываний с журналом исключений и сроками, когда запись истекает;
  • вариант встраивания — на сборке, в проверке перед слиянием или в реестре — с обоснованием выбора;
  • план работ этапами, где отмечено, на каких шагах выпуск можно остановить, а на каких нет;
  • список того, что нужно от ваших инженеров: доступы, сервисные учётные записи, окна изменений.

Опишите задачу как удобно: абзацем в письме или коротким созвоном с вашим инженером. Мы вернёмся с оценкой, планом работ и понятной картиной того, что изменится в выпуске после внедрения безопасности контейнеров.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1369
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    816
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1141