feat(PROJ-17): Admin Dashboard Systemauslastung immer anzeigen
- Systemauslastungs-Sektion wird immer gerendert (nicht nur bei Erfolg) - Fehlermeldung wenn /api/admin/system/stats nicht erreichbar ist - Feature-Status auf In Review gesetzt Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
# PROJ-4: E-Mail-Import: SMTP-Eingang (primär via BCC)
|
||||
|
||||
## Status: In Progress
|
||||
**Created:** 2026-03-12
|
||||
**Last Updated:** 2026-03-12
|
||||
|
||||
## 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_
|
||||
Reference in New Issue
Block a user