# 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 │ /audit.log │ └───────────────────────────┘ │ /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//` (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: ```bash 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): ```bash 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: ```rsyslog *.* 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.