Most security appliances detect attacks. Far fewer can prove they did — in a way an auditor will accept months or years later. Regulations like the EU's NIS2 Directive (Article 21), SOC 2, ISO 27001 and Cyber Essentials all require evidence that is signed, timestamped against a trusted time source, and tamper-evident.
The Defend-O-Tron records that evidence continuously while it protects your network. Every day, the device signs a manifest of the day's logs with an Ed25519 key anchored to NTP-attested time. Every minute, the collector tick adds new events to a hash-chained store. Every hour, the device re-verifies its own chain of custody and surfaces the result to your dashboards. When an auditor asks for proof, you produce a single signed ZIP covering whatever period they ask about — events, threat decisions, configuration snapshot, NTP attestation, and the daily chain of signed manifests, all in one package.
This is the kind of capability you'd typically pay extra for as a SIEM add-on on Cisco, Fortinet or Sophos. On the Defend-O-Tron it's built in and runs automatically.
The audit subsystem is built to produce evidence that maps cleanly onto the major cybersecurity frameworks. The tables below show which framework outcomes the device itself addresses, and which are operator or organizational responsibilities that the device's evidence supports.
What "addressed" means here. Frameworks describe outcomes, not products. Saying the device addresses a control means it implements the technical capability the control calls for. Achieving full conformance is always an organizational matter — the device gives you the evidence; you and your auditor make the determination.
The NIST Cybersecurity Framework 2.0 (NIST CSWP 29, February 2024) organizes cybersecurity outcomes into six Functions — GOVERN, IDENTIFY, PROTECT, DETECT, RESPOND, RECOVER — each broken down into Categories and Subcategories. The audit subsystem most directly addresses the PROTECT, DETECT and RESPOND Subcategories that concern log generation, continuous monitoring, adverse-event analysis, and incident-data preservation.
| Subcategory | Outcome | Defend-O-Tron status |
|---|---|---|
| PR.PS-04 | Log records are generated and made available for continuous monitoring | Addressed. Suricata IDS alerts, CrowdSec decisions, nftables packet counters, and Linux auditd events all flow into the events store and a Prometheus textfile that node-exporter scrapes for Grafana. The daily Ed25519-signed manifest hashes every rotated log file. |
| DE.CM-01 | Networks and network services are monitored to find potentially adverse events | Addressed. Continuous Suricata IDS + CrowdSec community blocklists + nftables named counters cover network monitoring end-to-end. |
| DE.CM-09 | Computing hardware and software, runtime environments, and their data are monitored | Partially addressed. Linux auditd rules ship enabled (file access, perm_mod, execve, modules, network, time-change); the rotated audit.log is hashed into the daily manifest. Parsing auditd events into the queryable event store is on the roadmap. |
| DE.AE-02 | Potentially adverse events are analyzed to better understand associated activities | Partially addressed. The Audit Evidence dashboard surfaces events for operator analysis; automated correlation is operator-side. |
| DE.AE-03 | Information is correlated from multiple sources | Addressed. A single unified events store stitches Suricata + CrowdSec + nftables into one queryable timeline per device. |
| DE.AE-06 | Information on adverse events is provided to authorized staff and tools | Addressed. Prometheus textfile → node-exporter → Grafana for operators; signed evidence ZIP for auditors. |
| DE.AE-07 | Cyber threat intelligence and other contextual information are integrated into the analysis | Partially addressed. CrowdSec community blocklists are integrated inline; offline IOC cross-reference (ThreatFox file hashes) against the captured SHA-256s is supported. |
| DE.AE-08 | Incidents are declared when adverse events meet the defined incident criteria | Operator responsibility. The device surfaces severity-classified events; declaration thresholds are an organizational policy decision. |
| RS.AN-06 | Actions performed during an investigation are recorded, and the records' integrity and provenance are preserved | Addressed. Daily Ed25519-signed manifest + chain-of-custody signed evidence ZIP. Verification works offline using the embedded pubring. |
| RS.AN-07 | Incident data and metadata are collected, and their integrity and provenance are preserved | Addressed. New in audit-deb 2.0.0: a per-row hash chain on the events and decisions tables. Each row's hash includes the previous row's hash, so any retroactive mutation breaks the chain immediately — not just at the daily manifest boundary. Every signed artifact carries the device serial, hostname, and image variant. |
| RS.MA-03 | Incidents are categorized and prioritized | Partially addressed. Suricata signature severity + CrowdSec scenario provide raw classification; full prioritization is operator-side. |
| ID.AM-08 | Systems, hardware, software, services, and data are managed throughout their life cycles | Partially addressed (device contribution). Every signed artifact embeds the device identity record (serial number, hostname, image variant) for fleet life-cycle correlation. |
ISO/IEC 27001:2022 is the cybersecurity management-system standard; ISO/IEC 27002:2022 is its controls catalog (published February 2022). The audit subsystem maps to the following 27002:2022 controls.
| Control | Title (27002:2022) | Defend-O-Tron status |
|---|---|---|
| 5.25 | Assessment and decision on information security events | Partially addressed. Events are surfaced for assessment via dashboards and the evidence ZIP; the decision step is operator-side. |
| 5.28 | Collection of evidence | Addressed. The defend-audit report evidence ZIP is purpose-built as the chain-of-custody pack — events, decisions, configuration snapshot, daily signed manifests, NTP attestation, all signed end-to-end. |
| 5.33 | Protection of records | Addressed for the audit signing key (per-device generation, mode 0400, redundant copy on SD card, pubring rotation history). Addressed for daily manifests (Ed25519 signature with key continuity across rotations). Partially addressed for the live events store — the per-row hash chain detects any tampering immediately, but the SQLite file itself is mutable by root. |
| 8.15 | Logging | Addressed. Activities, exceptions, faults, and other relevant events are produced (multi-source ingest), stored (SQLite WAL + 365-day default retention), protected (Ed25519-signed daily manifest + per-row hash chain + RFC 3161 trusted timestamps), and analysed (Grafana Audit Evidence dashboard). |
| 8.16 | Monitoring activities | Addressed. 60-second collector tick into the events store; node-exporter scrape; live Grafana surfacing. |
| 8.17 | Clock synchronization | Addressed. Chrony NTP discipline is mandatory; chrony logs are included in every evidence ZIP as time attestation. As of audit-deb 2.1.0, each daily manifest's signature is also anchored to an external clock via an RFC 3161 trusted timestamp from a pinned Time-Stamp Authority — see Trusted Timestamps below. |
Directive (EU) 2022/2555 — the NIS2 Directive — entered into force in January 2023 with member-state transposition by October 2024. Article 21(2) lists ten cybersecurity risk-management measures essential entities must implement.
| Art 21(2) | Measure | Defend-O-Tron status |
|---|---|---|
| (a) | Policies on risk analysis and information system security | Organizational responsibility. The device's evidence stream is an input to those policies. |
| (b) | Incident handling | Partially addressed. Detection and evidence preservation are device-side; the notification workflow per Article 23 (24-hour early warning, 72-hour notification, 1-month final report) is operator-side. |
| (c) | Business continuity, including backup management and disaster recovery, and crisis management | Out of scope at audit-deb. Handled at the appliance level via the A/B image-update system and the LUKS-backed data partition. |
| (d) | Supply chain security | Organizational responsibility. |
| (e) | Security in network and information systems acquisition, development and maintenance, including vulnerability handling | Organizational responsibility. |
| (f) | Policies and procedures to assess the effectiveness of cybersecurity risk-management measures | Partially addressed (device contribution). Periodic evidence ZIPs are the data backbone for the effectiveness review the operator runs. |
| (g) | Basic cyber hygiene practices and cybersecurity training | Organizational responsibility. |
| (h) | Policies and procedures regarding the use of cryptography and, where appropriate, encryption | Addressed for audit signing. Per-device Ed25519 keypair (no shared fleet key), rotation supported and audited via the pubring, retired keys retained so historical evidence remains verifiable. |
| (i) | Human resources security, access control policies and asset management | Partially addressed (device contribution). Each signed artifact carries the device's asset record; HR and access control are out of scope. |
| (j) | Multi-factor authentication or continuous authentication and secured communications | Out of scope at audit-deb. Provided by the appliance's authentication layer. |
NIST SP 800-61 Rev 3 (April 2025) is the Incident Response Recommendations and Considerations for Cybersecurity Risk Management. It restructured the older Rev 2 four-phase model (Preparation → Detection & Analysis → Containment/Eradication/Recovery → Post-Incident Activity) to align with the CSF 2.0 functions. Rev 2 was withdrawn on 3 April 2025; this page cites Rev 3.
| Topic | Defend-O-Tron status |
|---|---|
| Log sources as primary precursors and indicators | Addressed. Suricata, CrowdSec, nftables, and Linux auditd are all in the baseline log set the document recommends. |
| Evidence preservation and chain of custody | Addressed. Daily Ed25519-signed manifest plus chain-of-custody-signed evidence ZIP. Every action taken during an investigation against the evidence (verification, re-extraction, key rotation) is itself logged. |
| Time correlation across events | Addressed. All timestamps are UTC; chrony NTP discipline is mandatory; chrony logs ship in every evidence pack. |
| Provenance of incident data and metadata | Addressed. Device serial + hostname + image variant embedded in every signed artifact. Per-row hash chain on events and decisions provides intra-day provenance between manifest signings. |
| Forensic preservation against device compromise | Partially addressed. Per-row chain detects tampering; manifests anchor file hashes. An off-device evidence forwarder is on the roadmap for survive-the-device-wipe scenarios. |
The audit subsystem has a published roadmap of features that close remaining technical gaps in the matrix above. None of these are required by the frameworks today — they raise the assurance ceiling:
.tsr sibling is verified hourly by do-audit-selfcheck. See Trusted Timestamps.The audit subsystem aggregates evidence from every defense component on the device:
Every event is timestamped against the device's NTP-attested clock. The daily manifest hashes every log file the device ships and signs the hash list, so any tampering after-the-fact is detectable.
Inside the events store, the events and decisions tables carry a per-row hash chain (audit-deb 2.0.0+). Each new row's hash incorporates the previous row's hash, so any retroactive insert, delete, or modification breaks the chain at that row and every row thereafter — detected immediately, not just at the next daily manifest signing.
In addition to the daily manifest signing, the device runs an hourly self-check that re-verifies every signed manifest against the on-device pubring and writes the outcome to a Prometheus textfile. If a manifest is tampered with, its signature fails verification; the failure shows up on your dashboard within an hour without anyone having to download a verification ZIP.
The metrics exposed are:
| Metric | What it tells you |
|---|---|
do_audit_selfcheck_signatures_ok |
Manifest signatures that verified at the last self-check run |
do_audit_selfcheck_signatures_bad |
Manifest signatures that failed verification — should always be 0 |
do_audit_selfcheck_files_mismatched |
Files referenced by a manifest whose SHA-256 has since changed (only checked when [selfcheck] rehash_files = true in audit.conf) |
do_audit_selfcheck_files_missing |
Files referenced by a manifest that no longer exist on disk |
do_audit_selfcheck_last_run_ts |
Unix timestamp of the most recent self-check run |
A non-zero value on signatures_bad or files_mismatched is a tamper signal — investigate immediately.
Ed25519 signatures prove who signed a manifest. They do not prove when it was signed — the device's clock is the only witness, and an attacker who roots the device can backdate it. RFC 3161 trusted timestamps close that gap by anchoring each signature to an external clock maintained by a Time-Stamp Authority (TSA).
As of audit-deb 2.1.0, every daily manifest's Ed25519 signature is timestamped by an external TSA, and the resulting TimeStampResp is stored as a sibling .tsr file next to the manifest.
After do-audit-manifest produces and signs MANIFEST-YYYY-MM-DD.json:
SHA-256(base64-decode(signature.value)) — a 32-byte message imprint over the signature bytes.TimeStampReq containing that imprint to the configured TSA.(imprint, current TSA time) with its own key and returns a TimeStampResp.MANIFEST-YYYY-MM-DD.tsr next to the manifest (binary DER).This follows the standard PAdES / CAdES encrypted-data timestamp pattern. The imprint is over the signature bytes (not the manifest content), so the TSR can be reproduced from the manifest's on-disk form alone — no re-canonicalisation needed at verify time.
Without a TSR, an attacker who roots the device could:
With a TSR, that attack fails — the TSA's signature is over the original manifest signature bytes at the time it was issued. Any subsequent re-signing produces different signature bytes, so the imprint won't match. The auditor sees the discrepancy on verification.
The default audit.conf ships with FreeTSA (http://freetsa.org/tsr) — a free, public RFC 3161 service that does not require an account. The FreeTSA root CA is pinned in the deb at /usr/share/awesome-o-audit/tsa-roots/freetsa.crt.
To use a different TSA (e.g. a commercial one from DigiCert, Sectigo, or GlobalSign, or a self-hosted one):
/usr/share/awesome-o-audit/tsa-roots/yourtsa.crt (PEM format)./etc/awesome-o/audit.conf [timestamp]:
urls to your TSA's endpoint (comma-separated for fallback).roots to your PEM bundle path.sudo systemctl restart do-audit-manifest.timer do-audit-tsr-retry.timer.Removing the [timestamp] section entirely disables the feature cleanly — manifests still ship signed by the Ed25519 key alone, and verification still succeeds for manifests that have no .tsr sibling.
If the TSA is unreachable when a manifest is signed, the manifest still ships on time. do-audit-tsr-retry.timer fires hourly and walks the manifests directory for any MANIFEST-*.json without a matching .tsr, attempting to backfill them. Capped per run via [timestamp] retry_max_per_run (default 30) so the device doesn't pound a recovering TSA.
defend-audit verify automatically validates a sibling .tsr when present. The Ed25519 signature is verified first; then the TSR is checked against the pinned TSA roots and its message imprint compared to the manifest's signature. The TSA's reported time is also compared to the manifest's generated_utc and must fall within [timestamp] verify_tolerance_seconds (default 1 hour).
defend-audit verify manifests/MANIFEST-2026-04-15.json
What success looks like for a v2 manifest with a TSR:
signature OK (ed25519:abc1234...)
files: 142 listed, 0 mismatched, 0 missing
tsr OK (TSA=CN=www.freetsa.org,OU=Root CA,O=Free TSA at 2026-04-16T00:10:43Z)
Skip the TSR check with --skip-tsr if you're verifying an older v2 manifest that didn't get a TSR (or if you don't have the TSA root cert handy).
The Audit Evidence dashboard's integrity row shows:
| Metric | What it tells you |
|---|---|
do_audit_selfcheck_tsr_ok |
Manifests whose .tsr sibling verified at the last self-check |
do_audit_selfcheck_tsr_bad |
TSRs that failed verification — should be 0; non-zero = tamper OR stale TSA root |
do_audit_selfcheck_tsr_missing |
Manifests without a .tsr sibling (TSA was unreachable; backfill in progress) |
| TSR coverage | 100 * tsr_ok / signatures_ok — climbs toward 100% as backfill catches up |
The Defend-O-Tron ships a pre-built Grafana dashboard that summarizes the audit evidence in real time. It's titled Audit Evidence (folder audit in Grafana) and reads from a read-only snapshot of the audit event store — so your auditor can sit beside you and watch the same numbers go in.
Where to find it:

What you'll see, top to bottom:
When an auditor asks for evidence covering a period — say last quarter — you produce a single signed ZIP with the defend-audit report command from the admin terminal.
The admin terminal is built into the Cockpit interface — open the admin web UI, click Tools → Terminal, then enter the command below. You do not need to SSH separately.
sudo defend-audit report --from 2026-04-01 --to 2026-06-30 --out /home/admin/q2-evidence.zip
--from and --to are inclusive UTC dates in YYYY-MM-DD format.--out is the destination path. If you omit it, the ZIP is written next to where you ran the command and named defend-o-tron-audit-FROM-to-TO.zip.Useful flags:
--no-pdf — skip the rendered PDF of the NIS2 dashboard. Use this if grafana-image-renderer isn't deployed on your fleet (it's optional).--no-config-snapshot — skip the configuration archive. Useful if your auditor only needs the events.--json — emit a stable JSON envelope on stdout instead of human-readable text, for use by other tooling.| File | What it is |
|---|---|
events.csv |
Every IDS event in the period |
decisions.csv |
Every CrowdSec decision in the period |
dns_events.csv / file_events.csv / tls_events.csv |
Ransomware indicators (DGA, transferred-file hashes, suspicious TLS) |
config-snapshot.tar.gz |
The device's Suricata, CrowdSec, nftables, ulogd, chrony, and node-exporter configuration as it was at report time |
manifests/MANIFEST-YYYY-MM-DD.json |
The daily signed manifest for every day in the period (the chain-of-custody anchor) |
chrony-logs/ |
NTP attestation — proof the device clock was disciplined |
report.pdf (optional) |
Rendered snapshot of the NIS2 dashboard |
manifest.pubring.json |
The device's signing-key ring, so the auditor can verify everything offline |
chain-of-custody.json |
Ed25519-signed SHA-256 manifest of every other file in the ZIP |
The ZIP itself is written with mode 0640, root-owned. It's safe to copy to a USB drive, attach to a ticket, or upload to your compliance portal.
Anyone with the ZIP can verify it — your auditor doesn't need access to the device. The signing-key ring travels inside the ZIP, so verification works completely offline.
The verification tool is a self-contained static Linux binary (defend-audit) shipped inside the deb — no Python, no cryptography library, no other runtime dependencies. Auditors can copy it onto any modern Linux system and run it directly.
From an extracted ZIP, run:
defend-audit verify manifests/MANIFEST-2026-04-15.json --pubring manifest.pubring.json
What success looks like:
signature OK (ed25519:abc1234...)
files: 142 listed, 0 mismatched, 0 missing
What a tampered manifest looks like:
defend-audit verify: BAD signature (key ed25519:abc1234...)
What a tampered log file looks like:
signature OK (ed25519:abc1234...)
MISMATCH /var/log/suricata/eve-ids-2026-04-15.json
files: 142 listed, 1 mismatched, 0 missing
Useful flags:
--skip-files — verify the signature only, skip the per-file re-hashing. Faster for spot checks.--pubring /path/to/manifest.pubring.json — verify against the pubring shipped inside this ZIP instead of the one on a live device. Auditors should always use this option when working from an evidence pack on a separate system.--json — machine-readable envelope output for automated verification pipelines.Manifests written by audit-deb 1.x (Python era, manifest schema version 1) and 2.x (Go era, manifest schema version 2 with
chain_tips) both verify with the 2.xdefend-audit verifybinary. The verifier dispatches on the manifest'sversionfield; older evidence stays verifiable forever.
The signing-key ring keeps every key the device has ever used, each marked with valid_from and retired_at timestamps. Verifying any manifest looks up the key that was active when it was signed — not the key active today. So manifests signed before a compromise can still be proven authentic after the compromise, as long as you have a copy of the pubring from before the incident (which you do, in every evidence pack you've ever produced).
The audit signing key can be rotated at any time. Reasons you might rotate:
sudo defend-audit key-rotate
What you'll see:
rotated: retired ed25519:Y8nM3R9..., active is now ed25519:A4kP7w2... (at 2026-05-15T18:00:00Z)
What happens behind the scenes:
retired_at timestamp in the pubring.valid_from = now and retired_at = null./boot/defend-o-tron-auditor.key.bak).Key rotation does not invalidate past evidence. Every retired key stays in the pubring forever. Old manifests remain verifiable — they reference the key they were signed with, and that key entry never disappears.
The next daily manifest (and every one after) is signed with the new key. The pubring travels inside every evidence pack, so auditors verifying a multi-year period transparently see all the rotations in sequence.
The audit subsystem keeps 365 days of detailed events by default. The daily signed manifests, signing keys, and the underlying event store all live under a single directory:
/opt/data/auditor/
├── keys/
│ ├── manifest.key ← current private signing key (0400 root)
│ └── manifest.pubring.json ← public ring of every key ever used
├── manifests/
│ └── MANIFEST-YYYY-MM-DD.json ← daily signed manifest, one per day
├── events.sqlite ← live event store (WAL mode, with per-row hash chain)
└── share/
└── events.sqlite ← read-only snapshot for Grafana
A redundant copy of the signing private key lives at /boot/defend-o-tron-auditor.key.bak so an NVMe replacement does not lose the device's identity.
For a full backup of the audit history, copy /opt/data/auditor/ and its contents. Everything you need to produce or verify evidence packs lives under that one tree.
The audit state lives on the data partition (
/opt/data), separate from the OS image. Firmware updates do not affect audit history.
All operational values — retention windows, log glob patterns, LAPI URL, Grafana URL, ransomware-indicator filtering knobs, self-check options — live in a single dpkg-managed conffile:
/etc/awesome-o/audit.conf
Operator edits to this file survive package upgrades (it is a Debian conffile, so dpkg prompts before overwriting). The shipped defaults are sensible for a typical deployment; review and adjust for your environment.
grafana-image-renderer. If your deployment doesn't include it, use defend-audit report --no-pdf.