Sign inSign up

christophmotal/dmarc-parser

By christophmotal

Updated 4 months ago

Self-hosted DMARC + SMTP-TLS-RPT report viewer. Pulls from IMAP, Microsoft 365 or drop folder.

Image
Security
Monitoring & observability
1

520

christophmotal/dmarc-parser repository overview

DMARC Parser

A self-hosted analyser for DMARC aggregate reports (RFC 7489) and SMTP TLS reports (RFC 8460). Pull reports from one or more mailboxes, parse the XML / JSON payloads, store them in SQLite and inspect the results in a MudBlazor UI — without sending data to a third party.

Features

  • DMARC aggregate reports — XML, gzip, zip; per-record DKIM/SPF alignment, disposition, source-IP rDNS lookup
  • SMTP TLS reports (TLS-RPT) — JSON / gzip per RFC 8460; per-policy success/failure session counts and failure-detail breakdown
  • Three ingestion sources — drop folder, classic IMAP (basic auth), or Microsoft 365 mailbox via Graph API (Azure-AD client-credentials, no IMAP enablement needed)
  • Built-in mailbox self-test for both IMAP and M365 sources (round-trip Create → Search → Fetch → Move → Verify)
  • Manual upload for ad-hoc inspection of single report files
  • Dashboard with KPIs, pass-rate timeline, disposition split and top reporters
  • Reverse-proxy friendly — HTTP only on port 18080, terminate TLS upstream
  • Auto-migration — SQLite schema is applied on first start

Quick start

docker run -d \
  --name dmarc-parser \
  -p 18080:18080 \
  -v "$(pwd)/data:/app/data" \
  --restart unless-stopped \
  christophmotal/dmarc-parser:latest

…or with docker-compose:

services:
  dmarc-parser:
    image: christophmotal/dmarc-parser:latest
    container_name: dmarc-parser
    ports:
      - "18080:18080"
    volumes:
      - ./data:/app/data
    restart: unless-stopped

Open http://localhost:18080/, configure a mail source under Mail Sources, run the self-test, enable polling.

Volume layout

Everything writeable lives under /app/data:

PathPurpose
/app/data/db/SQLite database (dmarc.db) — reports, policies, config
/app/data/drop/Drop folder source: place report files here, get auto-ingested. Sub-folders processed/, error/, unsupported/ are created automatically
/app/data/logs/NLog file targets

The IMAP / M365 secrets in the database are encrypted with the ASP.NET Core Data Protection API, whose keys are persisted in the same SQLite database — back up dmarc.db to back up everything.

Configuration

Defaults work out of the box. To override settings, mount an appsettings.Production.json next to the container's working directory or pass standard ASP.NET Core environment variables:

environment:
  ConnectionStrings__Default: "Data Source=data/db/dmarc.db"
  FolderMailSource__DirectoryPath: "data/drop"
  Logging__LogLevel__Default: "Information"

The polling background service ticks every 60 seconds; per-source poll intervals are configured in the UI (default 60 minutes).

Ports

  • 18080/tcp — HTTP. The image does not terminate TLS — front it with a reverse proxy (Caddy, Traefik, nginx, IIS) for HTTPS.

Image

  • Platform: linux/amd64
  • Base: mcr.microsoft.com/dotnet/aspnet:10.0
  • Runs as: root by default for bind-mount ergonomics. Override with user: "1654:1654" in compose plus chown of the host data directory if you want non-root.

Tags

  • latest — most recent release

Architecture

Layered .NET solution: Core (entities + interfaces) → Application (services, parsers, ingestion) → Infrastructure (EF Core / MailKit / Microsoft Graph) → Web (Blazor Server). SQLite is single-file, no external DB dependency.

License

MIT — Copyright (c) 2026 Christoph Motal. See the LICENSE file in the source repository.

Tag summary

Content type

Image

Digest

sha256:e2991262f

Size

133.4 MB

Last updated

4 months ago

docker pull christophmotal/dmarc-parser