archivmail-export nutzte noch die alte storage.New(path string)-Signatur statt storage.Config (fehlender Keyfile/Compress hätte Rohbytes statt Klartext-EML exportiert). Toten Self-Assignment-Code in storage.go entfernt. Testdateien (storage, audit, api, userstore, auth) an aktuelle Signaturen angeglichen; auth-Tests liefen bisher gegen einen SQLite-Pfad statt Postgres- DSN und wurden auf das TEST_DATABASE_URL-Schema-Isolationsmuster der übrigen Pakete umgestellt. api_test.go las den Login-Token noch aus dem JSON-Body statt aus dem httpOnly-Cookie (Auth-Contract-Drift). TestParseMissingDate an tatsächliches Verhalten angepasst: der Parser lässt das Datum bewusst als Zero-Value, der time.Now()-Fallback sitzt in der Storage-Schicht — damit bleibt nachvollziehbar ob ein Datum aus der Mail stammt oder vom Archiv gesetzt wurde (GoBD). Verifiziert auf 192.168.1.132: go build/vet/test ./... komplett grün, kein Skip (Postgres + Manticore erreichbar). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019j28kGcaJAhBnrYX34hGdt
archivmail
Ein selbst gehostetes, unternehmenstaugliches Mail-Archiv-System. Empfängt E-Mails über SMTP (BCC-Journaling), IMAP, POP3 oder Datei-Upload, speichert sie verschlüsselt, indexiert sie für Volltextsuche (inkl. OCR) und stellt sie über eine Web-Oberfläche zur Verfügung.
Inhaltsverzeichnis
- Funktionsübersicht
- Architektur
- Voraussetzungen
- Installation
- Update
- Konfiguration
- Systemd-Dienste
- Funktionen im Detail
- Authentifizierung & Rollen
- Multi-Tenancy (Mandanten)
- SMTP-Eingang (BCC-Journaling)
- IMAP-Import & Auto-Sync
- POP3-Import
- EML/MBOX Web-Upload & CLI-Import
- Mailpiler Migration
- Speicherung & Verschlüsselung
- Volltext-Suche & OCR
- E-Mail-Ansicht
- E-Mail-Export
- eDiscovery Export
- DSGVO-Löschersuchen
- Retention-Policy & GoBD-Compliance
- Admin-Dashboard
- Audit-Log
- Integritätsprüfung
- LDAP / Active Directory
- TOTP Zwei-Faktor-Authentifizierung
- IMAP-Server-Schnittstelle (Read-Only)
- Prometheus Metriken
- Tenant-Voll-Export CLI
- REST API
- In Entwicklung
Funktionsübersicht
| Funktion | Status |
|---|---|
| Authentifizierung & Rollen (Admin / Auditor / User) | ✅ Deployed |
| TOTP Zwei-Faktor-Authentifizierung (2FA) | ✅ Deployed |
| Multi-Tenancy (Mandantenfähigkeit) | ✅ Deployed |
| LDAP / Active Directory Anbindung (global + pro Mandant) | ✅ Deployed |
| SMTP-Eingang via BCC-Journaling | ✅ Deployed |
| IMAP-Import manuell & automatischer Sync | ✅ Deployed |
| POP3-Import | ✅ Deployed |
| EML/MBOX Web-Upload & CLI-Import | ✅ Deployed |
| Mailpiler → archivmail Migration | ✅ Deployed |
| AES-256-GCM verschlüsselte Speicherung | ✅ Deployed |
| gzip-Kompression der Speicherobjekte | ✅ Deployed |
| Attachment-Deduplication (Hash-basiert) | ✅ Deployed |
| Message-ID-basierte Duplikatserkennung | ✅ Deployed |
| Manticore Search Volltext-Indexierung | ✅ Deployed |
| Volltext-Suche mit Filtern, Sortierung & Hervorhebung | ✅ Deployed |
| OCR & Anhang-Volltext-Indexierung (Tesseract + pdftotext) | ✅ Deployed |
| E-Mail-Threading (In-Reply-To / References) | ✅ Deployed |
| E-Mail-Ansicht mit HTML-Sandbox | ✅ Deployed |
| E-Mail-Export als EML / PDF / ZIP | ✅ Deployed |
| eDiscovery Export (ZIP + Metadaten-CSV) | ✅ Deployed |
| DSGVO-Löschersuchen (Adress-basiert, GoBD-konform) | ✅ Deployed |
| Retention-Policy (Löschsperre, Aufbewahrungsfristen nach Dokumentenart) | ✅ Deployed |
| SHA-256 Integritätsprüfung | ✅ Deployed |
| Audit-Log (unveränderbar, dual-write PostgreSQL + Flat-File) | ✅ Deployed |
| Admin-Dashboard (CPU, RAM, Disk, Archiv-Stats, Zeitreihe) | ✅ Deployed |
| Verschlüsselungsstatus-Healthcheck (PROJ-49) | ✅ Deployed |
| Gespeicherte Suchanfragen | ✅ Deployed |
| IMAP-Server-Schnittstelle (Read-Only Archivzugriff) | ✅ Deployed |
| Prometheus Metriken & Health-Check | ✅ Deployed |
| Tenant-Quotas & Usage-Limits | ✅ Deployed |
| Tenant-Voll-Export per CLI | ✅ Deployed |
| Self-Service Onboarding (Sign-up, Passwort-Reset) | ✅ Deployed |
| REST API für externe CRM-Anbindung | ✅ Deployed |
CLI: archivmail import / export / reindex |
✅ Deployed |
| Automatische Archivierungsregeln (SMTP/IMAP-Routing nach Domain/Absender) | ✅ Deployed |
| Vollständigkeits-Reconciliation (Zähl-Report Mailserver vs. Archiv) | ✅ Deployed |
Architektur
┌─────────────────────────────────────┐
│ archivmail (Go-Binary) │
│ │
Postfix BCC ──┤── SMTP-Daemon (Port 2525) │
IMAP-Server ──┤── IMAP-Importer + Scheduler │──► PostgreSQL
POP3-Server ──┤── POP3-Importer │ (Metadaten, Benutzer,
Web-Upload ──┤── HTTP API (Port 8080) │ Audit-Log, Tenants)
│ │ │
│ ▼ │──► /var/archivmail/store
│ Async Index Worker │ (AES-256-GCM, gzip)
│ OCR-Batch-Cron │
│ │ │──► Manticore Search (9306)
│ ▼ │ (Volltext-Index, OCR)
│ Manticore Index │
└─────────────────────────────────────┘
▲
│ /api/*
┌─────────────────────────────────────┐
│ Next.js Frontend (Port 3000) │
│ / /search /mail/[id] /admin │
│ /imap /profile │
└─────────────────────────────────────┘
Komponenten:
| Komponente | Technologie | Beschreibung |
|---|---|---|
| Backend | Go 1.24 (CGO_ENABLED=0) | REST API, SMTP-Daemon, IMAP/POP3-Importer, Storage, Indexierung |
| Frontend | Next.js 16 (TypeScript) | Web-Oberfläche, Tailwind CSS, shadcn/ui |
| Datenbank | PostgreSQL | Metadaten, Benutzer, Audit-Log, Session-Blacklist, Tenants |
| Volltextsuche | Manticore Search | BM25-Ranking, Wildcards, Feldpräfixe, OCR-Text |
| Speicherung | Dateisystem | AES-256-GCM verschlüsselt + gzip komprimiert, SHA-256 Integrität |
Voraussetzungen
Betriebssystem:
- Debian 13 (trixie) — Mindestanforderung für Neuinstallationen
- Debian 14+ wird durch automatische Go-Installation aus upstream unterstützt
Abhängigkeiten:
- Go ≥ 1.24 (wird automatisch von
install.sh/update.shaus dl.google.com installiert) - Node.js ≥ 20 + npm
- PostgreSQL ≥ 14
- Manticore Search ≥ 6.x (wird automatisch installiert)
- Tesseract OCR + poppler-utils (optional, für OCR-Funktion)
Architektur: amd64 und arm64 werden unterstützt
Ports (Standard):
8080– HTTP API (Backend)3000– Web-Frontend2525– SMTP-Eingang (BCC-Journaling)
Installation
Erstinstallation (empfohlen)
curl -fsSL https://gitea.perlbach24.de/scripte/archivmail/raw/branch/main/install.sh | bash
Das Skript prüft Voraussetzungen (Debian 13), installiert alle Abhängigkeiten (Go, Manticore Search, Node.js, PostgreSQL, Tesseract), richtet Systemd-Dienste ein und gibt am Ende die initialen Zugangsdaten aus.
Manuell
# Quellcode
git clone https://gitea.perlbach24.de/scripte/archivmail.git /opt/archivmail/_build
cd /opt/archivmail/_build
# Backend bauen
CGO_ENABLED=0 go build -buildvcs=false \
-o /opt/archivmail/bin/archivmail ./cmd/archivmail/
# Frontend bauen
npm ci && npm run build
rsync -a --delete .next/standalone/ /opt/archivmail/web/
rsync -a --delete .next/static/ /opt/archivmail/web/.next/static/
Konfigurationsdatei anlegen
mkdir -p /etc/archivmail /var/archivmail/{store,astore} /var/log/archivmail
cat > /etc/archivmail/config.yml << 'EOF'
server:
api_port: 8080
smtp_port: 2525
database:
host: 127.0.0.1
port: 5432
name: archivmail
user: archivmail
password: SICHERES_PASSWORT
sslmode: disable
storage:
store_path: /var/archivmail/store
astore_path: /var/archivmail/astore
keyfile: /etc/archivmail/keyfile
audit:
log_path: /var/log/archivmail/audit.log
retention_days: 0
smtp:
enabled: true
bind: ":2525"
domain: "archivmail.firma.de"
allowed_ips:
- 127.0.0.1
- 192.168.1.0/24
api:
bind: ":8080"
secret: ZUFAELLIGER_JWT_SECRET_MINDESTENS_32_ZEICHEN
index:
backend: manticore
manticore_dsn: "manticore@tcp(127.0.0.1:9306)/"
batch_size: 100
batch_mode: true
ocr:
batch_mode: true
EOF
# AES-256 Schlüssel generieren
dd if=/dev/urandom bs=32 count=1 > /etc/archivmail/keyfile
chmod 600 /etc/archivmail/keyfile
Update
# Auf dem Server als root:
bash /opt/archivmail/update.sh
# Oder direkt von Gitea:
curl -fsSL https://gitea.perlbach24.de/scripte/archivmail/raw/branch/main/update.sh | bash
Das Update-Skript:
- Prüft und installiert Go ≥ 1.24 automatisch aus upstream (OS-versionsunabhängig)
- Aktualisiert Quellcode aus Gitea
- Baut Backend (CGO_ENABLED=0) und Frontend (Next.js standalone)
- Stoppt Dienste, spielt Binaries ein
- Startet Dienste und prüft HTTP-Health (
/api/health)
Hinweis: Ein Reindex ist nur nach Schema-Änderungen am Index nötig:
archivmail reindex --config /etc/archivmail/config.yml
Konfiguration
Vollständige Konfigurationsreferenz
server:
fqdn: "archivmail.firma.de" # verwendet in SMTP-EHLO, IMAP-Greeting, generierten Links
api_port: 8080 # HTTP-API Port
smtp_port: 2525 # SMTP-Eingang Port
database:
host: 127.0.0.1
port: 5432
name: archivmail
user: archivmail
password: ""
sslmode: disable # disable | require | verify-full
storage:
store_path: /var/archivmail/store # Haupt-Mailspeicher (AES-256-GCM)
astore_path: /var/archivmail/astore # Anhang-Speicher
keyfile: /etc/archivmail/keyfile # 32-Byte AES-Schlüsseldatei
retention_days: 0 # globale Löschsperre, 0 = kein Lock (GoBD: z.B. 3650 für 10 Jahre)
min_retention_days: 0 # PROJ-51: erzwungenes Minimum — Regeln/Tenants dürfen nur verlängern
compress: true # gzip vor AES-256-GCM (spart ~40-60% Disk)
smtp:
enabled: true
bind: ":2525"
domain: "archivmail"
tls_cert: "" # Pfad zum TLS-Zertifikat (leer = kein TLS)
tls_key: ""
max_size_mb: 50
allowed_ips:
- 127.0.0.1
tenant_routing: "domain" # "domain" (tenant_domains/PROJ-43-Regeln) oder "default"
default_tenant_id: 0 # genutzt bei routing "default" oder wenn Domain-Lookup fehlschlägt
smtp_out:
host: "" # nur nötig für Self-Service-Mails (Passwort-Reset, Sign-up)
port: 587
user: ""
password: ""
tls: true
from: "archivmail <noreply@firma.de>"
api:
bind: ":8080"
secret: "" # JWT-Signaturschlüssel (mind. 32 Zeichen)
secure_cookies: false # true wenn TLS an diesem Server oder vertrauenswürdigem Proxy terminiert
trusted_proxies: [] # IPs/CIDRs deren X-Forwarded-For vertraut wird (leer = r.RemoteAddr)
index:
backend: manticore
manticore_dsn: "manticore@tcp(127.0.0.1:9306)/"
batch_size: 100
async_queue_size: 0 # 0 = Default
batch_mode: true # Indexierung als Cron-Batch statt Dauerbetrieb
ocr:
batch_mode: true # OCR als Cron-Batch statt Dauerbetrieb (PROJ-58)
paused_hours: [8, 18] # optional (PROJ-56): pausiert Verarbeitung im Zeitfenster (hier 08–18 Uhr)
imap_scheduler:
jitter_seconds: 240 # PROJ-56: Jitter-Fenster für automatischen Sync-Start, 0 = deaktiviert
reconciliation:
alert_threshold_pct: 50 # PROJ-52: Warn-Schwelle (% unter 7-Tage-Schnitt), 0 = jede Abweichung
imap_server:
enabled: false # Read-Only IMAP-Zugriff aufs Archiv (PROJ-26)
bind: ":1143" # plain; für TLS ":993" + tls_cert/tls_key setzen
tls_cert: ""
tls_key: ""
metrics:
enabled: false # Prometheus /metrics-Endpoint (PROJ-40)
token: "" # optionaler Bearer-Token zum Schutz von /metrics
audit:
log_path: /var/log/archivmail/audit.log
retention_days: 0 # 0 = unbegrenzt
logging:
path: "" # leer = stdout
level: info # debug | info | warn | error
Systemd-Dienste
| Dienst | Beschreibung | Port |
|---|---|---|
archivmail |
Go-Backend (API + SMTP + IMAP-Scheduler) | 8080, 2525 |
archivmail-web |
Next.js-Frontend | 3000 |
systemctl status archivmail archivmail-web
journalctl -u archivmail -f
journalctl -u archivmail-web -f
systemctl restart archivmail archivmail-web
Funktionen im Detail
Authentifizierung & Rollen
Globale Rollen:
| Rolle | Rechte |
|---|---|
superadmin |
Vollzugriff inkl. Mandantenverwaltung und globaler LDAP-Konfiguration |
admin |
Benutzer & IMAP verwalten, alle E-Mails suchen/exportieren, Dashboard |
auditor |
Audit-Log lesen, alle E-Mails suchen und exportieren |
user |
Nur eigene E-Mails (Matching auf E-Mail-Adresse) suchen und lesen |
Mandanten-Rollen (Multi-Tenant):
| Rolle | Rechte |
|---|---|
domain_admin |
Admin-Rechte innerhalb eines Mandanten |
domain_auditor |
Auditor-Rechte innerhalb eines Mandanten |
Sicherheit:
- Passwörter mit bcrypt (Cost 12)
- Sessions als httpOnly SameSite=Strict Cookie (
archivmail_session) - JWT mit kryptografischem JTI (16 Byte Entropie)
- Token-Blacklist in PostgreSQL (Logout invalidiert Token sofort)
- Rate-Limiting: max. 5 Fehlversuche in 15 Minuten → HTTP 429
- TOTP 2FA optional pro Benutzer aktivierbar
Erstmalige Einrichtung:
Beim ersten Start werden automatisch zwei Benutzer mit zufälligen Passwörtern angelegt:
╔══════════════════════════════════════════════════════════════╗
║ ARCHIVMAIL — ERSTMALIGE EINRICHTUNG ║
║ Initiale Zugangsdaten (NUR EINMAL ANGEZEIGT): ║
║ admin : <zufälliges Passwort> ║
║ auditor : <zufälliges Passwort> ║
║ Passwörter sofort nach dem ersten Login ändern! ║
╚══════════════════════════════════════════════════════════════╝
Multi-Tenancy (Mandanten)
archivmail unterstützt vollständige Mandantentrennung. Jeder Mandant hat:
- Eigene Benutzer und Rollen (
domain_admin,domain_auditor) - Eigene IMAP/POP3-Verbindungen
- Eigenes Logo (mit XSS-sicherer Validierung)
- Eigene Domain-Zuordnungen
- Eigene LDAP-Konfiguration
- Eigenes Speicher-Quota (optional)
API-Endpunkte:
GET /api/admin/tenants # Alle Mandanten auflisten
POST /api/admin/tenants # Mandant anlegen
GET /api/admin/tenants/{id} # Mandant details
PATCH /api/admin/tenants/{id} # Mandant bearbeiten
DELETE /api/admin/tenants/{id} # Mandant löschen
GET /api/admin/tenants/{id}/users # Benutzer eines Mandanten
GET /api/admin/tenants/{id}/domains # Domains eines Mandanten
POST /api/admin/tenants/{id}/domains # Domain hinzufügen
DELETE /api/admin/tenants/{id}/domains/{d} # Domain entfernen
POST /api/admin/tenants/{id}/logo # Logo hochladen
DELETE /api/admin/tenants/{id}/logo # Logo löschen
SMTP-Eingang (BCC-Journaling)
Der eingebettete SMTP-Daemon empfängt E-Mails von Postfix (oder anderem MTA) über BCC-Weiterleitung.
Absender → Postfix → Empfänger
│
└── always_bcc → archivmail SMTP (Port 2525)
│
▼
Speicherung + Indexierung
Postfix-Konfiguration (/etc/postfix/main.cf):
always_bcc = archiv@archivmail-host
Sicherheit:
- Kein SMTP AUTH — Vertrauen ausschließlich über IP-Allowlist (
smtp.allowed_ips) - 250 OK erst nach erfolgreicher Speicherung (kein Datenverlust)
- 250 OK auch bei Duplikaten (Postfix stellt nicht erneut zu)
- Optionale TLS/STARTTLS-Unterstützung
IMAP-Import & Auto-Sync
E-Mails von IMAP-Postfächern importieren — einmalig (Altbestände) oder automatisch als Hintergrundjob.
Verbindung einrichten (Web-UI unter /imap):
| Feld | Beschreibung |
|---|---|
| Host / Port | IMAP-Server-Adresse |
| TLS | ssl (IMAPS), starttls, none |
| Benutzername / Passwort | IMAP-Zugangsdaten (AES-256-GCM verschlüsselt in DB) |
| Modus | shared (gemeinsames Archiv) oder personal (Nutzer-zugeordnet) |
| Ausgeschlossene Ordner | Kommagetrennte Liste |
Inkrementeller Sync:
- UID-basiert mit UIDVALIDITY-Check: Nur neue Nachrichten seit letztem Sync
- Pro-Ordner UID-Tracking in
imap_folder_state-Tabelle - Exponentielles Backoff bei Fehlern
- Jitter bei gleichzeitigen Sync-Jobs (Last-Entzerrung)
Sync-Modus: shared (alle Mails zentral) oder personal (Mail-Adresse Matching auf Benutzer)
API-Endpunkte:
GET /api/imap # Verbindungen auflisten
POST /api/imap # Neue Verbindung anlegen
DELETE /api/imap/{id} # Verbindung löschen
PATCH /api/imap/{id} # Konto aktualisieren
POST /api/imap/test # Verbindung testen + Ordner auflisten
POST /api/imap/{id}/import # Vollständigen Import starten
GET /api/imap/{id}/progress # Import-Fortschritt abfragen
POST /api/imap/{id}/sync # Manuellen inkrementellen Sync auslösen
POP3-Import
E-Mails von POP3-Servern importieren (einmalig oder manuell ausgelöst).
API-Endpunkte:
GET /api/pop3 # Verbindungen auflisten
POST /api/pop3 # Verbindung anlegen
DELETE /api/pop3/{id} # Verbindung löschen
POST /api/pop3/test # Verbindung testen
POST /api/pop3/{id}/import # Import starten
GET /api/pop3/{id}/progress # Fortschritt abfragen
EML/MBOX Web-Upload & CLI-Import
Web-Upload (Admin-Bereich → Tab „Import"):
.eml— einzelne RFC-2822 E-Mail.mbox— MBOX-Datei mit beliebig vielen E-Mails- Hintergrund-Import mit Fortschrittsanzeige (Polling alle 1,5s)
CLI-Import:
archivmail import --file /pfad/zur/datei.eml
archivmail import --file /pfad/zur/datei.mbox
archivmail import --dir /pfad/zum/verzeichnis --recursive
archivmail import --dir /pfad/ --dry-run # Simulation
archivmail import --dir /pfad/ --json # JSON-Ausgabe
CLI-Export:
archivmail export --out /export/
archivmail export --out /export/archiv.mbox --format mbox
archivmail export --out /export/ \
--from absender@firma.de \
--date-from 2024-01-01 \
--date-to 2024-12-31 \
--query "Rechnung"
Mailpiler Migration
Vollständige Migration eines bestehenden mailpiler-Archivs nach archivmail.
# Auto-Modus (pilerexport → direct als Fallback)
archivmail import-piler --config /etc/archivmail/config.yml
# Direkt aus Store-Verzeichnis (ohne laufendes mailpiler)
archivmail import-piler \
--method direct \
--store-dir /var/piler/store \
--key-file /var/piler/store/piler.key
# Probe-Lauf
archivmail import-piler --dry-run --json
Unterstützt: AES-256-CBC Entschlüsselung, zlib Dekomprimierung, verschiedene mailpiler-Versionen.
Speicherung & Verschlüsselung
Verschlüsselung:
- Algorithmus: AES-256-GCM (authentifizierte Verschlüsselung)
- Schlüssel: 32-Byte-Datei (
keyfile) - Nonce: 12 Byte, kryptografisch zufällig, pro E-Mail neu generiert
Kompression:
- E-Mails werden vor der Verschlüsselung gzip-komprimiert
- Anhänge Hash-basiert dedupliziert (gleicher Inhalt → eine Datei)
Integrität:
- Jede E-Mail erhält als ID den SHA-256-Hash des Klartexts
- Duplikat-Erkennung via Content-Hash und Message-ID
GoBD-Hinweis (PROJ-49): Fehlt die Schlüsseldatei, speichert archivmail E-Mails unverschlüsselt und gibt beim Start eine WARN-Zeile aus.
archivmail statusund das Admin-Dashboard zeigen den Verschlüsselungsstatus (enabled/disabled) an.
Volltext-Suche & OCR
Suchfelder:
- Freitext (Betreff, Body, Absender, Empfänger, CC, BCC, Anhangsnamen, OCR-Text)
- Absender / Empfänger / CC / BCC-Filter
- Zeitraum (
date_from/date_to) - Nur Mails mit Anhängen (
has_attachment) - Sortierung:
date_desc(Standard),date_asc,relevance
Suchsyntax:
Rechnung 2024 # Mehrere Begriffe (AND)
"Angebot Projekt X" # Phrase
Rechn* # Wildcard
@from chef@firma.de # Feldsuche Absender
@subject Urlaubsantrag # Feldsuche Betreff
OCR (Anhang-Volltext-Indexierung):
- PDF, TIFF, PNG, JPEG: automatische OCR mit Tesseract
- PDF: Text-Extraktion via pdftotext (bevorzugt gegenüber OCR)
- OCR-Text wird in Manticore Search indexiert und ist volltext-durchsuchbar
- Status pro Mail:
pending/done/failed/not_applicable - Download des extrahierten OCR-Texts als .txt-Datei
- Läuft als Cron-Batch (konfigurierbar via
ocr.batch_mode)
Gespeicherte Suchanfragen:
GET /api/saved-searches # Liste
POST /api/saved-searches # Speichern
DELETE /api/saved-searches/{id} # Löschen
API:
GET /api/search?q=...&from=...&to=...&date_from=...&date_to=...&has_attachment=true&sort=date_desc&page=1&page_size=25
E-Mail-Ansicht
Vollständige Darstellung unter /mail/[id].
- HTML-Body in
<iframe sandbox="allow-same-origin">— JavaScript blockiert - Externe Inhalte (Tracking-Pixel) standardmäßig blockiert, per Klick freischaltbar
- Fallback auf Plaintext
- Anhänge einzeln herunterladbar
- Originale E-Mail-Header aufklappbar
- Thread-Ansicht (zusammenhängende E-Mails via In-Reply-To / References)
- Download als
.eml, Export als.pdf - OCR-Text-Download wenn verfügbar
- Integrity-Badge: ✅ OK / ⬜ ausstehend / ❌ Fehler
E-Mail-Export
| Format | Endpunkt | Beschreibung |
|---|---|---|
GET /api/export/pdf/{id} |
Einzelne Mail als PDF | |
| EML | GET /api/mails/{id}/raw |
Einzelne Mail als .eml |
| ZIP | POST /api/export/zip |
Mehrere Mails + Anhänge + manifest.csv |
ZIP-Export enthält: .eml pro Mail, manifest.csv mit Metadaten, optionale Anhänge. Max. 500 Mails pro Export. Jeder Export wird im Audit-Log erfasst.
eDiscovery Export
Strukturierter Export für rechtliche Anforderungen.
POST /api/export/ediscovery
{
"ids": ["hash1", "hash2"],
"include_attachments": true,
"include_metadata": true
}
Ausgabe: ZIP mit .eml-Dateien, metadata.csv (alle Felder), optionale Anhänge.
DSGVO-Löschersuchen
Workflow zur Bearbeitung von DSGVO-Auskunfts- und Löschanfragen (Art. 17 DSGVO).
Ablauf:
- Anfrage anlegen: E-Mail-Adresse der betroffenen Person + optionaler Zeitraum
- System durchsucht alle Mails in To, From, CC, BCC nach der Adresse
- Ergebnisübersicht: Anzahl betroffener Mails, Status je Mail (löschbar / gesperrt durch Retention)
- PDF-Bericht exportierbar (Audit-Nachweis)
- Löschbare Mails können auf Knopfdruck entfernt werden (GoBD-Vorrang: Mails mit aktiver Retention-Policy werden nicht gelöscht)
Status: open → partial (Teile gesperrt) / completed (alles gelöscht) / failed
API-Endpunkte:
GET /api/admin/dsgvo # Anfragen auflisten
POST /api/admin/dsgvo # Neue Anfrage erstellen
GET /api/admin/dsgvo/{id} # Anfrage-Details + Ergebnisliste
DELETE /api/admin/dsgvo/{id}/mails # Löschbare Mails entfernen
GET /api/admin/dsgvo/{id}/pdf # PDF-Bericht exportieren
Retention-Policy & GoBD-Compliance
Retention-Policy (PROJ-34):
- Konfigurierbare Mindestaufbewahrungsdauer pro Mandant
retain_until-Feld pro Mail (absolutes Datum)- Mails mit aktiver Retention können nicht gelöscht werden — auch nicht via DSGVO-Löschanfrage
- CLI:
archivmail retention --config /etc/archivmail/config.yml
Retention-Kategorien (PROJ-51): Mails können Dokumentenarten zugeordnet werden mit unterschiedlichen gesetzlichen Aufbewahrungsfristen:
| Kategorie | Frist |
|---|---|
| Handelsbrief | 6 Jahre |
| Buchungsbeleg / Rechnung | 10 Jahre |
| Steuerunterlagen | 10 Jahre |
| Arbeitsvertrag | 5 Jahre nach Ende |
| Personalakte | 10 Jahre |
| Allgemein | Konfigurierbar |
GoBD-Konformität:
- Audit-Log unveränderbar (dual-write: PostgreSQL + Flat-File, HMAC-Chain geplant)
- Verschlüsselter at-rest Speicher mit Integritätsprüfung
- Nutzer-Löschung GoBD-konform: E-Mails bleiben erhalten, Nutzerzuordnung wird anonymisiert
Automatische Archivierungsregeln (PROJ-43)
Erweitert das Domain-basierte SMTP-Routing (tenant_domains) um flexiblere Muster-Regeln:
- Regeln nach
from_domain,to_domain,from_addroderto_addr(inkl. Wildcard*.domain.de) - Höhere Priorität gewinnt bei mehreren Treffern
- SMTP-Daemon und IMAP-Import prüfen Regeln vor der Domain-Zuordnung
- Dry-Run: zeigt, welche bereits archivierten Mails eine Regel treffen würde, bevor sie aktiv geschaltet wird
- Verwaltung im Admin-Bereich (Tab „Routing-Regeln“) — CRUD unter
/api/admin/routing-rules - Bereits archivierte Mails werden nicht rückwirkend umgeroutet, nur neue Ingests
Vollständigkeits-Reconciliation (PROJ-52)
Täglicher Zähl-Report als Nachweis, dass keine Mail auf dem Weg ins Archiv verloren geht (VOI-Grundsatz 2):
- Cron (
archivmail reconcile, nachts) zählt pro Quelle (SMTP-Journal, IMAP-Konto, POP3-Konto, Datei-Import) die täglich archivierten Mails - Warn-Badge + Audit-Eintrag (
reconciliation_anomaly) bei >50 % Abweichung vom 7-Tage-Schnitt (Schwellenwert konfigurierbar überreconciliation.alert_threshold_pct) - Dashboard-Kachel „Vollständigkeits-Check“ mit den letzten 7 Tagen pro Quelle
- CSV-Export für Auditoren (
/api/admin/reconciliation/export.csv) - Tage ohne Aktivität werden explizit als
0ausgewiesen, nicht als fehlender Datensatz — damit ein ausgefallener Cron-Lauf selbst erkennbar bleibt
Admin-Dashboard
Erreichbar unter /admin.
Tabs:
| Tab | Inhalt |
|---|---|
| Dashboard | CPU (1/5/15 min), RAM, Festplatten, SMTP-Status, Archiv-Statistiken, erste/letzte Mail, Mail-Zeitreihe, Speicherprognose |
| Dienste | Systemd-Dienste starten / stoppen / neustarten |
| Benutzer | Benutzer & Rollen verwalten, Passwort zurücksetzen, sperren, löschen |
| Mandanten | Mandanten anlegen, bearbeiten, Quota setzen, LDAP konfigurieren |
| Audit-Log | Alle Ereignisse mit Paginierung und Filtern |
| Import | EML/MBOX-Dateien hochladen mit Fortschrittsanzeige |
| DSGVO | Löschersuchen verwalten, PDF-Berichte exportieren |
| Sicherheit | Sicherheits-Audit: Verschlüsselung, TLS, Konfiguration prüfen |
| Module | Übersicht aller Features mit Deployment-Status |
Audit-Log
Alle sicherheitsrelevanten Ereignisse werden lückenlos protokolliert — parallel in PostgreSQL und einer Flat-File (dual-write).
Erfasste Ereignisse (Auswahl):
| Ereignis | Beschreibung |
|---|---|
login_ok / login_fail |
Login-Versuche (Benutzer, IP) |
logout |
Abmeldung |
search |
Suchanfrage |
export_pdf / export_zip |
E-Mail-Export |
user_create / user_update / user_delete |
Benutzerverwaltung |
imap_import / pop3_import |
Import-Vorgänge |
dsgvo_request_create |
DSGVO-Anfrage erstellt |
dsgvo_mails_deleted |
DSGVO-Mails gelöscht |
tenant_create / tenant_delete |
Mandantenverwaltung |
API:
GET /api/audit?page=1&page_size=25&username=admin&event_type=login_ok
Integritätsprüfung
- Beim Speichern: SHA-256-Hash des Klartexts = Datei-ID
- Beim Prüfen: Datei laden → entschlüsseln → SHA-256 → Vergleich mit ID
- Hintergrundprüfung: beim Start + alle 5 Minuten
- Ergebnisse:
verify_ok,verified_atinemails-Tabelle - Anzeige in der E-Mail-Ansicht: ✅ / ⬜ / ❌
LDAP / Active Directory
Benutzer-Authentifizierung über LDAP/AD statt lokaler Accounts.
Konfiguration:
- Global (Superadmin) oder pro Mandant (Domain-Admin)
- Konfiguration und Test über Web-UI (
/admin→ Mandanten-LDAP) - Unterstützt: LDAP, LDAPS, StartTLS
- Gruppen-Mapping: LDAP-Gruppen → archivmail-Rollen
- Manuelle Synchronisation: LDAP-Benutzer importieren / aktualisieren
API-Endpunkte:
GET /api/admin/ldap # Globale LDAP-Konfiguration
POST /api/admin/ldap # Speichern
DELETE /api/admin/ldap # Löschen
POST /api/admin/ldap/test # Verbindung + Benutzer testen
GET /api/admin/tenants/{id}/ldap # Mandanten-LDAP-Konfiguration
POST /api/admin/tenants/{id}/ldap/sync # LDAP-Sync auslösen
TOTP Zwei-Faktor-Authentifizierung
- Optionale 2FA pro Benutzer (TOTP, RFC 6238)
- Kompatibel mit Google Authenticator, Authy, etc.
- Einrichtung: Profil-Seite → „2FA einrichten" → QR-Code scannen → Code bestätigen
- Deaktivierung nur mit gültigem TOTP-Code möglich
IMAP-Server-Schnittstelle (Read-Only)
archivmail stellt selbst einen IMAP-Server bereit, über den E-Mail-Clients auf das Archiv zugreifen können.
- Read-only — keine Schreiboperationen (kein APPEND, STORE, EXPUNGE)
- Authentifizierung mit archivmail-Zugangsdaten
- Rollenfilter:
usersieht nur eigene Mails
Prometheus Metriken
GET /metrics # Prometheus-Format (Bearer Token erforderlich)
GET /api/health # Health-Check (kein Auth)
Verfügbare Metriken: Anzahl archivierter Mails, Index-Lag, Import-Raten, OCR-Status, HTTP-Latenzen.
Tenant-Voll-Export CLI
Vollständiger Export aller Mails eines Mandanten als EML-Dateien.
archivmail tenant-export \
--config /etc/archivmail/config.yml \
--tenant-id 5 \
--out /export/mandant5/
# Mit Metadaten-CSV
archivmail tenant-export --tenant-id 5 --out /export/ --metadata
# Dry-run (Anzahl ohne Export)
archivmail tenant-export --tenant-id 5 --dry-run
REST API
Alle Endpunkte erfordern eine gültige Session (Cookie archivmail_session oder Authorization: Bearer <token>).
Authentifizierung
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| POST | /api/auth/login |
Login |
| GET | /api/auth/me |
Eingeloggter Benutzer |
| POST | /api/auth/logout |
Session invalidieren |
| POST | /api/auth/totp/setup |
TOTP-Einrichtung starten |
| POST | /api/auth/totp/confirm |
TOTP bestätigen |
| DELETE | /api/auth/totp |
TOTP deaktivieren |
Suche & Mails
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| GET | /api/search |
Volltext-Suche |
| GET | /api/mails/{id} |
E-Mail-Details |
| GET | /api/mails/{id}/raw |
Rohe EML |
| GET | /api/mails/{id}/attachments/{n} |
Anhang herunterladen |
| GET | /api/mails/{id}/thread |
Thread-Ansicht |
Export
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| GET | /api/export/pdf/{id} |
PDF-Export |
| POST | /api/export/zip |
ZIP-Export |
| POST | /api/export/ediscovery |
eDiscovery ZIP |
Admin
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| GET/POST | /api/users |
Benutzer auflisten / anlegen |
| PATCH/DELETE | /api/users/{id} |
Benutzer ändern / löschen |
| GET | /api/audit |
Audit-Log |
| GET | /api/admin/smtp/status |
SMTP-Status |
| GET | /api/admin/storage/stats |
Speicher-Statistiken |
| GET | /api/admin/system/stats |
System-Ressourcen |
| GET | /api/admin/services |
Dienste-Status |
| POST | /api/admin/services/{name}/action |
Dienst steuern |
| POST | /api/admin/upload |
EML/MBOX hochladen |
| GET | /api/admin/upload/{jobID}/progress |
Upload-Fortschritt |
| GET/POST | /api/admin/tenants |
Mandanten |
| GET/POST | /api/admin/dsgvo |
DSGVO-Anfragen |
IMAP / POP3
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| GET/POST | /api/imap |
IMAP-Verbindungen |
| DELETE/PATCH | /api/imap/{id} |
IMAP-Verbindung verwalten |
| POST | /api/imap/{id}/import |
Import starten |
| GET/POST | /api/pop3 |
POP3-Verbindungen |
| POST | /api/pop3/{id}/import |
POP3-Import starten |
In Entwicklung
| Funktion | Beschreibung |
|---|---|
| E-Mail als primärer Login | Tenant-User loggen sich mit E-Mail-Adresse statt Benutzername ein |