Add parsedmarc DMARC report analyzer on control

Deliver cnx.email DMARC aggregate/forensic reports to a dedicated dmarc@cnx.email
mailbox on mx1 and analyze them with parsedmarc on control, storing parsed
reports in a local loopback Elasticsearch and visualizing via the auto-provisioned
Grafana dashboard. parsedmarc fetches the mailbox over IMAPS across the mesh
(mx1.cnx.email pinned to its mesh address so TLS still validates), using a shared
mail-dmarc-cred clan var so mx1's mailserver and control see the same password.
This commit is contained in:
Berwn
2026-06-21 03:27:23 +07:00
parent b8bea27a9c
commit 60db8c60b0
6 changed files with 131 additions and 8 deletions
+21
View File
@@ -52,6 +52,27 @@ there is picked up):
- **CNX Uptime** (`uptime.json`) — per-host up/down status, current uptime,
availability over the selected window, and up/down history. Label-driven, so
every scraped host appears automatically.
- **parsedmarc** — DMARC aggregate/forensic report viewer. Auto-provisioned by
the `parsedmarc` module (not from `dashboards/`); reads its own Elasticsearch
datasource, not VictoriaMetrics. See [DMARC reports](#dmarc-reports) below.
## DMARC reports
The `cnx.email` DMARC record (`rua`/`ruf`) points at the `dmarc@cnx.email`
mailbox on `mx1`. **parsedmarc** on `control` (`modules/monitoring/parsedmarc.nix`)
polls that mailbox over IMAPS, parses the XML reports, and stores them in a local
**Elasticsearch** (`127.0.0.1:9200`, loopback-only); Grafana renders them via the
auto-provisioned parsedmarc dashboard + Elasticsearch datasource.
The IMAP fetch rides the **mesh**, not the public net: `control` pins
`mx1.cnx.email` to mx1's mesh address in `/etc/hosts`, so TLS still validates
against the public cert while the bytes stay on the overlay. The mailbox
passphrase is the shared `mail-dmarc-cred` clan var (so both mx1's mailserver and
control's parsedmarc see the same value):
```
clan vars get mx1 mail-dmarc-cred/passphrase
```
## Logs