Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CVE Tracker - Server Plugin

A lightweight shell-script agent that runs on a production deployment server and reports what's actually deployed there — which project commits, OS package versions, pinned service versions, server health, and ClamAV status — back to a CVE Tracker instance. This closes the gap between "the latest commit on main is fixed" and "the server that's actually running in production is still on a vulnerable commit, with 30 pending OS updates and a stale antivirus database."

It's developed as a submodule of the main cve-tracker repository (so its development can be managed and reviewed alongside the API it reports to), but on a production server it only needs to be cloned and run standalone — no other part of the monorepo is required there.

Features

  • Project tracking: reports which branch and commit is checked out for each mapped project on the server, and when that commit was made.
  • Pinned service tracking: admin-selected apt packages (e.g. nginx, docker-ce) that aren't part of a tracked project but should still be watched for CVEs.
  • OS package inventory: full dpkg package list plus /etc/os-release distro/version, fed into CVE Tracker's existing dependency-CVE pipeline (Debian/Ubuntu only in v1).
  • Server health: disk usage, memory usage, load average, uptime, pending update count, and whether a system restart is required (and how long it's been pending). Note: This is not explicitly relevant to the core concept of the CVE Tracker, but always relevant when checking server statuses regardless, as it provides an additional opportunity to detect issues ahead of them becoming critical.
  • ClamAV status (check-only): is it installed, is the daemon running, how stale is the virus database, what did the last scheduled scan find — with an optional companion script (setup-clamav.sh) to install and configure ClamAV if it isn't already.
  • One report per run: report.sh always sends the full current state; the CVE Tracker API computes the diff and status transitions server-side.
  • Non-blocking by design: cron runs (report.sh) never prompt for input. Only interactive runs (manage.sh, or a manual collect.sh) offer to walk you through fixing something (like ClamAV being unconfigured).

See docs/SPECIFICATION.md for the full design and exact report payload shape, and docs/DIAGRAMS.md for the script layout and data-flow diagram.

Getting Started

Prerequisites

  • Debian or Ubuntu (v1 only auto-detects these two via /etc/os-release; other distros are explicitly out of scope for now)
  • bash, jq, curl, gitmanage.sh/report.sh will tell you clearly if one is missing
  • A running CVE Tracker instance with SERVER_PLUGIN_TOKEN configured (see the main repo's CLAUDE.md / .env.example)
  • Root access — the plugin's config (/etc/cve-tracker-plugin/config.json) and cron entries live under root-only paths, so manage.sh/init.sh/collect.sh/report.sh all need sudo, alongside schedule-cron.sh (writes to /etc/cron.d) and setup-clamav.sh (installs packages, writes to /etc/cron.d)

Installation

Clone this repository directly onto the deployment server (as its own checkout, not as part of the main monorepo — the server only ever needs this submodule):

git clone https://github.com/zimmerman-team/devops.cve-tracker.server-plugin.git /opt/cve-tracker-plugin
cd /opt/cve-tracker-plugin
sudo ./bin/manage.sh

manage.sh is the only script you need to run directly. If the plugin isn't configured yet, it launches init.sh for you automatically. Run it with sudo: the config file lives under /etc/cve-tracker-plugin, and cron-driven reports run as root too (see Scheduling automatic reports), so the whole plugin lifecycle is root throughout.

Configuration

init.sh (invoked directly, or via manage.sh on first run) will prompt for:

  1. CVE Tracker API URL — e.g. https://cve-tracker.example.com
  2. SERVER_PLUGIN_TOKEN — must match the value configured in the CVE Tracker server's environment
  3. A server ID is generated automatically (UUID v4) — this is the server's permanent identity; losing the config file means the next report is treated as a brand-new server (no automatic merge)
  4. Project mapping — for each local git checkout on this server, map its local path to a repo name known to CVE Tracker (and optionally a branch override; by default the currently checked-out branch is auto-detected on every run)
  5. Pinned services (optional) — apt package names to track for CVEs even though they're not one of the mapped projects (e.g. nginx)

This writes /etc/cve-tracker-plugin/config.json (override the path via the CVE_TRACKER_PLUGIN_CONFIG environment variable). The file contains the shared bearer token, so it's written 0600 (owner read/write only).

Once the config is written, init.sh asks one more question: whether to schedule automatic daily reporting now (schedule-cron.sh with its default 09:00 schedule). Answering no just skips it — you can run report.sh manually first to confirm everything works, then schedule it later via schedule-cron.sh directly or Set up iterative reporting from the manage.sh menu.

Re-run init.sh (or choose Reconfigure from the manage.sh menu) any time to update the mapping or credentials — you'll be asked to confirm before it overwrites the existing config.

Usage

Running a report manually

sudo ./bin/report.sh

This runs collect.sh and POSTs the result to /api/deployments/report. It logs the response and exits non-zero on any failure (auth, network, or a server-side error), which makes it safe to wire into cron with failure alerting (e.g. a MAILTO entry, or systemd's OnFailure=).

Scheduling automatic reports

sudo ./bin/schedule-cron.sh                     # daily at 09:00 (default)
sudo ./bin/schedule-cron.sh --hour 6 --minute 30  # custom time
sudo ./bin/schedule-cron.sh --remove              # uninstall the cron entry

Installs /etc/cron.d/cve-tracker-plugin, running report.sh and logging to /var/log/cve-tracker-plugin/report.log.

Setting up ClamAV

collect.sh reports ClamAV status but never installs or configures anything itself. If it detects ClamAV is missing or misconfigured during an interactive run, it offers to hand off to setup-clamav.sh — this prompt is automatically skipped during unattended cron runs (report.sh always calls collect.sh --non-interactive).

You can also run it directly at any time:

sudo ./bin/setup-clamav.sh

This installs clamav + clamav-daemon, enables freshclam auto-updates, and schedules a daily scan (03:00 by default) whose findings feed back into the next report.

Checking status / reconfiguring / uninstalling

sudo ./bin/manage.sh

With an existing config, this shows a menu: Run report now (default) / Reconfigure / Show status / Set up iterative reporting (runs schedule-cron.sh with its default schedule; use schedule-cron.sh directly for custom --hour/--minute) / Set up ClamAV / Uninstall / Dry-run report (runs collect.sh --non-interactive, printing the payload without submitting it — useful for previewing a report before it's sent). Uninstall removes the cron entry and config file — it deliberately leaves ClamAV installed, since that's a security tool independent of this plugin.

Collecting a payload without submitting it

sudo ./bin/collect.sh --non-interactive   # prints the JSON payload to stdout, doesn't POST anything

Useful for debugging what a report would contain, or piping into jq to inspect a specific field.

Usage in Production

Checklist for a new production server:

  1. Confirm the server is Debian or Ubuntu.
  2. Confirm jq, curl, git are installed (apt-get install -y jq curl git if not).
  3. Confirm SERVER_PLUGIN_TOKEN is set on the CVE Tracker server and you have the value.
  4. git clone this repository somewhere stable (e.g. /opt/cve-tracker-plugin) — don't clone into a directory that might be wiped by a deploy process.
  5. Run sudo ./bin/manage.sh and complete init.sh: set the API URL and token, map every project directory that's actually deployed on this server, and optionally pin any standalone services you want CVE-tracked (e.g. nginx, docker-ce).
    1. CVE Tracker API URL: Deployed CVE tracker url without trailing slash (and without trailing /api).
    2. Server plugin token: as found in the deployment environment of the CVE Tracker.
    3. Hostname to report: the hostname of the server, or a clear identifying name such as "cve-tracker-prod"
    4. Repeat until done, when done, enter blank; Local path: path to the running projects. For example, for cve-tracker it might be home/USR/devops.cve-tracker.
      1. Repo name: name of the repository matching the name on git.
      2. Branch to report: either set a string, it will always check that branch, leave blank to auto-detect the branch it is on.
    5. Repeat until done, when done, enter blank; apt name of packages considered core, such as nginx, certbot, docker-ce. Versions are detected, no need to specify.
    6. Schedule automatic reporting: Y or just hit enter as default, sets up cron.
  6. Run sudo ./bin/report.sh once manually and confirm it succeeds — check the server's Projects tab to see the new entry appear under the relevant repo(s)
  7. Confirm /var/log/cve-tracker-plugin/report.log is being written to after the first scheduled run, and that cron failures would actually reach someone (e.g. system mail is configured, or route report.log into your existing log aggregation).
  8. If a project gets renamed or a server is decommissioned/rebuilt, re-run init.sh or manage.shReconfigure (renaming), or manage.shUninstall (decommissioning) rather than leaving stale config behind.

License

MIT

Development

This project was co-developed with AI to accelerate feature delivery. All code has been manually reviewed and tested for quality.

See docs/BASH.md for a walkthrough of the bash concepts used across bin/ and lib/, aimed at teammates less familiar with shell scripting, and docs/SPECIFICATION.md for the full design.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages