Files
mailadmin/README.md
2026-04-26 13:47:35 -05:00

192 lines
5.6 KiB
Markdown

# MailAdmin MVP
Erste Version einer Admin-Webapp für dein DMS/SES/S3/SQS/DynamoDB-Mail-System.
Die App ist bewusst **node-orientiert** gebaut: Sie läuft auf `node1`, `node2`, usw. und entdeckt die Domains dynamisch aus dem lokalen Docker Mailserver. Dadurch ist sie geeignet für dein Szenario, bei dem Domains neu hinzukommen oder zwischen Nodes umziehen.
## Was diese Version bereits kann
- Login mit eigenem Admin-User
- PostgreSQL als Admin-Datenbank
- dynamische Domain-Erkennung über `docker exec mailserver setup email list`
- Domains pro Node speichern: `node1`, `node2`, ...
- Mailboxen anzeigen
- Mailbox anlegen
- Mailbox löschen
- Passwort zurücksetzen
- Speicherverbrauch pro Inbox scannen
- Forward- und Auto-Reply-Regeln in DynamoDB bearbeiten
- Blocklisten in DynamoDB bearbeiten
- Audit Log für Admin-Aktionen
- Frontend wird vom Backend direkt ausgeliefert
- Docker Compose Deployment auf dem Mailserver
## Warum dynamische Domains berücksichtigt sind
Die Domainliste ist **nicht hart codiert**. Beim Start und bei jedem manuellen Resync liest die App die DMS-Accounts aus:
```bash
docker exec mailserver setup email list
```
Daraus werden Domains und Mailboxen abgeleitet und in Postgres gespiegelt.
Wenn eine Domain später auf einen anderen Node umzieht, passiert Folgendes:
- auf dem alten Node werden die lokalen Mailboxen nach einem Resync als `missing_on_node` markiert
- auf dem neuen Node wird dieselbe Domain beim Resync als `active` mit `current_node=node2` erkannt
- die App-Codebasis bleibt identisch; nur `.env` unterscheidet `NODE_NAME=node1` oder `NODE_NAME=node2`
## Struktur
```text
mailadmin-mvp/
backend/
src/
server.ts Express App, API, static frontend
config.ts zentrale Konfiguration über Env Vars
db.ts Postgres Pool + Migration + Initial Admin
routes/
auth.ts Login/Logout/Me
domains.ts Domains dynamisch vom DMS syncen/anzeigen
mailboxes.ts Mailbox CRUD, Usage, Rules, Blocklist
audit.ts Audit Log API
services/
dms.ts DMS Docker Integration + Usage Scan
sync.ts Sync DMS -> Postgres
dynamodb.ts email-rules + email-blocked-senders
audit.ts Audit helper
utils/
email.ts Email/domain/local-part helpers
shell.ts sicherer execFile wrapper
migrations/001_init.sql PostgreSQL Schema
Dockerfile Backend + Frontend Image
frontend/
index.html Single Page App
app.js UI Logik ohne Build-Step
styles.css einfache Admin-Oberfläche
deploy/
caddy/ Caddy-Hinweise
scripts/ Snippet-Hilfe für update-caddy-certs.sh
docker-compose.yml App + Postgres
.env.example Beispiel-Konfiguration
```
## Installation auf node1
```bash
cd /home/aknuth/git/email-amazon
unzip mailadmin-mvp.zip
cd mailadmin-mvp
cp .env.example .env
nano .env
```
Wichtige Werte in `.env`:
```env
MAILADMIN_DB_PASSWORD=ein-sicheres-passwort
MAILADMIN_JWT_SECRET=sehr-langes-random-secret
MAILADMIN_ADMIN_EMAIL=admin@bayarea-cc.com
MAILADMIN_ADMIN_PASSWORD=StartPassword123!
NODE_NAME=node1
NODE_HOSTNAME=node1.email-srvr.com
DMS_CONTAINER=mailserver
AWS_REGION=us-east-2
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
```
Start:
```bash
docker compose up -d --build
```
Logs:
```bash
docker logs -f mailadmin
```
## Installation auf node2
Gleicher Code, andere `.env`:
```env
NODE_NAME=node2
NODE_HOSTNAME=node2.email-srvr.com
```
Die Domainliste wird auch dort aus dem lokalen DMS gelesen.
## Caddy: mailadmin.{DOMAIN}
Dein bestehendes `update-caddy-certs.sh` generiert bereits dynamisch Domain-Blöcke. Ergänze im Domain-Loop zusätzlich diesen Block:
```caddy
# MailAdmin UI
mailadmin.DOMAIN_HERE {
encode gzip
reverse_proxy mailadmin:3000
}
```
Im Script sieht das ungefähr so aus:
```bash
OUTPUT="${OUTPUT}# MailAdmin UI\n"
OUTPUT="${OUTPUT}mailadmin.${domain} {\n"
OUTPUT="${OUTPUT} encode gzip\n"
OUTPUT="${OUTPUT} reverse_proxy mailadmin:3000\n"
OUTPUT="${OUTPUT}}\n\n"
```
Danach:
```bash
cd /home/aknuth/git/email-amazon/caddy
./update-caddy-certs.sh
docker exec caddy caddy reload --config /etc/caddy/Caddyfile
```
## Wichtige Sicherheitshinweise
Diese MVP-Version mountet `/var/run/docker.sock`, damit der Backend-Container `docker exec mailserver ...` ausführen kann. Das ist praktisch, aber mächtig. Für die nächste Version wäre ein kleiner dedizierter Local-Agent mit begrenzten Operationen sicherer.
Das Admin-Passwort wird nur beim ersten Start erstellt. Wenn du `MAILADMIN_ADMIN_PASSWORD` später änderst, wird der vorhandene User nicht überschrieben. Das ist Absicht.
## API Kurzüberblick
```text
POST /api/auth/login
POST /api/auth/logout
GET /api/auth/me
GET /api/domains?resync=true
POST /api/domains/resync
GET /api/mailboxes?domain=example.com
POST /api/mailboxes
DELETE /api/mailboxes/:email
POST /api/mailboxes/:email/password
POST /api/mailboxes/usage/rescan
GET /api/mailboxes/:email/rules
PUT /api/mailboxes/:email/rules
GET /api/mailboxes/:email/blocklist
PUT /api/mailboxes/:email/blocklist
GET /api/audit
```
## Nächste sinnvolle Ausbaustufen
1. Domain-Detailseite mit DNS/SES/S3/SQS/Caddy Status
2. Admin-User Verwaltung im UI
3. Quotas pro Mailbox
4. Soft-Delete mit Retention statt hartem Löschen
5. Outbound Reporting über Postfix Logs und später SES Events
6. Node-Migration Workflow: Domain gezielt von node1 auf node2 markieren und prüfen