Port Igniter
Get Started

Scans

The seven scan types Reef runs, how scan jobs move through their lifecycle, and how to tune what each scan looks at.

Product Support

Reef Scans listing and history page

Reef runs seven scan types against a monitored host. Each has its own tool and raw output format, but all of them are parsed server-side into the same Finding model, so triage, notifications, and filtering work identically regardless of which scan produced a result.

Job lifecycle

pending → claimed (agent polled it) → running (agent started it) → done / failed

A job expires instead if no result arrives within REEF_JOB_STALE_AFTER_SECONDS (default 3600s). canceled is a terminal state an operator sets from the scans table, a scan’s detail page, or the admin “Cancel selected jobs” action — the job moves to canceled immediately rather than waiting for the stale reaper. A queued job is simply dropped; a claimed/running one is stopped on the agent’s next check-in (canceled_job_ids), which kills the running scanner subprocess, discards the partial result, and lets the agent pick up its next job. A late result for an already-canceled job is refused, so it can’t resurrect.

How a scan gets started

  • Scheduled — a ScanSchedule, editable in the Django admin, dispatched by beat. Default schedules (nightly file integrity monitoring, hourly AuditD, weekly Lynis, daily ClamAV/YARA/Grype, weekly OpenSCAP) are created on first web start by manage.py reef_seed. You can remove non-applicable scans as required.
  • Manual — the toolbar’s Run scan button (POST /api/scans/). Manual jobs are claimed ahead of scheduled ones, and beat won’t stack a second scheduled run of a type that already has one queued.

Scan params

The Run scan dialog’s Params (JSON) field (and a ScanSchedule’s params) is merged over the type’s defaults, stored on the job, and passed verbatim to the agent runner. Unknown keys are ignored — there’s no validation. timeout (seconds, per-tool subprocess cap) works on every scan type. See each scan’s own page for its specific params.

Scan scope is bounded by default

Walking the entire host root takes hours on a real machine, so most scan types default to a bounded set of paths rather than scanning /:

  • fimREEF_FIM_DEFAULT_PATHS (/etc, /bin, …)
  • clamav → writable / higher-risk dirs (/home, /root, /tmp, /opt, …)
  • yara → the same set as ClamAV, plus /etc; files over 64 MiB are skipped, and heavy package-cache/VCS/build trees (node_modules, .venv, .git, …) are pruned by basename
  • grype → full dir:/host, but with heavy trees excluded during the syft walk (node_modules, .cache, var/lib/docker, …)

The scans

Scan What it checks
File Integrity Monitoring New / changed / removed files vs. a per-agent baseline
Auditd Kernel audit rule coverage + classified audit events
Lynis General host hardening audit with plain-language explanations
ClamAV Signature-based malware scanning
OpenSCAP CIS/STIG/PCI-DSS compliance scanning
Grype CVE scanning against an SBOM, with CISA KEV tagging
YARA Rule-based malware / indicator matching over files and process memory
Top