Перейти к содержимому

Чейнджлог

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

Мажорная версия ради крупной функции, а не ради поломки совместимости: сопоставление с CVE — первая ось оценки, не связанная с жизненным циклом. Существующие enodia.yaml, settings.yaml и файлы инвентаря работают без изменений — новый блок cve: опционален, и конфиг без него ведёт себя ровно так же, как в 1.2.

  • Сопоставление с CVE по двум локальным базам — БДУ ФСТЭК и NIST NVD. enodia их не скачивает: вы сами загружаете vulxml.zip из БДУ и годовые файлы NVD nvdcve-2.0-<год>.json.gz и указываете на них cve.bdu.path / cve.nvd.path в enodia.yaml (файл, а для NVD — также директория с файлами). Каждый источник работает и по отдельности. Оба разбираются потоково и кешируются: первый запуск после изменения базы занимает около минуты для всего NVD плюс БДУ, все последующие — меньше секунды. См. как их скачать, включая дополнительный сертификат УЦ, который нужен для bdu.fstec.ru.
  • Сопоставляются 52 пробы (в апстриме — 53 имени продуктов: 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 от 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 у каждого assessment, включая структурированную оценку 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 к подпроцессу p4, к которому они обращаются — любая другая проба в этом проекте ограничивает собственный транспорт таймаутом до того, как обратиться к сети, а эта пара — нет. Процесс p4, застрявший при попытке достучаться до недоступного прямого сервера (без ответа, без сброса соединения — ровно то сетевое поведение, из-за которого эти две пробы вообще обращаются к p4), зависал бесконечно, останавливая весь прогон сбора данных целиком. Сообщено напрямую по реальному зависанию в продакшне.
  • Пробы p4d и p4p — для Perforce Helix Core Server и Perforce Proxy. Собственный RPC wire-протокол Perforce был полностью реверс-инжинирен, и написанный вручную клиент корректно воспроизвёл его рукопожатие против реального прокси, но это же самое, подтверждённо корректное рукопожатие молча отбрасывается реальными прямыми серверами p4d по причинам, не видимым со стороны клиента. Обе пробы вместо этого обращаются к собственному CLI p4 оператора — первые пробы в enodia, запускающие внешний процесс вместо того, чтобы говорить по wire-протоколу напрямую. Путь к бинарнику настраивается для каждого таргета через 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 нет понятия «пусто» для значения-структуры, поэтому каждое наблюдение сериализовало в JSON-экспорте лишний "resolver":{}, а не только у SonarQube. Исправлено на указатель — по той же причине, по которой tlsVerified уже nullable, а не голый false.
  • debian сообщал голую мажорную версию (13) вместо реального point-релиза (13.6) — поле VERSION_ID в /etc/os-release у Debian никогда не несёт point-релиз, даже на полностью пропатченной установке; point-релиз живёт только в /etc/debian_version. debian перешёл с общего механизма osReleaseFamilyProbe на собственную, отдельную пробу, которая читает оба файла и доверяет содержимому debian_version только после подтверждения ID=debian и проверки, что это простое число через точки — реальный образ Ubuntu, как подтверждено, несёт идентичный файл с унаследованным, бессмысленным содержимым.
  • У ubuntu была та же проблема: VERSION_ID не меняется после выхода релиза, поэтому полностью пропатченный хост 22.04 сообщал голый 22.04, а не 22.04.5. ubuntu тоже перешёл с общего механизма на собственную пробу, предпочитая point-релиз из поля VERSION того же файла, когда оно строго точнее VERSION_ID. Все остальные продукты общего семейства SSH-проб для определения ОС были проверены по той же схеме; такого пробела больше ни у кого нет.

Никаких изменений в конфиге ни для одного из них — то же значение product:, те же credentials, тот же эндпоинт. Точнее стало только записываемое поле 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) — по собственному wire-протоколу напрямую, а растущий набор (практически любой мейнстримовый дистрибутив Linux, BSD-системы, macOS, OPNsense, Proxmox VE, TrueNAS, Synology DSM, сетевые устройства) опрашивается через SSH или вендорский HTTP API, а не в расчёте на то, что эндпоинт версии вообще существует.
  • product: generic — проба только на основе конфига для всего самописного, с намеренно замороженным словарём (без условий, циклов и шаблонизации).
  • Резолвинг жизненного цикла через endoflife.date и GitHub Releases, с кешированием на диске, оценка по трём независимым осям (дрейф патча, фаза жизненного цикла, более новая ветка), а не по одному схлопнутому вердикту — см. Концепции.
  • Четыре представления отчёта в виде таблицы, HTML, JSON и вывода для Prometheus.
  • enodia serve — HTTP-сервер, отдающий только снапшот; фоновый тикер собирает данные, обработчики лишь читают последний снапшот.
  • Схема конфига с подстановкой ${VAR}/${VAR:-default}, отдельным хранилищем credentials и закреплением/явным отказом от TLS для каждого таргета.
  • Пакеты: .deb, .rpm, .apk и .pkg.tar.zst для Arch, отдельный непривилегированный системный пользователь enodia, man-страницы для каждой команды, обычные архивы для Linux/Windows/macOS/Android (Termux) и образ контейнера — см. Начало работы. Контрольные суммы подписаны cosign keyless (OIDC, ключ не нужно ни хранить, ни защищать от утечки).