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

  1. 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)
  2. Graylog identity enrichment (stack/graylog/bootstrap-graylog.sh): a lookup table backed by the registrar plus a pipeline rule stamp host, role, site onto 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.
  3. 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 a wazuh-alerts stream 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.
  4. 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 at https://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-alerts around 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.

This site uses Just the Docs, a documentation theme for Jekyll.