Post-setup steps
The deploy script generates a personalized POST-SETUP.md (with your real IPs and domain filled in). This page is the same checklist with fuller explanations.
1. DNS and TLS
Every web UI is served by one Caddy wildcard site, *.<domain>, on the metrics VM, so *.<domain> must resolve to that VM from your clients.
DNS records
All names point at the metrics VM — including graylog and wazuh, which Caddy proxies to the other VMs. Create either the wildcard or the individual records:
| Type | Name | Value |
|---|---|---|
| A | *.<domain> | metrics VM IP |
or individually: grafana, prometheus, alertmanager, kuma, nodered, netdata, librenms, ntopng, graylog, wazuh — each an A record <name>.<domain> → metrics VM IP. Nothing is port-forwarded or exposed beyond the LAN, and no record is needed for the logs/SIEM VMs themselves (optional logs/siem A records are purely for convenience).
Where: in cloudflare mode, in the Cloudflare zone as DNS-only (grey cloud) records — the deploy creates the wildcard for you if you said yes to CF_CREATE_DNS; do not add _acme-challenge TXT records by hand (Caddy manages them). In internal mode, on your local DNS server. Your generated POST-SETUP.md lists the exact names and IPs.
TLS_MODE=cloudflare (default). Caddy requests a Let’s Encrypt wildcard certificate using ACME DNS-01: it writes the _acme-challenge TXT record through the Cloudflare API (token in /opt/alethurgy/.env, scope Zone:Read + DNS:Edit), so no port has to be open to the Internet and renewals are automatic. If you answered yes to creating the DNS record, the deploy also upserted a DNS-only (grey-cloud) *.<domain> A record → metrics VM IP. Check:
ssh root@<metrics-vm> docker logs caddy 2>&1 | grep -iE 'certificate obtained|error'
curl -sSI https://grafana.<domain> | head -1 # no -k needed
If issuance failed: confirm the token’s zone + permissions, that <domain> is inside a zone on that Cloudflare account, then docker restart caddy. A public A record pointing at a private IP is fine for DNS-01 but does reveal your LAN addressing; prefer local DNS (router/Pi-hole) for the A record if that matters to you.
TLS_MODE=internal. Caddy uses its own private CA. Create the DNS records on your internal resolver and trust the root cert on clients:
ssh root@<metrics-vm> docker exec caddy cat /data/caddy/pki/authorities/local/root.crt > caddy-root.crt
Import caddy-root.crt into your OS/browser trust store (on Linux: /usr/local/share/ca-certificates/ + update-ca-certificates).
2. Per-node agents
The deploy publishes ready-rendered installers at https://alethurgy.<domain>/ (a Caddy file-server on the metrics VM, same wildcard certificate). Each script installs the agents and then self-registers the host with Prometheus through a token-protected endpoint (/register) — a small registrar service writes file_sd target files that Prometheus watches, so no manual prometheus.yml edits and no reload are needed.
Browsing to https://alethurgy.<domain>/ opens the environment portal — links to every deployed service with a description of what each contains, the enrolment commands under an expandable section, the daily reports, the generated post-setup checklist, and project resources. (The former get.<domain> address redirects here.)
Linux (node_exporter + Wazuh agent + rsyslog→Graylog + cAdvisor when Docker is present; idempotent, re-run safe):
curl -fsSL https://alethurgy.<domain>/linux.sh | sudo bash -s -- --role app
Windows (windows_exporter on :9182 + Wazuh agent, firewall rule included), from an elevated PowerShell:
irm https://alethurgy.<domain>/windows.ps1 | iex
The Wazuh agent enrols automatically against the SIEM VM (authd :1515, password-less by default). Registered hosts appear under Prometheus → Status → Targets and in /opt/alethurgy/targets/ on the metrics VM (registered.log is the audit trail; the *.json files are editable if a host must be removed). The registration token lives in /opt/alethurgy/.env (AGENT_REGISTER_TOKEN) — anyone on the LAN who can fetch the script can also register a target, which is the accepted trade-off for a homelab; rotate the token in .env and re-run the deploy if needed.
3. Uptime Kuma
- Create the admin account, then an API key (Settings → API Keys).
- Put the key in
/opt/alethurgy/.env(KUMA_API_KEY=...), uncomment thebasic_authblock in theuptime-kumajob ofstack/prometheus/prometheus.yml.tpl, and re-run the deploy script — Kuma metrics (monitor status, response times, cert expiry) then feed the preloaded “Uptime Kuma” dashboard. - Add monitors for every service URL and DNS checks; build a status page; point notifications at your ntfy topic.
4. Network devices
- SNMP v3: create a user on each device, add devices in LibreNMS. For the Prometheus-side SNMP dashboards, see Configuration — SNMP.
- Syslog: point firewall/router/switch remote syslog at the logs VM, port 514 (UDP or TCP). In Graylog: System → Inputs → Syslog UDP on port 5140 (the container port that host 514 maps to).
- NetFlow/sFlow: configure export to the metrics VM, UDP 2055. netflow2ng converts flows to ZMQ for ntopng — no nProbe license needed. Verify under Interfaces → tcp://netflow2ng:5556 in ntopng.
5. Graylog streams and correlation
Create one stream per source class (firewall, switches, wazuh-alerts) with index sets sized to your disk. In pipeline rules, normalize fields to the same labels Prometheus uses — host, site, role — so an LLM (or you) can pivot between metrics and logs on the same keys.
6. Wazuh hardening
The official wazuh-docker single-node ships default credentials. On the SIEM VM, follow /opt/wazuh-docker/single-node/README.md to rotate admin (indexer/dashboard) and the API user, then restart the stack. Bridge alerts into Graylog by enabling syslog output in the manager’s ossec.conf:
<syslog_output>
<server>LOGS_VM_IP</server>
<port>5140</port>
<format>json</format>
</syslog_output>
7. UPS, notifications, automation, LLM/MCP
Covered on their own pages: Automation and LLM / MCP. Notification channel customization is in Configuration.
8. Record everything in inventory.md
Every host, agent, SNMP user, token, and topic gets a row in inventory.md — references only, never the secret value.