89 lines
4.5 KiB
Plaintext
89 lines
4.5 KiB
Plaintext
# Remote audit / syslog collector for the diskless fleet.
|
|
#
|
|
# Receives logs forwarded by booted diskless hosts and writes them
|
|
# per-source-host. Diskless hosts have an immutable, RAM-only overlay root,
|
|
# so their local audit log dies on reboot — this gives auditd somewhere durable
|
|
# to offload to (STIG remote-audit-offload, deviation #6 in docs/stig-deviations.md).
|
|
#
|
|
# Primary intake is syslog-over-TLS on 6514 (gtls; server cert issued by the
|
|
# fleet step-ca — see issue-cert.sh + README.md). Hosts authenticate the
|
|
# collector via the fleet CA baked in the image (x509/name); the collector does
|
|
# NOT require client certs (authMode "anon"): hosts are fleet-generic (no
|
|
# per-host state, invariant #1) and a baked fleet-wide client key would be
|
|
# shared secret material in the image. Sender access is instead constrained by
|
|
# the isolated boot LAN + the serving-host firewall scoping :6514 to it.
|
|
|
|
global(
|
|
workDirectory="/var/spool/rsyslog"
|
|
# TLS material for the 6514 listener, mounted from ./tls (issue-cert.sh).
|
|
# NOTE: deliberately NOT setting DefaultNetstreamDriver="gtls" here — that
|
|
# would flip every plain `protocol="tcp"` omfwd (the Wazuh relay below) to
|
|
# TLS and break it. TLS is enabled per-listener instead.
|
|
DefaultNetstreamDriverCAFile="/etc/rsyslog-tls/ca.crt"
|
|
DefaultNetstreamDriverCertFile="/etc/rsyslog-tls/server.crt"
|
|
DefaultNetstreamDriverKeyFile="/etc/rsyslog-tls/server.key"
|
|
)
|
|
|
|
# --- intake: syslog-over-TLS (the hardened image's 2f sender targets this) ---
|
|
module(load="imtcp" maxSessions="1000")
|
|
input(type="imtcp" port="6514"
|
|
streamDriver.name="gtls" streamDriver.mode="1" streamDriver.authMode="anon")
|
|
|
|
# --- intake: plain TCP syslog (LEGACY/migration) ---
|
|
# Kept for already-released images that still forward plaintext to :514.
|
|
# Disable (comment out + close the firewall port) once the fleet is on
|
|
# TLS-sending images — production must not accept plaintext audit records.
|
|
input(type="imtcp" port="514" streamDriver.name="ptcp")
|
|
# Some senders only speak UDP; uncomment to also accept it (lossy, no queue).
|
|
#module(load="imudp")
|
|
#input(type="imudp" port="514")
|
|
|
|
# Disk-assisted main queue so a brief disk stall or a burst of records doesn't
|
|
# drop audit events (the records keep flowing to spool, then drain to disk).
|
|
main_queue(
|
|
queue.type="LinkedList"
|
|
queue.filename="mainq"
|
|
queue.maxdiskspace="1g"
|
|
queue.saveOnShutdown="on"
|
|
)
|
|
|
|
# --- relay a COPY of audit records to the Wazuh SIEM (separate node) -----------
|
|
# Forwards audit/local6 records to the Wazuh manager's syslog listener on the
|
|
# dedicated SIEM node (wazuh1.bitasylum.org) for parsing/correlation/alerting,
|
|
# WHILE still writing the durable per-host files below (no `stop`, so records
|
|
# continue to the file actions). Own disk-assisted queue -> a Wazuh outage never
|
|
# blocks the file writes or drops records (resumeRetryCount=-1 spools + drains on
|
|
# reconnect). The serving host must resolve + route to the SIEM node. After
|
|
# editing, rebuild: `docker compose build audit && docker compose up -d audit`.
|
|
#
|
|
# ⚠ PLAINTEXT 514 — only acceptable if serving-host → SIEM-node is a TRUSTED
|
|
# private path. Audit records are sensitive; if this hop crosses any routed/
|
|
# untrusted network, switch to syslog-over-TLS (gtls, port 6514, fleet CA) BEFORE
|
|
# relying on it (ISM: protect logs in transit). See serving/siem/README.md.
|
|
if ($programname == 'audispd')
|
|
or ($programname startswith 'audit')
|
|
or ($syslogfacility-text == 'local6') then {
|
|
action(type="omfwd" target="wazuh1.bitasylum.org" port="514" protocol="tcp"
|
|
action.resumeRetryCount="-1"
|
|
queue.type="LinkedList" queue.filename="wazuhfwdq"
|
|
queue.maxDiskSpace="256m" queue.saveOnShutdown="on")
|
|
}
|
|
|
|
# --- per-source-host files (keyed by SENDER IP, not the claimed hostname) ---
|
|
template(name="HostAudit" type="string" string="/var/log/remote/%FROMHOST-IP%/audit.log")
|
|
template(name="HostMessages" type="string" string="/var/log/remote/%FROMHOST-IP%/messages.log")
|
|
|
|
# Audit records (audisp-syslog tags them 'audispd'/'audit', or forwards on the
|
|
# local6 facility) go to a dedicated per-host audit.log; everything else to
|
|
# messages.log. Files/dirs are created 0640/0750 (audit logs aren't world-read).
|
|
if ($programname == 'audispd')
|
|
or ($programname startswith 'audit')
|
|
or ($syslogfacility-text == 'local6') then {
|
|
action(type="omfile" dynaFile="HostAudit"
|
|
dirCreateMode="0750" fileCreateMode="0640")
|
|
stop
|
|
}
|
|
|
|
action(type="omfile" dynaFile="HostMessages"
|
|
dirCreateMode="0750" fileCreateMode="0640")
|