Сканування Docker-образів на вразливості (Trivy/Snyk/Grype)

Вразливість у базовому шарі образу потрапляє в робоче середовище разом із релізом і виринає вже під навантаженням. Ми налаштовуємо сканування Docker-образів під ключ: перевірка на кожному етапі збірки, зрозумілі звіти, регламент оновлення. Критичні знахідки зупиняють випуск до виправлення, а вікно вразливості скорочується з тижнів до доби.
Часті запитання

Що ламається без сканування Docker-образів

Образ збирається з базового шару, який оновлюють раз на пів року-рік. За цей час у ньому накопичуються застарілі залежності: бібліотеки з відомими уразливостями залишаються всередині, бо застосунок від них не відмовився, а базовий шар ніхто не перезбирав.

Сканування Docker-образів починається саме з цього шару — там найбільше знахідок високої критичності, і вони однаково зачіпають усі сервіси, зібрані на спільній основі.

Друга точка деградації — сама збірка. Менеджер пакетів у Dockerfile тягне версії без фіксації, у фінальний образ потрапляють пакети зі складу для збірки та утиліти, які в роботі контейнера не беруть участі.

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

Ризик експлуатації з'являється там, де уразлива залежність доступна ззовні. Контейнер за замовчуванням стартує з правами root, бібліотека розбирає зовнішні дані — і одна неперевірена залежність стає точкою входу, невидимою ні в логах застосунку, ні на моніторингу.

Далі сценарій один: уразливість живе в проді місяцями й випливає лише на інциденті після викладки. Закриття вимагає перезбирання всіх сервісів на спільному базовому шарі, повторної перевірки образів у реєстрі, відкату релізу й ротації секретів. Розбираємо, як це закривається скануванням на кожному етапі.

Що дає раннє виявлення уразливостей у збірці

Уразливість у базовому образі або транзитивній залежності випливає не тоді, коли її почали експлуатувати, а коли хтось через місяці дивиться на старий тег.

Раннє виявлення уразливостей переносить перевірку на кожен крок збірки й одночасно фіксує склад образу: яка версія пакета потрапила в який шар і якою зміною.

Простежуваність залежностей перетворює «десь усередині» на конкретний рядок переліку компонентів — і закривати її можна точково, а не перезбирати все наосліп.

Ефект вимірний. Швидкість закриття дефектів змінюється з тижнів на години: критичне оновлення потрапляє в збірку того ж дня, коли з'являється в базі уразливостей, бо перевірка вбудована в конвеєр, а не живе окремим звітом.

Частка відкатів релізу через залежність, що випливла, прямує до нуля — несумісне оновлення відсікається до викладки. Обсяг ручного розбору скорочується, коли інженер бачить не весь список, а лише нові знахідки щодо базової лінії.

Так іде цілий клас відмов: бойове середовище з уразливим базовим образом, який «збиралися оновити», та інциденти через закинутий пакет, про який у проєкті вже ніхто не пам'ятав.

Скорочення простою тут — наслідок, а не гасло: реліз не розбирають вручну, відкат іде на раніше перевірений образ.

Технічно це набір політик: поріг критичності, на якому збірка зупиняється; список винятків з обов'язковим обґрунтуванням і терміном перегляду; порівняння з базовою лінією, щоб старі знахідки не тонули в шумі хибних спрацювань.

Ми запускаємо Trivy у конвеєрі, складаємо результат у машинозчитуваний звіт і прив'язуємо його до конкретного артефакту — тому питання «в якому релізі прийшла ця залежність» закривається запитом, а не розкопками.

Режими перевірки: ручний прогін чи контроль у збірці

Режими відрізняються не сканером, а моментом, коли вердикт стає обов'язковим. Чим раніше спрацьовує перевірка, тим дешевше правка — але тим менше контексту: локально немає політики релізу, а в конвеєрі немає даних про те, як образ поводитиметься в робочому середовищі. Тому на практиці режими не замінюють, а доповнюють один одного.

Варіант Коли підходить Обмеження
Разова ручна перевірка Розбір інциденту, аудит уже зібраного образу, розвідка перед впровадженням Закриває один знімок стану; результат застаріває разом з оновленням баз уразливостей
Контроль на машині розробника Швидкий зворотний зв'язок до відправки в репозиторій Немає єдиної політики, версії баз у всіх різні, перевірку легко вимкнути
Перевірка в складальному конвеєрі Основний бар'єр: збірка падає на критичних знахідках до публікації Потрібні налаштоване оновлення баз і розумний поріг, інакше збірки гальмують і їх починають обходити
Контроль на вході в реєстр Страховка для сторонніх образів і збірок в обхід конвеєра Блокує публікацію, але не повідомляє авторові, що саме виправляти
Періодичний обхід Ловить уразливості, розкриті вже після релізу, і закинуті теги Знахідки приходять заднім числом — потрібен власник, який закриє їх перезбиранням

Робоча схема — перевірка в конвеєрі як обов'язковий бар'єр плюс регулярний обхід реєстру за розкладом, одним і тим самим сканером, щоб вердикти збігалися.

Поріг за критичністю та списки винятків з датою перегляду тримаємо поруч з описом збірки: без дати виняток швидко перетворюється на вічну сліпу зону.

Етапи впровадження контролю уразливостей у команді

Впровадження контролю уразливостей — це не встановлення сканера, а зміна процесу збірки: перевірка має стояти там, де виправлення займає хвилини, а не дні. Ідемо кроками — від розбору поточного реєстру до передачі регламенту команді.

  1. Аудит поточної збірки та реєстру. Розбираємо базові образи, частоту перезбирання, кількість тегів і вік шарів. Уже тут видно, звідки береться основна маса знахідок.

  2. Схема контролю. Визначаємо точки перевірки: під час збірки, під час відправки в реєстр, перед викаткою. Конкретний сканер (Trivy, Grype) тут вторинний — важливіше, де стоїть перевірка і який рівень критичності блокує випуск, а який дає лише попередження.

  3. Налаштування порогів і винятків. Поріг задаємо за критичністю, а не за загальною кількістю знахідок. У кожного винятку — власник і термін перегляду, інакше список винятків з часом перекриває саму перевірку.

  4. Перевірка на стенді. Проганяємо на копії реєстру, звіряємо результат з ручним розбором кількох образів, заміряємо частку хибних спрацювань до потрапляння в робочий контур.

Вартість — за індивідуальним розрахунком

  • Перевірка на реальних збірках. Кілька релізів ідуть у режимі попередження: звіти команда отримує, випуск не блокується. Так налаштовуються правила, а не гальмується робота.

  • Передача регламенту й навчання. Віддаємо документ: що робити при знахідці, як її виправити, як оформити виняток, хто відповідає за базові образи.

Далі пороги та винятки переглядаються за розкладом — закинуті базові образи й застарілі винятки дають найбільше шуму у звітах.

Політики доступу, звіти та регламент оновлення

Сканування Docker-образів приносить користь не звітом, а набором артефактів, які живуть у репозиторії й працюють без нашої участі. Нижче — те, що залишається в команди: конфігурації, схема запуску, правила реагування та документи для розробників.

Налаштування зберігаються поруч із кодом і версіонуються, тому перевірка на локальній машині, під час збірки образу й за розкладом іде за одними правилами. Політики Trivy описуються декларативно й переносяться між середовищами без правок.

  • Конфігурації перевірок — файли політик із порогами: який рівень критичності зупиняє збірку, який лише фіксується у звіті.
  • Схема контролю — де запускається перевірка: перед злиттям, під час збірки образу, вночі за розкладом. І як поводиться збірка, якщо бази уразливостей недоступні.
  • Політика реагування — терміни усунення за рівнями критичності, хто вирішує, чи випускати образ із відкритою знахідкою, як ескалюється прострочення.
  • Перелік винятків — запис на кожне відхилення: обґрунтування, відповідальний, дата перегляду. Знахідка без виправлення живе з терміном, а не забувається.
  • Регламент оновлення базового шару — як часто образ перезбирається на свіжій базі, як перевіряється сумісність і як виглядає відкат.
  • Звіти за збірками — що видно по кожній збірці: новий пакет, автор зміни, історія за тегами, без запуску сканера вручну.
  • Інструкції для команди — пам'ятки: що робити при спрацюванні, як оформити виняток, куди дивитися при спірній знахідці.

Кейс: вікно уразливості скоротили з тижнів до доби

Замовник — продуктова команда з щоденними релізами: 25–30 збірок на тиждень, і майже всі йшли в прод без перевірки. Критична уразливість у базовому образі жила в проді від тижня до двох, а дізнавалися про неї із зовнішнього повідомлення, а не зі свого контуру. Розбір інциденту щоразу починався з питання «який образ узагалі зараз у проді».

Ми вбудували перевірку в конвеєр збірки: Trivy переглядає шари образу й маніфести залежностей на етапі, де викатку ще можна зупинити.

Правило блокування налаштували не за загальною кількістю знахідок, а за рівнями — збірка падає лише на критичних і високих із підтвердженим шляхом експлуатації, решта йде до списку завдань з датою розбору.

Метрики до й після: вікно уразливості скоротилося з 11–14 днів до 18–24 годин, бо оновлення базового образу автоматично перезбирає залежні сервіси.

Частка хибних спрацювань упала з 40% до 8% — завдяки файлу винятків, який ми ведемо разом із командою, а не «налаштували одного разу й забули». Ручний розбір скоротився з 6 годин на тиждень до 40 хвилин: інженер дивиться лише те, що справді потребує рішення. Розбір інцидентів тепер іде за списком компонентів із версіями зі звіту, а не за логами наосліп.

Що робити, якщо реєстр образів уже розгорнуто?

Якщо реєстр уже розгорнуто, переносити й перезбирати його не потрібно: сканер підключається до нього як до звичайного джерела й читає маніфести та шари через той самий програмний інтерфейс, яким користується викладка.

Реєстр залишається робочим, а перевірка стає ще одним кроком складального конвеєра — після збірки образу й до публікації тегу.

Починаємо з режиму звіту: сканер розбирає образи мовчки й складає результати в окреме сховище, нічого не блокуючи.

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

Міграція без зупинки викладок будується на паралельному проході: старі теги залишаються доступними, нові проходять перевірку, а блокування вмикається спочатку лише для критичних знахідок у наших шарах.

Базові образи, де виправлень ще немає, на першому етапі йдуть до списку винятків з датою перегляду — викладки не стають, але борг не ховається.

Сумісність із поточною збіркою забезпечується тим, що сканування не змінює ні інструмент збірки, ні структуру шарів: достатньо додати крок і видати сканеру доступ до реєстру на читання.

Кеш шарів продовжує працювати, час збірки зростає на десятки секунд, а на незмінених шарах майже не зростає. Політику перевірок тримаємо у файлі поруч з описом збірки й версіонуємо — відкат робиться однією зміною.

Далі залишається розширювати покриття: підключати до тих самих правил інші репозиторії та поступово знімати винятки. Реєстр уже розгорнуто — змінюється не він, а момент, у який ми дізнаємося про уразливість.

Хибні спрацювання та повільна збірка: часті сумніви

Сканер, який на першому запуску віддає сотні рядків, перестають читати за тиждень — не тому, що він поганий, а тому що у звіті немає пріоритету.

Сигнал з'являється після трьох налаштувань: фільтр за критичністю та наявністю виправленої версії, відсів недосяжного коду й короткий список винятків з обґрунтуванням і датою перегляду. Після цього залишаються одиниці записів, і кожен потребує рішення.

Час збірки закривається кешуванням: результат за незміненим шаром перевикористовується, база уразливостей оновлюється окремим завданням. Перевірка вішається на збірку образу, а не на кожен коміт, і зупиняє конвеєр лише на узгодженому рівні критичності.

Уразливість у базовому шарі — питання меж відповідальності: дистрибутив усередині базового образу оновлює власник шаблону, прикладні залежності — команда сервісу. Регламент фіксує, хто і в який термін закриває кожну категорію, інакше знахідка висить між командами.

Сканер видає сотні уразливостей, небезпечні одиниці — як це розвести?

Відсікаємо за трьома ознаками: критичність, наявність виправленої версії в апстрімі та досяжність уразливого коду із застосунку. Залишок іде до списку винятків із власником і датою перегляду — виняток без терміну перетворюється на забуту діру.

Перевірка загальмує збірку й викатку — наскільки?

Основний час з'їдають перше сканування й оновлення бази уразливостей, далі результат за незміненими шарами береться з кешу. Поріг налаштовується: блокуємо критичне з доступним виправленням, решта — повідомлення у звіті.

Обговоримо задачу: що уточнюємо на першому дзвінку

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

  • Як влаштований складальний конвеєр: де збираються образи, скільки сервісів, хто володіє базовими шарами.
  • Що вже в реєстрі: скільки тегів на сервіс, як глибоко зберігається історія, чи є політика очищення — від цього залежить час першого повного сканування.
  • Які сканери застосовуються зараз (Trivy, Grype, Snyk) і на якому етапі — локально, на сервері збірки чи вже в кластері.
  • Що саме має зупиняти збірку: лише критичні рівні, наявність виправленої версії, уразливості у виконуваних шарах.
  • Вимоги до звітів і доступів: формат вивантаження (SBOM, SARIF), куди йдуть результати, доступ на читання до реєстру без права запису.
  • Хто у вашій команді відповідає за оновлення базових образів — без власника процесу правило блокування швидко вимикають.

У відповідь надсилаємо оцінку обсягу робіт, покроковий план впровадження з точками відкату та критерії приймання: яку частку уразливостей закриває перший прохід, як поводиться конвеєр при збої сканера, що робити з образами, які вже в реєстрі. Опишіть задачу — повернемося з оцінкою та планом.

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

Останні роботи

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