"In Entwicklung" und Funktionsübersicht listeten PROJ-43/PROJ-52 noch als Planned, obwohl seit 2026-07-04 deployt. Config-Referenz fehlten mehrere produktiv genutzte Sektionen (server.fqdn, api.trusted_proxies/secure_cookies, smtp_out, smtp.tenant_routing, storage.retention_days/min_retention_days/ compress, ocr.paused_hours, imap_scheduler, reconciliation, imap_server, metrics) — jetzt vollständig dokumentiert.
939 lines
32 KiB
Markdown
939 lines
32 KiB
Markdown
# 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](#funktionsübersicht)
|
||
- [Architektur](#architektur)
|
||
- [Voraussetzungen](#voraussetzungen)
|
||
- [Installation](#installation)
|
||
- [Update](#update)
|
||
- [Konfiguration](#konfiguration)
|
||
- [Systemd-Dienste](#systemd-dienste)
|
||
- [Funktionen im Detail](#funktionen-im-detail)
|
||
- [Authentifizierung & Rollen](#authentifizierung--rollen)
|
||
- [Multi-Tenancy (Mandanten)](#multi-tenancy-mandanten)
|
||
- [SMTP-Eingang (BCC-Journaling)](#smtp-eingang-bcc-journaling)
|
||
- [IMAP-Import & Auto-Sync](#imap-import--auto-sync)
|
||
- [POP3-Import](#pop3-import)
|
||
- [EML/MBOX Web-Upload & CLI-Import](#emlmbox-web-upload--cli-import)
|
||
- [Mailpiler Migration](#mailpiler-migration)
|
||
- [Speicherung & Verschlüsselung](#speicherung--verschlüsselung)
|
||
- [Volltext-Suche & OCR](#volltext-suche--ocr)
|
||
- [E-Mail-Ansicht](#e-mail-ansicht)
|
||
- [E-Mail-Export](#e-mail-export)
|
||
- [eDiscovery Export](#ediscovery-export)
|
||
- [DSGVO-Löschersuchen](#dsgvo-löschersuchen)
|
||
- [Retention-Policy & GoBD-Compliance](#retention-policy--gobd-compliance)
|
||
- [Admin-Dashboard](#admin-dashboard)
|
||
- [Audit-Log](#audit-log)
|
||
- [Integritätsprüfung](#integritätsprüfung)
|
||
- [LDAP / Active Directory](#ldap--active-directory)
|
||
- [TOTP Zwei-Faktor-Authentifizierung](#totp-zwei-faktor-authentifizierung)
|
||
- [IMAP-Server-Schnittstelle (Read-Only)](#imap-server-schnittstelle-read-only)
|
||
- [Prometheus Metriken](#prometheus-metriken)
|
||
- [Tenant-Voll-Export CLI](#tenant-voll-export-cli)
|
||
- [REST API](#rest-api)
|
||
- [In Entwicklung](#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.sh` aus 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-Frontend
|
||
- `2525` – SMTP-Eingang (BCC-Journaling)
|
||
|
||
---
|
||
|
||
## Installation
|
||
|
||
### Erstinstallation (empfohlen)
|
||
|
||
```bash
|
||
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
|
||
|
||
```bash
|
||
# 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
|
||
|
||
```bash
|
||
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
|
||
|
||
```bash
|
||
# 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:
|
||
1. Prüft und installiert Go ≥ 1.24 automatisch aus upstream (OS-versionsunabhängig)
|
||
2. Aktualisiert Quellcode aus Gitea
|
||
3. Baut Backend (CGO_ENABLED=0) und Frontend (Next.js standalone)
|
||
4. Stoppt Dienste, spielt Binaries ein
|
||
5. 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
|
||
|
||
```yaml
|
||
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 |
|
||
|
||
```bash
|
||
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:**
|
||
```bash
|
||
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:**
|
||
```bash
|
||
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.
|
||
|
||
```bash
|
||
# 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 status`
|
||
> und 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 |
|
||
|--------|----------|--------------|
|
||
| PDF | `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:**
|
||
1. Anfrage anlegen: E-Mail-Adresse der betroffenen Person + optionaler Zeitraum
|
||
2. System durchsucht alle Mails in To, From, CC, BCC nach der Adresse
|
||
3. Ergebnisübersicht: Anzahl betroffener Mails, Status je Mail (löschbar / gesperrt durch Retention)
|
||
4. PDF-Bericht exportierbar (Audit-Nachweis)
|
||
5. 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_addr` oder `to_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 über `reconciliation.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 `0` ausgewiesen, 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_at` in `emails`-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: `user` sieht 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.
|
||
|
||
```bash
|
||
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 |
|