Betrieb
Betrieb
Section titled “Betrieb”Diese Seite beschreibt, was ZPO für den laufenden Betrieb mitbringt: das
Audit-Log als Geschichte aller Änderungen, die eingebaute Sicherung, Alarme
über SMTP und Webhook, den /metrics-Endpunkt für Prometheus und den
Notzugang per CLI, wenn die Oberfläche einmal nicht erreichbar ist.
Audit-Log
Section titled “Audit-Log”ZPO zeichnet jede Änderung an der HTTP-Grenze auf — dort sind Akteur und IP des Aufrufs bekannt. Aufgezeichnet werden Standorte, Proxy- und DNS-Knoten, Backend-Pools, Dienste, Zertifikate, ACME-Konten, DNS-Provider, Benutzer und API-Schlüssel sowie Anmeldungen, Sicherungen und Rücksicherungen.
Jeder Eintrag enthält:
- Aktion —
create,update,delete,rollback,login,backupoderrestore, - Entität und Entitäts-ID — etwa
proxy_hostmit der ID des Dienstes, - Vorher und Nachher als JSON — die Grundlage zum Zurückrollen,
- Benutzer und IP des Aufrufs; Systemvorgänge bleiben ohne Benutzer.
Geheimnis-Felder (Passwörter, Tokens, Schlüssel) sind in den Domain-Structs von der Serialisierung ausgenommen und tauchen nicht im Log auf. Einträge werden unbegrenzt aufbewahrt — das Log ist die Geschichte der Infrastruktur. Ein Schreibfehler im Audit-Log wird nur protokolliert und verhindert die Bedienhandlung nicht.
Das Log liegt in der Oberfläche unter Einrichtung → Audit, gefiltert nach Entität. Jeder Eintrag zeigt Vorher und Nachher.
Zurückrollen aus dem Log
Section titled “Zurückrollen aus dem Log”Einträge zu einem Dienst (proxy_host) mit gefülltem Vorher-Stand
lassen sich per Knopf zurückrollen: Existiert der Dienst noch, wird er auf
den alten Stand aktualisiert; wurde er gelöscht, wird er mit neuer ID neu
angelegt — Standort-Auswahl und Überschreibungen kommen aus dem
Audit-Eintrag mit. Für andere Entitäten gibt es keinen definierten
Rückweg. Dasselbe kann der CLI-Notzugang, siehe
Notzugang.
Sicherung
Section titled “Sicherung”Die eingebaute Sicherung erzeugt über VACUUM INTO eine konsistente Kopie
der Datenbank — auch während ZPO läuft — und packt sie als
zpo-backup-<zeitstempel>.tar.gz. Im Paket liegen:
| Datei | Inhalt |
|---|---|
zpo.db | konsistente Kopie der Datenbank — alle Standorte, Knoten, Dienste, Pools, Zertifikate samt Schlüsseln, Zugänge, Profile, Benutzer, Audit-Log und Ereignisse |
config.json | die Grundeinstellungen des Servers |
secret.key.sealed | nur mit Sicherungspasswort: der Hauptschlüssel, verschlüsselt (Argon2id + AES-256-GCM) |
MANIFEST.json | Version, Zeitpunkt, ob der Schlüssel dabei ist, und die SHA-256-Prüfsumme jedes Teils |
Der Hauptschlüssel
Section titled “Der Hauptschlüssel”Mit secret.key sind alle gespeicherten Zugangsdaten verschlüsselt:
Knoten-Passwörter, DNS-Provider, private Schlüssel der Zertifikate,
SFTP-Passwort. Eine Sicherung ohne ihn ist auf einem neuen Rechner nur
halb brauchbar.
- Mit Sicherungspasswort (mindestens 12 Zeichen) kommt der Schlüssel verschlüsselt mit in jede Sicherung. Eine Sicherung ist dann allein vollständig wiederherstellbar; das Passwort gut aufbewahren — ohne es bleibt der Schlüssel verschlossen.
- Ohne Sicherungspasswort bleibt der Schlüssel draußen und gehört in eine eigene, getrennte Sicherung (siehe Installation).
Einstellungen
Section titled “Einstellungen”Unter Allgemeine Einstellungen → Sicherung:
| Einstellung | Bedeutung |
|---|---|
| Aktiv | Schaltet den Zeitplan ein. |
| Intervall (Stunden) | Abstand der Sicherungen, 1 bis 720. |
| Aufbewahren | Anzahl der vorgehaltenen Sicherungen, 1 bis 500 — beim Verzeichnis wie bei SFTP. |
| Ziel | Verzeichnis auf dem ZPO-Host oder SFTP. |
| Verzeichnis | Leer oder relativ heißt: im Datenverzeichnis, Vorgabe backups (beim Debian-Paket /var/lib/zpo/backups). |
| SFTP-Host, -Port, -Benutzer, -Passwort, -Pfad | Zielangaben; der Port fällt auf 22 zurück. |
| Sicherungspasswort | siehe oben; leer lassen heißt unverändert. |
Schreibrechte: Unter systemd läuft ZPO mit DynamicUser und darf nur in
seinem Datenverzeichnis schreiben — alles andere ist schreibgeschützt. Das
Debian-Paket legt deshalb /var/lib/zpo/backups gleich mit an
(StateDirectory=zpo zpo/backups). Ein anderes Verzeichnis prüft ZPO schon
beim Speichern, indem es probehalber hineinschreibt. Für Sicherungen auf
einem anderen Rechner ist SFTP der vorgesehene Weg.
SFTP: Den Schlüssel des Servers merkt sich ZPO bei der ersten Verbindung und verlangt ihn danach — zeigt der Server einen anderen, bricht die Sicherung ab. Wer den Server tauscht, speichert das Ziel mit dem neuen Host neu.
Letzte Sicherung und letzter Fehler stehen in der Ansicht, Jetzt sichern löst die Sicherung sofort aus. Die Dateiliste zeigt das Verzeichnisziel.
Wiederherstellung
Section titled “Wiederherstellung”Die Rücksicherung läuft aus der Oberfläche: Sicherungsdatei wählen, bei einer Sicherung mit Schlüssel das Sicherungspasswort eingeben. ZPO prüft vorher alles und fasst bis dahin nichts an:
- die Prüfsumme jedes Teils gegen das Manifest,
- die Version — eine Sicherung aus einer neueren ZPO-Version wird abgelehnt,
- den Schlüssel — der mitgesicherte oder, ohne ihn, der laufende muss die Zugangsdaten der Sicherung öffnen,
- die Datenbank selbst (
PRAGMA integrity_check).
Dann legt ZPO Datenbank, Konfiguration (mit dem Datenbankpfad dieses
Rechners) und gegebenenfalls den Schlüssel bereit und startet neu. Eingesetzt
wird beim Start, bevor die Datenbank geöffnet ist; die WAL-Dateien der
alten Datenbank verschwinden dabei — SQLite würde sie sonst auf die neue
anwenden. systemd (Restart=always) oder Docker bringen den Prozess wieder
hoch.
Von Hand geht es genauso: ZPO stoppen, Paket entpacken, zpo.db und
config.json im Datenverzeichnis ersetzen, zpo.db-wal und zpo.db-shm
löschen, ZPO starten.
IP-Gruppen und Rate-Limits
Section titled “IP-Gruppen und Rate-Limits”IP-Gruppen sind benannte CIDR-Listen (mindestens ein Netz, Name 2 bis 64 Zeichen). Ein Dienst, der eine Gruppe gebunden hat, ist nur aus deren Netzen erreichbar — Clients außerhalb bekommen ein 403. Das Rate-Limit eines Dienstes begrenzt die Anfragen je Client-IP innerhalb von zehn Sekunden (0 bis 100000, 0 schaltet es aus); darüber antwortet der Proxy mit 429.
Beides wirkt über die Map-Dateien zpo_ipgroups.map und
zpo_ratelimits.map (siehe Knoten einrichten):
Einträge setzt ZPO über die Runtime-API zur Laufzeit — kein Reload des
Proxys. Eine Gruppe lässt sich nicht löschen, solange noch Dienste sie
gebunden haben; der Aufruf nennt die Anzahl.
Alarme
Section titled “Alarme”Ereignisse aus dem Zertifikats-Erneuerer, dem Failover und dem Abgleich gehen über die Alarmkanäle hinaus. Der Alarmdienst läuft im Minutentakt und verschickt die Ereignisse, die noch nicht alarmiert sind — so übersteht die Alarmierung einen Neustart. Erst wenn alle aktiven Kanäle bedient waren, gilt ein Ereignis als alarmiert; ein streikender Kanal lässt nichts untergehen.
| Typ | Bedeutung |
|---|---|
cert_expiry | Ein Zertifikat läuft ab, ohne dass eine Erneuerung in Sicht ist. |
cert_renewal_missing | Eine fällige Erneuerung ist fehlgeschlagen. |
failover_outage | Ein Proxy ist ausgefallen. |
failover_switch | Der DNS-Schwenk wurde ausgelöst. |
failover_failback | Zurückschwenken nach der Karenzzeit. |
failover_maintenance | Ein Knoten wurde in Wartung genommen. |
site_down | Ein ganzer Standort antwortet nicht mehr — ZPO schwenkt bewusst nicht. |
node_offline | Ein einzelner Knoten ist unerreichbar. |
drift | Der Vollabgleich hat eine Abweichung gefunden. |
crowdsec_down | Der CrowdSec-Schutz eines Proxys wirkt nicht: LAPI antwortet nicht, Lesezugang abgewiesen, Bouncer steht, ist nicht verdrahtet oder holt keine Sperren ab, CrowdSec liest oder versteht die Logs nicht. |
crowdsec_recovered | Entwarnung: CrowdSec wirkt wieder. |
Alle Ereignisse stehen außerdem in der Oberfläche unter Ereignisse und lassen sich dort bestätigen; gelöscht werden sie nicht.
Kanal: SMTP
Section titled “Kanal: SMTP”Host, Port (Vorgabe 587), Benutzer und Passwort, Absender und Empfänger (kommagetrennt). STARTTLS wird genutzt, wenn der Server es anbietet; ohne Benutzer entfällt die Anmeldung. Betreff und Text tragen Typ, Zeit und Nachricht des Ereignisses.
Kanal: Webhook
Section titled “Kanal: Webhook”Ein JSON-POST an die konfigurierte Adresse (http:// oder https://)
mit type, message, time und source: "zpo"; ein optionaler Token
geht als Authorization: Bearer mit. HTTP-Status ab 300 gilt als
Fehlschlag.
Die Einstellungen liegen unter Allgemeine Einstellungen → Alarme. Passwort und Token werden verschlüsselt gespeichert; beim Ändern heißt ein leeres Feld: der bisherige Wert bleibt. Jeder Kanal hat einen eigenen Testknopf — Test-E-Mail senden und Webhook testen. Der Test nimmt die Werte, die gerade in der Maske stehen, auch vor dem Speichern, und zeigt die Antwort des Servers, wenn er scheitert.
Beim SMTP-Versand gilt: Port 465 spricht TLS von Anfang an, jeder andere Port
(üblich 587) wechselt per STARTTLS, sobald der Server es anbietet. Eine
Anmeldung ohne Verschlüsselung lehnt ZPO ab, außer gegen localhost.
Statistik
Section titled “Statistik”Die Ansicht Statistik zeigt, was durch die Proxys läuft und was abgewehrt wird — gesamt oder eingegrenzt auf einen Standort, einen Proxy oder einen Dienst, für 24 Stunden, 7 oder 30 Tage:
- Verkehr: Aufrufe, Datenmenge, Fehlantworten (4xx) und Serverfehler (5xx), als Verlauf und je Dienst. Ohne Auswahl eines Dienstes zählt alles, was an die Proxys kam — auch, was sie selbst beantwortet haben (gesperrt, abgewiesen, unbekannter Name).
- Abwehr: von der WAF geblockte Anfragen, CrowdSec-Alarme mit Angriffsmuster, angegriffenem Dienst, Herkunftsland und Adresse, dazu die aktiven Sperren.
Dafür liest ZPO alle fünf Minuten die Zähler von HAProxy (über die Data Plane API) und der WAF (Metriken des Agents) und speichert die Differenz zum letzten Stand — HAProxy zählt nur seit seinem Start bzw. Reload. CrowdSec- Alarme holt ZPO mit dem Maschinen-Zugang je LAPI; was ZPO selbst abgleicht, zählt nicht als Angriff. Aufbewahrung: 5-Minuten-Werte zwei Tage, Stundenwerte und Alarme 90 Tage. Die Statistik beginnt mit dem Update auf 0.7 — ältere Zahlen gibt es nicht.
Metriken für Prometheus
Section titled “Metriken für Prometheus”Der Endpunkt /metrics steht außerhalb der API und ist ohne Anmeldung
lesbar, damit Prometheus ihn erreichen kann. Der Konfigurationsschlüssel
metrics_token schützt ihn bei Bedarf — als
Authorization: Bearer <token> oder als ?token=… (siehe
Konfiguration).
| Kennzahl | Typ | Bedeutung |
|---|---|---|
zpo_uptime_seconds | Gauge | Laufzeit des Prozesses. |
zpo_node_status{kind,node,status} | Gauge | Zustand je Knoten (1 = aktueller Zustand). |
zpo_objects_pending{kind,node} | Gauge | Offene Aufträge des Abgleichs je Knoten. |
zpo_certificate_days_left{name} | Gauge | Verbleibende Tage bis zum Zertifikatsablauf — ein Alarm darauf deckt den drohenden Ablauf ab. |
zpo_events_total{type} | Counter | Ereignisse je Typ seit Bestehen der Datenbank. |
Notzugang und Wartung
Section titled “Notzugang und Wartung”Liegt die Oberfläche hinter einem Proxy, den ZPO selbst verwaltet, darf eine fehlerhafte Änderung nicht aussperren. Zwei Wege führen zurück hinein:
local_portin der Konfiguration — ein zusätzlicher Listener auf127.0.0.1, siehe Konfiguration.zpo rollback— ein Subcommand, das direkt auf der Datenbank arbeitet, ohne HTTP und ohne den Hauptschlüssel:
# Dienst auf den letzten Audit-Stand zurückrollen (stellt auch# gelöschte Dienste wieder her):zpo rollback -data /var/lib/zpo --host app.beispiel.de
# Notbremse: Dienst deaktivieren — der Abgleich entfernt die# Routen beim nächsten Lauf:zpo rollback -data /var/lib/zpo --disable-host app.beispiel.deOhne -data gilt das Verzeichnis des Binaries, wie beim Dienst.
Das Datenverzeichnis
Section titled “Das Datenverzeichnis”| Datei | Inhalt |
|---|---|
config.json | Grundeinstellungen, siehe Konfiguration |
zpo.db | SQLite-Datenbank — alle Zustände und Einstellungen |
secret.key | der Hauptschlüssel — mit Sicherungspasswort Teil der Sicherung, sonst getrennt sichern |
backups/ | Vorgabeverzeichnis der Sicherungen |
version.json | Versionsmarke der Installation; steuert die Datenübernahme beim Update |
Beim Debian-Paket ist das /var/lib/zpo, im Container /data.
Updates
Section titled “Updates”Debian-Paket: apt update && apt install zpo — das Paket startet
einen laufenden Dienst neu. Der Dienst läuft als systemd-Unit mit
dynamischem Benutzer (kein root); Geheimnisse wie ZPO_SECRET_KEY
gehören in /etc/zpo/secret.env (Rechte 0600), das die Unit
einliest. Vor dem Update eine Sicherung auslösen — und daran denken,
dass secret.key separat liegt.
Docker: neues Image ziehen und den Container mit demselben Volume auf
/data neu erzeugen:
docker pull registry.techeve.de/techeve/zpo:latestdocker stop zpo && docker rm zpodocker run -d --name zpo -p 8080:8080 -v zpo-data:/data \ registry.techeve.de/techeve/zpo:latestIn beiden Fällen liest ZPO beim Start die version.json neben der
Datenbank und zieht die Daten automatisch auf den Stand der neuen
Version.
Nach dem Update die Proxys aktualisieren: Bringt eine neue Version eigene Inhalte mit — etwa neue Fehlerseiten — oder schreibt sie die Konfiguration anders auf den Knoten, sieht der Abgleich darin keine Änderung am Sollzustand. Unter Proxy-Knoten spielt der Knopf Konfiguration aktualisieren (Kreispfeile) deshalb alles, was ZPO auf diesem Proxy führt, sofort neu ein. Lehnt der Knoten einen Teil ab, nennt ZPO die Anzahl; die Einzelheiten stehen unter Abgleich. Deaktivierte Proxys bekommen auch auf Knopfdruck nichts.