Dienste und Backend-Pools
Dienste und Backend-Pools
Section titled “Dienste und Backend-Pools”Ein Dienst (Proxy-Host) ist ein Hostname, der auf ein Ziel zeigt — ein Backend-Pool oder ein Einzelziel — und an ausgewählten Standorten veröffentlicht wird.
Dienst anlegen
Section titled “Dienst anlegen”| Einstellung | Bedeutung |
|---|---|
| Hostname | Der öffentliche Name, z. B. app.beispiel.de. Er ist je Eingangsport eindeutig: Auf einem eigenen Port darf derselbe Name zu einem anderen Dienst führen. |
| Eingangsport | Vorgabe sind die Standardports 80 und 443. Ein eigener Port (etwa 8443) legt auf den Proxys einen weiteren TLS-Eingang an; der Dienst ist dann nur dort erreichbar, nicht zusätzlich über 443. |
| Ziel | Pool (empfohlen) oder Einzelziel aus Adresse und Port. |
| Protokoll zum Ziel | http (Vorgabe) oder https. Bei https prüft die Zertifikatsprüfung das Zertifikat des Ziels — nur für selbstsignierte oder interne Zertifikate abschalten. |
| ForceHTTPS | leitet http mit 301 auf https um — je Dienst, nicht global. |
| HSTS | setzt den Strict-Transport-Security-Header (nur auf verschlüsselten Antworten). |
| Sicherheitsköpfe | setzt X-Content-Type-Options: nosniff, X-Frame-Options: SAMEORIGIN und Referrer-Policy: strict-origin-when-cross-origin. |
| Von CrowdSec prüfen lassen | an (Vorgabe): Von CrowdSec gesperrte Adressen bekommen die Sperrseite. Aus für Maschinenzugriffe wie APIs, Webhooks oder Paketquellen — dann gelten auch WAF, Prüfseite und Köderpfade nicht. Wirkt nur auf Proxys mit CrowdSec (siehe Knoten einrichten). |
| WAF | Virtuelle Patches (Vorgabe): gezielte Regeln gegen bekannte Lücken und typische Angriffe, kaum Fehlalarme. Streng: dazu das OWASP Core Rule Set, blockierend — erst nach einer Einfahrzeit einschalten, es kann harmlose Anfragen treffen. Aus: nur die Sperren. Geprüft wird über CrowdSec AppSec, also nur auf Proxys mit CrowdSec. |
| Browser-Prüfung | Browser lösen vor dem ersten Besuch einmal eine unsichtbare JavaScript-Prüfung (Bot-Erkennung von CrowdSec), Bots und Skripte scheitern. Suchmaschinen, Feeds, Monitoring und typische API-Pfade (/api/, /v1/ …) sind ausgenommen. Nur mit WAF; nichts für Maschinenzugriffe. |
| Köderpfade | Wer /.env, /.git/, /.aws/, /.ssh/, /wp-config.php, /phpmyadmin oder /server-status abfragt, bekommt 404 und wird sofort gesperrt. Nicht für Dienste, die einen dieser Pfade wirklich ausliefern. |
| Captcha bei Verdacht erlauben | an (Vorgabe): Eine auffällige Adresse (Sperrstufe 1) bekommt erst die Prüfseite von zpo-captcha und kommt nach gelöster Rechenaufgabe durch. Aus für Dienste, die Programme statt Browser nutzen (APIs, Git, WebDAV, Apps): Dort geht die Anfrage in Stufe 1 durch, bis die Sperre der Stufe 2 an HAProxy und Router greift. Siehe Knoten einrichten → Zwei Sperrstufen. |
| Login-Schutz | begrenzt die Anmeldeversuche (POST auf die Anmeldepfade) je Client in zehn Minuten, darüber 429. Vorlagen für Proxmox VE, WordPress, GitLab und Odoo oder eigene Pfade. Ein eigener Pfad ist der, an den das Anmeldeformular sendet (bei einer Single-Page-App meist ein API-Pfad wie /api/v1/auth/login), nicht die Adresse im Browser — alles ab # erreicht den Proxy nie, solche Pfade weist ZPO ab. Gezählt werden Versuche, nicht Fehlschläge — WordPress und GitLab antworten auf ein falsches Passwort nicht mit 401. Wirkt auf jedem Proxy. |
| WebSocket | lässt Verbindungsaufwertungen durch und hebt das Tunnel-Timeout des Backends auf eine Stunde an, solange kein eigener Wert eingestellt ist. |
| Zertifikat | ein Zertifikat aus der Zertifikatsverwaltung binden. Ohne Zertifikat bleibt der Dienst http bzw. fällt auf den Platzhalter der Grundkonfiguration zurück. |
| IP-Gruppe | beschränkt den Dienst auf die Netze der Gruppe — sonst 403. Ohne Gruppe ist der Dienst für jeden erreichbar. |
| Rate-Limit | Anfragen je Client-IP in zehn Sekunden; 0 schaltet die Begrenzung aus. |
| Fehlerraten-Grenze | höchstens so viele Fehlantworten (4xx des Ziels) je Client in zehn Sekunden, danach 429 — Scanner fallen so auf, bevor CrowdSec sie erkennt. 0 heißt aus. |
| Verbindungsgrenze | höchstens so viele offene Verbindungen je Client, darüber 429. 0 heißt aus. |
| DNS an/aus | ZPO trägt den Hostnamen auf den Resolvern der beteiligten Standorte ein — mit der Adresse des Proxys, der dort steht. |
| TTL | die TTL der DNS-Einträge, wo der Resolver eine je Eintrag annimmt (RouterOS). Klein halten, damit ein Failover-Schwenk zeitnah wirkt. |
| Standorte | Vorgabe: alle Standorte — auch künftige. Alternativ eine ausdrückliche Auswahl. |
| Overrides | abweichende DNS-Adresse je Standort, wenn nicht der dortige Proxy das Ziel sein soll. |
Eingabeprüfung
Section titled “Eingabeprüfung”Anmeldepfade, eigene HTTP-Header und Pfadregeln landen als Map-Einträge oder Konfigurationszeilen bei HAProxy. Was HAProxy so nicht übernehmen könnte, markiert die Maske schon beim Tippen direkt am Feld. Solange etwas markiert ist, bleibt „Speichern“ gesperrt. Der Server prüft dieselben Regeln, auch für Änderungen über die API.
| Feld | Nicht erlaubt |
|---|---|
| Anmeldepfad | # (das Fragment bleibt im Browser), ?, Leerzeichen, < > * ; $ & { } "; der Pfad muss mit / beginnen |
| Header-Name | alles außer Buchstaben, Ziffern und - _ . — # leitet in der HAProxy-Konfiguration einen Kommentar ein |
| Header-Wert | Umlaute, " und ein %, das kein HAProxy-Ausdruck ist. Erlaubt sind %[src], %[req.hdr(host)] und ähnliche sowie %% für ein wörtliches Prozentzeichen |
| Pfadregel | #, Leerzeichen, " und '; Präfix und exakter Pfad beginnen mit / |
Backend-Pools
Section titled “Backend-Pools”Ein Pool ist eine wiederverwendbare Gruppe von Zielservern.
| Einstellung | Bedeutung |
|---|---|
| Balance | roundrobin (Vorgabe), leastconn oder source — Letzteres bindet einen Client über seine IP an denselben Server, für Dienste mit Sitzungen im Arbeitsspeicher. |
| Protokoll zum Ziel | wie beim Dienst: http oder https, mit optionaler Zertifikatsprüfung. |
| Health-Check | läuft immer, auf zwei Wegen. Aktiv: HAProxy baut alle paar Sekunden eine Verbindung zu jedem Member auf (Vorgabe: alle 2 s, nach 3 Fehlschlägen „down”, nach 2 Erfolgen wieder „up”). Mit HTTP-Prüfung und Pfad wie /health zählt nur eine Antwort mit 2xx oder 3xx. Passiv: HAProxy beobachtet zusätzlich den laufenden Verkehr; scheitern drei Verbindungen in Folge, ist der Member sofort aus der Verteilung und seine offenen Sitzungen werden beendet. Zurück kommt er in beiden Fällen erst, wenn die aktive Prüfung wieder gelingt. |
Jedes Member ist ein Zielserver mit:
- Name und Adresse:Port,
- Gewicht (1–256, Vorgabe 100) für ungleich starke Server,
- Backup — springt erst ein, wenn alle regulären Member ausgefallen sind,
- Wartung — nimmt den Server aus der Verteilung, ohne ihn zu löschen,
- maxconn — begrenzt die gleichzeitigen Verbindungen zu diesem Server; 0 heißt unbegrenzt. Der Schutz für ein schwächeres Ziel.
Die Übersicht zeigt, welche Dienste einen Pool gerade nutzen.
Sitzungen, die an einem Server hängen. roundrobin und leastconn
verteilen jede Anfrage neu. Für Anwendungen, deren Sitzung an einem
Knoten hängt, reicht das nicht — das bekannteste Beispiel ist die Konsole
eines Proxmox-Clusters: Das VNC-Ticket entsteht auf dem Knoten, der die
API-Anfrage bekam, und der anschließende WebSocket muss genau dort
ankommen. Für solche Pools source wählen oder einen Sitzungskeks
setzen (siehe unten). Die Tunnel-Frist für WebSocket bekommt ein Pool von
selbst: ohne eigenen Wert eine Stunde.
Leistung und Ausfallsicherheit
Section titled “Leistung und Ausfallsicherheit”Am Pool — und am Dienst mit Einzelziel — steht der aufklappbare Abschnitt „Leistung & Ausfallsicherheit”. Überall gilt: 0 oder leer heißt Vorgabe des Proxys aus der Grundkonfiguration; ZPO schreibt nur, was eingestellt ist.
| Einstellung | Bedeutung |
|---|---|
| Zeitüberschreitungen | Verbindungsaufbau, Antwort des Ziels, Warteschlange, HTTP-Anfrage, Keep-Alive und Tunnel — je in Millisekunden. Das Tunnel-Timeout ist der relevante Wert für WebSocket. |
| Wiederholungen | Wie oft eine gescheiterte Verbindung erneut versucht wird (Vorgabe des Proxys: 3). |
| Redispatch | schickt den nächsten Versuch an einen anderen Server statt erneut an denselben. |
| Verbindungswiederverwendung | never, safe, aggressive, always — hält Verbindungen zum Ziel offen und nutzt sie erneut. Der größte Leistungshebel bei vielen kurzen Anfragen. |
| Kompression | packt textuelle Antworten (HTML, CSS, JavaScript, JSON) mit gzip, wenn der Client das annimmt. |
| Sitzungskeks | Sticky Sessions: Der Proxy setzt einen Keks mit dem Servernamen und führt den Client so immer zum selben Server — ohne den Keks dem Ziel zu zeigen (insert indirect nocache). |
| Beständige Verteilung | hash-type consistent: Fällt ein Server aus, behalten die übrigen ihre Clients — sonst verteilt source alle neu. |
| Prüfabstand, fall, rise | Feinjustierung des Health-Checks: Abstand in Millisekunden, Fehlversuche bis „down”, Erfolge bis „up”. |
Leistungs-Profile
Section titled “Leistungs-Profile”Statt jeden Wert einzeln einzustellen, lässt sich ein Leistungs-Profil als Vorlage übernehmen (Allgemeine Einstellungen → Leistungs-Profile). Mitgeliefert werden:
| Profil | Für |
|---|---|
| Standard | ausgewogene Werte für Webanwendungen und Websites |
| High load & API | REST/GraphQL-APIs mit vielen kurzen Anfragen — knappe Zeiten, aggressive Wiederverwendung |
| Maximum protection / DDoS | strenge Zeiten gegen Slowloris und ressourcenhungrige Angriffe |
| Uploads & WebSocket | große Uploads, Streaming, lang offene WebSocket-Verbindungen |
| WordPress | WordPress und andere PHP-Seiten: 3 Minuten Antwortzeit für wp-admin, Updates, Importe und WooCommerce, längere Warteschlange bei Lastspitzen, Kompression an, Health-Check alle 5 Sekunden |
Beim WordPress-Profil bewusst nicht gesetzt ist der Sitzungskeks: WordPress hält seine Sitzungen in Keksen und der Datenbank, nicht auf dem einzelnen Server. Liegen Uploads nur lokal auf einem von mehreren Servern, braucht es dagegen einen — oder besser ein gemeinsames Upload-Verzeichnis.
Pfadregeln
Section titled “Pfadregeln”Für Teile eines Dienstes lassen sich eigene Regeln setzen — wie
location-Blöcke bei nginx. Der Reiter Pfade in der Dienstmaske
nimmt sie auf; jede Regel besteht aus einem Pfad und einer Aktion:
| Pfad | Bedeutung |
|---|---|
| beginnt mit | /admin trifft /admin, /admin/ und alles darunter |
| genau | /login trifft nur genau diesen Pfad |
| regulärer Ausdruck | ^/api/v[0-9]+/ für alles, was sich nicht als Präfix fassen lässt |
| Aktion | Wirkung |
|---|---|
| sperren | Antwort mit 403, 404, 410 oder 500 — der Pfad erreicht das Ziel nie |
| nur für Zugangsliste | Nur wer zur gewählten Zugangsliste gehört, kommt durch; der Rest des Dienstes bleibt, wie er ist. Je nach Modus der Liste gibt es 403 oder eine Anmeldung |
| umleiten | Umleitung mit 301, 302, 307 oder 308 auf eine Adresse oder einen anderen Pfad |
Die erste passende Regel gewinnt; die Reihenfolge lässt sich in der
Maske ändern. Typisch: Ein Dienst ist öffentlich, /admin aber nur aus dem
internen Netz erreichbar — eine Regel „beginnt mit /admin · nur für
Zugangsliste intern“.
Pfadregeln wirken auch bei Diensten auf einem Pool: Sie stehen im gemeinsamen Backend, jede prüft aber die Hostnamen ihres Dienstes mit. Eine Änderung lädt HAProxy neu, wie bei den eigenen HTTP-Headern. Eine Zugangsliste, die eine Pfadregel nutzt, lässt sich nicht löschen.
Was ZPO daraus auf den Knoten macht
Section titled “Was ZPO daraus auf den Knoten macht”Nach jeder Änderung rechnet ZPO den vollständigen Sollzustand aus und trägt ihn auf alle beteiligten Knoten:
- Der Hostname steht in
zpo_hosts.mapund zeigt auf das Backend. - Zugangsliste und Rate-Limit stehen in
zpo_ipgroups.map,zpo_auth.mapundzpo_ratelimits.map— Letztere im Format<limit>/<liste>/<schalter>/<modus>/<fehlerprofil>/<fehlergrenze>/<verbindungsgrenze>(hintere Felder nur, wenn gesetzt). Die Schalter:f(Force HTTPS),h(HSTS),s(Sicherheitsköpfe),c(CrowdSec aus),w(WAF),x(CRS blockierend),b(Browser-Prüfung),t(Köderpfade),n(kein Captcha in Stufe 1). - Die Anmeldepfade des Login-Schutzes stehen in
zpo_login.map(<host><pfad>→ Höchstzahl), die Netze vertrauenswürdiger IP-Gruppen inzpo_trusted.map. - Das Backend wird als
zpo_<name>in der Konfiguration angelegt, inklusive Balance, Health-Check, Membern und den eingestellten Reglern.
Map-Einträge und der Wartungszustand einzelner Server wirken über die Runtime-API ohne Reload. Einen Reload braucht nur die strukturelle Änderung: ein neues Backend oder eine neue TLS-Bindung. Der Live-Fortschritt zeigt jeden Teilschritt je Knoten an; ein Knoten, der gerade offline ist, holt die Änderung beim Wiedersehen nach.
Fehlerseiten
Section titled “Fehlerseiten”Statt der schlichten Standardtexte von HAProxy liefert ZPO eigene Fehlerseiten aus. Sie stehen in Fehlerprofilen unter Allgemeine Einstellungen → Fehlerseiten; jeder Dienst wählt eines im Reiter Security, ohne Wahl gilt das Profil Standard, das ZPO bei der Einrichtung anlegt.
Ein Profil hat eine Seite je Fall:
| Fall | Status | Wann |
|---|---|---|
| Unbekannter Name | 404 | Unter dem Hostnamen gibt es keinen Dienst — immer aus dem Standardprofil. |
| Kein Zugang (intern) | 403 | Zugangsliste oder Pfadregel weist einen Client aus einem privaten Netz ab. |
| Kein Zugang (extern) | 403 | Dasselbe für Clients von außen. |
| Gesperrt (CrowdSec) | 403 | CrowdSec hat die Adresse gesperrt oder die WAF eine Anfrage — immer aus dem Standardprofil. |
| Anmeldung | 401 | Basic Auth der Zugangsliste (aus dem Standardprofil) oder einer Pfadregel (Profil des Dienstes). |
| Zu viele Anfragen | 429 | Rate-Limit, Fehlerraten- oder Verbindungsgrenze, Login-Schutz. |
| Interner Fehler | 500 | |
| Ungültige Antwort | 502 | Das Ziel antwortet unbrauchbar. |
| Nicht erreichbar | 503 | Kein Server des Dienstes erreichbar. |
| Zeitüberschreitung | 504 | Das Ziel antwortet nicht rechtzeitig. |
| Wartung | 503 | Der Dienst steht im Wartungsmodus (siehe unten). |
Ein neues Profil entsteht als Kopie — vom Standard oder einem anderen Profil —, es sind also sofort alle Seiten da. Jede Seite ist ein großes HTML-Feld mit kleiner Vorschau und „In neuem Tab öffnen“. Eine Seite muss vollständig sein: CSS, SVG und Bilder eingebettet, höchstens 15000 Byte; nachgeladen wird nichts (die Seite trägt eine Content-Security-Policy, die das verhindert). Der Statuscode bleibt dabei echt — eine hübsche 403 ist technisch eine 403.
Dienste auf einem Pool teilen sich das Backend: Die 5xx-Seiten kommen aus dem gemeinsamen Profil ihrer Dienste, sonst aus dem Standard.
Latenz in der Übersicht
Section titled “Latenz in der Übersicht”Die Spalte Latenz zeigt die Antwortzeit des Ziels: wie lange der Proxy auf die Antwort des Dienstes wartet, gemittelt von HAProxy über die letzten Anfragen. Die Werte kommen aus der Statistik der Data Plane API und werden alle zehn Sekunden aktualisiert; ein Schalter ist dafür nicht nötig. Solange ein Dienst keine Anfragen bekommen hat, steht dort „—“. Die Einzelwerte (Verbindungsaufbau, Warteschlange, Gesamtdauer, Zahl der Anfragen) zeigt der Tooltip. Läuft ein Dienst auf mehreren Proxys, gilt der langsamere; Dienste auf einem Pool teilen sich die Werte ihres Pools.
Wartungsmodus
Section titled “Wartungsmodus”Drei Ebenen, für drei Fälle:
- Dienst in Wartung: Der Schalter mit dem Schraubenschlüssel in der Dienstliste lenkt alle Namen des Dienstes auf die Wartungsseite seines Fehlerprofils (Status 503). Backend, Zertifikat, Zugangsregeln und DNS bleiben stehen; umgeschaltet wird nur der Eintrag in der Host-Map, also ohne Reload — beim Beenden ist der Dienst sofort wieder da. Die Seite pflegst du wie alle anderen unter Fehlerseiten im Reiter „Wartung“.
- Member eines Pools in Wartung: Der Server bleibt im Backend, bekommt aber
keinen Verkehr mehr (
maint) — für Updates an einem einzelnen Ziel. - Proxy-Knoten in Wartung: ZPO nimmt den Knoten vorab aus den DNS-Sätzen, bevor er heruntergefahren wird. Der saubere Weg statt des Ausfalls — siehe Failover.