Files
sysops 46096db802 feat(PROJ-49): Verschlüsselungspflicht at-rest sichtbar machen (Healthcheck & Warnung)
storage.loadKey() startet bei fehlendem/unlesbarem/ungültigem Keyfile
weiterhin unverschlüsselt (kein Hard-Fail), aber:
- einmalige WARN-Logzeile beim Start mit konkretem Grund
- neuer Healthcheck-Prüfpunkt "Encryption" in archivmail status
- Dashboard-API liefert encryption.enabled
- README: GoBD-Hinweis zu storage.keyfile

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 20:01:38 +02:00

840 lines
26 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# archivmail
Ein selbst gehostetes, unternehmenstaugliches Mail-Archiv-System. Empfängt E-Mails über SMTP (BCC-Journaling), IMAP oder Datei-Upload, speichert sie verschlüsselt, indexiert sie für Volltextsuche und stellt sie über eine Web-Oberfläche zur Verfügung.
---
## Inhaltsverzeichnis
- [Funktionsübersicht](#funktionsübersicht)
- [Architektur](#architektur)
- [Voraussetzungen](#voraussetzungen)
- [Installation](#installation)
- [Konfiguration](#konfiguration)
- [Systemd-Dienste](#systemd-dienste)
- [Funktionen im Detail](#funktionen-im-detail)
- [Authentifizierung & Rollen](#authentifizierung--rollen)
- [SMTP-Eingang (BCC-Journaling)](#smtp-eingang-bcc-journaling)
- [IMAP-Import & Auto-Sync](#imap-import--auto-sync)
- [EML/MBOX Web-Upload](#emlmbox-web-upload)
- [Speicherung & Verschlüsselung](#speicherung--verschlüsselung)
- [Volltext-Suche](#volltext-suche)
- [E-Mail-Ansicht](#e-mail-ansicht)
- [E-Mail-Export](#e-mail-export)
- [Admin-Dashboard](#admin-dashboard)
- [Audit-Log](#audit-log)
- [Integritätsprüfung](#integritätsprüfung)
- [CLI Import & Export](#cli-import--export)
- [Mailpiler Migration](#mailpiler-migration)
- [REST API](#rest-api)
- [In Entwicklung](#in-entwicklung)
- [Update](#update)
---
## Funktionsübersicht
| Funktion | Status |
|----------|--------|
| Authentifizierung & Rollen (Admin / Auditor / User) | ✅ Deployed |
| SMTP-Eingang via BCC-Journaling | ✅ Deployed |
| IMAP-Import manuell & automatischer Sync | ✅ Deployed |
| EML/MBOX Web-Upload (Admin) | ✅ Deployed |
| AES-256-GCM verschlüsselte Speicherung | ✅ Deployed |
| Manticore Search Volltext-Indexierung (async) | ✅ Deployed |
| Volltext-Suche mit Filtern & Sortierung | ✅ Deployed |
| E-Mail-Ansicht mit HTML-Sandbox | ✅ Deployed |
| E-Mail-Export als EML / PDF / ZIP | ✅ Deployed |
| Admin-Dashboard (CPU, RAM, Disk, Archiv-Stats) | ✅ Deployed |
| Audit-Log (Suche, Login, Import, Export) | ✅ Deployed |
| SHA-256 Integritätsprüfung | ✅ Deployed |
| CLI: `archivmail import` / `export` | ✅ Deployed |
| Mailpiler → archivmail Migration | ✅ Deployed |
| Dienste-Verwaltung im Admin-Bereich | ✅ Deployed |
| Ordner- & Label-Verwaltung | 🔄 In Progress |
| POP3-Import | 🔄 In Progress |
| REST API für externe Anbindung (CRM) | 🔄 In Progress |
| LDAP / Active Directory | 🔄 In Progress |
---
## Architektur
```
┌─────────────────────────────────────┐
│ archivmail (Go-Binary) │
│ │
Postfix BCC ──┤── SMTP-Daemon (Port 2525) │
IMAP-Server ──┤── IMAP-Importer + Scheduler │──► PostgreSQL
Web-Upload ──┤── HTTP API (Port 8080) │ (Metadaten)
│ │ │
│ ▼ │──► /var/archivmail/store
│ Async Index Worker │ (AES-256-GCM)
│ │ │
│ ▼ │──► Manticore Search (Port 9306)
│ Manticore Index │ (Volltext-Index)
└─────────────────────────────────────┘
│ /api/*
┌─────────────────────────────────────┐
│ Next.js Frontend (Port 3000) │
│ / /search /mail/[id] /admin │
│ /imap │
└─────────────────────────────────────┘
```
**Komponenten:**
| Komponente | Technologie | Beschreibung |
|------------|-------------|--------------|
| Backend | Go 1.24 | REST API, SMTP-Daemon, IMAP-Importer, Storage, Indexierung |
| Frontend | Next.js 16 (TypeScript) | Web-Oberfläche, Tailwind CSS, shadcn/ui |
| Datenbank | PostgreSQL | Metadaten, Benutzer, Audit-Log, Session-Blacklist |
| Volltextsuche | Manticore Search | BM25-Ranking, Wildcards, Feldpräfixe |
| Speicherung | Dateisystem | AES-256-GCM verschlüsselt, SHA-256 Integrität |
---
## Voraussetzungen
**Server:**
- Debian 12 / Ubuntu 22.04 oder neuer
- Go ≥ 1.24 (CGO_ENABLED=0, keine C-Abhängigkeiten)
- Node.js ≥ 20
- PostgreSQL ≥ 14
- Manticore Search ≥ 6.x
**Ports (Standard):**
- `8080` HTTP API (Backend)
- `3000` Web-Frontend
- `2525` SMTP-Eingang (BCC-Journaling)
---
## Installation
### Automatisch (empfohlen)
```bash
curl -fsSL https://gitea.perlbach24.de/scripte/archivmail/raw/branch/main/update.sh | bash
```
Das Skript:
1. Klont/aktualisiert den Quellcode
2. Baut Backend (Go, CGO_ENABLED=0) und Frontend (Next.js)
3. Stoppt Dienste, spielt Binaries ein, startet Dienste neu
4. Führt Datenbankmigrationen durch und reindexiert Manticore
### 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 # Postfix-Server-IP(s)
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
EOF
# AES-256 Schlüssel generieren
dd if=/dev/urandom bs=32 count=1 > /etc/archivmail/keyfile
chmod 600 /etc/archivmail/keyfile
```
---
## Konfiguration
### Vollständige Konfigurationsreferenz
```yaml
server:
api_port: 8080 # HTTP-API Port
smtp_port: 2525 # SMTP-Eingang Port (Fallback wenn smtp.bind nicht gesetzt)
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 (siehe Hinweis unten)
smtp:
enabled: true
bind: ":2525" # TCP-Adresse zum Lauschen
domain: "archivmail" # EHLO-Domainname
tls_cert: "" # Pfad zum TLS-Zertifikat (leer = kein TLS)
tls_key: "" # Pfad zum TLS-Schlüssel
max_size_mb: 50 # Maximale E-Mail-Größe in MB
allowed_ips: # Nur diese IPs dürfen zustellen
- 127.0.0.1
api:
bind: ":8080"
secret: "" # JWT-Signaturschlüssel (mind. 32 Zeichen, zufällig)
index:
backend: manticore # manticore (Standard)
manticore_dsn: "manticore@tcp(127.0.0.1:9306)/" # Manticore Search DSN
batch_size: 100 # Dokumente pro Index-Batch
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
Das System läuft mit zwei Systemd-Units:
| Dienst | Beschreibung | Port |
|--------|--------------|------|
| `archivmail` | Go-Backend (API + SMTP + IMAP-Scheduler) | 8080, 2525 |
| `archivmail-web` | Next.js-Frontend | 3000 |
```bash
# Status prüfen
systemctl status archivmail archivmail-web
# Logs
journalctl -u archivmail -f
journalctl -u archivmail-web -f
# Neustart
systemctl restart archivmail archivmail-web
```
---
## Funktionen im Detail
### Authentifizierung & Rollen
**Rollen:**
| Rolle | Rechte |
|-------|--------|
| `admin` | Vollzugriff: Benutzer verwalten, IMAP einrichten, Dienste steuern, alles suchen/exportieren |
| `auditor` | Audit-Log lesen, alle E-Mails suchen und exportieren |
| `user` | Nur eigene E-Mails suchen und lesen (Matching auf E-Mail-Adresse) |
**Sicherheit:**
- Passwörter mit bcrypt (Cost 12)
- Sessions als httpOnly SameSite=Strict Cookie (`archivmail_session`)
- JWT mit zufälligem JTI (kryptografische Entropie, 16 Byte)
- Token-Blacklist in PostgreSQL (Logout invalidiert Token sofort)
- Rate-Limiting: max. 5 Fehlversuche in 15 Minuten → HTTP 429
- Login-Versuche in `login_attempts`-Tabelle protokolliert
- Letzter Login wird gespeichert (`last_login_at`)
**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! ║
╚══════════════════════════════════════════════════════════════╝
```
---
### SMTP-Eingang (BCC-Journaling)
Der eingebettete SMTP-Daemon empfängt E-Mails von Postfix (oder anderem MTA) über BCC-Weiterleitung.
**Funktionsweise:**
```
Absender → Postfix → Empfänger
└── always_bcc → archivmail SMTP (Port 2525)
Speicherung + Indexierung
```
**Postfix-Konfiguration (`/etc/postfix/main.cf`):**
```
# Alle ausgehenden Mails archivieren:
always_bcc = archiv@archivmail-host
# Oder granular per Nutzer:
sender_bcc_maps = hash:/etc/postfix/sender_bcc
```
**Sicherheit:**
- Kein SMTP AUTH Vertrauen ausschließlich über IP-Allowlist
- IP-Allowlist in `smtp.allowed_ips` konfigurieren
- 250 OK erst nach erfolgreicher Speicherung (kein Datenverlust)
- 250 OK auch bei Duplikaten (Postfix stellt nicht erneut zu)
- Maximale E-Mail-Größe konfigurierbar (`smtp.max_size_mb`, Standard: 50 MB)
- Optionale TLS/STARTTLS-Unterstützung (`smtp.tls_cert` / `smtp.tls_key`)
**API-Endpunkt:**
```
GET /api/admin/smtp/status
```
---
### 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 |
|------|--------------|
| Name | Bezeichnung der Verbindung |
| Host / Port | IMAP-Server-Adresse |
| TLS | `ssl` (IMAPS), `starttls`, `none` |
| Benutzername / Passwort | IMAP-Zugangsdaten (Passwort AES-256-GCM verschlüsselt in DB) |
| Ausgeschlossene Ordner | Ordner die nicht importiert werden |
**Sync-Intervall:**
| Wert | Verhalten |
|------|-----------|
| 0 | Automatischer Sync deaktiviert |
| 51440 | Sync alle N Minuten (Hintergrund-Goroutine) |
**Inkrementeller Sync:**
- UID-basiert: Nur neue Nachrichten seit letztem Sync werden heruntergeladen
- Exponentielles Backoff bei Fehlern: 1s → 60s → 300s (3 Versuche)
- Duplikat-Erkennung via Content-Hash
**API-Endpunkte:**
```
GET /api/imap # Verbindungen auflisten
POST /api/imap # Neue Verbindung anlegen
DELETE /api/imap/{id} # Verbindung löschen
PATCH /api/imap/{id} # Sync-Intervall ändern
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
```
---
### EML/MBOX Web-Upload
E-Mails direkt über die Admin-Oberfläche hochladen (Tab „Import" unter `/admin`).
**Unterstützte Formate:**
- `.eml` einzelne RFC-2822 E-Mail
- `.mbox` MBOX-Datei mit beliebig vielen E-Mails
**Ablauf:**
1. Dateien per Drag-and-Drop oder Datei-Dialog hochladen
2. Backend startet Hintergrund-Import-Job, gibt sofort `job_id` zurück
3. Frontend pollt alle 1,5 Sekunden den Fortschritt
4. Abschlussbericht: Importiert / Übersprungen (Duplikate) / Fehler
**API-Endpunkte:**
```
POST /api/admin/upload # Multipart-Upload starten
GET /api/admin/upload/{jobID}/progress # Fortschritt abfragen
```
---
### Speicherung & Verschlüsselung
Alle E-Mails werden verschlüsselt auf dem Dateisystem gespeichert.
**Verschlüsselung:**
- Algorithmus: AES-256-GCM (authentifizierte Verschlüsselung)
- Schlüssel: 32-Byte-Datei (`keyfile` in Konfiguration)
- Nonce: 12 Byte, kryptografisch zufällig, pro E-Mail neu generiert
- Dateiformat: `[12-Byte Nonce][verschlüsselte Daten]`
> **Wichtig (GoBD, PROJ-49):** `storage.keyfile` ist technisch optional — fehlt es,
> startet der Dienst weiter, speichert E-Mails dann aber **unverschlüsselt**. Für
> produktive, GoBD-konforme Installationen ist `storage.keyfile` quasi-pflicht und
> sollte immer gesetzt sein. Ist keine (gültige, 32 Byte große) Schlüsseldatei
> konfiguriert, gibt archivmail beim Start eine deutliche WARN-Zeile aus, und
> sowohl `archivmail status` (Eintrag „Encryption") als auch das Admin-Dashboard
> zeigen den Status `disabled` an.
**Datei-ID / Integrität:**
- Jede E-Mail erhält als ID den SHA-256-Hash des Klartexts
- Duplikat-Erkennung: gleicher Hash → gleiche Datei, Speicherung übersprungen
- ID dient gleichzeitig als Integritätsnachweis
**PostgreSQL-Metadaten (`emails`-Tabelle):**
| Spalte | Typ | Beschreibung |
|--------|-----|--------------|
| `id` | TEXT PK | SHA-256 Hash des E-Mail-Rohtexts |
| `from_addr` | TEXT | Absender |
| `to_addrs` | TEXT[] | Empfänger |
| `subject` | TEXT | Betreff |
| `message_id` | TEXT | RFC-2822 Message-ID |
| `mail_date` | TIMESTAMPTZ | Sendedatum |
| `size_bytes` | INTEGER | Größe in Bytes |
| `has_attachments` | BOOLEAN | Hat Anhänge |
| `stored_at` | TIMESTAMPTZ | Archivierungszeitpunkt |
| `indexed_at` | TIMESTAMPTZ | Indexierungszeitpunkt (NULL = ausstehend) |
| `verify_ok` | BOOLEAN | Letztes Integritätsprüfungsergebnis |
| `verified_at` | TIMESTAMPTZ | Zeitpunkt der letzten Prüfung |
**Async Index Worker:**
- Eingehende E-Mails werden sofort gespeichert
- Indexierung erfolgt asynchron über einen Go-Channel (Queue-Größe: 1000)
- Backfill beim Start: Nicht indexierte E-Mails werden nachindexiert
---
### Volltext-Suche
Suche über alle archivierten E-Mails per Manticore Search unter `/search`.
**Suchfelder:**
- Freitext (durchsucht Betreff, Body, Absender, Empfänger, Anhangsnamen)
- Absender-Filter (`from`)
- Empfänger-Filter (`to`)
- Zeitraum (`date_from` / `date_to`, ISO 8601: `2024-01-01`)
- 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
```
**Paginierung:** 25 Ergebnisse pro Seite (konfigurierbar via `page_size`)
**Rollenfilter:**
- `user`: sieht nur E-Mails an/von der eigenen E-Mail-Adresse
- `admin` / `auditor`: sieht alle E-Mails
**API-Endpunkt:**
```
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 einer archivierten E-Mail unter `/mail/[id]`.
**Funktionen:**
- HTML-Body original dargestellt in `<iframe sandbox="allow-same-origin">` JavaScript aus der Mail wird blockiert
- Externe Inhalte (Bilder, Tracking-Pixel) standardmäßig blockiert, per Klick freischaltbar
- Fallback auf Plaintext wenn kein HTML vorhanden
- Anhänge einzeln herunterladbar
- Originale E-Mail-Header aufklappbar
- Download als `.eml` (Rohdatei)
- Export als `.pdf`
- Integrity-Badge: ✅ verifiziert OK / ⬜ noch nicht geprüft / ❌ Integritätsfehler
**API-Endpunkte:**
```
GET /api/mails/{id} # E-Mail-Details inkl. Body
GET /api/mails/{id}/attachments/{index} # Anhang herunterladen
GET /api/mails/{id}/raw # Rohe EML-Datei
```
---
### E-Mail-Export
**Formate:**
| 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 + optional Anhänge |
**ZIP-Export:**
```json
POST /api/export/zip
{
"ids": ["sha256hash1", "sha256hash2"],
"attachments": true
}
```
ZIP enthält:
- Eine `.eml`-Datei pro E-Mail
- `manifest.csv` mit Metadaten (ID, Absender, Empfänger, Betreff, Datum, Größe)
- Anhänge wenn `attachments: true`
**Limits:**
- Max. 500 Mails pro ZIP-Export
- Jeder Export wird im Audit-Log erfasst
---
### Admin-Dashboard
Erreichbar unter `/admin` (nur Admins).
**Tabs:**
| Tab | Inhalt |
|-----|--------|
| **Dashboard** | CPU-Last (1/5/15 min), RAM, Festplatten, API-Status, SMTP-Status, Archiv-Statistiken, erste/letzte archivierte Mail |
| **Dienste** | Systemd-Dienste starten / stoppen / neustarten, externe Verbindungen sperren/freigeben |
| **Benutzer** | Benutzer anlegen, Rollen ändern, Passwort zurücksetzen, sperren/freischalten, löschen |
| **Audit-Log** | Alle Audit-Ereignisse mit Paginierung (25/Seite) |
| **Import** | EML/MBOX-Dateien hochladen, Fortschritt und Abschlussbericht |
| **Module** | Übersicht aller Features mit Deployment-Status |
**Dashboard API-Endpunkte:**
```
GET /api/admin/system/stats # CPU, RAM, Disks, erste/letzte Mail
GET /api/admin/smtp/status # SMTP-Daemon Status und Statistiken
GET /api/admin/storage/stats # Anzahl archivierter Mails und Gesamtgröße
GET /api/admin/services # Systemd-Dienste
POST /api/admin/services/{name}/action # start | stop | restart | enable | disable
```
---
### Audit-Log
Alle sicherheitsrelevanten Ereignisse werden lückenlos protokolliert.
**Erfasste Ereignisse:**
| Ereignis | Beschreibung |
|----------|--------------|
| `login_ok` | Erfolgreicher Login (Benutzer, IP) |
| `login_fail` | Fehlgeschlagener Login (Benutzer, IP) |
| `logout` | Logout |
| `search` | Suchanfrage (Suchbegriff, Benutzer) |
| `export_pdf` | PDF-Export einer E-Mail |
| `export_zip` | ZIP-Export (Anzahl Mails) |
| `user_create` | Neuer Benutzer angelegt |
| `user_update` | Benutzerdaten geändert |
| `user_delete` | Benutzer gelöscht |
| `imap_import` | IMAP-Import gestartet/abgeschlossen |
**Speicherung:** Parallel in PostgreSQL-Tabelle und Flat-File (`audit.log_path`)
**API:**
```
GET /api/audit?page=1&page_size=25&username=admin&event_type=login_ok
```
---
### Integritätsprüfung
Jede archivierte E-Mail wird regelmäßig auf Unverändertheit geprüft.
**Funktionsweise:**
1. Beim Speichern: SHA-256-Hash des Klartexts = Datei-ID
2. Beim Prüfen: Datei laden → entschlüsseln → SHA-256 berechnen → mit ID vergleichen
3. Bei Abweichung: Warnung im Log + `verify_ok = false` in DB
**Hintergrundprüfung:**
- Läuft beim Start einmal sofort durch
- Danach alle 5 Minuten wiederholt
- Ergebnisse in `emails`-Tabelle: `verify_ok`, `verified_at`
**Ergebnis in der E-Mail-Ansicht:**
```
✅ Integrität OK (geprüft: 2024-03-15 14:22:00)
❌ INTEGRITÄTSFEHLER E-Mail wurde möglicherweise verändert
⬜ Noch nicht geprüft
```
---
### CLI Import & Export
Das `archivmail`-Binary kann auch ohne laufenden Daemon als CLI-Tool eingesetzt werden.
**Import:**
```bash
# Einzelne EML-Datei
archivmail import --file /pfad/zur/datei.eml
# MBOX-Datei
archivmail import --file /pfad/zur/datei.mbox
# Verzeichnis (alle EML/MBOX-Dateien)
archivmail import --dir /pfad/zum/verzeichnis
# Rekursiv
archivmail import --dir /pfad/ --recursive
# Simulation (kein Speichern)
archivmail import --file datei.eml --dry-run
# JSON-Ausgabe für Skripting
archivmail import --dir /pfad/ --json
```
**Export:**
```bash
# Alle Mails als EML in Verzeichnis
archivmail export --out /export/
# Als MBOX
archivmail export --out /export/archiv.mbox --format mbox
# Mit Filtern
archivmail export --out /export/ \
--from absender@firma.de \
--date-from 2024-01-01 \
--date-to 2024-12-31 \
--query "Rechnung"
# Vorhandene Dateien überschreiben
archivmail export --out /export/ --force
# JSON-Ausgabe
archivmail export --out /export/ --json
```
**Alle Befehle:**
```
archivmail serve Daemon starten (Standard)
archivmail import EML/MBOX importieren
archivmail import-piler Aus mailpiler migrieren
archivmail export Exportieren
archivmail version Version anzeigen
archivmail help Hilfe
```
---
### Mailpiler Migration
Vollständige Migration eines bestehenden mailpiler-Archivs nach archivmail.
**Methode 1: `pilerexport` (empfohlen)**
Erfordert das mailpiler-Tool `pilerexport` auf dem Server. Verarbeitet Entschlüsselung und Dekomprimierung automatisch.
```bash
# Alle Mails migrieren
archivmail import-piler --config /etc/archivmail/config.yml
# Mit Datumsfilter
archivmail import-piler --date-from 2020-01-01 --date-to 2024-12-31
# Benutzerdefinierter Export-Ordner (bleibt erhalten)
archivmail import-piler --export-dir /mnt/migration/export
```
**Methode 2: Direkt (ohne laufendes mailpiler)**
Liest `.m`-Dateien direkt aus dem mailpiler Store-Verzeichnis und verarbeitet sie ohne dass mailpiler installiert sein muss.
```bash
archivmail import-piler \
--method direct \
--store-dir /var/piler/store \
--key-file /var/piler/store/piler.key
```
Unterstützt:
- AES-256-CBC Entschlüsselung (IV in ersten 16 Bytes der Datei)
- zlib Dekomprimierung
- Mehrfache Fallback-Versuche für verschiedene mailpiler-Versionen
- Unkryptierte/unkomprimierte Dateien als letzter Fallback
**Auto-Modus (Standard):**
`--method auto` versucht zuerst `pilerexport`, fällt auf `direct` zurück:
```bash
archivmail import-piler --config /etc/archivmail/config.yml
```
**Alle Optionen:**
```
--config archivmail Konfigurationsdatei
--method auto | pilerexport | direct (Standard: auto)
--pilerexport Pfad zum pilerexport Binary (auto-erkennung)
--export-dir Ausgabeverzeichnis für pilerexport
--store-dir mailpiler Store-Verzeichnis (Standard: /var/piler/store)
--key-file mailpiler AES-Schlüsseldatei (Standard: /var/piler/store/piler.key)
--date-from Export ab Datum YYYY-MM-DD (pilerexport-Methode)
--date-to Export bis Datum YYYY-MM-DD (pilerexport-Methode)
--dry-run Simulation ohne Speichern
--json JSON-Ausgabe
```
**Typischer Migrationsablauf:**
```bash
# 1. Probe-Lauf
archivmail import-piler --dry-run --json
# 2. Migration mit Protokoll
archivmail import-piler 2>&1 | tee /var/log/archivmail/migration.log
# 3. Ergebnis prüfen
tail -20 /var/log/archivmail/migration.log
```
---
## 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: `{"username":"...","password":"..."}` |
| GET | `/api/auth/me` | Eingeloggter Benutzer |
| POST | `/api/auth/logout` | Session invalidieren |
### 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 |
### Export
| Methode | Endpunkt | Beschreibung |
|---------|----------|--------------|
| GET | `/api/export/pdf/{id}` | PDF-Export |
| POST | `/api/export/zip` | ZIP-Export |
### Admin
| Methode | Endpunkt | Beschreibung |
|---------|----------|--------------|
| GET | `/api/users` | Benutzerliste |
| POST | `/api/users` | Benutzer anlegen |
| PATCH | `/api/users/{id}` | Benutzer ändern |
| DELETE | `/api/users/{id}` | Benutzer 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 |
### IMAP
| Methode | Endpunkt | Beschreibung |
|---------|----------|--------------|
| GET | `/api/imap` | Verbindungen auflisten |
| POST | `/api/imap` | Verbindung anlegen |
| DELETE | `/api/imap/{id}` | Verbindung löschen |
| PATCH | `/api/imap/{id}` | Sync-Intervall setzen |
| POST | `/api/imap/test` | Verbindung testen |
| POST | `/api/imap/{id}/import` | Vollständigen Import starten |
| GET | `/api/imap/{id}/progress` | Import-Fortschritt |
| POST | `/api/imap/{id}/sync` | Manuellen Sync auslösen |
---
## In Entwicklung
| Funktion | Beschreibung |
|----------|--------------|
| **Ordner- & Label-Verwaltung** | E-Mails in Ordner ablegen und mit Labels versehen |
| **POP3-Import** | E-Mails von POP3-Servern importieren |
| **REST API (extern)** | Vollständige API für CRM-Anbindung und externe Systeme |
| **LDAP / Active Directory** | Benutzer-Authentifizierung über LDAP/AD statt lokaler Accounts |
---
## 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 führt automatisch durch:
1. Quellcode aktualisieren (git pull)
2. Backend neu bauen (CGO_ENABLED=0)
3. Frontend neu bauen (Next.js standalone)
4. Dienste stoppen
5. Binaries und Frontend einspielen
6. Datenbankmigrationen durchführen
7. Dienste starten und Status prüfen