Files
archivmail/features/PROJ-4-import-smtp.md
T
sysops 7c29ee88bd docs: vollständige README, PROJ-2 Web-Upload, PROJ-19 Mailpiler-Migration
README.md:
- Vollständige Dokumentation aller implementierten Funktionen
- Konfigurationsreferenz, Installation, Systemd, REST-API-Übersicht
- In-Progress-Features klar gekennzeichnet

PROJ-2 (EML/MBOX Web-Upload):
- POST /api/admin/upload – Multipart-Upload mit Hintergrund-Job
- GET /api/admin/upload/{jobID}/progress – Polling
- Admin-Tab "Import" mit Drag-and-Drop, Fortschrittsbalken, Abschlussbericht

PROJ-19 (Mailpiler Migration):
- archivmail import-piler mit Methoden: pilerexport | direct | auto
- Direct: AES-256-CBC + zlib mit defensiven Fallbacks
- pilerexport: Wrapper um mailpilers Export-Tool

Status-Updates: PROJ-3, PROJ-4, PROJ-6, PROJ-7, PROJ-10, PROJ-11 → Deployed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 09:23:34 +01:00

6.5 KiB
Raw Blame History

PROJ-4: E-Mail-Import: SMTP-Eingang (primär via BCC)

Status: Deployed

Created: 2026-03-12 Last Updated: 2026-03-17

Hinweis

Dies ist der primäre Eingangsweg. archivmail enthält einen eingebetteten SMTP-Daemon, der ausschließlich E-Mails empfängt kein Versand, keine Weiterleitung, kein MTA. Postfix (oder ein anderer Mailserver) wird per BCC-Mapping oder Always-BCC-Regel so konfiguriert, dass er eine Kopie jeder E-Mail an archivmails SMTP-Daemon zustellt.

Absender → Postfix (MTA) → Empfänger
                │
                └── BCC/always_bcc → archivmail SMTP-Daemon (nur Empfang)
                                              │
                                              ▼
                                      Storage Coordinator

IMAP und EML/MBOX-Upload sind sekundäre/ergänzende Methoden (z.B. für Altbestände).

Dependencies

  • Requires: PROJ-5 (Speicherung & Indexierung) eingehende E-Mails werden gespeichert
  • Kein Login nötig für den Empfang SMTP-Eingang läuft unabhängig vom HTTP-Server

User Stories

  • Als Mailserver möchte ich E-Mails per BCC an archivmail zustellen, damit diese automatisch archiviert werden.
  • Als Admin möchte ich den eingebetteten SMTP-Server konfigurieren (Port, TLS, erlaubte Absender-IPs).
  • Als Admin möchte ich festlegen, welche Absender-IPs/Domains akzeptiert werden, damit nur der eigene Mailserver zustellen darf.
  • Als System möchte ich eingehende E-Mails sofort nach Empfang indexieren, damit sie innerhalb von Sekunden durchsuchbar sind.
  • Als Admin möchte ich den Status des SMTP-Empfängers sehen (läuft, Port, letzte empfangene E-Mail).

Acceptance Criteria

  • Eingebetteter SMTP-Server lauscht auf konfigurierbarem Port (Standard: 25 oder 2525)
  • TLS/STARTTLS-Unterstützung für verschlüsselte Übertragung
  • IP-Allowlist: nur eingetragene Mailserver-IPs dürfen zustellen (Standard: nur localhost/127.0.0.1)
  • Optionale Domain-Allowlist als zusätzliche Prüfebene
  • E-Mails werden sofort nach Empfang gespeichert und indexiert
  • SMTP-Quittierung (250 OK) erst nach erfolgreicher Speicherung
  • Admin-UI zeigt: Port, TLS-Status, Anzahl empfangener E-Mails, letzte Aktivität
  • Fehlerhafte/abgelehnte E-Mails werden geloggt

Edge Cases

  • E-Mail ohne Absender (Envelope-From leer) → annehmen aber markieren
  • Sehr große E-Mail (> 50 MB) → konfigurierbare Maximalgröße, Ablehnung mit 552-Fehlercode
  • SMTP-Server-Port bereits belegt → klare Fehlermeldung beim Start
  • Parallele Verbindungen (viele E-Mails gleichzeitig) → Connection-Pooling
  • Duplicate Message-ID → überspringen wie bei anderen Import-Methoden

Technical Requirements

  • RFC 5321 (SMTP) konformer reiner Empfänger kein SMTP-Versand, keine Queue, kein Relay
  • Kein SMTP AUTH Zugang ausschließlich über IP-Allowlist (nur Postfix-IP eingetragen)
  • Maximale Nachrichtengröße konfigurierbar (Standard: 50 MB)
  • Startet als eigenständiger Goroutine/Service neben dem HTTP-Server
  • Postfix-Konfiguration (außerhalb von archivmail, Dokumentation in README):
    • always_bcc = archiv@archivmail-host in Postfix main.cf, oder
    • Sender/Recipient BCC-Maps für granulare Kontrolle

Tech Design (Solution Architect)

Systemübersicht

Absender → Postfix (MTA) → Empfänger (normale Zustellung)
                │
                └── always_bcc / BCC-Map
                         │
                         ▼ SMTP (Port 2525)
               archivmail SMTP-Daemon
               (nur Empfang, kein Versand)
                         │
                         ▼
               Storage Coordinator (PROJ-5)
               (speichern + indexieren)

Komponentenstruktur

archivmail (Go-Binary)
│
├── HTTP-Server (Web-GUI + API)
│
└── SMTP-Daemon                       ← startet parallel zum HTTP-Server
    ├── TCP Acceptor                  ← lauscht auf Port 2525 (konfigurierbar)
    ├── IP Allowlist Guard            ← prüft Absender-IP vor SMTP-Dialog
    ├── Session Handler (pro Verbindung, eigene Goroutine)
    │   ├── TLS/STARTTLS Handler      ← optional, Zertifikat aus config.yml
    │   └── Size Limiter              ← bricht DATA-Phase bei Überschreitung ab
    └── Handoff → Storage Coordinator ← übergibt E-Mail nach vollständigem Empfang

SMTP-Dialogfluss

Postfix
  │  TCP-Verbindung auf Port 2525
  ▼
IP Allowlist Guard
  ├─ IP unbekannt → Verbindung trennen (kein SMTP-Dialog)
  └─ IP erlaubt → weiter
  │
  ▼
220 archivmail SMTP ready
  │
EHLO mail.firma.de
250 OK (kein AUTH angeboten  reiner Empfänger)
  │
MAIL FROM: <absender@firma.de>
250 OK
  │
RCPT TO: <archiv@archivmail>
250 OK
  │
DATA
354 Start input
  … E-Mail-Inhalt … (max. 50 MB)
.
  │
  ├─ Zu groß → 552 Message size exceeds limit
  ├─ Duplikat (Message-ID) → 250 OK (still, kein Fehler  Postfix soll nicht retrying)
  └─ Neu → Storage Coordinator → verschlüsselt speichern + indexieren
                │
                ▼
250 OK         ← erst nach erfolgreicher Speicherung
  │
QUIT

Technische Entscheidungen

Entscheidung Begründung
Reiner Empfänger, kein MTA archivmail ist kein Mailserver keine ausgehende Queue, kein Relay-Risiko, kein Open-Relay
Kein SMTP AUTH Vertrauen basiert auf IP, nicht auf Passwort Postfix und archivmail laufen im gleichen Netz
250 OK bei Duplikat Postfix würde bei Fehler die Mail in die Retry-Queue stellen sinnlos, da Duplikat bereits archiviert
250 OK erst nach Speicherung Solange Postfix keine Bestätigung hat, behält er die Mail und versucht erneut kein Datenverlust
Port 2525 Port 25 erfordert root-Rechte; 2525 läuft als unprivilegierter archivmail-Systembenutzer
Eine Goroutine pro Session Viele parallele Verbindungen ohne Blocking; jede Session ist isoliert

Postfix-Konfiguration (Dokumentation, außerhalb von archivmail)

# /etc/postfix/main.cf  einfachste Variante (alle Mails)
always_bcc = archiv@archivmail-host

# Oder granular per Sender-BCC-Map:
# sender_bcc_maps = hash:/etc/postfix/sender_bcc
# empfänger@firma.de   archiv@archivmail-host

Go-Abhängigkeiten

Paket Zweck
github.com/emersion/go-smtp Eingebetteter SMTP-Daemon (RFC 5321, nur Empfang)
crypto/tls TLS/STARTTLS (Go Stdlib)
net IP-Prüfung (Go Stdlib)

QA Test Results

To be added by /qa

Deployment

To be added by /deploy