Перейти до вмісту

Зіставлення з CVE

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

  • БДУ ФСТЕК — база даних вразливостей ФСТЕК (Росія), bdu.fstec.ru.
  • NIST NVD — Національна база даних вразливостей США, nvd.nist.gov.

Кожна працює і сама по собі; якщо налаштовано обидві, їхні знахідки обʼєднуються за CVE. Це повністю необовʼязкова функція: конфігурація без блоку cve: поводиться точно так само, як у 1.x.

enodia ніколи не завантажує бази даних сама

Section titled “enodia ніколи не завантажує бази даних сама”

Файли завантажуєте Ви, Ви вирішуєте, коли їх оновлювати, і Ви вказуєте enodia, де вони лежать. В enodia немає жодного шляху виконання, який сам звертався б до bdu.fstec.ru чи nvd.nist.gov, — з тих самих міркувань закритої мережі, що й у двофазній архітектурі: машині, на якій запускається check, для зіставлення з CVE не потрібен доступ до інтернету, лише копія файлів.

Один файл — повне вивантаження ФСТЕК (близько 33 МБ у zip-архіві):

Terminal window
curl -fL --cacert ru-chain.pem \
-o /var/lib/enodia/cve/bdu/vulxml.zip \
https://bdu.fstec.ru/files/documents/vulxml.zip

bdu.fstec.ru використовує сертифікат національного центру сертифікації Росії (Мінцифри), якого немає у звичайних системних сховищах довіри, — звичайний curl завершується помилкою сертифіката. Крім того, сервер не надсилає свій проміжний сертифікат, а curl (на відміну від браузера) не завантажує відсутній сертифікат сам, тож установлення лише кореневого недостатньо. Зберіть bundle з кореневого та проміжного сертифіката, який указано в сертифікаті сайту:

Terminal window
curl -fsS -o root.crt https://gu-st.ru/content/lending/russian_trusted_root_ca_pem.crt
curl -fsS -o sub.crt http://nuc-cdp.digital.gov.ru/cdp/subca_ssl_rsa2024.crt
{ cat root.crt; echo; cat sub.crt; } > ru-chain.pem

Перевірено наживо 2026-09-23. Якщо це перестане працювати, найімовірніше, проміжний сертифікат замінили: поточний указано в полі Authority Information Access самого сертифіката сайту (openssl s_client -connect bdu.fstec.ru:443 | openssl x509 -noout -ext authorityInfoAccess). curl -k теж завантажить файл, але пропустить перевірку того, що Ви збираєтеся подати у свій звіт з безпеки.

Один файл на рік, nvdcve-2.0-<year>.json.gz, з 2002 до поточного року. Покладіть потрібні в один каталог:

Terminal window
mkdir -p /var/lib/enodia/cve/nvd && cd /var/lib/enodia/cve/nvd
for y in $(seq 2002 "$(date +%Y)"); do
curl -fsSLO "https://nvd.nist.gov/feeds/json/cve/2.0/nvdcve-2.0-$y.json.gz"
done

Файл поточного року оновлюється щодня; старіші роки змінюються рідко. Кожен файл має супровідний .meta (nvdcve-2.0-<year>.meta) з розміром і sha256 — зверніть увагу, що хеш рахується від нестиснутого JSON, а не від .gz.

Блок cve: в enodia.yaml — не в settings.yaml, оскільки він змінює оцінювання, а не лише відображення:

enodia.yaml
schemaVersion: 1
cve:
bdu:
path: /var/lib/enodia/cve/bdu/vulxml.zip
nvd:
path: /var/lib/enodia/cve/nvd
targets:
- id: gitlab-main
product: gitlab
address: https://gitlab.example.com
credentials: gitlab-token
Поле Приймає
cve.bdu.path .xml, .zip (вивантаження в опублікованому вигляді) або .tar.gz/.tgz
cve.nvd.path один файл .json, .json.gz або .json.zip чи каталог із такими файлами

Відносні шляхи обчислюються відносно каталогу файлу конфігурації, у якому їх указано, — так само, як credentials_file. Блок читається з тієї конфігурації, яку фактично використовує запуск, — --config, $ENODIA_CONFIG або стандартні шляхи пошуку. Це стосується й check --from inventory.jsonl: інвентар, зібраний усередині закритої мережі, зіставляється там, де запускається check, якщо там знайдено конфігурацію з блоком cve:. Якщо конфігурацію не знайдено взагалі, check --from усе одно працює, просто без CVE.

Налаштований шлях, якого не існує, — це помилка, а не мовчазний пропуск: check завершується з stat ...: no such file or directory, а не створює звіт, у якому непомітно немає жодної CVE. enodia config validate перевіряє форму блоку (зокрема перевірку керівних символів, описану нижче), але не існування файлів — це перевіряється лише тоді, коли запуск фактично їх завантажує.

Перший запуск і кешування

Section titled “Перший запуск і кешування”

Обидва джерела розбираються потоково, а результат кешується в каталозі кешу ОС ($XDG_CACHE_HOME/enodia/cve, тобто за замовчуванням ~/.cache/enodia/cve у Linux; ~/Library/Caches/enodia/cve у macOS; %LocalAppData%\enodia\cve у Windows). Перший запуск після зміни файлу розбирає його повністю — близько хвилини для всього NVD разом із БДУ; вимірювання 2026-09-23 для БДУ разом лише з файлом NVD за 2026 рік — 25 с. Кожен наступний запуск читає кеш: 0,2 с для тих самих даних, кеш на 11 МБ. TTL немає — ключем кешу є самі файли (розмір і час зміни) та власні таблиці продуктів enodia, тож заміна файлу, додавання року до каталогу NVD чи оновлення enodia кожне саме по собі запускає перебудову.

enodia serve перечитує блок cve: і файли на кожному циклі --interval (дешево, з кешу), тож заміна файлів із cron набуває чинності без перезапуску сервера.

Де зʼявляються знахідки

Section titled “Де зʼявляються знахідки”
  • check — стовпець CVES у поданнях compact і drift: кількість різних CVE, що зачіпають саме цю версію. - означає відсутність знахідок — жодна не зачіпає цю версію, немає блоку cve: або enodia не зіставляє цей продукт (див. нижче); сам стовпець присутній завжди. lifecycle і fleet цього стовпця не містять.
  • export --format html — той самий стовпець з інформаційним посиланням, що відкриває список для кожної цілі: по рядку на CVE, найкритичніші першими, з посиланнями на NVD, cve.org і, для знахідок БДУ, на сторінку bdu.fstec.ru; російський текст БДУ, якщо БДУ містить цю CVE, інакше — англійський опис NVD; і оцінка у вигляді кольорових бейджів, наприклад CRITICAL · CVSS 3.1 9.8. Це чистий CSS — офлайн-звіт за замовчуванням, як і раніше, не містить жодного JavaScript.
  • export --format json — кожна знахідка з кожного джерела повністю, у масиві cves кожної оцінки: джерело (bdu/nvd), ID бюлетеня, ID CVE, заголовок, власний текст критичності від джерела, зіставлена назва продукту або CPE, діапазон версій і розібрана оцінка CVSS. На відміну від таблиці та HTML-списку, які рахують по рядку на CVE, JSON зберігає знахідку кожного джерела окремо — та сама CVE може зʼявитися один раз від БДУ і по разу на кожен відповідний CPE з NVD.
  • export --format prometheus — без даних про CVE.

CVE не впливають на критичність чи код завершення. SEVERITY, як і раніше, обчислюється лише з осей патча/життєвого циклу/гілки, і --fail-on теж знає лише ці три осі — знахідка є фактом, на який варто поглянути, а не вердиктом, який enodia винесла замість Вас. Чи повинна CVE підвищувати критичність і як саме — відкрите питання в upstream.

Які продукти зіставляються

Section titled “Які продукти зіставляються”

52 з 90 продуктів; назву кожного вендора/продукту перевірено дослівно на реальних повних вивантаженнях — джерела для кожного продукту див. на його власній сторінці в розділі Налаштування продуктів.

Не зіставляються, кожен — з певної причини:

  • Дистрибутиви Linux загального призначення (Debian, Ubuntu, RHEL, Alma, Rocky, Fedora, RED OS, Astra Linux, …) — їхні CVE є вразливостями пакетів; номер релізу не може сказати, які пакети відтоді оновлено.
  • BSD-системи та Oracle Solaris — NVD записує їхні рівні патчів (-p5 у FreeBSD, errata в OpenBSD) у поле CPE, яке цей механізм зіставлення не читає; зіставлення лише за релізом позначало б повністю оновлений хост усіма CVE, будь-коли виправленими в цьому релізі.
  • ESXi і vCenter — та сама проблема: майже всі їхні записи — це літерали на кшталт 7.0 + update_1.
  • Synology DSM — межі на кшталт 6.2.4-25556-3, які суворий парсер діапазонів відхиляє.
  • TrueNAS — занадто мало записів, і версії в них позначено інакше, ніж повідомляє проба.
  • Немає придатних даних у жодному з джерел — Kitsu, Zou, postgres_exporter, Perforce Proxy, Perforce Helix Swarm.
  • generic — власноруч написаний парсер не має ідентичності продукту, за якою можна було б шукати.

Зіставлення з урахуванням редакції

Section titled “Зіставлення з урахуванням редакції”

GitLab, HashiCorp Vault, Nextcloud і MongoDB публікують окремі списки CVE для своїх community- та enterprise-редакцій. Їхні проби записують власну редакцію сервера в extra.enterprise, і community-екземпляр більше не бачить знахідок, що стосуються лише enterprise: на реальних даних GitLab 19.2.2 CE бачить 4 з 9 записів NVD, Nextcloud 27.1.3 CE — 11 з 23. Якщо редакція невідома (старіший сервер, який її не повідомляє), зберігаються всі знахідки.

Проба ssh охоплює будь-яку реалізацію SSH, тож зіставлення виконується за банером: OpenSSH_… шукається як OpenSSH, dropbear_… — як Dropbear, а для будь-якого іншого SSH-стека пошук не виконується зовсім, замість того щоб позичати CVE OpenSSH.

  • БДУ може завищувати кількість знахідок між гілками. Один запис БДУ часто містить окремий діапазон для кожної гілки супроводу, і всі вони мають спільну нижню межу, тож версія, яка вже є виправленням у своїй гілці, все одно може потрапити в ширший діапазон сусідньої гілки (задокументований приклад — Confluence 8.3.3 і CVE-2023-22515). Діапазони NVD для тієї самої CVE мають власні нижні межі й такої проблеми не мають. enodia свідомо схиляється до того, щоб повідомити знахідку для повторної перевірки, а не мовчки пропустити реальну.
  • Записи NVD зовсім без обмеження версій відкидаються. За вимірюваннями на повних вивантаженнях, це майже завжди були CVE давністю в десятки років, привʼязані до поточних релізів; ціна — рідкісна справді невиправлена CVE, записана таким чином.
  • Умови NVD для кількох продуктів («вразливий лише з бібліотекою Y») не обчислюються — проба повідомляє один продукт на ціль, тож кожен вразливий запис для зіставленого продукту враховується сам по собі.