Files
diskless-workstation/serving/siem
2026-06-27 08:52:17 +00:00
..
2026-06-27 08:52:17 +00:00
2026-06-27 08:52:17 +00:00
2026-06-27 08:52:17 +00:00
2026-06-27 08:52:17 +00:00
2026-06-27 08:52:17 +00:00

Wazuh SIEM — fleet integration

The fleet's auditd stream is analysed by Wazuh running on its own node: wazuh1.bitasylum.org (deployed + managed independently — keeping the memory-hungry indexer off the serving host, which runs SPDK = the fleet's root disk / a SPOF; see TODO #6/#7). This directory is the fleet ↔ Wazuh integration, not a deployment of Wazuh.

Ingestion is agentless (no agent in the diskless image — that would carry per-host registration state, breaking invariant #1). The host side is unchanged; the serving-host collector relays a copy to the SIEM node:

host:  auditd → audisp-syslog (LOCAL6) → rsyslog omfwd ─┐
                                                         ▼  TCP/514
serving host:  audit-collector (rsyslog) ──relay(omfwd)──► wazuh1.bitasylum.org
                  │ still writes durable per-host files        (manager :514 syslog
                  └ disk-assisted queue (store-and-forward)     → indexer → dashboard)

The collector keeps its durable file copy + disk queue and relays a copy, so a SIEM outage never drops audit records or blocks the file writes.

To turn it on (two ends)

1. On the SIEM node (wazuh1): add the syslog reception block — insert config/fleet-remote-syslog.xml into the manager's ossec.conf, set <allowed-ips> to the serving host's IP, and make sure the manager's TCP syslog port is reachable (the upstream single-node compose + docker-compose.override.yml publish 514/tcp). Restart the manager.

2. On the serving host: the relay is already wired in ../audit-collector/rsyslog.conf, targeting wazuh1.bitasylum.org:514. Apply it by rebuilding the collector image (the conf is COPY'd in at build):

cd serving && docker compose build audit && docker compose up -d audit
# the serving host must RESOLVE + ROUTE to wazuh1.bitasylum.org

Decode the fleet's auditd (custom decoder + rules)

The fleet ships auditd agentlessly via audisp-syslog, and STIG sets name_format = hostname (keep it — compliance), which prepends node=<host> to each record. Wazuh's built-in auditd decoder expects the line to start with type=, so it decodes nothing ("decoder":{}) — rule.groups: audit stays empty. Install the fleet decoder + rules on the master so the records decode + alert.

Declarative (recommended) — bind-mount via compose, using the image's /wazuh-config-mount mechanism (entrypoint copies the tree into /var/ossec at startup; correct ownership, survives --force-recreate, no docker cp). Add to the wazuh.master service (see docker-compose.override.yml) — put the files next to your compose / wazuh_manager.conf:

    volumes:
      - ./config/local_decoder.xml:/wazuh-config-mount/etc/decoders/local_decoder.xml
      - ./config/local_rules.xml:/wazuh-config-mount/etc/rules/local_rules.xml
docker compose up -d --force-recreate wazuh.master
docker exec <master> grep -iE 'error|rules|decoder' /var/ossec/logs/ossec.log | tail   # no errors
# verify decoding interactively — paste a full_log line (the `Jun 27 ... node=...`):
docker exec -it <master> /var/ossec/bin/wazuh-logtest

In a cluster, mount on the master only — Wazuh syncs etc/decoders + etc/rules to the workers. A config change needs a recreate/restart (the copy is at startup).

Quick one-off test without editing compose (lost on recreate): docker cp config/local_decoder.xml <master>:/var/ossec/etc/decoders/ && docker cp config/local_rules.xml <master>:/var/ossec/etc/rules/ && docker exec <master> /var/ossec/bin/wazuh-control restart wazuh-logtest should show decoder 'fleet-auditd' and audit.type extracted, firing rule 100100 (+ a higher rule for auth/SELinux types). Then in the dashboard: rule.groups: fleet_audit populates. (The base rule is level 0 — captured but not alerted — so the high-volume SYSCALL/PATH stream doesn't flood alerts; only security-relevant types alert. Tune config/local_rules.xml.)

Full audit trail (not just alerts): to make every record searchable (forensics / ISM retention), enable archive indexing — <logall_json>yes</logall_json> on the manager and archives.enabled: true in the manager's /etc/filebeat/filebeat.yml, then add the wazuh-archives-* index pattern in the dashboard. High-volume — slim the auditd rules on the host or filter before indexing.

Verify

# on the SIEM node, after a diskless host has booted + generated auditd events:
docker compose logs wazuh.manager | grep -i syslog     # listener up, source accepted
# Wazuh dashboard → Security events: auditd records from the boot-LAN hosts appear,
# decoded (type=SYSCALL/USER_LOGIN/...) and rule-tagged.

If nothing arrives: the manager logs rejected sources — confirm <allowed-ips> matches the serving host's IP as wazuh1 sees it (may be its management IP, not SERVER_IP), then tighten to a /32.

⚠ Protect the hop — it's now on the wire

Co-located it was loopback; serving-host → wazuh1 now crosses the network, and audit records are sensitive (ISM: protect logs in transit). The relay ships plaintext 514 for first bring-up — only acceptable on a trusted private path. Before relying on it, switch to syslog-over-TLS (gtls, port 6514, the manager's cert + the fleet CA) on both the relay (omfwd with the TLS driver) and the manager <remote> block. Same CA work as the secure-path / audit-offload TLS TODO.

Production checklist

  • TLS the relay → wazuh1 hop (above).
  • Rotate all Wazuh credentials on the node (indexer admin, API, dashboard).
  • Restrict the dashboard/API (:443/:55000) to admin hosts / VPN — never the boot LAN.
  • allowed-ips → /32 of the serving host.
  • Retention/archival: indexer ISM for the ISM-mandated retention + cold archive.
  • SSP: update the "Detect" section + ISM event-logging controls once bench-verified, and record the retention design.

Files here

File Where it's used
config/fleet-remote-syslog.xml the <remote> block to add to the manager on wazuh1
docker-compose.override.yml reference overlay if wazuh1 uses the upstream single-node compose
.env.example reference env for deploying the wazuh1 node

(The actual fleet-side relay lives in ../audit-collector/rsyslog.conf.)