Files
diskless-workstation/serving/audit-collector/README.md
T
2026-06-18 12:03:45 +00:00

3.8 KiB

Audit / log collector (receive side)

An rsyslog container that receives logs forwarded by booted diskless hosts and writes them to durable, per-source-host files. Diskless hosts run on an immutable erofs root with a RAM-only volatile overlay, so their local /var/log/audit/audit.log is lost on every reboot — this gives auditd somewhere permanent to offload to. It implements the remote-audit-offload that STIG deviation #6 (docs/stig-deviations.md) lists as future hardening.

booted host                              serving host
┌───────────────────────────┐           ┌──────────────────────────────┐
│ auditd → audisp-syslog     │  TCP/514  │ audit (this container)        │
│      → rsyslog (forward)   ├──────────►│ rsyslogd → /var/log/remote/   │
│         to ${AUDIT_HOST}   │  syslog   │   <sender-ip>/audit.log       │
└───────────────────────────┘           │   <sender-ip>/messages.log    │
                                         └──────────────────────────────┘

What this provides (the receiver)

  • Listens on TCP/514 (plain syslog). Disk-assisted queue so bursts / brief stalls don't drop records.
  • Writes per sender IP (not the claimed hostname): audit records → audit.log, everything else → messages.log, under ./logs/<ip>/ (bind-mounted, inspectable on the host).
  • Host-networked, so hosts reach it at ${AUDIT_HOST} (resolved to the serving host by the stack's dnsmasq), matching the boot/NVMe DNS pattern.

Run it with the rest of the stack:

cd serving
docker compose build audit
docker compose up -d audit
docker compose logs -f audit          # startup + connection messages
tail -F audit-collector/logs/*/audit.log

Quick self-test (send a line as if from a host):

logger -n 127.0.0.1 -P 514 -T -t audispd "test audit record"
ls audit-collector/logs/                 # a 127.0.0.1/ dir appears

What's still needed (the sender — in the image)

This container only receives. To make hosts actually send, the hardened image needs (not yet wired — keep no per-host state, use the generic ${AUDIT_HOST} name, never a per-host address):

  1. auditd → syslog: enable the audisp-syslog plugin (/etc/audit/plugins.d/syslog.conf: active = yes), so audit events also go to the local syslog socket.

  2. rsyslog forward rule: a drop-in (e.g. /etc/rsyslog.d/60-fleet-remote.conf) forwarding to the collector with a disk-assisted action queue, so a network blip doesn't drop records:

    *.* action(type="omfwd" target="audit.fleet.lab" port="514" protocol="tcp"
               queue.type="LinkedList" queue.fileName="fwdq"
               queue.maxDiskSpace="256m" queue.saveOnShutdown="on"
               action.resumeRetryCount="-1")
    
  3. Bake audit.fleet.lab (the generic name) — DNS resolves it per environment.

Once the sender is wired, flip STIG deviation #6 in docs/stig-deviations.md from "local-only" to "offloading to ${AUDIT_HOST}" and the rsyslog_remote_loghost rule should pass.

Production hardening (lab simplifications to revisit)

The lab stack is plaintext TCP, mirroring the HTTP-boot/no-TLS posture. For a secured fleet:

  • TLS: rsyslog gtls driver (mutual auth with the boot-infra CA), or RELP + TLS (imrelp/omrelp) for guaranteed, acknowledged delivery.
  • Restrict senders by subnet ($AllowedSender) or firewall :514 to the boot LAN.
  • Add log rotation/retention (logrotate sidecar or rsyslog outchannel) and ship to long-term storage / SIEM.