Files
duffyduck 06d7e00e49 fix(kerio): korrekte Admin-API gemäß Delivery.idl + Pop3Account-Doku
- Methoden: Delivery.getPop3AccountList / addPop3AccountList /
  setPop3Account (vorher geraten als Pop3Accounts.set/.create →
  Method not found).
- Pop3Account-Felder mit den richtigen Namen: isActive (statt enabled),
  mode (statt sslMode), authentication (statt authType), und
  leaveOnServer.removeAfterPeriod als OptionalLong-Wrapper.
  Falsche Namen wurden von Kerio still ignoriert → Sammler war inaktiv.
- User-Struct: allowPasswordChange=false (statt mayChangePassword,
  das es nicht gibt). emailAddresses weggelassen, Kerio leitet die
  primäre Adresse aus loginName+domain ab.
- Kerio-Step in 2 Sub-Steps aufgeteilt: User (skip wenn vorhanden) +
  POP3 (upsert). Damit wird bei einem zweiten Lauf der Sammler nicht
  übersprungen, nur weil der User schon existiert.
- POP3-Sammler ist jetzt UPSERT: existierende werden via setPop3Account
  überschrieben → Selbstreparatur kaputter Einträge + Passwort-
  Änderungen aus der CSV ziehen sich von selbst nach.

GUI: 👁/🙈-Toggle pro Passwort-Feld (Klartext temporär einsehbar).

Filenames der Sammel-PDFs + Admin-Report ohne Zeitstempel –
erneuter Lauf überschreibt statt anzuhäufen.

README: Ablauf-Sektion + Idempotenz-Tabelle aktualisiert; Kerio-
Caveat ersetzt durch konkrete Methoden-/Feld-Liste mit Doku-Link.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 14:09:06 +02:00

300 lines
15 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.
# deploy-email-plesk-kerio-nextcloud
Tool, um neue Mitarbeiter:innen-Konten in **einem** Rutsch über drei Systeme
auszurollen und am Ende eine PDF mit den Zugangsdaten zu erzeugen:
1. **Plesk** Mailpostfach anlegen (nur Mailserver-Login, keine Plesk-GUI).
2. **Kerio Connect** Benutzer anlegen + POP3-Sammler einrichten, der die
Mails alle paar Minuten vom Plesk-Server abholt
(14 Tage auf dem Server belassen, SSL).
3. **Nextcloud** Benutzer (Username = `vorname.nachname`, lowercase,
Umlaute transliteriert) mit Gruppe und Speicherquota anlegen.
4. **PDF** pro Benutzer eine PDF + eine Sammel-PDF mit allen Zugangsdaten.
CLI **und** Tkinter-GUI mit „+ Zeile"-Endlosfeldern.
---
## Installation
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
$EDITOR .env
```
Tkinter ist Teil der Python-Standardbibliothek, unter Debian/Ubuntu ggf.
`sudo apt install python3-tk`.
## Konfiguration (`.env`)
### Plesk-Backend wählen (`PLESK_BACKEND`)
Dreistufige Wahl, je nachdem welchen Zugriff du auf das Plesk hast:
| Backend | Wann? | Was passiert |
| -------- | ---------------------------------------------------------- | ------------------------------------------------------------------------- |
| `manual` | **Shared-Host beim Kunden** kein API, kein SSH (Default) | Tool legt nichts in Plesk an. Im Webinterface manuell anlegen, dann Tool laufen lassen (oder andersrum Kerio-POP3-Sammler funktioniert erst, wenn das Postfach existiert). |
| `api` | Eigener/dedizierter Plesk mit REST-API | Anlegen via `/api/v2/cli/mail/call` (entspricht `plesk bin mail`). Auth über `PLESK_API_KEY` (bevorzugt) oder `PLESK_USER` / `PLESK_PASSWORD`. |
| `ssh` | Eigener Plesk, API blockiert, aber SSH offen | `paramiko` öffnet SSH und ruft `plesk bin mail` direkt. Auth über Key (`PLESK_SSH_KEY`) oder Passwort (`PLESK_SSH_PASSWORD`). Bei Bedarf `PLESK_SSH_USE_SUDO=true`. |
> SSH-Backend braucht zusätzlich `paramiko`: `pip install paramiko`.
> Für `manual` reicht das Standard-`requirements.txt`.
### Restliche Variablen
| Variable | Beschreibung |
| -------------------------- | ------------------------------------------------------------------- |
| `KERIO_ADMIN_USER` | i.d.R. `Admin` |
| `KERIO_ADMIN_PASSWORD` | Adminpasswort |
| `KERIO_ADMIN_PORT` | Standard `4040` |
| `NEXTCLOUD_ADMIN_USER` | Admin-User (App-Passwort empfohlen) |
| `NEXTCLOUD_ADMIN_PASSWORD` | Admin- oder App-Passwort |
| `POP3_PORT` | POP3-Sammler in Kerio (default `995` = POP3S) |
| `POP3_SSL` | Leer → Auto: `110` ⇒ aus, sonst an. Manuell `true`/`false`. |
| `POP3_KEEP_DAYS` | Tage, die Mails auf Plesk verbleiben (default `14`) |
| `SMTP_PORT` | Nur für die PDF-Anzeige (default `465`, Mailprogramm-Konfig) |
| `IMAP_PORT` | Nur für die Minimal-PDF-Anzeige (default `993` = IMAPS) |
| `VERIFY_TLS` | `false` nur bei Test/selbst signierten Zertifikaten |
---
## Plesk-API-Key per SSH erzeugen (nur für `PLESK_BACKEND=api`)
Plesk lässt das Anlegen von API-Keys **nicht** in der Web-GUI zu.
Per SSH auf dem Plesk-Host:
```bash
# Login als root oder Plesk-Admin
plesk bin secret_key --create -ip-address 0.0.0.0/0 -description "deploy-tool"
# Ausgabe-Beispiel:
# API key was successfully generated. Key:
# 1a2b3c4d-1234-5678-9abc-deadbeef0001
```
Den Key in `.env` als `PLESK_API_KEY=…` eintragen.
Tipp: `-ip-address` möglichst auf die IP einschränken, von der das Tool
ausgeführt wird (z.B. `-ip-address 192.0.2.10`).
Vorhandene Keys listen / löschen:
```bash
plesk bin secret_key --list
plesk bin secret_key --delete <key>
```
---
## CSV-Format
UTF-8, Trennzeichen `;` *oder* `,` (wird automatisch erkannt). Kopfzeile
case-insensitive. Beispiel: [`example.csv`](./example.csv).
| Spalte | Pflicht | Bedeutung |
| --------------------- | :-----: | ------------------------------------------------------------------ |
| `Vorname` | ja | Vorname |
| `Name` | ja | Nachname |
| `emailadresse` | ja | volle Mailadresse, ist Login bei Plesk + Kerio |
| `pleskhost` | ja | Hostname Plesk-Mailserver **auch im `manual`-Modus Pflicht**, weil Kerio davon per POP3 abholt |
| `keriohost` | ja | Hostname Kerio Connect (Admin-API auf Port 4040, Webmail auf 443) |
| `nextcloudhost` | ja | Nextcloud-Hostname |
| `kerioemailkennwort` | ja | Passwort für den Kerio-User |
| `pleskemailkennwort` | ja | Passwort für das Plesk-Mailpostfach |
| `nextcloudgruppe` | nein | Gruppe in Nextcloud (wird angelegt falls nicht vorhanden) |
| `nextcloudspeicher` | nein | Speicher in **GB**. Leer = unlimitiert |
| `nextcloudkennwort` | ja | Passwort für den Nextcloud-User |
> Der **Nextcloud-Username** wird aus Vor-/Nachname abgeleitet
> (`vorname.nachname`, lowercase, ä→ae, ö→oe, ü→ue, ß→ss). Die Emailadresse
> aus der CSV wird im Nextcloud-Profil als E-Mail eingetragen.
> **Hostnamen-Eingabe ist tolerant**: `cloud.foo.de`, `https://cloud.foo.de`
> und `https://cloud.foo.de/` werden alle akzeptiert Schema (`http(s)://`)
> und Trailing-Slash werden automatisch gestrippt, sodass beim URL-Bau
> kein doppeltes `https://https://…` entsteht.
---
## Aufruf
### CLI
Voller Lauf (Plesk + Kerio + Nextcloud + PDFs):
```bash
python deploy.py --csv kunden.csv --output ./output
```
Nur PDFs aus der CSV neu erzeugen, ohne Plesk/Kerio/Nextcloud anzufassen
(z.B. wenn die Konten schon angelegt sind oder eine PDF wiederholt
ausgedruckt werden soll):
```bash
python deploy.py --csv kunden.csv --pdf-only
```
Weitere Flags:
| Flag | Bedeutung |
| ------------ | --------------------------------------------------------------- |
| `--csv PATH` | CSV-Datei einlesen |
| `--output D` | Verzeichnis für PDFs + Admin-Report (default `./output`) |
| `--pdf-only` | Nur PDFs schreiben, keine Account-Anlage |
| `--gui` | GUI starten (auch ohne `--csv` aufrufbar) |
Exit-Code `0` wenn alle Konten ohne Fehler verarbeitet wurden, sonst `1`.
### GUI
```bash
python deploy.py --gui
# oder einfach
python deploy.py
```
Das Fenster startet maximiert. Jeder Account ist eine **Karte** mit zwei
Zeilen: oben die Person (Vorname, Name, Email) + Lösch-Button, unten drei
Service-Gruppen (Plesk / Kerio / Nextcloud) mit Host + Passwort. Passwort-
Felder sind per Default maskiert (`•`); ein **👁-Toggle** neben jedem
Passwort schaltet temporär auf Klartext (🙈) und wieder zurück. Die Karten
sind mit `#1, #2, …` durchnummeriert, Fehlermeldungen referenzieren diese
Nummern.
Buttons in der Toolbar:
| Button | Wirkung |
| ------------------ | ------------------------------------------------------------------ |
| `+ Zeile` | Neue leere Karte am Ende anhängen |
| `CSV laden …` | Felder aus einer bestehenden CSV befüllen |
| `CSV speichern …` | Aktuell ausgefüllte Karten als CSV exportieren (Round-Trip-fähig) |
| `Ausgabeordner …` | Zielverzeichnis für PDFs + Admin-Report wählen |
| `📄 Nur PDF` | Nur PDFs schreiben, keine API-Aufrufe |
| `Ausführen ▶` | Konten anlegen + PDFs + Admin-Report |
| `✕ löschen` (rot) | Karte entfernen (auch die letzte es bleibt eine leere) |
> Die per `CSV speichern …` exportierte Datei enthält **Klartext-Passwörter**
> sicher ablegen / verschlüsselt versenden, und die `*.csv` ist via
> `.gitignore` (Ausnahme `example.csv`) standardmäßig vom Repo ausgeschlossen.
Log unten im Fenster zeigt Fortschritt; nach dem Lauf öffnet eine Hinweis-Box
mit dem Pfad zur Sammel-PDF.
---
## Ablauf je Konto
```
Plesk: Mailpostfach anlegen
- PLESK_BACKEND=manual → übersprungen (manuell in Plesk-GUI anlegen)
- PLESK_BACKEND=api/ssh → automatisch via `plesk bin mail`
Kerio User: anlegen oder überspringen wenn schon vorhanden.
Beim Anlegen wird `allowPasswordChange=false` gesetzt
(User darf sein Passwort nicht selbst ändern).
Kerio POP3-Sammler: UPSERT existierender wird via Delivery.setPop3Account
mit aktuellen Werten überschrieben, sonst neu via
Delivery.addPop3AccountList. So werden alte/kaputte Sammler
automatisch repariert und Passwort-Änderungen aus der CSV
ziehen sich beim nächsten Lauf von selbst nach.
(Port aus POP3_PORT=995, SSL Auto-Erkennung,
14 Tage auf Plesk belassen.)
Nextcloud: User vorname.nachname mit Gruppe + Quota anlegen
(übersprungen wenn vorhanden).
PDFs schreiben (Einzel + Sammel, voll + minimal) und Admin-Report.
```
Am Ende werden pro Lauf folgende Dateien geschrieben (alle in `output/`,
**keine Zeitstempel** im Namen → erneuter Lauf überschreibt):
| Datei | Inhalt |
| -------------------------------------- | --------------------------------------------------------------------- |
| `zugangsdaten_<email>.pdf` | **Voll** pro Benutzer: Plesk-Mailpostfach + Kerio + Nextcloud |
| `zugangsdaten_minimal_<email>.pdf` | **Minimal** pro Benutzer: nur Email (Kerio) + Cloud (Nextcloud) |
| `zugangsdaten_gesamt.pdf` | Sammel-PDF aller voller Datensätze |
| `zugangsdaten_gesamt_minimal.pdf` | Sammel-PDF aller minimalen Datensätze |
| `_admin_report.txt` | Status pro Konto (✓/·/⚠/✗) inkl. Zeitstempel im Header. **NICHT für den Kunden** Admin-Doku. |
Die **Minimal-PDF** enthält genau das, was der Endkunde fürs Mailprogramm
und die Cloud-Anmeldung braucht (Mailadresse, Kennwort, SMTP, IMAP, Cloud-URL,
Cloud-Username, Cloud-Kennwort) ohne Backend-Details wie POP3-Sammler oder
Plesk-Mailserver.
### Idempotenz bestehende Konten werden übersprungen oder aktualisiert
Jeder Sub-Schritt wird **einzeln** geprüft. Im Admin-Report stehen die
Schritte separat (z.B. `Kerio User` und `Kerio POP3` als zwei Zeilen):
| Sub-Schritt | Prüfung | Wenn vorhanden |
| ------------- | ------------------------------------------------------------- | ----------------------------------------------- |
| Plesk | `mail --info` (api/ssh) bzw. ohnehin Manual-Modus | übersprungen |
| Kerio User | `Users.get` mit `loginName` + `domainId` | übersprungen |
| Kerio POP3 | `Delivery.getPop3AccountList`, Match auf (deliveryAddress, server, userName) | **aktualisiert** via `Delivery.setPop3Account` (kein Skip! repariert kaputte Einträge + zieht CSV-Änderungen mit) |
| Nextcloud | `GET /ocs/v2.php/cloud/users/<vorname.nachname>` | übersprungen (keine Quota-/Gruppen-Änderung) |
→ Eine CSV kann gefahrlos mehrfach laufen. Statuswerte:
`✓ angelegt` / `✓ aktualisiert` / `· übersprungen` / `⚠ manuell` / `✗ Fehler`.
**Caveats**:
- Kerio-User-Prüfung matcht `loginName` *in der zur Mailadresse passenden
Domain* Aliase auf einer anderen Domain werden nicht erkannt.
- Nextcloud prüft den abgeleiteten Username `vorname.nachname` existiert
derselbe Mensch dort unter abweichendem Username, wird das nicht gefunden.
- Kerio-POP3 wird absichtlich aktualisiert statt übersprungen: ohne diese
Selbstreparatur bliebe ein einmal kaputt angelegter Sammler dauerhaft
defekt. Nebeneffekt: ein in der Kerio-Webadmin manuell verstellter
Sammler wird beim nächsten Tool-Lauf wieder auf die CSV-Werte gezogen.
## Workflow bei `PLESK_BACKEND=manual` (Shared Host)
1. CSV vorbereiten / in der GUI eintippen.
2. Tool laufen lassen → Kerio-User + POP3-Sammler + Nextcloud-User werden
angelegt, PDFs geschrieben, Admin-Report aufgelistet welche Mailpostfächer
manuell anzulegen sind.
3. Im Plesk-Webinterface des Kunden für jeden Eintrag die Mailadresse mit
exakt dem in der CSV vergebenen Plesk-Mail-Passwort einrichten.
4. Sobald das Postfach existiert, holt der Kerio-Sammler automatisch
eingehende Mails ab.
---
## Hinweise / Caveats
- **Kerio API-Methoden** entsprechen der offiziellen Kerio-Connect-Doku
(Delivery.idl + User-Struct, siehe [Kerio Admin API Reference](https://manuals.gfi.com/en/kerio/api/connect/admin/reference/jsonrpc_specification.html)).
Konkret verwendet: `Session.login`, `Domains.get`, `Users.get`,
`Users.create`, `Delivery.getPop3AccountList`,
`Delivery.addPop3AccountList`, `Delivery.setPop3Account`. Pop3Account-
Felder: `isActive`, `server`, `port`, `mode` (NoSsl/SpecialPort/StlsCommand),
`authentication` (PlainPop3/Apop), `userName`, `password`,
`deliveryAddress`, `leaveOnServer{enabled, removeAfterPeriod{enabled,value}}`.
- **Plesk REST-CLI-Wrapper**: nutzt `/api/v2/cli/mail/call` (entspricht
`plesk bin mail`). Verfügbar ab Plesk Obsidian.
- **Nextcloud OCS**: die Admin-Credentials brauchen das Recht „Benutzer
verwalten". App-Passwort empfohlen, damit der Account nicht 2FA-geschützt
bleibt.
- **TLS**: `VERIFY_TLS=false` nur in Testumgebungen. Self-signed
Zertifikate gehören in einen lokalen Trust-Store, nicht ignoriert.
- **Passwörter** stehen sowohl in der CSV als auch in den PDFs im Klartext.
CSV nach erfolgreichem Lauf löschen, PDFs verschlüsselt versenden.
## Dateien
```
deploy.py CLI-Entry + Orchestrierung
gui.py Tkinter-GUI mit Endlosfeldern
config.py .env-Loader
models.py Account / Result Datentypen
pdf.py ReportLab PDF-Erzeugung (kunden-tauglich)
clients/plesk.py Plesk REST-CLI-Wrapper (PLESK_BACKEND=api)
clients/plesk_ssh.py Plesk SSH-Wrapper, paramiko (PLESK_BACKEND=ssh)
clients/kerio.py Kerio JSON-RPC Admin-Client
clients/nextcloud.py Nextcloud OCS-Client
example.csv Beispiel-Eingabedatei
.env.example Beispiel-Konfiguration
```