Correlating user and machine activity with events
Correlation in this stack is not a separate engine — it is a shared identity model applied everywhere, plus a small amount of glue that joins what each tool already collects.
What each source already knows (built in)
| Source | Native activity data | Identity it carries |
|---|---|---|
| Wazuh | logins/logoffs, sudo/su, failed auth, FIM, process & package inventory (syscollector), MITRE-mapped rules | agent name (= host), username, source IP of the auth attempt |
| Graylog | firewall/router/switch syslog, any forwarded system log | source IP (gl2_remote_ip), whatever the message contains |
| ntopng | per-host flows, nDPI L7 application classification (which apps a machine talks to) | IP/MAC (live; community edition keeps no 24 h history) |
| Prometheus | resource usage per host, exporter metrics | host/site/role labels |
| Loki | app/system logs on the monitoring VMs | host label |
The join key across all of them is the host / site / role label set — and, for sources that only know an IP, the mapping IP → host.
The glue this repo adds
- One inventory, produced as a side effect of enrolment. Every endpoint that runs the
alethurgy.<domain>installer registers host/IP/role with the registrar. That inventory is served back out:GET /lookup/<ip>— single-host lookup (used by Graylog)GET /hosts.json,/hosts.csv— full map (used by reporting)
- Graylog identity enrichment (
stack/graylog/bootstrap-graylog.sh): a lookup table backed by the registrar plus a pipeline rule stamphost,role,siteonto every incoming message based on its source IP. From then on, “all events for host X” is a field query, and Graylog fields line up with Prometheus/Loki labels — the convention that makes cross-tool correlation work. - Wazuh → Graylog bridge (
stack/wazuh/configure-bridge.sh): the manager forwards alerts (JSON over syslog, level ≥ 3) to Graylog’s 5140 input, where they land in awazuh-alertsstream and get the same enrichment. User activity (who logged in where, failed auth bursts) and network events (from the same machine’s IP) are now searchable side by side. - Daily correlation report (
stack/reporter/): every morning a report joins, per host: 24 h resource usage (Prometheus), 24 h log volume (Graylog), 24 h security/auth alerts (wazuh-alerts stream), and current traffic + top L7 applications (ntopng). It also lists unregistered sources — IPs producing logs that no one enrolled, which is both a coverage gap and a basic anomaly signal. Published athttps://alethurgy.<domain>/reports/, summarised to ntfy.
Asking correlation questions
- “What did machine X do yesterday?” — open the daily report row for X; drill down: Graylog
host:X, Wazuh agent X, ntopng host view. - “Who was logged in when the firewall flagged that IP?” — Graylog:
host:<mapped host> AND stream:wazuh-alertsaround the timestamp. - “Which app is eating the WAN?” — ntopng L7 view (live), or the report’s top-talkers section for the morning summary.
- Ad-hoc/LLM: the MCP layer (Grafana, Netdata; see 6. LLM/MCP) can query Prometheus/Loki with the same labels the enrichment writes into Graylog.
Limits (deliberate)
- ntopng community keeps no flow history; the report snapshots it. Real 24 h top-talkers need ntopng Pro/ClickHouse (v2 candidate).
- DNS analytics exist only as L7/DNS protocol counters unless you point device DNS at Pi-hole and forward its logs to Graylog.
- IP→user mapping is only as good as Wazuh auth events on that host; DHCP churn between report runs can misattribute an IP — keep leases long or reservations for monitored machines.