83 lines
3.8 KiB
Markdown
83 lines
3.8 KiB
Markdown
# 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:
|
|
|
|
```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.
|