Managing the Version Zoo: How Enodia Was Built for Service Inventory Tracking EOL and CVE Data

A DevOps engineer developed enodia, an open-source Go-based CLI tool, to solve the problem of tracking hundreds of service versions across infrastructure, including PostgreSQL, MySQL, nginx, Debian, and Jira. The tool collects real versions through product-specific probes, then cross-references them against endoflife.date calendars and CVE databases from NVD and Russia's FSTEC BDU. It separates collection and evaluation phases, uses three independent axes for status (PATCH, LIFECYCLE, BRANCH), and supports air-gapped environments by allowing offline CVE data import. Early versions of the MySQL probe caused self-blocking on servers due to connection error counting, which was fixed by completing authentication attempts. The developer contributed multiple products and historical data back to endoflife.date and added support for ten Linux distributions using vendor OVAL and Security Tracker feeds. The project is distributed as a single AGPL-3.0 binary with YAML configuration and environment-variable credential handling.

HabrTranslated from Russian

Read at source

A DevOps engineer faced a growing challenge managing version sprawl across both personal labs and large production environments. Services such as PostgreSQL 13, long-untouched Jira instances, outdated Debian point releases, NAS appliances, hypervisors, BMCs, and routers accumulated over time. Manual tracking became impossible once the count reached hundreds of assets.

Initial attempts using Ansible playbooks to gather OS versions and export them into Google Sheets proved unsustainable. Reports required constant regeneration, lacked built-in EOL or CVE context, and could not reach services without SSH access such as databases, ticketing systems, or network devices.

Search for existing solutions

Existing tools each addressed only part of the problem. endoflife.date provided support calendars but no knowledge of deployed assets. nvchecker tracked upstream releases without deployment visibility. Renovate and Dependabot operated on code repositories rather than live servers. Container-focused tools ignored non-Docker workloads, while uptime monitors answered only whether services were alive.

No single solution combined real deployed versions with support timelines and known vulnerabilities, leading to the creation of enodia.

How enodia works

Enodia is a single-binary Go CLI released under AGPL-3.0. Users describe their environment once in enodia.yaml. The tool then probes each target using protocol-native methods: the PostgreSQL probe speaks the native wire protocol, the Redis probe uses RESP, Jira queries REST APIs, and operating systems connect via SSH. 123 product-specific probes currently exist, covering Atlassian products, GitLab, Jenkins, databases, brokers, VMware, Proxmox, NAS devices, BMCs, pfSense, RouterOS, and 31 operating systems. A generic probe supports URL-plus-regex or JSON-path extraction for everything else.

Enodia explicitly verifies that the reported product matches the configured one. If a user specifies MySQL but receives a MariaDB banner, an error is raised instead of silently recording an incorrect version.

Operation is split into two phases. The collect command gathers facts into JSONL without performing any evaluation. The check command then evaluates the inventory against calendars and CVE data. This separation enables air-gapped workflows where collection occurs inside the perimeter and evaluation uses external data imported on removable media.

Instead of a single pass/fail status, enodia reports three independent axes: PATCH (current or behind within the branch), LIFECYCLE (active, security-only, or EOL), and BRANCH (latest, newer, or newer LTS). These combine into severity levels that determine exit codes suitable for CI pipelines.

Early technical challenges

The original MySQL probe read the server greeting without authenticating. Servers counted these aborted connections toward max_connect_errors, eventually blocking the entire source host. The fix involved completing a login attempt with an invalid password so the server registers a proper authentication failure rather than an aborted connection.

MariaDB versions 10.x prefix their version string with “5.5.5-” for compatibility. Early enodia releases misclassified these as ancient MySQL 5.5.5. The product verification logic now correctly identifies MariaDB even when the banner mimics MySQL.

Debian reports its major version in /etc/os-release but stores the full point release in /etc/debian_version. Ubuntu freezes VERSION_ID at the LTS base while placing the point release only in VERSION. VMware vCenter and ESXi use “Update N” notation that naive parsers truncated. Enodia’s version parser now understands vendor-specific update schemes.

Data sources for EOL and CVE

Primary EOL data comes from endoflife.date. The author contributed new products including Jira Service Management and pgAdmin, complete branch histories for Confluence, Bitbucket, and Bamboo, and corrected EOL dates for several Atlassian products. Additional products remain under review.

CVE information is aggregated from NVD and Russia’s FSTEC BDU. Ten Linux distributions are supported through native feeds: Debian via Security Tracker, Ubuntu/Mint/RHEL/Rocky/Alma/Oracle/Astra/RED OS via OVAL, and Alpine via secdb. All CVE databases can be updated once and then used offline.

BDU certificate handling required manual assembly of the Russian Trusted root and intermediate certificates because the server omits the intermediate in the TLS handshake. The configuration accepts a custom CA file to maintain proper validation.

Meridian digestThe week's most consequential security stories, distilled into one briefing.See the digest

More in Vulnerabilities & Exploits

Invisible SMS of Death Crashes Android Phone Service, Blocking Even Emergency Calls
Telegram Voice Call Flaw Enables Remote Code Execution on Android Devices
Cisco Talos Details KeyDrift Malware Exploiting Critical CVE-2026-20127 Zero-Day in Catalyst SD-WAN