# 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) | 🔄 Planned | | Vollständigkeits-Reconciliation (Zähl-Report) | 🔄 Planned | --- ## 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: 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 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 api: bind: ":8080" secret: "" # JWT-Signaturschlüssel (mind. 32 Zeichen) index: backend: manticore manticore_dsn: "manticore@tcp(127.0.0.1:9306)/" batch_size: 100 batch_mode: true # Indexierung als Cron-Batch statt Dauerbetrieb ocr: batch_mode: true # OCR als Cron-Batch statt Dauerbetrieb 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 : ║ ║ auditor : ║ ║ 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 `