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

Журнал змін

Канонічне джерело — власний CHANGELOG.md enodia; ця сторінка його віддзеркалює, синхронізується разом з рештою сайту на кожному релізі й містить посилання на інші розділи цієї документації там, де зміна впливає на те, як Ви насправді щось налаштовуєте. Теги мають формат MAJOR.MINOR.PATCH+BUILD, без префікса v; +BUILD — це метадані збірки semver, які використовуються лише для перезбирання без функціональних змін, а не для того, щоб оминути реальне підвищення версії.

Мажорна версія заради великої функції, а не через несумісність: зіставлення з CVE — перша вісь оцінювання, яка не стосується життєвого циклу. Наявні enodia.yaml, settings.yaml і файли інвентарю працюють без змін — новий блок cve: необовʼязковий, а конфігурація без нього поводиться точно так само, як у 1.2.

  • Зіставлення з CVE з двома локальними базами даних, БДУ ФСТЕК і NIST NVD. enodia ніколи не завантажує їх сама: Ви отримуєте vulxml.zip від БДУ та щорічні файли NVD nvdcve-2.0-<year>.json.gz і вказуєте на них у cve.bdu.path / cve.nvd.path в enodia.yaml (файл або, для NVD, каталог файлів). Кожне джерело працює і саме по собі. Обидва розбираються потоково й кешуються: перший запуск після зміни бази даних триває близько хвилини для всього NVD разом із БДУ, кожен наступний — менше секунди. Див. як їх завантажити, зокрема додатковий сертифікат CA, потрібний для bdu.fstec.ru.
  • Зіставляється 52 проби (53 назви продуктів в upstream — ssh рахується і як OpenSSH, і як Dropbear) — кожна проба, для якої є придатні дані в будь-якому з джерел. Свідомо не зіставляються, кожен з указаною причиною: дистрибутиви Linux загального призначення (їхні CVE стосуються рівня пакетів), BSD-системи та Solaris, ESXi/vCenter і Synology DSM (рівні патчів і суфікси збірок, які механізм зіставлення поки не читає), — див. які продукти зіставляються, а також власну сторінку кожного продукту.
  • Зіставлення з урахуванням редакції для GitLab, Vault, Nextcloud і MongoDB: community-екземпляр більше не бачить знахідок, що стосуються лише enterprise (на реальних даних GitLab 19.2.2 CE бачить 4 з 9 записів NVD, Nextcloud 27.1.3 CE — 11 з 23). Ці чотири проби тепер записують редакцію свого сервера в extra.enterprise; за невідомої редакції зберігаються всі знахідки.
  • Цілі ssh зіставляються як OpenSSH або Dropbear за своїм банером; для будь-якого іншого SSH-стека пошук CVE не виконується, замість того щоб брати CVE OpenSSH.
  • Стовпець CVES у поданнях compact і drift команди check, що рахує різні CVE.
  • Список за кожною CVE в export --format html, на чистому CSS без JavaScript, тож inline-звіт залишається офлайн-файлом без жодного <script>: по рядку на CVE з посиланнями на NVD, cve.org і bdu.fstec.ru, російський текст БДУ, якщо БДУ містить цю CVE, кольорова оцінка CRITICAL · CVSS 3.1 9.8, найкритичніші першими.
  • export --format json містить кожну знахідку з кожного джерела в масиві cves кожної оцінки, зокрема структуровану оцінку CVSS, розібрану з обох джерел.
  • Проба fortios для Fortinet FortiGate — через його REST API з токеном REST API Admin.
  • HTML-звіти в режимі CDN запамʼятовують для кожного глядача закрите попередження «потрібен доступ до інтернету».
  • Блок cve: читається з тієї конфігурації, яку фактично використовує запуск, — --config, $ENODIA_CONFIG або стандартні шляхи пошуку.
  • Шляхи Windows працюють без лапок, в одинарних лапках, з прямими скісними рисками або як UNC-шляхи. У подвійних лапках YAML \t і \n стають табуляцією та переведенням рядка, тому такий шлях відхиляється під час завантаження з підказкою.
  • cisco-ios-xe остаточно вилучено з дорожньої карти.
  • p4d/p4p не застосовували timeout до підпроцесу CLI p4, який вони викликають, — кожна інша проба в цьому дереві обмежує власний транспорт значенням timeout, перш ніж звертатися до мережі, а ця — ні. Процес p4, що завис на зʼєднанні з недосяжним прямим сервером (без відповіді, без скидання зʼєднання — саме та мережева поведінка, через яку ці дві проби взагалі викликають p4), висів нескінченно, зупиняючи весь прогін збирання. Повідомлено безпосередньо за реальним зависанням у продакшені.
  • Проби p4d і p4p для Perforce Helix Core Server і Perforce Proxy. Власний мережевий RPC-протокол Perforce було повністю розібрано методом зворотної розробки, і власноруч написаний клієнт коректно відтворив його рукостискання з реальним проксі, але саме це рукостискання, коректність якого перевірено до байта, реальні прямі сервери p4d мовчки відкидають із причин, невидимих з боку клієнта. Натомість обидві проби викликають власний CLI p4 оператора — це перші проби в enodia, що запускають зовнішній процес, а не говорять мережевим протоколом напряму. Шлях до бінарника налаштовується для кожної цілі через options.binary (за замовчуванням — p4 з $PATH); у Windows це працює так само, якщо вказати p4.exe. Відповідь проксі відрізняється від відповіді прямого сервера наявністю власного поля proxyVersion — кожна проба відхиляє відповідь іншого вигляду.
  • Парсер виводу p4 -Ztag не прибирав закінчення рядків Windows: справжній p4.exe пише \r\n, залишаючи кінцевий \r усередині значень полів на кшталт ServerID.
  • probe.Observation.Resolver (додано в 1.1.0+0 для SonarQube) був звичайною структурою, а не вказівником — omitempty в encoding/json не має поняття «порожньо» для значення-структури, тож кожне спостереження, а не лише від SonarQube, серіалізувало в JSON-експортах зайве "resolver":{}. Виправлено на вказівник — з тієї ж причини tlsVerified уже може мати значення null, а не просто false.
  • debian повідомляв лише мажорну версію (13) замість фактичного точкового релізу (13.6) — VERSION_ID у /etc/os-release Debian ніколи його не містить, навіть на повністю оновленій системі; точковий реліз є лише в /etc/debian_version. debian перейшов зі спільного механізму osReleaseFamilyProbe на власну окрему пробу, яка читає обидва файли й довіряє debian_version лише після підтвердження ID=debian і того, що його вміст — звичайне число з крапками: було підтверджено, що реальний образ Ubuntu містить такий самий файл із безглуздим успадкованим вмістом.
  • ubuntu мав ту саму прогалину: VERSION_ID ніколи не змінюється після виходу релізу, тож повністю оновлений хост 22.04 повідомляв просто 22.04, а не 22.04.5. ubuntu теж перейшов зі спільного механізму на власну пробу, яка віддає перевагу точковому релізу з власного поля VERSION в os-release, коли воно строго точніше за VERSION_ID. Кожен інший продукт спільного сімейства ідентифікації ОС через SSH перевірено так само; жоден з решти такої прогалини не має.

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

  • Резолвер життєвого циклу github-tags для продукту, який не публікує GitHub Releases зовсім, лише теги не у форматі з крапками, — дав pgAdmin його перший робочий резолвер (теги pgadmin-org/pgadmin4 мають вигляд REL-9_17, перетворюються на 9.17, і обирається тег з найвищою розібраною версією, а не перший).
  • Змінна середовища GITHUB_TOKEN — автентифікує кожен запит до життєвого циклу на основі GitHub, піднімаючи ліміт без автентифікації з 60 запитів на годину до 5000 на годину. Див. Підтримувані продукти.
  • Проба тепер може перевизначати резолвер життєвого циклу свого продукту для окремого спостереження — для рідкісного випадку, коли правильний календар можна визначити лише після того, як побачено власну відповідь вендора з версією. Уперше використано, щоб розділити SonarQube на SonarQube Server і SonarQube Community Build — два окремі продукти після розділення SonarSource наприкінці 2024 року, що відстежуються як дві різні сторінки endoflife.date з різними даними циклів.
  • Раніше збої резолвера показувалися у звіті лише як resolver_error, без жодної можливості відрізнити ліміт запитів GitHub від збою DNS чи зміненого API. Тепер enodia check/export у такому разі виводять справжню першопричину помилки в stderr.
  • SonarQube завжди порівнювався з календарем життєвого циклу Community Build, навіть для екземпляра SonarQube Server, — збирання його версії працювало, але звіт у будь-якому разі показував незіставлений цикл. Тепер резолвер визначається для кожного екземпляра за самим рядком версії.
  • Публікацію образу контейнера (ghcr.io/epicmorg/enodia, також віддзеркалюється на Docker Hub і Quay) повністю винесено з власного конвеєра релізів цього репозиторію в монорепозиторій EpicMorg/docker з власним розкладом збирання цього репозиторію. Адреса опублікованого образу та теги (latest, 1, точна версія) не змінилися, але сам образ тепер лише linux/amd64 і працює від імені root — див. Початок роботи.

Перший реліз. collect → inventory.jsonl → evaluate → assessment → render від початку до кінця, перевірено на реальній продакшен-інфраструктурі:

  • 87 проб, по одному файлу на кожну, вкомпільовані та явно зареєстровані — більшість говорить HTTP, деякі (Redis, PostgreSQL, MySQL, MongoDB) — напряму власним мережевим протоколом, а дедалі більший набір (усі поширені дистрибутиви Linux, BSD-системи, macOS, OPNsense, Proxmox VE, TrueNAS, Synology DSM, мережеві пристрої) опитується через SSH або HTTP API вендора, замість того щоб припускати, що endpoint із версією взагалі існує.
  • product: generic — проба, що задається лише конфігурацією, для будь-яких внутрішніх систем, зі свідомо замороженим словником (без умов, циклів чи шаблонів).
  • Визначення життєвого циклу за endoflife.date і GitHub Releases, з кешуванням на диску, з оцінюванням за трьома незалежними осями (відставання патча, фаза життєвого циклу, новіша гілка), а не одним згорнутим вердиктом, — див. Концепції.
  • Чотири подання звіту для табличного, HTML-, JSON- і Prometheus-виводу.
  • enodia serve — HTTP-сервер, що віддає лише знімки; фоновий таймер збирає дані, а обробники запитів тільки читають останній знімок.
  • Схема конфігурації з підстановкою ${VAR}/${VAR:-default}, окремим сховищем облікових даних і закріпленням TLS/явним дозволом на insecure для кожної цілі.
  • Пакування: .deb, .rpm, .apk і .pkg.tar.zst для Arch, окремий непривілейований системний користувач enodia, man-сторінки для кожної команди, звичайні архіви для Linux/Windows/macOS/Android (Termux) і образ контейнера — див. Початок роботи. Контрольні суми підписано cosign keyless (OIDC, жодного ключа, яким треба керувати чи який може витекти).