Dies ist die mehrseitige Druckansicht dieses Abschnitts. .
HAProxy 3.4.6-66 Dokumentation
- 1: Grundlagen der Lastverteilung
- 2: Was HAProxy ist und wie es funktioniert
- 3: Grundfunktionen
- 4: Standardfunktionen
- 5: Erweiterte Funktionen
- 6: Dimensionierung und Leistung
- 7: Versionen, Pakete und Upgrades
- 8: Ergänzende Produkte und Alternativen
- 9: Dokumentation und Community
- 10: 1. Kurzer Überblick über HTTP
- 11: 2. HAProxy konfigurieren
- 12: 3. Globaler Abschnitt
- 13: 4. Proxys
- 14: 5. Bind- und Server-Optionen
- 15: 6. Cache
- 16: 7. ACLs und Sample-Abruf
- 17: 8. Protokollierung
- 18: 9. Unterstützte Filter
- 19: 10. FastCGI-Anwendungen
- 20: 11. Stick Tables und Peers
- 21: 12. Weitere Abschnitte
- 22: 1. Voraussetzungen
- 23: 2. HAProxy-Architektur
- 24: 3. HAProxy starten
- 25: 4. HAProxy stoppen und neu starten
- 26: 5. Grenzen für Dateideskriptoren
- 27: 6. Speicherverwaltung
- 28: 7. CPU-Auslastung
- 29: 8. Protokollierung
- 30: 9. Statistiken und Überwachung
- 31: 10. Einfachere Konfigurationsverwaltung
- 32: 11. Bekannte Fallstricke vermeiden
- 33: 12. Fehlerdiagnose und Leistungsprobleme
- 34: 13. Sicherheitsaspekte
HAProxy ist ein freier, schneller und zuverlässiger Reverse-Proxy für Hochverfügbarkeit, TCP- und HTTP-Lastverteilung sowie die Verwaltung des Anwendungsverkehrs. Diese Sammlung enthält die vollständige deutsche Übersetzung der drei grundlegenden HAProxy-3.4-Handbücher, neu gegliedert als eine flache Markdown-Lesefolge für OINK.
Diese Ausgabe folgt den offiziellen englischen Handbüchern des Wartungszweigs zum Stand 3.4.6-66. Die neueste stabile Version ist 3.4.6 (v3.4.6); der Dokumentationsstand enthält Änderungen nach dieser Veröffentlichung. Die genaue Quelle ist Commit 16acce1dac1d
.
Handbuch auswählen
- Einsteigerhandbuch — 9 Themen zu Lastverteilung, HAProxy-Architektur, Funktionen, Dimensionierung, Versionen und Ökosystem.
- Konfigurationshandbuch — 12 Kapitel zu Proxys, ACLs, Samples, Protokollierung, Filtern und sämtlichen Optionsgruppen.
- Verwaltungshandbuch — 13 Kapitel zu Start, Neuladen, Ressourcen, Protokollierung, Statistiken, Runtime-CLI, Fehlerbehebung und Sicherheit.
Umfang dieser Ausgabe
| Handbuch | Originalquelle | Lokale Gliederung |
|---|---|---|
| Einsteigerhandbuch | 1,695 Zeilen | 9 flache Themenseiten |
| Konfigurationshandbuch | 33,216 Zeilen | 12 flache Kapitelseiten |
| Verwaltungshandbuch | 5,305 Zeilen | 13 flache Kapitelseiten |
Alle 34 Leseseiten liegen direkt im HAProxy-Dokumentationsverzeichnis. Drei nicht verlinkte Trennelemente gliedern die Handbücher in der Seitenleiste, ohne zusätzliche Verzeichnisebenen oder Einträge in der Seitennavigation einzuführen.
Die vollständigen festgelegten Quelldateien und SHA-256-Prüfsummen liegen unter sources/haproxy/. Der Lizenzhinweis des Originalprojekts
und der GPLv2-Text
werden zusammen mit den Handbüchern veröffentlicht. Für jede Seite ist eine geprüfte Übersetzung ins vereinfachte Chinesisch verfügbar.
1 - Grundlagen der Lastverteilung
Dieses Dokument führt in HAProxy ein, sowohl für neue Nutzer als auch für diejenigen, die ältere Versionen kennen und sich erneut damit vertraut machen möchten. Es liefert vor allem die Informationen, mit denen sich beurteilen lässt, ob HAProxy für die eigenen Anforderungen geeignet ist. Erfahrene Nutzer finden hier möglicherweise Lösungsansätze für bisherige Ideen, weil ihnen eine neue Funktion noch nicht bekannt war. Darüber hinaus behandelt das Dokument die Dimensionierung und den Produktlebenszyklus und vergleicht HAProxy mit Produkten, deren Funktionen sich teilweise überschneiden.
Das Dokument bietet keine Hilfe oder Hinweise zur Konfiguration, verweist aber auf die dafür geeignete Dokumentation. Der Leitfaden ist in der HAProxy-Seitenleiste als flache Folge von Themenseiten angeordnet.
Lastverteilung fasst mehrere Komponenten so zusammen, dass ihre gesamte Verarbeitungskapazität die Kapazität jeder einzelnen übersteigt. Dies erfolgt skalierbar und ohne Eingriff des Endnutzers. In der Zeit, die eine Komponente für eine Operation benötigt, können dadurch mehrere Operationen gleichzeitig ausgeführt werden. Eine einzelne Operation läuft jedoch weiterhin jeweils auf nur einer Komponente und wird durch die Lastverteilung nicht schneller. Um alle Komponenten zu nutzen und vollständig von der Lastverteilung zu profitieren, müssen stets mindestens so viele Operationen wie Komponenten sowie ein effizientes Verteilungsverfahren vorhanden sein. Ein anschauliches Beispiel sind mehrere Fahrspuren einer Autobahn: In derselben Zeit können mehr Autos passieren, ohne dass sich ihre individuelle Geschwindigkeit erhöht.
Beispiele für Lastverteilung:
- Prozessplanung in Mehrprozessorsystemen
- Lastverteilung auf Verbindungen, etwa EtherChannel oder Bonding
- Lastverteilung über IP-Adressen, etwa ECMP oder DNS-Round-Robin
- Lastverteilung auf Server durch Load-Balancer
Das Verfahren oder die Komponente, die die Last verteilt, heißt Load-Balancer. In Webumgebungen spricht man von einem Netzwerk-Load-Balancer oder meist einfach von einem Load-Balancer, da dies der mit Abstand bekannteste Anwendungsfall der Lastverteilung ist.
Ein Load-Balancer kann auf verschiedenen Ebenen arbeiten:
-
auf Verbindungsebene: Er wählt aus, über welche Netzwerkverbindung ein Paket gesendet wird;
-
auf Netzwerkebene: Er bestimmt die Route, der eine Folge von Paketen folgt;
-
auf Serverebene: Er entscheidet, welcher Server eine Verbindung oder Anfrage verarbeitet.
Es gibt zwei unterschiedliche Technologien für verschiedene, teilweise überlappende Anforderungen. In beiden Fällen ist zu beachten, dass Lastverteilung den Datenverkehr von seinem natürlichen Weg ablenkt. Dies verlangt stets eine gewisse Sorgfalt, damit alle Routingentscheidungen ausreichend konsistent bleiben.
Die erste Technologie arbeitet auf Paketebene und verarbeitet Pakete mehr oder weniger einzeln. Zwischen eingehenden und ausgehenden Paketen besteht eine 1:1-Beziehung, sodass sich der Datenverkehr auf beiden Seiten des Load-Balancers mit einem gewöhnlichen Netzwerkmitschnitt verfolgen lässt. Dieses Verfahren kann sehr günstig und extrem schnell sein. Meist wird es in Hardware mit ASICs umgesetzt und erreicht Leitungsgeschwindigkeit, etwa in Switches mit ECMP. Gewöhnlich ist es zustandslos, kann aber auch die Sitzung berücksichtigen, zu der ein Paket gehört, und damit zustandsbehaftet arbeiten; dies wird als layer4-LB oder L4 bezeichnet. Wenn die Pakete unverändert bleiben, kann DSR unterstützt werden: Der Server antwortet direkt, ohne erneut den LB zu durchlaufen. Den Inhalt kennt dieses Verfahren jedoch kaum. Es eignet sich sehr gut zur Lastverteilung auf Netzwerkebene, wird aber gelegentlich auch für sehr einfache, schnelle Lastverteilung auf Server verwendet.
Die zweite Technologie verarbeitet den Inhalt von Sitzungen. Dazu muss sie eingehende Datenströme zusammensetzen und als Ganzes verarbeiten. Der Inhalt kann geändert werden; der ausgehende Datenstrom wird anschließend in neue Pakete zerlegt. Deshalb übernehmen meist Proxys diese Aufgabe, die oft Load-Balancer für Schicht 7 oder L7 genannt werden. Auf beiden Seiten bestehen getrennte Verbindungen. Zwischen Größe und Anzahl der eingehenden und ausgehenden Pakete gibt es keinen Zusammenhang. Clients und Server müssen nicht dasselbe Protokoll verwenden, etwa IPv4 statt IPv6 oder Klartext statt SSL. Die Verarbeitung ist immer zustandsbehaftet, und der Rückverkehr muss den Load-Balancer durchlaufen. Der zusätzliche Aufwand kann verhindern, dass Leitungsgeschwindigkeit erreicht wird, besonders bei kleinen Paketen. Dafür bietet das Verfahren viele Möglichkeiten und wird meist vollständig in Software umgesetzt, auch innerhalb von Hardware-Appliances. Es eignet sich sehr gut zur Lastverteilung auf Server.
Paketbasierte Load-Balancer werden meist im Durchleitungsmodus eingesetzt: Sie liegen auf dem normalen Verkehrsweg und lenken Pakete gemäß ihrer Konfiguration um. Der Rückverkehr muss sie nicht zwingend passieren. Wird jedoch die Netzwerkzieladresse geändert, um den Datenverkehr zum richtigen Ziel zu führen, muss der Rückverkehr durch den Load-Balancer laufen. Erlaubt das Routing dies nicht, kann der Load-Balancer zusätzlich die Quelladresse der Pakete durch seine eigene ersetzen und den Rückweg dadurch erzwingen.
Proxy-basierte Load-Balancer werden ohne Architekturänderung als Server mit eigenen IP-Adressen und Ports eingesetzt. Manchmal müssen Anwendungen angepasst werden, damit Clients die IP-Adresse des Load-Balancers statt direkt die des Servers verwenden. Dafür müssen manche Load-Balancer Serverantworten verändern, etwa das HTTP-Headerfeld Location bei HTTP-Weiterleitungen. Einige Proxy-basierte Load-Balancer können auch Datenverkehr für fremde Adressen abfangen und beim Verbindungsaufbau zum Server die Clientadresse verwenden. Dadurch lassen sie sich wie gewöhnliche Router oder Firewalls im Durchleitungsmodus einsetzen, ähnlich paketbasierten Load-Balancern. Dies ist besonders bei Produkten beliebt, die Paket- und Proxy-Modus kombinieren. DSR ist dabei selbstverständlich weiterhin nicht möglich; der Rückverkehr muss zum Load-Balancer geroutet werden.
Ein sehr gut skalierbarer Schichtenaufbau kann mit einem vorgeschalteten Router beginnen, der Datenverkehr über mehrere lastverteilte Verbindungen empfängt. Über ECMP verteilt er diesen auf eine erste Schicht mehrerer zustandsbehafteter, paketbasierter L4-Load-Balancer. Diese L4-Load-Balancer leiten ihn an eine noch größere Anzahl Proxy-basierter L7-Load-Balancer weiter, die den Inhalt auswerten und den endgültigen Zielserver bestimmen.
Mit der Anzahl der Komponenten und möglichen Verkehrswege steigt das Ausfallrisiko. In sehr großen Umgebungen ist es sogar normal, dass ständig einige defekte Komponenten repariert oder ersetzt werden. Lastverteilung ohne Kenntnis des Zustands des gesamten Systems verschlechtert die Verfügbarkeit erheblich. Jeder sinnvoll ausgelegte Load-Balancer prüft deshalb, ob seine Zielkomponenten noch aktiv und erreichbar sind, und sendet keinen Datenverkehr mehr an fehlerhafte Komponenten. Dafür gibt es verschiedene Verfahren.
Am häufigsten werden regelmäßig Prüfanfragen gesendet, um die Funktionsfähigkeit einer Komponente festzustellen. Diese Prüfungen heißen Health Checks und müssen die zu erkennenden Fehler abbilden. Ein Ping erkennt beispielsweise nicht, dass ein Webserver abgestürzt ist und nicht mehr auf einem Port lauscht. Ein Verbindungsversuch zu diesem Port erkennt dies dagegen. Eine weitergehende Anfrage kann sogar prüfen, ob der Server noch funktioniert und auf seine Datenbank zugreifen kann. Health Checks wiederholen die Prüfung oft einige Male, um gelegentliche Messfehler abzufangen. Das Prüfintervall muss kurz genug sein, damit eine fehlerhafte Komponente nach einem Ausfall nicht zu lange weiterverwendet wird.
Andere Verfahren beobachten Stichproben des an ein Ziel gesendeten Produktionsverkehrs und entfernen Komponenten, die unpassende Antworten liefern. Dabei wird allerdings ein Teil des Produktionsverkehrs beeinträchtigt, was nicht immer akzeptabel ist. Die Kombination beider Verfahren verbindet ihre Vorteile: Beide erkennen Fehler, aber nur Health Checks erkennen deren Behebung. Ein weiteres Verfahren nutzt zentrale Zustandsmeldungen. Ein zentraler Überwachungsagent informiert alle Load-Balancer regelmäßig über den Zustand sämtlicher Komponenten. Alle erhalten damit eine Gesamtsicht auf die Infrastruktur, allerdings mitunter weniger genau oder verzögert. Dieses Verfahren eignet sich besonders für Umgebungen mit vielen Load-Balancern und Servern.
Load-Balancer für Schicht 7 müssen außerdem Sitzungspersistenz gewährleisten, auch als Stickiness bezeichnet. Mehrere aufeinanderfolgende Anfragen oder Verbindungen derselben Quelle, etwa eines Endnutzers, müssen dabei meist dasselbe Ziel erreichen. Das bekannteste Beispiel ist der Warenkorb eines Onlineshops. Erzeugt jeder Klick eine neue Verbindung, muss der Nutzer stets zu dem Server gelangen, auf dem sein Warenkorb liegt. Die Auswertung des Inhalts erleichtert es, Merkmale der Anfrage zur Bestimmung des Zielservers zu verwenden, reicht aber nicht immer aus. Wird beispielsweise die Quelladresse als Schlüssel verwendet, kann ein Hash-Verfahren jede IP-Adresse anhand einer Division durch die Anzahl verfügbarer Server stets demselben Server zuordnen. Fällt jedoch ein Server aus, ändert sich das Ergebnis. Plötzlich gelangen alle Nutzer zu einem anderen Server und verlieren ihren Warenkorb. Die Lösung besteht darin, das gewählte Ziel zu speichern und denselben Besucher unabhängig von der Anzahl verfügbarer Server immer dorthin zu leiten. Diese Information kann im Speicher des Load-Balancers liegen und muss bei mehreren Load-Balancern gegebenenfalls repliziert werden. Alternativ kann sie auf verschiedene Weise beim Client gespeichert werden, sofern dieser sie bei jeder Anfrage wieder übermittelt, etwa durch eingefügte Cookies oder eine Weiterleitung auf eine Subdomain. Zusätzlich entfällt damit die Abhängigkeit von instabilen oder ungleich verteilten Merkmalen wie der Quell-IP-Adresse. Dies ist der wichtigste Grund für einen Load-Balancer auf Schicht 7 statt auf Schicht 4.
Um Cookies, das Host-Headerfeld, URLs oder andere Informationen auszulesen, muss ein Load-Balancer SSL/TLS-Datenverkehr möglicherweise entschlüsseln und beim Weiterleiten an den Server wieder verschlüsseln. Dieser hohe Aufwand erklärt, weshalb manche stark ausgelasteten Infrastrukturen sehr viele Load-Balancer benötigen.
Ein Load-Balancer für Schicht 7 führt zahlreiche komplexe Operationen aus, etwa Entschlüsselung, Auswertung und Änderung des Inhalts, Cookie-Abgleich und Serverauswahl. Dabei kann er durchaus Probleme verursachen. Häufig wird er jedoch für Probleme verantwortlich gemacht, die er lediglich sichtbar gemacht hat. Oft stellt sich heraus, dass Server instabil sind und regelmäßig ausfallen, dass Webseiten fest eingebaute Links enthalten, die Clients am Load-Balancer vorbei direkt zu einem bestimmten Server führen, oder dass Server unter hoher Last so langsam antworten, dass Zeitüberschreitungen entstehen. Deshalb ist die Protokollierung bei Lastverteilung auf Schicht 7 äußerst wichtig. Sobald ein Problem gemeldet wird, ist es wichtig zu klären, ob der Load-Balancer falsch entschieden hat und gegebenenfalls warum, damit es nicht erneut passiert.
2 - Was HAProxy ist und wie es funktioniert
Die Schreibweise “HAProxy” bezeichnet das Produkt, “haproxy” dagegen das ausführbare Programm, das Softwarepaket oder einen Prozess. Häufig werden beide Schreibweisen jedoch für beide Bedeutungen verwendet; ausgesprochen werden sie H-A-Proxy. Ursprünglich stand “haproxy” für „High Availability Proxy“, und der Name wurde in zwei getrennten Wörtern geschrieben. Heute bedeutet er ausschließlich “HAProxy”.
3.1. Was HAProxy ist und was nicht
HAProxy ist:
-
ein TCP-Proxy: Er nimmt TCP-Verbindungen über einen lauschenden Socket an, verbindet sich mit einem Server und verknüpft beide Sockets für die bidirektionale Datenübertragung. Auf beiden Seiten werden IPv4, IPv6 und sogar UNIX-Sockets unterstützt. Dadurch lassen sich Adressen verschiedener Familien einfach ineinander überführen.
-
ein HTTP-Reverse-Proxy, in der HTTP-Terminologie ein „Gateway“: Er tritt als Server auf, empfängt HTTP-Anfragen über Verbindungen eines lauschenden TCP-Sockets und leitet sie über andere Verbindungen an Server weiter. Auf beiden Seiten ist jede Kombination aus HTTP/1.x und HTTP/2 möglich. Bei ALPN über TLS erkennt er das verwendete Protokoll auf jeder Seite automatisch.
-
ein System zum Terminieren, Initiieren und Auslagern von SSL: SSL/TLS kann auf der Verbindung vom Client, auf der Verbindung zum Server oder auf beiden verwendet werden. Viele Einstellungen lassen sich je Name über SNI festlegen und ohne Neustart zur Laufzeit ändern. Solche Konfigurationen skalieren sehr gut; es gibt Berichte über Zehntausende bis Hunderttausende eingesetzte Zertifikate.
-
ein TCP-Normalisierer: Da das Betriebssystem die Verbindungen lokal terminiert, besteht kein Zusammenhang zwischen beiden Seiten. Ungültige Pakete, Flag-Kombinationen, Fensterankündigungen, Sequenznummern, unvollständige Verbindungen bei SYN-Floods und anderer ungewöhnlicher Datenverkehr gelangen daher nicht auf die Gegenseite. Dies schützt anfällige TCP-Stacks vor Protokollangriffen und erlaubt eine Optimierung der Verbindung zum Client, ohne den TCP-Stack der Server anzupassen.
-
ein HTTP-Normalisierer: Bei aktivierter HTTP-Verarbeitung leitet er nur gültige, vollständige Anfragen weiter und schützt damit vor vielen Protokollangriffen. Außerdem korrigiert er Abweichungen, für die die Spezifikation Toleranz vorsieht, etwa mehrzeilige Header, damit sie auf den Servern keine Probleme verursachen.
-
ein Werkzeug zur Korrektur von HTTP: Er kann die URL sowie beliebige Anfrage- oder Antwort-Header ändern, korrigieren, ergänzen, entfernen oder umschreiben. Das hilft bei Interoperabilitätsproblemen in komplexen Umgebungen.
-
ein inhaltsabhängiger Verteiler: Anhand beliebiger Merkmale einer Anfrage entscheidet er, an welchen Server die Anfrage oder Verbindung geht. So können mehrere Protokolle wie HTTP, HTTPS und SSH über denselben Port verarbeitet werden.
-
ein Load-Balancer für Server: Er verteilt TCP-Verbindungen und HTTP-Anfragen. Im TCP-Modus gilt die Entscheidung für die gesamte Verbindung, im HTTP-Modus für jede einzelne Anfrage.
-
ein Regler für den Datenverkehr: Er begrenzt Raten an verschiedenen Stellen, schützt Server vor Überlastung und passt Prioritäten anhand des Inhalts an. Durch Paketmarkierungen kann er diese Informationen sogar an niedrigere Schichten und externe Netzwerkkomponenten weitergeben.
-
ein Schutz gegen DDoS und Dienstmissbrauch: Er führt zahlreiche Statistiken etwa je IP-Adresse, URL oder Cookie, erkennt Missbrauch und reagiert darauf, indem er Verursacher verlangsamt, blockiert oder auf veraltete Inhalte umleitet.
-
ein Beobachtungspunkt für die Netzwerkdiagnose: Die präzisen Protokollangaben werden häufig verwendet, um Netzwerkprobleme einzugrenzen.
-
ein System zum Auslagern der HTTP-Komprimierung: Er komprimiert Antworten, die der Server unkomprimiert liefert, und verkürzt dadurch die Ladezeit bei schlechter Anbindung oder in Mobilfunknetzen mit hoher Latenz.
-
ein Proxy mit Cache: Er kann Antworten im RAM zwischenspeichern. Solange ein Objekt vorhanden und gültig ist, entfällt bei weiteren Anfragen die erneute Netzwerkübertragung vom Server. Auf dauerhaftem Speicher legt er jedoch keine Objekte ab. Diese Cache-Funktion ist wartungsfrei ausgelegt und soll ausschließlich die wertvollen Ressourcen von haproxy schonen, nicht die des Servers. Caches zur Serveroptimierung benötigen erheblich mehr Einstellmöglichkeiten und Flexibilität. Wird ein solcher umfassender Cache benötigt, sollte Varnish Cache verwendet werden. Es lässt sich besonders bei SSL/TLS auf einer der beiden Seiten hervorragend mit haproxy kombinieren.
-
ein FastCGI-Gateway: FastCGI lässt sich als andere Darstellung von HTTP auffassen. HAProxy kann deshalb die Last direkt auf eine beliebige Kombination von FastCGI-Anwendungsservern verteilen, ohne eine weitere Gateway-Schicht einzufügen. Das spart Ressourcen und senkt den Wartungsaufwand.
HAProxy ist nicht:
-
ein expliziter HTTP-Proxy, über den Browser auf das Internet zugreifen. Dafür gibt es sehr gute Open-Source-Programme wie Squid. HAProxy kann jedoch davor eingesetzt werden, um Lastverteilung und Hochverfügbarkeit bereitzustellen.
-
ein Werkzeug zur Bereinigung von Daten: Es ändert weder Anfrage- noch Antwortkörper.
-
ein Server für statische Webseiten: Beim Start isoliert es sich in einer chroot-Umgebung und gibt Berechtigungen ab. Danach greift es nicht mehr auf das Dateisystem zu und kann deshalb nicht als statischer Webserver eingesetzt werden. Dynamische Server werden jedoch über FastCGI unterstützt. Für statische Inhalte gibt es sehr gute Open-Source-Programme wie Apache oder NGINX. HAProxy lässt sich einfach davor einsetzen, um Lastverteilung, Hochverfügbarkeit und Beschleunigung bereitzustellen.
-
ein paketbasierter Load-Balancer: Es sieht weder IP-Pakete noch UDP-Datagramme und führt weder NAT noch DSR aus. Das sind Aufgaben niedrigerer Schichten. Kernel-Komponenten wie IPVS, Linux Virtual Server, erledigen dies bereits sehr gut und ergänzen HAProxy hervorragend.
3.2. Wie HAProxy arbeitet
HAProxy arbeitet ereignisgesteuert und nicht blockierend. Es verbindet eine sehr schnelle I/O-Schicht mit einem prioritätsgesteuerten Scheduler für mehrere Threads. Seine auf Datenweiterleitung ausgerichtete Architektur bewegt Daten mit möglichst wenigen Operationen so schnell wie möglich. Um CPU-Caches effizient zu nutzen, bleiben Verbindungen möglichst lange derselben CPU zugeordnet. Ein Schichtenmodell mit Umgehungsmöglichkeiten auf jeder Ebene sorgt dafür, dass Daten höhere Ebenen nur bei Bedarf erreichen. Der Großteil der Verarbeitung findet im Kernel statt. HAProxy unterstützt ihn dabei durch Hinweise und verzichtet auf manche Operationen, wenn sie voraussichtlich später zusammengefasst werden können. Typischerweise entfallen daher im TCP- oder HTTP-Close-Modus 15% der Verarbeitungszeit auf HAProxy und 85% auf den Kernel; im HTTP-Keep-Alive-Modus sind es etwa 30% für HAProxy und 70% für den Kernel.
Ein einzelner Prozess kann viele Proxy-Instanzen ausführen. Berichten zufolge funktionieren selbst Konfigurationen mit 300000 verschiedenen Proxys in einem Prozess problemlos. Ein System mit einer CPU und einem Kern reicht für mehr als 99% der Nutzer deutlich aus. Für Container und virtuelle Maschinen werden deshalb die kleinstmöglichen Images empfohlen, um Betriebskosten zu sparen und die Fehlerbehebung zu vereinfachen. Der Rechner, auf dem HAProxy läuft, darf jedoch niemals auslagern. Seine CPU darf weder künstlich gedrosselt werden, etwa durch Zuweisung eines CPU-Anteils im Hypervisor, noch mit rechenintensiven Prozessen geteilt werden, die eine hohe Latenz bei Kontextwechseln verursachen.
Mit einem Thread pro CPU-Kern kann HAProxy die gesamte verfügbare Rechenleistung nutzen. Dies ist vor allem für SSL oder Weiterleitungsraten über 40 Gbps hilfreich. Dabei muss Kommunikation zwischen mehreren physischen CPUs unbedingt vermieden werden, da sie starke Engpässe im Netzwerk-Stack und in HAProxy selbst verursachen kann. Auch wenn es zunächst widersprüchlich erscheint, sollte bei Leistungsproblemen oft zuerst die Anzahl der von HAProxy verwendeten CPUs reduziert werden.
Zum Betrieb benötigt HAProxy nur die ausführbare Datei haproxy und eine Konfigurationsdatei. Für die Protokollierung werden ein korrekt eingerichteter syslog-Daemon und eine Protokollrotation dringend empfohlen. Protokolle können auch an stdout/stderr gesendet werden, was in Containern nützlich ist. HAProxy liest die Konfigurationsdateien vor dem Start ein und versucht anschließend, alle lauschenden Sockets zu binden. Scheitert etwas, verweigert er den Start. Danach kann HAProxy nicht mehr fehlschlagen. Es treten also keine Laufzeitfehler auf: Wenn HAProxy startet, arbeitet es, bis es gestoppt wird.
Nach dem Start erledigt HAProxy genau 3 Aufgaben:
-
eingehende Verbindungen verarbeiten;
-
regelmäßig den Zustand der Server prüfen, die sogenannten Health Checks;
-
Informationen mit anderen haproxy-Knoten austauschen.
Die Verarbeitung eingehender Verbindungen ist wegen der vielen Konfigurationsmöglichkeiten mit Abstand die komplexeste Aufgabe. Sie lässt sich aber in die folgenden 9 Schritte zusammenfassen:
-
Eingehende Verbindungen über lauschende Sockets annehmen. Diese gehören zu einer Konfigurationseinheit namens “frontend”, die eine oder mehrere lauschende Adressen referenziert;
-
die Regeln des Frontends auf diese Verbindungen anwenden. Dabei können Verbindungen blockiert, Header geändert oder Verbindungen für interne Applets wie die Statistikseite oder CLI abgefangen werden;
-
die eingehenden Verbindungen an eine weitere Konfigurationseinheit namens “backend” übergeben. Sie stellt eine Serverfarm dar und enthält deren Serverliste und Lastverteilungsstrategie;
-
die Regeln des Backends auf diese Verbindungen anwenden;
-
anhand der Lastverteilungsstrategie den Zielserver für die Verbindung wählen;
-
die Regeln des Backends auf die Antwortdaten anwenden;
-
die Regeln des Frontends auf die Antwortdaten anwenden;
-
den Ablauf detailliert protokollieren;
-
bei HTTP zum zweiten Schritt zurückkehren und auf eine neue Anfrage warten, andernfalls die Verbindung schließen.
Frontends und Backends werden manchmal als halbe Proxys betrachtet, weil sie jeweils nur eine Seite einer durchgehenden Verbindung abdecken: Das Frontend kümmert sich um die Clients, das Backend um die Server. HAProxy unterstützt außerdem vollständige Proxys, die Frontend und Backend exakt vereinen. Für HTTP wird die Konfiguration meist in Frontends und Backends aufgeteilt. Da jedes Frontend eine Verbindung an jedes Backend übergeben kann, eröffnet dies viele Möglichkeiten. Bei reinen TCP-Proxys bringt diese Trennung selten Vorteile; vollständige Proxys können die Konfiguration dann übersichtlicher machen.
3 - Grundfunktionen
Dieser Abschnitt beschreibt Funktionen von HAProxy. Manche werden von jedem modernen Load-Balancer erwartet, andere ergeben sich unmittelbar aus der Architektur von HAProxy. Weitergehende Funktionen behandelt der nächste Abschnitt.
3.3.1. Grundfunktionen: Proxy-Betrieb
Im Proxy-Betrieb werden Daten über zwei unabhängige Verbindungen zwischen Client und Server übertragen. Dafür und für die Verbindungsverwaltung unterstützt HAProxy folgende Grundfunktionen:
-
Eine bereinigte Verbindung zum Server schützt ihn vor Fehlern und Angriffen auf der Clientseite;
-
Lauschen auf mehreren IP-Adressen und/oder Ports, auch auf Portbereichen;
-
transparentes Annehmen: Abfangen von Datenverkehr für beliebige IP-Adressen, die nicht einmal zum lokalen System gehören müssen;
-
der Serverport muss nicht dem lauschenden Port entsprechen. Er kann auch um einen festen Wert verschoben werden, was bei Portbereichen nützlich ist;
-
transparenter Verbindungsaufbau: Beim Verbinden mit dem Server kann bei Bedarf die IP-Adresse des Clients oder eine beliebige andere verwendet werden;
-
Bereitstellung einer zuverlässigen IP-Adresse für den Rückweg bei Load-Balancern (LBs) an mehreren Standorten;
-
Entlastung der Server durch Puffer und gegebenenfalls kurzlebige Verbindungen, wodurch die Zahl gleichzeitiger Verbindungen und der Speicherbedarf sinken;
-
Optimierung von TCP-Stacks, etwa SACK, und der Überlastungssteuerung sowie Verringerung der Auswirkungen der RTT;
-
Unterstützung unterschiedlicher Protokollfamilien auf beiden Seiten, etwa IPv4/IPv6/Unix;
-
Durchsetzung von Zeitüberschreitungen auf mehreren Ebenen je nach Verbindungsphase, damit ausgefallene Clients oder Server sowie Angreifer Ressourcen nicht zu lange belegen;
-
Protokollprüfung: HTTP, SSL oder Nutzdaten werden untersucht. Ungültige Protokollelemente werden zurückgewiesen, sofern ihre Annahme nicht ausdrücklich angeordnet wurde;
-
Durchsetzung von Richtlinien, damit nur erlaubter Datenverkehr weitergeleitet wird;
-
eingehende und ausgehende Verbindungen können auf bestimmte Netzwerk-Namespaces beschränkt werden, nur unter Linux. So lässt sich leicht ein mandantenfähiger Load-Balancer für mehrere Container aufbauen;
-
das PROXY-Protokoll übermittelt die Client-IP-Adresse auch bei Nicht-HTTP-Datenverkehr an den Server. Diese HAProxy-Erweiterung wurde inzwischen von mehreren Drittanbieterprodukten übernommen, zum Zeitpunkt der Erstellung mindestens von folgenden:
- Client: haproxy, stud, stunnel, exaproxy, ELB, squid
- Server: haproxy, stud, postfix, exim, NGINX, squid, node.js, varnish
3.3.2. Grundfunktionen: SSL
Nach Einschätzung von Google-Ingenieuren zählt der SSL-Stack von HAProxy zu den funktionsreichsten (http://istlsfastyet.com/ ). Zu den häufig genutzten Funktionen gehören:
-
Leistungsfähiges SNI-basiertes Hosting mehrerer Websites ohne Begrenzung ihrer Anzahl. Mindestens eine bekannte Installation betreibt 50000 Domains mit eigenen Zertifikaten;
-
Wildcard-Zertifikate verringern die Anzahl benötigter Zertifikate;
-
zertifikatsbasierte Clientauthentifizierung mit konfigurierbaren Regeln für den Fall, dass kein gültiges Zertifikat vorgelegt wird. So kann beispielsweise eine andere Serverfarm bereitgestellt werden, über die das Clientzertifikat erneuert wird;
-
die Authentifizierung des Backend-Servers stellt sicher, dass tatsächlich der richtige Server und kein zwischengeschalteter Angreifer angesprochen wird;
-
die Authentifizierung gegenüber dem Backend-Server bestätigt diesem, dass sich der erwartete haproxy-Knoten verbindet;
-
die TLS-Erweiterungen NPN und ALPN ermöglichen es, die Verarbeitung von SPDY/HTTP2-Verbindungen zuverlässig auszulagern und die Daten unverschlüsselt an Backend-Server weiterzugeben;
-
OCSP-Stapling verkürzt die erste Seitenladezeit weiter, indem eine OCSP-Antwort direkt mitgeliefert wird, wenn der Client eine Certificate Status Request anfordert;
-
dynamische Record-Größen bieten zugleich hohe Leistung und geringe Latenz. Sie verkürzen die Seitenladezeit deutlich, da der Browser bereits weitere Objekte abrufen kann, während noch Pakete unterwegs sind;
-
alle relevanten Informationen der SSL/TLS-Schicht stehen jederzeit für Protokollierung, Zugriffskontrolle, Berichte und andere Zwecke bereit. Sie können in HTTP-Header oder als PROXY-Protokollerweiterung eingebettet werden. Der entlastete Server erhält damit alle Informationen, die er auch bei eigener SSL-Terminierung hätte.
-
bestimmte bekannte Angriffe werden selbst bei anfälligen SSL-Bibliotheken erkannt, protokolliert und blockiert, etwa Heartbleed gegen bestimmte OpenSSL-Versionen.
-
zustandslose Sitzungswiederaufnahme nach RFC 5077 mit der TLS-Ticket-Erweiterung. TLS-Tickets können über die CLI aktualisiert werden. Häufiger Ticketwechsel ermöglicht damit Perfect Forward Secrecy.
3.3.3. Grundfunktionen: Überwachung
HAProxy legt großen Wert auf Verfügbarkeit. Deshalb überwacht es den Serverzustand und meldet anderen Netzwerkkomponenten seinen eigenen Zustand:
-
Der Serverzustand wird kontinuierlich mit serverspezifischen Parametern überwacht. Damit wird geprüft, ob der Weg zum Server für gewöhnlichen Datenverkehr funktioniert;
-
Health Checks verwenden getrennte Hysteresen für den Wechsel in den verfügbaren und den ausgefallenen Zustand, um ständige Zustandswechsel zu vermeiden;
-
Prüfungen können eine andere Adresse, einen anderen Port oder ein anderes Protokoll verwenden. So lässt sich ein einzelner Dienst prüfen, der als repräsentativ für mehrere Dienste gilt, etwa der HTTPS-Port eines HTTP+HTTPS-Servers.
-
Server können den Zustand anderer Server übernehmen und gleichzeitig als ausgefallen gelten. Dadurch können Server mit mehreren Diensten als Ganzes aus der Verteilung genommen werden, und niemand gelangt zu einem nur teilweise funktionsfähigen Server;
-
Agenten auf dem Server können Last und Zustand überwachen. Ein Server kann seine Last, seinen Betriebszustand und seinen administrativen Zustand unabhängig von den Health Checks melden. Ein einfacher Agent ermöglicht es, diese Selbsteinschätzung zusätzlich zu den Prüfungen des gesamten Zugriffswegs zu berücksichtigen;
-
verschiedene Prüfverfahren stehen zur Verfügung: TCP-Verbindungsaufbau, HTTP-Anfrage, SMTP-Hello, SSL-Hello, LDAP, SQL, Redis und send/expect-Skripte, jeweils mit oder ohne SSL;
-
Zustandsänderungen erscheinen mit Fehlerursache in den Protokollen und auf der Statistikseite, etwa mit der beim Erkennen des Fehlers empfangenen HTTP-Antwort. Außerdem kann eine E-Mail an eine konfigurierbare Adresse gesendet werden;
-
die Statistikschnittstelle meldet ebenfalls den Serverzustand. Er kann für Routingentscheidungen genutzt werden, um den Datenverkehr je nach Größe und/oder Zustand auf verschiedene Farmen zu verteilen, etwa beim Ausfall einer Verbindung zwischen Rechenzentren (DC);
-
HAProxy kann über Health-Check-Anfragen Informationen wie Servernamen, Gewicht oder Anzahl anderer Server der Farm übermitteln. Die Server können damit ihre Antworten und Entscheidungen anpassen, beispielsweise Backups verschieben, um mehr CPU-Leistung freizuhalten;
-
Server können über Health Checks mehr als nur „an“ oder „aus“ melden, etwa den Wunsch, herunterzufahren und deshalb keine neuen Besucher mehr zu erhalten;
-
HAProxy selbst kann externen Komponenten wie Routern oder anderen Load-Balancern seinen Zustand melden. So lassen sich umfassende Infrastrukturen mit mehreren Pfaden und Schichten aufbauen.
3.3.4. Grundfunktionen: Hochverfügbarkeit
Wie jeder für den ernsthaften Einsatz ausgelegte Load-Balancer legt HAProxy großen Wert auf Verfügbarkeit, um eine möglichst hohe Dienstkontinuität zu gewährleisten:
-
Nur funktionsfähige Server werden verwendet; die übrigen werden automatisch aus den Serverfarmen ausgeschlossen. Unter bestimmten Bedingungen kann ihre Verwendung dennoch erzwungen werden;
-
geordnetes Herunterfahren erlaubt es, Server ohne Beeinträchtigung bestehender Verbindungen aus einer Farm zu nehmen;
-
fallen aktive Server aus, übernehmen automatisch Backup-Server. So gehen Sitzungen nach Möglichkeit nicht verloren. Dies ermöglicht außerdem mehrere Wege zum selben Server, etwa über verschiedene Schnittstellen;
-
fallen zu viele Server aus, kann für die gesamte Farm ein Fehlerzustand gemeldet werden. Zusammen mit den Überwachungsfunktionen kann eine vorgeschaltete Komponente dadurch für einen Dienst einen anderen Load-Balancer-Knoten (LB) wählen;
-
die zustandslose Architektur erleichtert den Clusteraufbau. HAProxy gewährleistet möglichst hohe Dienstkontinuität, ohne Informationen speichern zu müssen, die bei einem Ausfall verloren gehen könnten. Eine Übernahme erfolgt dadurch möglichst nahtlos;
-
gute Integration mit dem üblichen VRRP-Daemon keepalived: HAProxy meldet ihm problemlos seinen Zustand und unterstützt wechselnde virtuelle IP-Adressen sehr gut. Hinweis: Ausschließlich IP-Redundanzprotokolle wie VRRP/CARP anstelle von Cluster-Lösungen wie Heartbeat verwenden. Sie bieten den schnellsten, nahtlosesten und zuverlässigsten Switchover.
3.3.5. Grundfunktionen: Lastverteilung
HAProxy bietet umfangreiche Funktionen zur Lastverteilung, die leider bei vielen anderen Produkten fehlen:
-
Mindestens 10 Lastverteilungsverfahren werden unterstützt. Manche verwenden Eingabedaten und eröffnen dadurch unbegrenzt viele Möglichkeiten. Häufig verwendet werden round-robin, das bei kurzen Verbindungen reihum jeden Server auswählt; leastconn, das bei langen Verbindungen unter den Servern mit der kleinsten Verbindungszahl den am längsten nicht verwendeten auswählt; source, das für SSL- oder Terminalserver-Farmen direkt von der Clientquelladresse abhängt; URI, das für HTTP-Caches direkt die HTTP-URI verwendet; hdr, das den Inhalt eines bestimmten HTTP-Headerfelds verwendet; und first, das bei kurzlebigen virtuellen Maschinen alle Verbindungen auf möglichst wenige Server konzentriert, damit ungenutzte Server ausgeschaltet werden können;
-
alle genannten Verfahren unterstützen serverspezifische Gewichte. So können verschiedene Servergenerationen in einer Farm kombiniert oder kleine Anteile des Datenverkehrs gezielt an bestimmte Server gesendet werden, etwa für Diagnosezwecke oder eine neue Softwareversion;
-
round-robin, leastconn und konsistentes Hashing unterstützen dynamische Gewichte. Diese können zur Laufzeit über die CLI oder sogar durch einen Agenten auf dem Server geändert werden;
-
überall dort, wo dynamische Gewichte unterstützt werden, ist auch slow-start verfügbar. Damit übernimmt ein Server schrittweise Datenverkehr. Dies ist wichtig für empfindliche Anwendungsserver, die Klassen zur Laufzeit kompilieren müssen, sowie für kalte Caches, die vor der vollen Auslastung zunächst gefüllt werden müssen;
-
Hashing kann unter anderem die Clientquelladresse, URL-Bestandteile, Elemente der Abfragezeichenfolge, Headerfeldwerte, POST-Parameter oder RDP-Cookies verwenden;
-
konsistentes Hashing verhindert eine umfangreiche Neuverteilung, wenn Server zur Farm hinzugefügt oder daraus entfernt werden. Das ist für große Cache-Farmen besonders wichtig und ermöglicht die schrittweise Füllung kalter Caches mit slow-start;
-
interne Messwerte wie Verbindungszahlen je Server und Backend oder freie Verbindungsplätze eines Backends ermöglichen sehr ausgefeilte Lastverteilungsstrategien.
3.3.6. Grundfunktionen: Sitzungspersistenz
Lastverteilung für Anwendungen wäre ohne Sitzungspersistenz nutzlos. HAProxy bietet umfassende Möglichkeiten, Besucher auch beim Hinzufügen oder Entfernen von Servern sowie bei Ausfällen und Wiederanläufen demselben Server zuzuordnen. Einige Verfahren kommen ohne Replikation aus und funktionieren deshalb auch bei weit voneinander entfernten Load-Balancer-Knoten:
-
Informationen zur Sitzungspersistenz können bei Bedarf an unterschiedlichen Stellen abgeglichen und erlernt werden. Beispielsweise kann JSESSIONID sowohl in einem Cookie als auch in der URL abgeglichen werden. Bis zu 8 Quellen können gleichzeitig erlernt werden; jede kann auf eine andere Stick Table verweisen;
-
Persistenzinformationen können aus beliebigen sichtbaren Merkmalen einer Anfrage oder Antwort stammen, etwa Quelladresse, Position und Länge von TCP-Nutzdaten, HTTP-Abfrageparametern, Headerfeldwerten oder Cookies.
-
Stick Tables werden im Multi-Master-Verfahren zwischen allen Knoten repliziert;
-
häufig benötigte Merkmale wie SSL-ID oder RDP-Cookies für TSE-Farmen sind direkt zugänglich und dadurch einfach zu verwenden;
-
alle Persistenzregeln können dynamisch durch ACLs bedingt werden;
-
bestimmte Server, etwa Backup-Server, können von der dauerhaften Zuordnung ausgeschlossen werden. Sobald der reguläre Server wieder verfügbar ist, übernimmt er die Last automatisch zurück. Dies wird häufig in Umgebungen mit mehreren Pfaden eingesetzt;
-
bei HTTP wird häufig auf das Erlernen verzichtet und stattdessen ein eigenes Persistenz-Cookie verwendet. Es kann erkannt, umgeschrieben, eingefügt oder mit einem Präfix versehen werden, damit sich der Client den zugewiesenen Server merkt;
-
der Server kann das Persistenz-Cookie bei der Abmeldung ändern oder löschen. Besucher, die die Anwendung verlassen, werden dadurch automatisch vom Server gelöst;
-
ACL-Regeln können die Sitzungspersistenz unabhängig vom Serverzustand gezielt ignorieren oder erzwingen. Zusammen mit erweiterten Health Checks lässt sich so prüfen, ob ein gerade eingerichteter Server funktioniert, bevor er öffentlich freigegeben wird;
-
ein neuartiges Verfahren begrenzt die maximale Leerlaufzeit und Gesamtdauer von Cookies. So kann die Persistenz auch auf nie ausgeschalteten Geräten wie Smartphones, TV-Geräten und Haushaltsgeräten geordnet beendet werden, ohne die Cookies dauerhaft speichern zu müssen;
-
mehrere Servereinträge können dieselben Persistenzschlüssel verwenden. Dadurch bleibt die Zuordnung in Umgebungen mit mehreren Pfaden erhalten, wenn ein Pfad ausfällt;
-
soft-stop sorgt dafür, dass nur Nutzer mit vorhandenen Persistenzinformationen weiterhin ihren zugewiesenen Server erreichen. Neue Nutzer gelangen nicht mehr dorthin.
3.3.7. Grundfunktionen: Protokollierung
Die Protokollierung ist für einen Load-Balancer äußerst wichtig. Einerseits wird er oft zu Unrecht für Probleme verantwortlich gemacht, die er lediglich sichtbar macht. Andererseits sitzt er an einem zentralen Punkt der Infrastruktur, an dem normale und ungewöhnliche Aktivitäten ausgewertet und mit anderen Komponenten in Beziehung gesetzt werden müssen.
HAProxy erstellt sehr detaillierte Protokolle mit Millisekundengenauigkeit und dem genauen Zeitpunkt der Verbindungsannahme. Dieser lässt sich in Firewall-Protokollen wiederfinden, etwa zur NAT-Zuordnung. Schon standardmäßig enthalten TCP- und HTTP-Protokolle alle wesentlichen Angaben zur Fehlerbehebung: Quell-IP-Adresse und -Port, Frontend, Backend, Server, Zeitmessungen für Anfrageempfang, Warteschlange, Verbindungsaufbau, Antwort-Header und Datenübertragung, globalen Prozesszustand, Verbindungszahlen, Warteschlangenzustand, Anzahl der Wiederholungsversuche, genaue Persistenzaktionen, Gründe für Verbindungsabbrüche und erfasste Header mit sicherer Ausgabekodierung. Das Format lässt sich erweitern oder ersetzen, um beliebige abgerufene Daten, Variablen und erfasste Werte aufzunehmen. So können etwa die kumulierte Anzahl von Anfragen oder die Anzahl verschiedener von einem Client besuchter URLs protokolliert werden.
Die Protokollstufe kann mit gewöhnlichen ACLs je Anfrage angepasst werden. So lassen sich störende Meldungen automatisch unterdrücken und bei ungewöhnlichem Verhalten eines kleinen Teils des Datenverkehrs stattdessen Warnungen ausgeben, etwa bei zu vielen URLs oder HTTP-Fehlern einer Quelladresse. Verwaltungsereignisse werden ebenfalls mit eigenen Stufen protokolliert, beispielsweise der Ausfall oder die Wiederherstellung eines Servers.
Jedes Frontend und Backend kann mehrere unabhängige Protokollziele verwenden, was den Mandantenbetrieb erleichtert. Meldungen werden vorzugsweise über UDP gesendet, gegebenenfalls JSON-kodiert. Zur Sicherstellung der Zustellung werden sie nach einer konfigurierbaren Zeilenlänge abgeschnitten. Alternativ können sie an stdout/stderr, einen beliebigen Dateideskriptor oder einen Ringpuffer gesendet werden, den ein Client zum Abrufen der Meldungen abonnieren kann.
3.3.8. Grundfunktionen: Statistiken
HAProxy bietet eine webbasierte Statistikschnittstelle mit Authentifizierung, Sicherheitsstufen und Geltungsbereichen. Jeder Hosting-Kunde kann so eine eigene Seite erhalten, die nur seine Instanzen zeigt. Diese Seite kann unter einer verborgenen URL der regulären Website liegen, sodass kein zusätzlicher Port geöffnet werden muss. Sie kann auch die Verfügbarkeit anderer HAProxy-Knoten anzeigen, damit auf einen Blick erkennbar ist, ob alles wie erwartet funktioniert. Die Übersicht bietet zahlreiche Details, etwa Fehlerursachen, Zeit seit dem letzten Zugriff oder der letzten Änderung. Die Daten sind auch als CSV-Tabelle verfügbar, die andere Werkzeuge zur Diagrammerstellung importieren können. Die Seite kann sich automatisch aktualisieren und als Überwachungsanzeige auf einem großen Bildschirm dienen. Im Administrationsmodus lässt sich außerdem der Serverzustand ändern, um Wartungsarbeiten zu erleichtern.
Zusätzlich steht ein Prometheus-Exporter bereit, damit die Statistiken je nach Bereitstellung in einem anderen Format genutzt werden können.
4 - Standardfunktionen
Dieser Abschnitt stellt einige Funktionen vor, die in HAProxy sehr häufig verwendet werden, aber nicht unbedingt in anderen Load-Balancern vorhanden sind.
3.4.1. Standardfunktionen: Informationen abrufen und konvertieren
HAProxy unterstützt den Abruf von Informationen mit zahlreichen „Sample-Abruffunktionen“. Dabei werden einzelne Informationen, sogenannte Samples, zur unmittelbaren Verwendung extrahiert. Dies dient der Sitzungsbindung, dem Aufbau von Bedingungen, der Ausgabe von Informationen in Protokollen oder der Ergänzung von HTTP-Headern.
Samples lassen sich aus verschiedenen Quellen abrufen:
-
Konstanten: Ganzzahlen, Zeichenketten, IP-Adressen, Binärblöcke;
-
dem Prozess: Datum, Umgebungsvariablen, Zustand von Server/Frontend/Backend/Prozess, Byte- und Verbindungszähler sowie -raten, Warteschlangenlänge, Zufallsgenerator, …
-
Variablen: Variablen je Sitzung, Anfrage oder Antwort;
-
der Clientverbindung: Quell- und Zieladressen sowie -ports und alle zugehörigen Statistikzähler;
-
der SSL-Clientsitzung: Protokoll, Version, Algorithmus, Cipher, Schlüssellänge, Sitzungs-ID, alle Felder der Client- und Serverzertifikate, Zertifikatsseriennummer, SNI, ALPN, NPN, Unterstützung bestimmter Erweiterungen durch den Client;
-
dem Inhalt der Anfrage- und Antwortpuffer: beliebige Nutzdaten anhand von Offset und Länge, Datenlänge, RDP-Cookie, Dekodierung des SSL-Hello-Typs, Dekodierung von TLS-SNI;
-
HTTP (Anfrage und Antwort): Methode, URI, Pfad, Query-String-Argumente, Statuscode, Header-Werte, Header-Wert an einer bestimmten Position, Cookies, erfasste Werte, Authentifizierung, Elemente des Nachrichtenkörpers;
Ein Sample kann anschließend mehrere Operatoren, sogenannte „Konverter“, zur Umwandlung durchlaufen. Ein Konverter nimmt ein Sample entgegen und erzeugt ein neues, möglicherweise mit einem völlig anderen Typ. Beispielsweise kann ein Konverter nur die ganzzahlige Länge der Eingabezeichenkette zurückgeben oder eine Zeichenkette in Großbuchstaben umwandeln. Vor der endgültigen Verwendung eines Samples lassen sich beliebig viele Konverter nacheinander anwenden. Von den verfügbaren Sample-Konvertern werden folgende besonders häufig verwendet:
-
Arithmetische und logische Operatoren ermöglichen komplexe Berechnungen mit den Eingabedaten, etwa Verhältnisse und Prozentsätze oder einfache Umrechnungen zwischen Einheiten;
-
IP-Adressmasken sind nützlich, um Adressen zu größeren Netzen zusammenzufassen;
-
Datendarstellung: URL-Dekodierung, base64, hex, JSON-Zeichenketten, Hashing;
-
Zeichenkettenumwandlung: Teilzeichenketten an festen Positionen und mit fester Länge extrahieren, bestimmte Felder anhand von Trennzeichen oder bestimmte Wörter extrahieren, Groß-/Kleinschreibung ändern, Ersetzungen anhand regulärer Ausdrücke vornehmen;
-
Datumsumwandlung: in das HTTP-Datumsformat konvertieren, Ortszeit in UTC umrechnen und umgekehrt, einen Offset addieren oder subtrahieren;
-
einen Eintrag in einer Stick Table nachschlagen, um Statistiken oder den zugewiesenen Server zu ermitteln;
-
einen Schlüssel anhand einer Map-Datei in einen Wert umwandeln (vor allem für Geolokalisierung).
3.4.2. Standardfunktionen: Maps
Maps sind leistungsfähige Konverter: Beim Start wird eine Datei mit zwei Spalten in den Speicher geladen. Anschließend wird jedes Eingabe-Sample in der ersten Spalte gesucht. Wird der Eintrag gefunden, liefert die Map das zugehörige Muster aus der zweiten Spalte, andernfalls einen Standardwert. Die Ausgabe ist ebenfalls ein Sample und lässt sich daher weiter umwandeln, auch durch zusätzliche Map-Abfragen. Maps werden am häufigsten eingesetzt, um die IP-Adresse eines Clients einer AS-Nummer oder einem Ländercode zuzuordnen, da sie für Netzwerkadressen die längste Übereinstimmung unterstützen. Sie lassen sich aber auch für zahlreiche andere Zwecke verwenden.
Eine ihrer Stärken ist die Aktualisierbarkeit im laufenden Betrieb: über die CLI oder über bestimmte Aktionen, die andere Samples verwenden. Damit können Maps Informationen zwischen aufeinanderfolgenden Zugriffen speichern und wieder abrufen. Eine weitere Stärke ist die Indexierung mit Binärbäumen. Dadurch bleiben sie selbst mit Hunderttausenden von Einträgen äußerst schnell, sodass sich Geolokalisierung mit geringem Aufwand und Ressourcenbedarf einrichten lässt.
3.4.3. Standardfunktionen: ACLs und Bedingungen
Die meisten Vorgänge in HAProxy können an Bedingungen geknüpft werden. Bedingungen entstehen durch Verknüpfen mehrerer ACLs mit logischen Operatoren (AND, OR, NOT). Jede ACL besteht aus einer Reihe von Prüfungen mit folgenden Elementen:
-
einer Sample-Abrufmethode, die das zu prüfende Element abruft;
-
einer optionalen Folge von Konvertern, die das Element umwandeln;
-
einer Liste von Mustern für den Abgleich;
-
einer Abgleichmethode, die festlegt, wie die Muster mit dem Sample verglichen werden
Beispielsweise kann das Sample aus dem HTTP-Header “Host” stammen, dann in Kleinbuchstaben umgewandelt und schließlich mit der Methode für reguläre Ausdrücke gegen mehrere entsprechende Muster geprüft werden.
Technisch basieren ACLs und Maps auf demselben Kern. Sie verwenden genau dieselbe interne Struktur und dieselben Musterabgleichmethoden und bieten dieselbe Leistung. Der einzige wesentliche Unterschied ist, dass ACLs statt eines Samples lediglich „gefunden“ oder „nicht gefunden“ zurückgeben. ACL-Muster können direkt in der Konfigurationsdatei angegeben werden und benötigen keine eigene Datei. ACLs lassen sich benennen, um ihre Verwendung zu vereinfachen oder Konfigurationen verständlicher zu machen. Eine benannte ACL kann mehrmals definiert werden; ihre Definitionen werden nacheinander ausgewertet, bis eine davon zutrifft.
Es stehen etwa 13 verschiedene Musterabgleichmethoden bereit, darunter IP-Adressmasken, Ganzzahlbereiche, Teilzeichenketten und reguläre Ausdrücke. Sie arbeiten wie Funktionen. Wie in einer Programmiersprache wird nur das Nötige ausgewertet: Ist eine mit OR verknüpfte Bedingung bereits wahr, werden die folgenden nicht mehr ausgewertet. Ist eine mit AND verknüpfte Bedingung bereits falsch, wird der Rest der Bedingung ebenfalls nicht mehr ausgewertet.
Die Anzahl definierter ACLs ist praktisch unbegrenzt; einige häufig verwendete ACLs sind bereits vorgegeben. Die Erfahrung zeigt jedoch, dass die Fehlerbehebung bei Konfigurationen mit vielen benannten ACLs recht schwierig ist. Mitunter sind anonyme, direkt angegebene ACLs einfacher, weil weniger Verweise außerhalb des gerade untersuchten Abschnitts verfolgt werden müssen.
3.4.4. Standardfunktionen: Inhaltsabhängige Weiterleitung
HAProxy unterstützt einen Mechanismus zur inhaltsabhängigen Weiterleitung. Eine Verbindung oder Anfrage trifft an einem Frontend ein, und die darin enthaltenen Informationen werden verarbeitet. Mit ACL-basierten Bedingungen lässt sich anhand dieser Informationen entscheiden, welches Backend die Anfrage bearbeitet. Der Datenverkehr wird somit je nach Anfrageinhalt an das eine oder andere Backend geleitet. Am häufigsten wird anhand des Host-Headers und/oder von Pfadbestandteilen (Unterverzeichnissen oder Dateiendungen) entschieden, ob eine HTTP-Anfrage ein statisches Objekt oder die Anwendung betrifft. Zugriffe auf statische Objekte gehen an ein Backend mit schnellen, schlanken Servern, alle übrigen an einen komplexeren Anwendungsserver. So entsteht eine fein abgestufte Lösung für virtuelles Hosting. Damit können mehrere Technologien bequem innerhalb einer Gesamtlösung zusammenarbeiten.
Ein weiterer Anwendungsfall der inhaltsabhängigen Weiterleitung ist die Wahl verschiedener Lastverteilungsalgorithmen anhand unterschiedlicher Kriterien. Ein Cache kann beispielsweise einen URI-Hash verwenden, während eine Anwendung Round-Robin nutzt.
Außerdem können mehrere Kunden jeweils einen kleinen Anteil einer gemeinsamen Ressource nutzen, indem Verbindungsgrenzen je Backend und damit je Kunde durchgesetzt werden.
Regeln zur inhaltsabhängigen Weiterleitung skalieren sehr gut, wobei ihre Leistung von Anzahl und Komplexität der verwendeten ACLs abhängen kann. Es lassen sich aber auch dynamische Regeln schreiben, bei denen ein Sample-Wert unmittelbar zum Backend-Namen wird und überhaupt keine ACLs nötig sind. Solche Konfigurationen funktionieren Berichten zufolge im Produktivbetrieb mit mindestens 300000 Backends problemlos.
3.4.5. Standardfunktionen: Stick Tables
Stick Tables speichern üblicherweise Informationen zur Sitzungsbindung, also einen Verweis auf den Server, an den ein bestimmter Besucher geleitet wurde. Als Schlüssel dient die dem Besucher zugeordnete Kennung (seine Quelladresse, die SSL-ID der Verbindung, ein HTTP- oder RDP-Cookie, die aus der URL oder den Nutzdaten extrahierte Kundennummer, …). Der gespeicherte Wert ist die Kennung des Servers.
Stick Tables können 3 verschiedene Sample-Typen als Schlüssel verwenden: Ganzzahlen, Zeichenketten und Adressen. In einem Proxy kann nur eine Stick Table referenziert werden; sie wird überall mit dem Namen des Proxys bezeichnet. Bis zu 8 Schlüssel lassen sich parallel verfolgen. Die Serverkennung wird während der Verarbeitung der Anfrage oder Antwort eingetragen, sobald sowohl Schlüssel als auch Server bekannt sind.
Der Inhalt einer Stick Table kann im Aktiv/Aktiv-Betrieb mit anderen HAProxy-Knoten, den sogenannten „Peers“, sowie beim Neuladen mit dem neuen Prozess repliziert werden. Dadurch verfügen alle Lastverteilungsknoten über dieselben Informationen und treffen dieselbe Weiterleitungsentscheidung, wenn die Anfragen eines Clients auf mehrere Knoten verteilt werden.
Da Stick Tables nach einem Merkmal zur Erkennung des Clients indiziert sind, speichern sie oft zusätzliche Informationen, etwa Statistiken je Client. Diese zusätzlichen Statistiken benötigen weiteren Speicherplatz und müssen ausdrücklich deklariert werden. Gespeichert werden können beispielsweise ein- und ausgehende Bandbreite, Anzahl gleichzeitiger Verbindungen, Verbindungsrate und -anzahl innerhalb eines Zeitraums, Anzahl und Häufigkeit von Fehlern sowie bestimmte Markierungen und Zähler. Damit solche Informationen ohne Bindung an einen bestimmten Server geführt werden können, gibt es eine spezielle Funktion zur Nachverfolgung. Sie verfolgt unabhängig von den Regeln zur Sitzungsbindung bis zu 3 Schlüssel aus verschiedenen Tabellen gleichzeitig. Jede gespeicherte Statistik lässt sich über die CLI suchen, ausgeben und löschen. Dies erweitert die Möglichkeiten zur Fehlerbehebung im laufenden Betrieb.
Mit diesem Mechanismus können wiederkehrende Besucher bevorzugt oder die bereitgestellte Dienstqualität an gutes oder schlechtes Verhalten angepasst werden. Meist dient er jedoch der Bekämpfung von Dienstmissbrauch und allgemein von DDoS-Angriffen, da sich damit komplexe Modelle erstellen lassen, die bestimmtes Fehlverhalten mit hoher Verarbeitungsgeschwindigkeit erkennen.
3.4.6. Standardfunktionen: Formatierte Zeichenketten
HAProxy muss an vielen Stellen Zeichenketten verarbeiten, etwa in Protokollen, Weiterleitungen oder beim Hinzufügen von Headern. Für größtmögliche Flexibilität wurden formatierte Zeichenketten eingeführt, ursprünglich für die Protokollierung. Daher heißen sie weiterhin “log-format”. Diese Zeichenketten enthalten Escape-Zeichen, über die sich verschiedene dynamische Daten wie Variablen und Sample-Abrufausdrücke einfügen lassen. Auch die Kodierung kann beim Umwandeln des Ergebnisses in eine Zeichenkette angepasst werden, etwa durch Hinzufügen von Anführungszeichen. Damit lassen sich Header-Inhalte, Antwortdaten und sogar Antwortvorlagen erzeugen oder Protokollzeilen anpassen. Damit häufig benötigte Zeichenketten einfach aufgebaut werden können, stehen außerdem etwa 50 spezielle Kürzel für oft protokollierte Informationen bereit.
3.4.7. Standardfunktionen: HTTP-Umschreiben und -Weiterleiten
Einen Load-Balancer vor eine dafür nicht vorgesehene Anwendung zu setzen, kann ohne geeignete Werkzeuge schwierig sein. Häufig müssen Anfrage- und Antwort-Header angepasst werden, damit der Load-Balancer als Ursprungsserver erscheint und fest codierte Angaben korrigiert werden. Dazu gehören Änderungen am Anfragepfad (von denen dringend abgeraten wird), am Host-Header-Feld, am Location-Header-Feld von Weiterleitungsantworten sowie an den Attributen für Pfad und Domain von Cookies. Manche Server geben in ihren Antworten auch zu viele Informationen preis und werden dadurch anfälliger für gezielte Angriffe. Theoretisch ist es zwar nicht Aufgabe eines Load-Balancers, dies zu bereinigen; praktisch befindet er sich jedoch an der günstigsten Stelle der Infrastruktur, um eine vollständige Bereinigung sicherzustellen.
Gelegentlich muss der Load-Balancer auch Anfragen abfangen und mit einer Weiterleitung an eine neue Ziel-URL beantworten. Weiterleiten und Umschreiben werden zwar mitunter verwechselt, sind aber völlig unterschiedliche Konzepte: Beim Umschreiben sehen Client und Server unterschiedliche Inhalte und sind sich über den Ort der besuchten Seite uneinig. Eine Weiterleitung fordert den Client dagegen auf, die neue URL aufzurufen, sodass er denselben Ort wie der Server sieht.
HAProxy bietet dafür verschiedene Möglichkeiten zum Umschreiben und Weiterleiten, darunter:
-
Umschreiben von URLs und Headern in Anfragen und Antworten anhand regulärer Ausdrücke. Reguläre Ausdrücke sind das häufigste Werkzeug zum Ändern von Header-Werten, weil sie sich leicht handhaben lassen und gut verstanden werden;
-
Header lassen sich auch anhand formatierter Zeichenketten anhängen, löschen oder ersetzen. Dadurch können Informationen wie der clientseitige TLS-Algorithmus und Cipher übermittelt werden;
-
HTTP-Weiterleitungen können jeden 3xx-Code mit einer relativen, absoluten oder vollständig dynamischen URI (formatierte Zeichenkette) verwenden;
-
HTTP-Weiterleitungen unterstützen zusätzliche Optionen, etwa das Setzen oder Löschen eines bestimmten Cookies, das Entfernen des Query-Strings oder das Ergänzen eines fehlenden Schrägstrichs;
-
Eine leistungsfähige “return”-Direktive ermöglicht es, jeden Teil einer Antwort wie Status, Header oder Nachrichtenkörper mit dynamischen Inhalten oder sogar Vorlagendateien anzupassen.
-
Alle Vorgänge unterstützen ACL-basierte Bedingungen;
3.4.8. Standardfunktionen: Serverschutz
HAProxy unternimmt viel, um die Verfügbarkeit von Diensten zu maximieren. Dazu schützt er Server umfassend vor Überlastung und Angriffen. Der erste und wichtigste Punkt ist, dass nur vollständige und gültige Anfragen an die Server weitergeleitet werden. Zum einen muss HAProxy die Protokollelemente finden, die er zur Synchronisierung mit dem Bytestrom benötigt. Zum anderen lässt sich erst bei einer vollständigen Anfrage feststellen, ob einzelne Elemente ihre Bedeutung verändern. Der unmittelbare Vorteil ist, dass die Server keinen ungültigen oder unvollständigen Anfragen ausgesetzt sind. Dies schützt sehr wirksam vor Slowloris-Angriffen, die auf HAProxy fast keine Auswirkungen haben.
Ein weiterer wichtiger Punkt sind die Puffer für Anfragen und Antworten in HAProxy. Eine Anfrage wird erst dann an den Server gesendet, wenn sie vollständig vorliegt; die gesamte Antwort wird sehr schnell aus dem lokalen Netzwerk gelesen. Dadurch wird die serverseitige Verbindung nur sehr kurz genutzt, was die Serverressourcen möglichst weitgehend schont.
Darauf aufbauend kann HAProxy die Zahl gleichzeitiger Verbindungen oder ausstehender Anfragen an einen Server gezielt begrenzen. So wird der Server nie überlastet, selbst wenn er bei Verkehrsspitzen durchgehend mit 100% seiner Kapazität arbeitet. Überschüssige Anfragen warten einfach in einer Warteschlange, bis ein Platz frei wird. Diese erhebliche Ressourcenersparnis verkürzt die Antwortzeiten meist so stark, dass die Verarbeitung letztlich tatsächlich schneller ist als bei Überlastung des Servers. Wartende Anfragen können an andere Server umverteilt oder bereits in der Warteschlange abgebrochen werden, wenn der Client abbricht. Dies schützt die Server auch vor dem „Neuladeeffekt“: Klickt ein Besucher bei einer langsam ladenden Seite auf „Neu laden“, entsteht gewöhnlich bei jedem Klick eine weitere Anfrage, die den Server im überlasteten Zustand hält.
Der Slow-Start-Mechanismus schützt außerdem neu startende Server vor hohem Verkehrsaufkommen, solange sie noch ihren Start abschließen oder Klassen kompilieren.
Für den Schutz auf Protokollebene kann der HTTP-Parser so gelockert werden, dass er nicht standardkonforme, aber harmlose Anfragen oder Antworten akzeptiert und sogar korrigiert. Fehlerhafte Anwendungen bleiben dadurch erreichbar, während eine Korrektur entwickelt wird. Gleichzeitig werden die betreffenden Nachrichten vollständig erfasst und mit einem ausführlichen Bericht versehen, der Entwicklern hilft, den Fehler in der Anwendung zu finden. Die gefährlichsten Protokollverstöße werden zuverlässig erkannt, behandelt und behoben. So werden fehlerhafte Anfragen oder Antworten mit zwei Content-length-Headern korrigiert, wenn deren Werte exakt übereinstimmen. Unterscheiden sie sich, werden die Nachrichten abgewiesen, da daraus ein Sicherheitsproblem entsteht. Die Protokollprüfung ist nicht auf HTTP beschränkt, sondern auch für andere Protokolle wie TLS oder RDP verfügbar.
Wird ein Protokollverstoß oder ein Angriff erkannt, gibt es verschiedene Reaktionsmöglichkeiten: die übliche Antwort “HTTP 400 bad request”, das Schließen der Verbindung mit einem TCP-Reset oder das Vortäuschen eines Fehlers nach langer Verzögerung (“tarpit”), um den Angreifer zu verwirren. All dies schützt die Server, weil der angreifende Client von einem Angriff abgehalten wird, dessen Fortsetzung sehr aufwendig wird.
HAProxy bietet außerdem weitergehende Möglichkeiten zum Schutz vor versehentlichen Datenlecks und der Vermischung von Sitzungen. Er kann verdächtige Serverantworten protokollieren und protokolliert außerdem Antworten, die die Vertraulichkeit eines Besuchers beeinträchtigen könnten; optional kann er sie auch blockieren. Ein Beispiel ist ein zwischenspeicherbares Cookie in einer zwischenspeicherbaren Antwort. Ein zwischengeschalteter Cache könnte es an einen anderen Besucher ausliefern, sodass beide versehentlich dieselbe Sitzung verwenden.
5 - Erweiterte Funktionen
3.5.1. Erweiterte Funktionen: Verwaltung
HAProxy ist für einen äußerst stabilen Betrieb und eine sichere Verwaltung in üblichen Produktionsumgebungen ausgelegt. Er wird als einzelne ausführbare Datei bereitgestellt und benötigt keinen Installationsvorgang. Mehrere Versionen können problemlos nebeneinander bestehen. Instanzen lassen sich daher nach ihrer Wichtigkeit schrittweise aktualisieren, statt alle gleichzeitig umzustellen; dieses Vorgehen wird empfohlen. Konfigurationsdateien können leicht versioniert werden. Die Konfigurationsprüfung erfolgt unabhängig vom laufenden Betrieb, ohne einen Dienst neu starten zu müssen, der anschließend möglicherweise nicht mehr startet. Dabei lassen sich auch komplexere Fehler erkennen, etwa eine Regel, die eine andere verdeckt, oder eine nicht funktionierende Sitzungspersistenz. Ausführliche Warnungen und Konfigurationshinweise helfen bei der Behebung. Die Rückwärtskompatibilität von Konfigurationsdateien reicht weit zurück: Version 1.5 unterstützt noch vollständig Konfigurationen für Version 1.1, die 13 Jahre zuvor geschrieben wurden. Version 1.6 entfernt lediglich kaum verwendete, veraltete Schlüsselwörter, deren Aufgaben anders gelöst werden können. Das Aktualisieren von Konfiguration und Software erfolgt ohne Betriebsunterbrechung, indem alte und neue Prozesse nebeneinander laufen und jeweils ihre eigenen Verbindungen bedienen. Beim Start werden Systemzustand, Build-Optionen und Bibliothekskompatibilität gemeldet.
Erweiterte Funktionen erlauben es Anwendungsadministratoren, einen Server geordnet außer Betrieb zu nehmen: Sie können feststellen, wann keine Aktivität mehr vorhanden ist, ihn aus dem Betrieb nehmen, stoppen und aktualisieren, dabei sicherstellen, dass er keinen Datenverkehr erhält, und ihn anschließend über den normalen Zugriffspfad testen, ohne ihn bereits öffentlich freizugeben. Dafür muss HAProxy nicht verändert werden. So können selbst komplexe Arbeiten im Produktionsbetrieb während der Geschäftszeiten durchgeführt werden, wenn alle technischen Ressourcen verfügbar sind.
Der Prozess geht möglichst sparsam mit Ressourcen um. Speicherpools verkürzen die Zuteilungszeit und begrenzen Fragmentierung. Nutzdatenpuffer werden freigegeben, sobald ihr Inhalt gesendet ist. Außerdem lassen sich feste Speichergrenzen erzwingen: Bei Erreichen der Grenze müssen Verbindungen auf einen freien Puffer warten, statt weiteren Speicher zuzuteilen. Damit lässt sich der Speicherverbrauch in Umgebungen mit strengen Vorgaben begrenzen.
Eine Befehlszeilenschnittstelle (CLI) steht über einen UNIX- oder TCP-Socket bereit, um Operationen auszuführen und Diagnoseinformationen abzurufen. Alle Aktionen über diesen Socket kommen ohne Konfigurationsänderung aus und dienen deshalb vorwiegend vorübergehenden Anpassungen. Über die Schnittstelle lassen sich Adresse, Gewicht und Status eines Servers ändern, Statistiken abfragen und Zähler zurücksetzen, Tabellen zur Sitzungspersistenz ausgeben und leeren, bei Bedarf anhand von Schlüsselkriterien gezielt auswählen, Verbindungen auf Client- und Serverseite ausgeben und beenden sowie erfasste Fehler mit genauer Ursachen- und Positionsanalyse anzeigen. Außerdem können ACL- und Map-Einträge ausgegeben, hinzugefügt und entfernt, gemeinsame TLS-Geheimnisse aktualisiert und Verbindungs- sowie Ratenbegrenzungen für beliebige Frontends zur Laufzeit angewendet werden, was bei gemeinsam genutztem Hosting nützlich ist. Ein einzelnes Frontend kann deaktiviert werden, um einen lauschenden Port freizugeben, etwa wenn tagsüber keine Betriebsänderungen erlaubt sind, aber dennoch eine Korrektur nötig ist. Auch Zertifikate und ihre Konfiguration lassen sich zur Laufzeit aktualisieren. Zudem können Traces aller Verarbeitungsschritte des Datenverkehrs aktiviert und eingesehen werden.
Für Umgebungen, die SNMP verlangen, gibt es mindestens zwei Agenten. Einer wird mit dem HAProxy-Quellcode geliefert und verwendet das Perl-Modul Net-SNMP. Ein weiterer gehört zu den kommerziellen Paketen und benötigt kein Perl. Ihr Funktionsumfang ist ungefähr gleich.
Häufig wird empfohlen, auf dem Rechner mit HAProxy 4 Werkzeuge zu installieren:
-
socat für den Zugriff auf die CLI; manche netcat-Varianten können dies ebenfalls in gewissem Umfang;
-
halog aus der neuesten HAProxy-Version: Das Werkzeug analysiert native TCP- und HTTP-Protokolle äußerst schnell, mit 1 bis 2 GB pro Sekunde. Es gewinnt daraus Informationen und Statistiken, etwa Anfragen pro URL oder Quelladresse, nach Antwortzeit oder Fehlerrate sortierte URLs und Abschlusscodes. Es wurde für Produktionsserver entwickelt, um Probleme im laufenden Betrieb zu untersuchen, und muss deshalb bereits einsatzbereit installiert sein;
-
tcpdump wird dringend empfohlen, um Netzwerkmitschnitte für die Untersuchung von Problemen anzufertigen, die in den Protokollen sichtbar wurden. Irgendwann können sich die Sicht der Anwendung und die Analyse von haproxy widersprechen. Dann zeigen nur Netzwerkmitschnitte, welche Seite recht hat. Auch Fehler in Netzwerk-Stacks und Hypervisoren werden häufig mit tcpdump aufgedeckt;
-
strace ergänzt tcpdump. Es zeigt, was HAProxy tatsächlich sieht, und hilft, Ursachen im Betriebssystem von Ursachen in HAProxy zu unterscheiden. Bei einem vermuteten HAProxy-Fehler wird häufig eine strace-Ausgabe angefordert;
3.5.2. Erweiterte Funktionen: Systemspezifische Fähigkeiten
Je nach Betriebssystem stehen zusätzliche Funktionen zur Verfügung oder werden benötigt. HAProxy unterstützt mehrere Plattformen, wird aber hauptsächlich unter Linux entwickelt. Deshalb sind einige Funktionen nur dort verfügbar.
Transparente Bindung und Verbindungsherstellung, die Bindung von Verbindungen an eine bestimmte Netzwerkschnittstelle sowie das Binden mehrerer Prozesse an dieselbe IP-Adresse und dieselben Ports stehen nur unter Linux und BSD zur Verfügung. Nur Linux verteilt eingehende Anfragen jedoch im Kernel auf die verfügbaren Prozesse.
Unter Linux gibt es weitere Funktionen und Optimierungen. Netzwerk-Namespaces, auch „Container“ genannt, erlauben es HAProxy, als Gateway zwischen allen Containern zu arbeiten. Für clientseitige Verbindungen können MSS, Netfilter-Markierungen und das IP-TOS-Feld gesetzt werden. Auf der lauschenden Seite wird TCP FastOpen unterstützt. TCP-User-Timeouts erlauben dem Kernel, Verbindungen schnell zu beenden, wenn er vor Ablauf der konfigurierten Zeitüberschreitung erkennt, dass der Client nicht mehr erreichbar ist. TCP-Splicing lässt den Kernel Daten zwischen den beiden Seiten einer Verbindung weiterleiten und vermeidet dadurch mehrere Kopien im Speicher. Mit der Bind-Option “defer-accept” wird eine eingehende Verbindung erst gemeldet, wenn Daten in den Kernel-Puffern vorliegen. Die Option “tcp-smart-connect” ermöglicht es, die Anfrage zusammen mit dem ACK zu senden, das den Verbindungsaufbau bestätigt; dies wird manchmal „Piggybacking“ genannt. Unter Linux steuert HAProxy zudem verzögerte TCP-ACKs sorgfältig, um möglichst viele Netzwerkpakete einzusparen.
Manche Systeme haben eine unzuverlässige Uhr, die vor- und zurückspringt. Früher trat dies bei einigen NUMA-Systemen auf, deren Prozessoren nicht dieselbe Uhrzeit sahen. In jüngerer Zeit ist es in virtualisierten Umgebungen häufiger geworden, in denen die virtuelle Uhr keinen Bezug zur tatsächlichen Uhr hat. Dadurch entstehen große Zeitsprünge, gelegentlich wurden bis zu 30 Sekunden beobachtet. Das verursacht generell erhebliche Probleme bei der Durchsetzung von Zeitüberschreitungen. HAProxy führt deshalb eine eigene monotone Uhr auf Grundlage der Systemuhr, misst aber deren Abweichungen und gleicht sie aus. Selbst mit einer sehr schlechten Systemuhr bleiben Timer so hinreichend genau, und Zeitüberschreitungen funktionieren weiterhin. Das Problem betrifft sämtliche Software auf solchen Systemen und ist nicht HAProxy-spezifisch. Typische Folgen sind unbegründete Zeitüberschreitungen oder eingefrorene Anwendungen. Wird dieses Verhalten festgestellt, muss es behoben werden, auch wenn HAProxy sich selbst dagegen schützt.
Unter Linux kann ein neu startender Prozess mit seinem Vorgänger kommunizieren und dessen lauschende Dateideskriptoren übernehmen. Dadurch werden die lauschenden Sockets beim Austausch des Prozesses zu keinem Zeitpunkt unterbrochen.
3.5.3. Erweiterte Funktionen: Skripte
HAProxy kann mit Unterstützung für die eingebettete Sprache Lua gebaut werden. Damit eröffnen sich viele Möglichkeiten für komplexe Änderungen an Anfragen und Antworten, Routingentscheidungen, Statistikverarbeitung und mehr. Mit Lua lassen sich sogar parallele Verbindungen zu anderen Servern aufbauen, um Informationen auszutauschen. So kann beispielsweise ein Authentifizierungssystem entwickelt werden, auch wenn dies aufwendig ist. Weitere Informationen zur Verwendung von Lua stehen in der Dokumentation in “doc/lua-api/index.rst”.
3.5.4. Erweiterte Funktionen: Tracing
Administratoren können sich jederzeit über die CLI verbinden und Tracing für verschiedene interne Teilsysteme aktivieren. Mehrere voreingestellte Detailstufen erlauben in der Praxis Ausgaben von einer Zeile bis zu 500 Zeilen pro Anfrage. Filter und ein automatischer Mechanismus zum Starten, Stoppen und Pausieren der Erfassung ermöglichen es, gezielt auf ein Ereignis zu warten und es im Detail zu beobachten. Das ist besonders hilfreich bei Protokollverstößen fehlerhafter Server und Clients sowie bei Denial-of-Service-Angriffen.
6 - Dimensionierung und Leistung
Typischerweise entfallen im TCP- oder HTTP-Close-Modus 15% der Verarbeitungszeit auf HAProxy und 85% auf den Kernel. Im HTTP-Keep-Alive-Modus sind es etwa 30% für HAProxy und 70% für den Kernel. Betriebssystem und Systemoptimierung beeinflussen die Gesamtleistung daher stark.
Die Anforderungen unterscheiden sich erheblich: Manche Nutzer konzentrieren sich auf Bandbreite, andere auf Anfragerate, gleichzeitige Verbindungen oder SSL-Leistung. Dieser Abschnitt gibt einige Anhaltspunkte für die Planung.
Jede Operation verursacht Aufwand, der sich zum Aufwand der übrigen Operationen addiert. Unter bestimmten Umständen ist er vernachlässigbar, unter anderen kann er überwiegen.
Für die Verarbeitung von Anfragen einer Verbindung gilt:
-
Das Weiterleiten von Daten kostet weniger als das Auswerten von Anfrage- oder Antwort-Headern;
-
das Auswerten von Anfrage- oder Antwort-Headern kostet weniger als der Aufbau und anschließende Abbau einer Verbindung zu einem Server;
-
Aufbau und Abbau einer Verbindung kosten weniger als die Wiederaufnahme einer TLS-Sitzung;
-
die Wiederaufnahme einer TLS-Sitzung kostet weniger als ein vollständiger TLS-Handshake mit Schlüsselberechnung;
-
eine untätige Verbindung benötigt weniger CPU-Leistung als eine Verbindung mit Daten in ihren Puffern;
-
ein TLS-Kontext benötigt noch mehr Speicher als eine Verbindung mit Daten;
In der Praxis ist die Verarbeitung von Nutzdatenbytes somit günstiger als die von Headerbytes. Hohe Netzwerkbandbreiten lassen sich deshalb mit großen Objekten, also wenigen Anfragen pro Datenmenge, leichter erreichen als mit kleinen Objekten und entsprechend vielen Anfragen. Daher wird die maximale Bandbreite immer mit großen Objekten gemessen, die Anfrage- und Verbindungsraten dagegen mit kleinen.
Manche Operationen skalieren gut über mehrere Prozesse auf mehreren CPUs, andere weniger gut. Die Netzwerkbandbreite lässt sich nur begrenzt steigern, da bei großen Objekten selten die CPU den Engpass bildet. Meist begrenzen die Netzwerkbandbreite und die Datenbusse zu den Netzwerkschnittstellen. Die Verbindungsrate skaliert wegen einiger Sperren beim Zugriff auf die lokale Porttabelle des Systems schlecht über mehrere Prozessoren. Die Anfragerate über dauerhafte Verbindungen skaliert dagegen sehr gut: Sie benötigt wenig Speicher und Netzwerkbandbreite und keinen Zugriff auf gesperrte Strukturen. Auch die TLS-Schlüsselberechnung skaliert sehr gut, da sie vollständig CPU-gebunden ist. Die Wiederaufnahme von TLS-Sitzungen skaliert mäßig gut und erreicht ihre Grenzen bei etwa 4 Prozessen. Danach gleicht der Aufwand für den Zugriff auf die gemeinsame Tabelle die geringen zusätzlichen Leistungsgewinne aus.
Ein sehr gut optimiertes System erreicht ungefähr die folgenden Leistungswerte. Sie sind als Größenordnungen zu verstehen. Je nach Prozessor, IRQ-Einstellungen, Speichertyp, Netzwerkschnittstelle, Betriebssystemoptimierung und weiteren Faktoren sind erhebliche Abweichungen in beide Richtungen zu erwarten.
Die folgenden Werte wurden mit einem Core i7 bei 3.7 GHz, einer Netzwerkkarte (NIC) mit zwei 10-Gbps-Ports, Linux-Kernel 3.10, HAProxy 1.6 und OpenSSL 1.0.2 ermittelt. HAProxy lief als einzelner Prozess auf einem exklusiv zugewiesenen CPU-Kern; zwei weitere Kerne waren für Netzwerk-Interrupts reserviert:
-
20 Gbps maximale Netzwerkbandbreite bei unverschlüsselter Übertragung von Objekten ab 256 kB, 10 Gbps bei Objekten ab 41kB;
-
4.6 Gbps TLS-Datenverkehr mit AES256-GCM und großen Objekten;
-
83000 TCP-Verbindungen pro Sekunde vom Client zum Server;
-
82000 HTTP-Verbindungen pro Sekunde vom Client zum Server;
-
97000 HTTP-Anfragen pro Sekunde im Server-Close-Modus, also Keep-Alive zum Client und Schließen der Verbindung zum Server;
-
243000 HTTP-Anfragen pro Sekunde mit durchgehendem Keep-Alive;
-
300000 gefilterte TCP-Verbindungen pro Sekunde zur DDoS-Abwehr
-
160000 HTTPS-Anfragen pro Sekunde im Keep-Alive-Modus über dauerhafte TLS-Verbindungen;
-
13100 HTTPS-Anfragen pro Sekunde mit wiederaufgenommenen TLS-Verbindungen;
-
1300 HTTPS-Verbindungen pro Sekunde mit jeweils neu ausgehandeltem TLS und RSA2048;
-
20000 gleichzeitige, voll ausgelastete Verbindungen pro GB RAM einschließlich des Speichers für Systempuffer; mit sorgfältiger Optimierung sind bessere Werte möglich, dieser Wert ist jedoch leicht zu erreichen.
-
etwa 8000 gleichzeitige TLS-Verbindungen nur auf der Clientseite pro GB RAM einschließlich des Speichers für Systempuffer;
-
etwa 5000 gleichzeitige durchgehende TLS-Verbindungen auf beiden Seiten pro GB RAM einschließlich des Speichers für Systempuffer;
Ein neuerer Benchmark mit HAProxy 2.4 im Mehrthreadbetrieb auf einem ARM-Graviton2-Prozessor mit 64 Kernen bei AWS erreichte 2 Millionen HTTPS-Anfragen pro Sekunde bei Antwortzeiten unter einer Millisekunde und 100 Gbps Datenverkehr:
Als Faustregel sinkt die Anfragerate von TLS-Keep-Alive zur TLS-Wiederaufnahme sowie von der TLS-Wiederaufnahme zur TLS-Neuaushandlung jeweils um den Faktor 10. Zwischen HTTP-Keep-Alive und HTTP-Close sinkt sie dagegen nur um den Faktor 3. Eine weitere Faustregel: Ein hoch getakteter Kern mit AES-Befehlen schafft etwa 20 Gbps AES-GCM pro Kern.
Eine weitere nützliche Faustregel ist, dass HAProxy auf derselben Serverhardware etwa folgende Anzahl von Servern vollständig auslasten kann:
-
etwa 5-10 Server für statische Dateien oder Caching-Proxys;
-
etwa 100 Antivirus-Proxys;
-
etwa 100-1000 Anwendungsserver, abhängig von der verwendeten Technologie.
7 - Versionen, Pakete und Upgrades
HAProxy ist ein Open-Source-Projekt unter der GPLv2-Lizenz. Jeder darf es weiterverbreiten, sofern auf Anfrage auch Zugang zum Quellcode gewährt wird, insbesondere wenn Änderungen vorgenommen wurden.
Die Entwicklung von HAProxy erfolgt im Hauptzweig “master”, auch “mainline” genannt. Sobald der Code als stabil gilt, werden daraus neue Zweige abgeleitet. Viele Websites setzen freiwillig Entwicklungszweige im Produktionsbetrieb ein, entweder um zum Projekt beizutragen oder weil sie eine besonders neue Funktion benötigen. Ihre Rückmeldungen sind sehr wertvoll, um Fehler zu beheben und die Gesamtqualität und Stabilität der entstehenden Version einzuschätzen.
Die aus ausreichend stabilem Code erzeugten neuen Zweige bilden eine stabile Version und werden im Allgemeinen mehrere Jahre gepflegt. Ein sofortiger Wechsel auf einen neueren Zweig ist daher auch dann nicht nötig, wenn nicht der neueste verwendet wird. Nach der Veröffentlichung eines stabilen Zweigs darf er nur Fehlerkorrekturen erhalten. Sehr selten kommen kleinere Funktionserweiterungen hinzu, wenn sie den Nutzern die Arbeit erleichtern. Alle Korrekturen eines stabilen Zweigs stammen zwingend aus dem master-Zweig. Dadurch geht beim Upgrade keine Korrektur verloren. Patches zur Fehlerbehebung bitte deshalb gegen master und nicht gegen einen stabilen Zweig erstellen. Möglicherweise ist der Fehler dort bereits behoben. Dieses Verfahren sorgt zudem dafür, dass Regressionen in stabilen Zweigen äußerst selten sind. Es gibt daher keinen Grund, nicht auf die neueste Version des verwendeten Zweigs zu aktualisieren.
Zweige tragen zwei durch einen Punkt getrennte Zahlen, etwa “1.6”. Seit 1.9 konzentrieren sich Zweige mit ungerader zweiter Zahl vor allem auf sensible technische Änderungen und richten sich eher an erfahrene Nutzer, da sie wahrscheinlich mehr Fehler auslösen als die übrigen. Sie werden nur etwa ein Jahr gepflegt und dürfen nicht dort eingesetzt werden, wo im Notfall kein Rollback möglich ist. Eine vollständige Versionsnummer enthält eine oder zwei weitere Zahlen für den Korrekturstand. Beispielsweise ist 1.5.14 die 14. Korrekturversion im Zweig 1.5 nach der Veröffentlichung von 1.5.0. Sie enthält 126 Korrekturen einzelner Fehler, 24 Dokumentationsaktualisierungen und 75 weitere rückportierte Patches, von denen die meisten zur Behebung der genannten 126 Fehler benötigt wurden. Bestehende Funktionen dürfen in einem stabilen Zweig niemals geändert oder entfernt werden. So bleiben Upgrades innerhalb desselben Zweigs stets unbedenklich.
HAProxy ist aus verschiedenen Quellen mit unterschiedlichen Veröffentlichungsrhythmen verfügbar:
-
Die offizielle Community-Website http://www.haproxy.org/ bietet den Quellcode der neuesten Entwicklungsversion, sämtlicher stabiler Versionen sowie nächtliche Snapshots jedes Zweigs. Der Veröffentlichungsrhythmus ist langsam: Zwischen stabilen Versionen oder Entwicklungssnapshots liegen mehrere Monate. Auch sehr alte Versionen werden dort noch unterstützt. Alles wird nur als Quellcode bereitgestellt und muss daher selbst gebaut beziehungsweise paketiert werden;
-
GitHub unter https://github.com/haproxy/haproxy/ spiegelt ausschließlich den Entwicklungszweig und bindet Issue-Tracker, kontinuierliche Integration und Werkzeuge zur Messung der Codeabdeckung ein. Dieses Angebot richtet sich ausschließlich an Mitwirkende;
-
Zahlreiche Betriebssysteme, etwa Linux-Distributionen und BSD-Ports, liefern langfristig gepflegte Versionen. Diese enthalten nicht immer alle Korrekturen der offiziellen Versionen, aber zumindest die kritischen. Für die meisten Nutzer, die keine anspruchsvollen Konfigurationen benötigen und Aktualisierungen einfach halten möchten, ist dies häufig eine gute Wahl;
-
Kommerzielle Versionen von http://www.haproxy.com/ bieten professionell unterstützte Pakete für verschiedene Betriebssysteme oder Appliances. Sie basieren auf aktuellen stabilen Versionen und enthalten zusätzlich stark nachgefragte Funktionen, die aus der nächsten Version rückportiert wurden. Sie sind die beste Wahl für Nutzer, die neue Funktionen mit der Zuverlässigkeit eines stabilen Zweigs, sehr schnelle Fehlerbehebung oder einfach einen Supportvertrag für ein Open-Source-Produkt suchen;
Um festzustellen, ob die eingesetzte Version die neueste ihres Zweigs ist, wie folgt vorgehen:
-
Prüfen, welche ausführbare HAProxy-Datei verwendet wird. Manche Systeme liefern HAProxy bereits mit, während die Administration eine eigene Version an anderer Stelle installiert. Daher in den Startskripten nachsehen, welche Datei tatsächlich aufgerufen wird;
-
Die Herkunft der HAProxy-Version bestimmen. Meist genügt “haproxy -v”. Eine Entwicklungsversion sieht wie folgt aus; hinter der Zweignummer steht “dev”:
Eine stabile Version sieht wie folgt aus. Dasselbe gilt für unveränderte stabile
Versionen der Betriebssystemanbieter:
Ein nächtlicher Snapshot einer stabilen Version enthält dagegen eine hexadezimale
Zeichenfolge hinter der Versionsnummer und statt des Veröffentlichungsdatums
das Datum des Snapshots:
Jedes andere Format kann auf ein systemspezifisches Paket mit eigenen Patches hinweisen.
HAProxy-Enterprise-Versionen verwenden beispielsweise
folgendes Format (<branch>-<latest commit>-<revision>):
Frühere Versionen vor 2.4 gaben den Prozessnamen mit einem Bindestrich zwischen "HA" und
"Proxy" aus. Dies gilt auch für die oben gezeigten Beispiele, die nur zur Darstellung des
korrekten Formats angepasst wurden. In Skripten dieses Wort daher besser ignorieren oder
einen weniger strengen Abgleich verwenden. Neuere Versionen ergänzen zudem eine URL zur
Projektwebsite.
Ab Version 2.1 gibt es außerdem eine Zeile "Status". Sie nennt, ob die Version für den
Produktionsbetrieb geeignet ist und gegebenenfalls bis wann, sowie einen Link zur Liste
bekannter Fehler dieser Version.
- Bei systemspezifischen Paketen im Paket-Repository oder Aktualisierungssystem des Anbieters prüfen, ob das System noch unterstützt wird und der verwendete Zweig weiterhin Korrekturen erhält. Bei Community-Versionen von haproxy.org die Website besuchen, den Status des Zweigs prüfen und die neueste Version mit der installierten vergleichen. Ist die eigene Version älter, kann sie aktualisiert werden. Wird der Zweig nicht mehr gepflegt, ist ein Upgrade bereits deutlich überfällig. Dann muss ein Wechsel auf einen neueren Zweig erwogen werden; dabei die README sorgfältig lesen.
HAProxy muss entsprechend seiner Bezugsquelle aktualisiert werden. Üblicherweise erfolgt dies über das Paketaktualisierungsverfahren des Systemanbieters. Bei einer Installation aus dem Quellcode nach dem Entpacken die README im Quellverzeichnis lesen und den Anweisungen für das verwendete Betriebssystem folgen.
8 - Ergänzende Produkte und Alternativen
HAProxy lässt sich gut mit einigen der folgenden Produkte kombinieren. Deshalb werden sie hier erwähnt, auch wenn sie nicht direkt zu HAProxy gehören.
4.1. Apache HTTP Server
Apache ist der De-facto-Standard unter den HTTP-Servern. Das sehr umfangreiche, modulare Projekt unterstützt sowohl die Auslieferung von Dateien als auch dynamische Inhalte. Es kann als Frontend für Anwendungsserver dienen, Anfragen als Proxy weiterleiten und Antworten zwischenspeichern. In all diesen Fällen wird häufig ein vorgeschalteter Load-Balancer benötigt. Apache unterstützt verschiedene Betriebsarten mit unterschiedlichem Ressourcenbedarf. Manche Module verlangen weiterhin das aufwendigere Prefork-Modell und verhindern dadurch eine gute Skalierung bei vielen Verbindungen. HAProxy kann hier erheblich helfen, indem er die Verbindungszahl pro Server auf einen sicheren Wert begrenzt. Dadurch wird der Server deutlich schneller, und seine Ressourcen bleiben für die Anwendung verfügbar.
Apache kann die Clientadresse mit der Erweiterung “mod_rpaf” aus dem Header X-Forwarded-For auslesen. HAProxy setzt diesen Header automatisch, wenn “option forwardfor” konfiguriert ist. Außerdem kann HAProxy einen mit dem Internet verbundenen Apache gut schützen, da er vielen Arten von DoS-Angriffen besser standhält.
4.2. NGINX
NGINX ist der zweite De-facto-Standard unter den HTTP-Servern und deckt wie Apache viele Funktionen ab. Sein Modell ähnelt dem von HAProxy, sodass er problemlos Zehntausende gleichzeitige Verbindungen verarbeitet. Wird er als Gateway zu Anwendungen eingesetzt, etwa mit dem mitgelieferten PHP FPM, kann eine Begrenzung der Frontend-Verbindungen die PHP-Anwendung entlasten. HAProxy hilft dabei sowohl als gewöhnlicher Load-Balancer als auch bei der Regulierung des Datenverkehrs, um PHP durch weniger Überlastung zu beschleunigen. Da beide Produkte dank ihrer ereignisgesteuerten Architektur wenig CPU-Leistung benötigen, können sie oft problemlos auf demselben System installiert werden. NGINX implementiert das PROXY-Protokoll von HAProxy. So kann HAProxy die Verbindungsinformationen des Clients an NGINX weitergeben, damit die Anwendung alle relevanten Angaben erhält. Einige Benchmarks haben außerdem gezeigt, dass konsistentes Hashing in einem vor NGINX eingesetzten HAProxy bei der Auslieferung großer statischer Dateien vorteilhaft ist: Es verbessert die Cache-Trefferrate des Betriebssystems, die sich im Wesentlichen mit der Anzahl der Serverknoten vervielfacht.
4.3. Varnish
Varnish ist ein intelligenter Reverse-Proxy mit Cache, der sich am besten als Beschleuniger für Webanwendungen beschreiben lässt. Varnish implementiert kein SSL/TLS und konzentriert seine gesamte CPU-Leistung auf seine Kernaufgabe. Da auch Varnish das PROXY-Protokoll von HAProxy implementiert, lässt sich HAProxy einfach davor einsetzen, um SSL-Verarbeitung und Lastverteilung zu übernehmen und alle relevanten Clientinformationen weiterzugeben. Varnish kann komprimierte Objekte aus dem Cache dekomprimieren, wenn ein Server sie komprimiert geliefert hat, komprimiert sie aber nicht selbst. Unterstützen die Backend-Server keine Komprimierung, kann HAProxy die ausgehenden Daten komprimieren. Bei mehr als geringem Datenverkehr ist die Komprimierung auf dem Load-Balancer allerdings selten sinnvoll.
Bei großen Cache-Farmen mit mehreren Knoten kann HAProxy die Last durch konsistentes URL-Hashing gezielt auf die Cache-Knoten verteilen und doppelte Cache-Inhalte vermeiden. Die gesamte Cache-Kapazität entspricht dann der Summe aller Knoten. Zusätzlich kann das kurzzeitige Zwischenspeichern sehr kleiner, einfacher Objekte in HAProxy Netzwerk-Roundtrips einsparen und die CPU-Last auf HAProxy- und Varnish-Knoten senken. Dies ist nur möglich, wenn Varnish diese Objekte nicht weiter verarbeitet. Häufig wird dies als „Favicon-Cache“ bezeichnet; damit lässt sich unter Umständen ein erheblicher Anteil unnötiger nachgelagerter Anfragen vermeiden. Vor einem anderen Cache darf HAProxy jedoch nicht für längere Zeit, also mehr als wenige Sekunden, zwischenspeichern. Das würde die Fehlerbehebung erheblich erschweren, ohne nennenswerte zusätzliche Einsparungen zu bringen.
4.4. Alternativen
Linux Virtual Server, kurz LVS oder IPVS, ist der in den Linux-Kernel integrierte Load-Balancer für Schicht 4. Er arbeitet auf Paketebene und verarbeitet TCP und UDP. Meist ist er eher eine Ergänzung als eine Alternative, da er keinerlei Kenntnis von Schicht 7 hat.
Pound ist ein weiterer bekannter Load-Balancer. Er ist wesentlich einfacher und hat deutlich weniger Funktionen als HAProxy. Für viele sehr einfache Konfigurationen eignen sich jedoch beide. Sein Autor legt den Schwerpunkt seit jeher auf gut prüfbaren Code und möchte den Funktionsumfang klein halten. Die Architektur mit Threads skaliert bei hohen Verbindungszahlen weniger gut, dennoch ist Pound ein gutes Produkt.
Pen ist ein recht schlanker Load-Balancer. Er unterstützt SSL und hält Clientzuordnungen in einer Tabelle fester Größe mit den IP-Adressen der Clients. Ein paketorientierter Modus ermöglicht Direct Server Return und in gewissem Umfang UDP. Pen ist für geringe Last ausgelegt; die Zuordnungstabelle enthält nur 2048 Einträge.
NGINX kann in gewissem Umfang Last verteilen, auch wenn dies eindeutig nicht seine Hauptaufgabe ist. Serverausfälle werden anhand des Produktionsverkehrs erkannt, die Verfahren zur Lastverteilung sind eingeschränkter, und die Sitzungspersistenz ist sehr begrenzt. In einfachen Bereitstellungen, in denen NGINX bereits vorhanden ist, kann dies dennoch sinnvoll sein. Da NGINX gut mit HAProxy zusammenarbeitet, lässt sich HAProxy problemlos später ergänzen, wenn die Grenzen erreicht sind.
Auch Varnish verteilt Last auf seine Backend-Server und unterstützt echte Health Checks. Sitzungspersistenz implementiert es jedoch nicht. Wie bei NGINX kann dies für den Anfang ausreichen, solange keine Sitzungspersistenz benötigt wird. Da HAProxy und Varnish sehr gut zusammenarbeiten, lässt sich HAProxy auch hier später leicht ergänzen, um den Funktionsumfang zu erweitern.
9 - Dokumentation und Community
1. Verfügbare Dokumentation
Die vollständige HAProxy-Dokumentation besteht aus den folgenden Dokumenten. Die jeweils passende Dokumentation spart Zeit und liefert die genaueste Antwort auf die eigene Fragestellung. Bitte keine Fragen an die Mailingliste senden, deren Antworten bereits in diesen Dokumenten stehen.
-
intro.txt(dieses Dokument): behandelt die Grundlagen der Lastverteilung, HAProxy als Produkt, seine Fähigkeiten und Grenzen, bekannte Fallstricke, Einschränkungen einzelner Betriebssysteme, Bezugsquellen, Weiterentwicklung, die Versorgung mit allen bekannten Fehlerkorrekturen, Aktualisierungen sowie Ergänzungen und Alternativen. -
management.txt: erklärt den Start von haproxy, die Verwaltung zur Laufzeit und auf mehreren Knoten sowie die Durchführung nahtloser Upgrades. -
configuration.txt: das Referenzhandbuch erläutert sämtliche Konfigurationsschlüsselwörter und ihre Optionen. Es dient als Nachschlagewerk für Konfigurationsänderungen. -
coding-style.txt: richtet sich an Entwickler, die Code zum Projekt beitragen möchten, und erläutert den einzuhaltenden Programmierstil. Er ist nicht besonders streng, und auch der vorhandene Code hält ihn nicht vollständig ein. Beiträge, die zu stark davon abweichen, werden jedoch abgelehnt.
-
proxy-protocol.txt: die De-facto-Spezifikation des PROXY-Protokolls, das HAProxy und verschiedene Produkte von Drittanbietern implementieren.
-
security.txt: beschreibt die Meldung von Sicherheitsproblemen und erläutert, was als Schwachstelle gilt und was nicht.
-
README: beschreibt, wie HAProxy aus dem Quellcode gebaut wird
5. Kontakte
Entwickler und andere Mitglieder der Community sind in der Regel am besten über die Mailingliste unter haproxy@formilux.org zu erreichen. Die Liste und ihre Archive sind öffentlich; vertrauliche Informationen sollten daher nicht veröffentlicht werden. Dort sind etwa tausend Nutzer mit unterschiedlicher Erfahrung vertreten. Selbst sehr komplexe Fragen erhalten meist relativ schnell eine passende Antwort. Vorschläge sind ebenfalls willkommen. Wer Schwierigkeiten mit E-Mail hat, kann die Discourse-Plattform unter http://discourse.haproxy.org/ nutzen. Dort lesen allerdings weniger Personen mit, und die meisten Fragen werden von einem sehr kleinen Team bearbeitet. Bitte in jedem Fall geduldig und respektvoll mit denjenigen umgehen, die ihre Freizeit dafür einsetzen, anderen zu helfen.
Ein vermuteter, aber noch nicht sicher bestätigter Fehler wird am besten auf der Mailingliste gemeldet. Wer überzeugt ist, einen Fehler gefunden zu haben, die aktuelle Version seines Zweigs verwendet und bereits ein GitHub-Konto besitzt, kann direkt unter https://github.com/haproxy/haproxy/ ein Issue mit allen verfügbaren Einzelheiten anlegen. Auch dort sind die Informationen öffentlich; daher nichts veröffentlichen, was später bereut werden könnte. Da der Issue-Tracker die Diskussion als langen Verlauf darstellt, sehr umfangreiche Ausgaben von mehreren hundert Zeilen oder mehr bitte als Anhang beifügen, statt sie in den Text einzufügen.
Bei einem vermuteten Sicherheitsproblem ist die Datei doc/security.txt zu beachten. Sie erläutert, was bei HAProxy als Schwachstelle gilt und was nicht, und wie eine tatsächliche Schwachstelle vertraulich gemeldet wird. Die meisten Verdachtsfälle erweisen sich als gewöhnliche Fehler, die besser auf dem oben beschriebenen Weg gemeldet werden.
Vollständige lokale Handbuchsammlung
Herkunft dieser Ausgabe
- Ausgabe: HAProxy 3.4.6-66, Dokumentationsstand des Wartungszweigs
- Neueste stabile Version: HAProxy 3.4.6, Tag
v3.4.6 - Quell-Commit:
16acce1dac1d - Gerenderte Upstream-Handbücher: docs.haproxy.org/3.4/
- Lokale Lizenzkopien: HAProxy-Lizenzhinweis und GPLv2
10 - 1. Kurzer Überblick über HTTP
Dieses Dokument beschreibt die Konfigurationssprache der oben angegebenen Version. Es enthält keine Hinweise, Beispiele oder Empfehlungen. Dafür stehen das Referenzhandbuch und das Architekturhandbuch zur Verfügung. Die nummerierten Kapitel sind in der flachen HAProxy-Seitenleiste zur direkten Navigation angeordnet.
Im HTTP-Modus analysiert und indiziert HAProxy sowohl Anfragen als auch Antworten vollständig. Dadurch lassen sich Abgleichkriterien für nahezu jeden Bestandteil ihres Inhalts festlegen.
Dafür ist es wichtig, den Aufbau von HTTP-Anfragen und -Antworten sowie ihre Zerlegung durch HAProxy zu verstehen. Damit wird es leichter, korrekte Regeln zu schreiben und Fehler in vorhandenen Konfigurationen zu finden.
HTTP ist durch eine Reihe von RFCs standardisiert, denen HAProxy möglichst genau folgt:
- RFC 9110: HTTP-Semantik (Bedeutung der Protokollelemente)
- RFC 9111: HTTP-Caching (Regeln für HTTP-Caches)
- RFC 9112: HTTP/1.1 (Darstellung, Interoperabilitätsregeln, Sicherheit)
- RFC 9113: HTTP/2 (Darstellung, Interoperabilitätsregeln, Sicherheit)
- RFC 9114: HTTP/3 (Darstellung, Interoperabilitätsregeln, Sicherheit)
Außerdem spezifizieren RFC 8999 bis 9002 die QUIC-Transportschicht, die das HTTP/3-Protokoll verwendet.
1.1. Das HTTP-Transaktionsmodell
HTTP arbeitet transaktionsorientiert: Jede Anfrage führt zu genau einer Antwort. Ursprünglich gab es in Protokollversion 1.0 nur eine Anfrage je Verbindung. Der Client baut eine TCP-Verbindung zum Server auf und sendet darüber eine Anfrage. Der Server antwortet, anschließend wird die Verbindung geschlossen. Eine weitere Anfrage erfordert dann eine neue Verbindung:
In diesem oft “HTTP close” genannten Modus gibt es ebenso viele Verbindungsaufbauten wie HTTP-Transaktionen. Da der Server die Verbindung nach der Antwort schließt, muss der Client die Inhaltslänge nicht kennen. Mit dem Schließen der Verbindung betrachtet er die Antwort als vollständig. Werden Antworten wegen Netzwerkfehlern abgeschnitten, kann der Client sie deshalb irrtümlich für vollständig halten. Früher wurden dadurch gelegentlich unvollständige Bilder auf dem Bildschirm angezeigt.
Der transaktionsorientierte Aufbau ermöglichte eine Erweiterung, bei der die Verbindung zwischen aufeinanderfolgenden Transaktionen offen bleibt. Dabei muss der Server jedoch für jede Antwort die Inhaltslänge angeben, damit der Client nicht endlos wartet. Dazu dient der besondere Header “Content-length”. Dieser “keep-alive” genannte Modus kam mit HTTP/1.1 hinzu; einige HTTP/1.0-Implementierungen unterstützen ihn ebenfalls. Zwischen Anfragen wiederverwendete Verbindungen heißen persistente Verbindungen:
Vorteile sind die geringere Latenz zwischen Transaktionen, der geringere Rechenaufwand auf dem Server und die Möglichkeit, abgeschnittene Antworten zu erkennen. Der Modus ist meist schneller als das Schließen nach jeder Antwort, aber nicht immer: Manche Clients begrenzen die Zahl gleichzeitiger Verbindungen stärker, wodurch eine schlechte Netzwerkverbindung weniger gut ausgeglichen wird. Zudem müssen manche Server Verbindungen lange offen halten, um auf eine mögliche weitere Anfrage zu warten. Viele Verbindungen können dann viel Speicher belegen. Zu frühes Schließen kann dagegen Anfragen unterbrechen, die genau in diesem Moment eintreffen.
In diesem Modus muss die Antwortgröße vorab bekannt sein. Bei dynamisch erzeugten oder komprimierten Inhalten ist das nicht immer möglich. Deshalb wurde der “chunked mode” eingeführt. Statt sofort die Gesamtgröße anzukündigen, meldet der Sender nur die Größe des nächsten bereits gepufferten Antwortblocks, des sogenannten Chunks. Mit einem Block der Größe null kann er die Übertragung jederzeit beenden. Der Header Content-Length wird in diesem Modus nicht verwendet.
Eine weitere Verbesserung ist Pipelining. Dabei bleibt Keep-Alive aktiv, der Client wartet jedoch nicht auf die erste Antwort, bevor er die zweite Anfrage sendet. Das ist beim Abruf vieler Bilder einer Seite nützlich:
Dies kann die Leistung erheblich verbessern, da die Netzwerklatenz zwischen aufeinanderfolgenden Anfragen entfällt. Viele HTTP-Implementierungen unterstützen Pipelining nicht korrekt, weil HTTP keine Möglichkeit bietet, eine Antwort der zugehörigen Anfrage zuzuordnen. Deshalb muss der Server genau in der Reihenfolge der eingegangenen Anfragen antworten. Nach mehreren Einführungsversuchen verschiedener Clients wurde Pipelining in der Praxis wegen seiner Unzuverlässigkeit auf manchen Servern vollständig aufgegeben. Server müssen es dennoch unterstützen.
Die nächste Verbesserung ist Multiplexing, wie es HTTP/2 und HTTP/3 verwenden. Mehrere Transaktionen, also Anfrage-Antwort-Paare, laufen parallel über eine einzige Verbindung und kommen unabhängig voneinander mit ihrer jeweiligen Geschwindigkeit voran. Multiplex-Protokolle führen dafür den Begriff Stream ein: eine dieser parallelen Kommunikationen über dieselbe Verbindung. Jeder Stream erhält normalerweise eine innerhalb der Verbindung eindeutige Kennung. Beide Endpunkte erkennen daran, wohin die Daten gehören. Clients starten häufig viele Streams gleichzeitig, bis zu 100 und manchmal mehr, und lassen den Server die Anfragen bearbeiten und je nach Verfügbarkeit der Antworten in beliebiger Reihenfolge beantworten. Multiplexing verringert vor allem die Anzahl der Hin- und Rückläufe deutlich und beschleunigt das Laden von Seiten über Netzwerke mit hoher Latenz. Bei bildreichen Websites ist bisweilen zu sehen, wie alle Bilder gleichzeitig geladen werden.
Diese Protokolle komprimieren außerdem Header-Felder, um weniger Bytes übertragen zu müssen. Das verbessert ihre Effizienz, macht sie ohne geeignete Werkzeuge jedoch praktisch weder von Hand bearbeitbar noch mit bloßem Auge lesbar, wie es bei HTTP/1 möglich war. Deshalb stellt die Fachliteratur einschließlich dieses Dokuments HTTP-Nachrichten weiterhin in HTTP/1-Syntax dar, auch für neuere Protokollversionen.
HTTP/2 hat konstruktionsbedingte Einschränkungen. Paketverluste betreffen beispielsweise alle Streams gleichzeitig. Benötigt ein Client viel Zeit zum Abruf eines Objekts, etwa weil er es auf die Festplatte schreiben muss, kann er den Abruf verlangsamen und währenddessen den Zugriff auf dahinter wartende Daten unmöglich machen. Dies heißt Head-of-Line-Blocking, kurz HoL-Blocking oder auch nur HoL.
HTTP/3 verwendet QUIC, das seinerseits auf UDP aufsetzt. QUIC beseitigt Head-of-Line-Blocking auf der Transportebene durch unabhängig behandelte Streams. Bei Paketverlusten beeinträchtigt ein betroffener Stream die anderen nicht; auf alle lässt sich parallel zugreifen. QUIC unterstützt auch die Migration von Verbindungen, die HAProxy derzeit jedoch nicht unterstützt.
Für persistente Verbindungen verwendet HAProxy standardmäßig Keep-Alive. Es verarbeitet jede Anfrage und Antwort und lässt die Verbindung auf beiden Seiten zwischen dem Ende einer Antwort und der nächsten Anfrage ruhen. Bei einer HTTP/2-Verbindung vom Client verarbeitet es alle Anfragen parallel und lässt die Verbindung bis zu weiteren Anfragen offen und inaktiv, wie bei einer HTTP-Verbindung mit Keep-Alive.
HAProxy unterstützt im Wesentlichen 3 Verbindungsmodi:
-
keep alive: Alle Anfragen und Antworten werden verarbeitet. Die Verbindungen zum Client und zum Server bleiben für weitere Anfragen offen. Dies ist der Standard und passt zum modernen Web sowie zu HTTP/2 und HTTP/3.
-
server close: Die Verbindung zum Server wird nach der Antwort geschlossen.
-
close: Nach dem Ende der Antwort wird die Verbindung auf beiden Seiten aktiv geschlossen.
Außerdem kann die serverseitige Verbindung standardmäßig für jede Anfrage eines beliebigen Clients wiederverwendet werden, wie es die HTTP-Spezifikation verlangt. Benötigte Informationen zu einem bestimmten Client, etwa seine Quelladresse, müssen daher mit jeder Anfrage übertragen werden. Bei HTTP/2 zum Server ordnet HAProxy die Verbindung standardmäßig demselben Client zu, um Head-of-Line-Blocking zwischen Clients zu vermeiden.
1.2. Begriffe
Die Begriffe in HAProxy haben sich mit dem HTTP-Protokoll und dessen Verwendung weiterentwickelt. Anfangs unterschieden sich Verbindung, Sitzung, Stream und Transaktion kaum. Mit der Zeit wurden diese Begriffe genauer abgegrenzt, um den modernen HTTP-Versionen zu entsprechen. Einige ältere Bezeichnungen bleiben aus Kompatibilitätsgründen in der Konfiguration oder der Befehlszeilenschnittstelle sichtbar.
Für die aktuelle HAProxy-Version gelten folgende Definitionen:
-
Verbindung: Ein einzelner bidirektionaler Kommunikationskanal zwischen einem entfernten Teilnehmer, also Client oder Server, und HAProxy auf der niedrigsten möglichen Ebene. Meist entspricht er einem TCP-Socket zwischen einem Paar aus IP-Adressen und Ports. Clientseitig sind Verbindungen die ersten Objekte, die beim Verbindungsaufbau zu HAProxy entstehen. Regeln auf Verbindungsebene werden zuerst angewendet.
-
Sitzung: Ergänzt eine Verbindung um Kontextinformationen, etwa transportbezogene Daten wie TLS-Schlüssel oder Variablen. In HAProxy bezeichnete der Begriff lange durchgehende HTTP/1.0-Kommunikation zwischen zwei Endpunkten. Deshalb erscheint er noch in Namen mancher CLI-Befehle oder Statistiken, obwohl heute Streams gemeint sind. Hilfetexte und Beschreibungen versuchen, dies eindeutig zu machen. Auf Netzwerkebene ist der Begriff weiterhin gültig, etwa für TCP-Sitzungen im Betriebssystem oder durch eine Firewall, ebenso für Anwendungen außerhalb von HTTP, etwa eine telnet- oder SSH-Sitzung. Er darf nicht mit Anwendungssitzungen verwechselt werden, die einen vollständigen Benutzerkontext in einem Cookie speichern und demselben Server zugeleitet werden müssen.
-
Stream: Entspricht genau einer durchgehenden bidirektionalen Kommunikation auf Anwendungsebene, auf die Analysen und Änderungen angewendet werden können. Bei HTTP enthält er eine einzelne Anfrage und die zugehörige Antwort. Er entsteht beim Eingang der Anfrage und endet mit der vollständigen Auslieferung der Antwort. In diesem Zusammenhang besteht eine 1:1-Beziehung zum Stream eines Multiplex-Protokolls. Bei TCP-Kommunikation gibt es einen Stream je Verbindung.
-
Transaktion: Besteht nur aus einer Anfrage und der zugehörigen Antwort. Vor der Einführung von Streams wurde der Begriff zusammen mit Sitzungen verwendet; heute besteht eine 1:1-Beziehung zwischen Transaktion und Stream. Sichtbar ist er vor allem im Variablengültigkeitsbereich “txn”, der während der gesamten Transaktion und damit des Streams gilt.
-
Anfrage: Bezeichnet den Datenverkehr vom Client zum Server. Der Begriff wird vorwiegend bei HTTP verwendet, um anzugeben, wo Operationen ausgeführt werden, bei TCP aber ebenso zur Angabe der Verarbeitungsrichtung. In Zählern dienen Anfragen oft als Einheit für Verkehr oder Aktivität. Sie führen nicht immer zu einer Antwort, etwa bei Fehlern. Da es jedoch keine unaufgeforderten Antworten ohne Anfragen gibt, bleiben Anfragen ein sinnvolles Maß für die Gesamtaktivität. Bei TCP gibt es ebenso viele Anfragen wie Verbindungen.
-
Antwort: Bezeichnet den Datenverkehr vom Server zum Client oder von HAProxy zum Client, wenn HAProxy die Antwort selbst erzeugt, etwa bei einer HTTP-Weiterleitung.
-
Dienst: Bezeichnet meist eine interne Verarbeitung in HAProxy, für die kein Server erforderlich ist, etwa die Statistikseite, der Cache oder Lua-Code für eine kleine Anwendung. Ein Dienst liest normalerweise eine Anfrage, führt Operationen aus und erzeugt eine Antwort.
1.3. HTTP-Anfrage
Als Beispiel dient folgende HTTP-Anfrage:
1.3.1. Die Anfragezeile
Zeile 1 ist die Anfragezeile. Sie besteht immer aus 3 Feldern:
- einer Methode: GET
- einer URI: /serv/login.php?lang=en&profile=2
- einer Versionsangabe: HTTP/1.1
Die Felder werden durch sogenannte LWS getrennt, linearen Leerraum nach dem Standard. Meist sind das Leerzeichen; möglich sind aber auch Tabulatoren oder Zeilenumbrüche beziehungsweise Wagenrückläufe, gefolgt von Leerzeichen oder Tabulatoren. Die Methode selbst darf keinen Doppelpunkt (’:’) enthalten und besteht ausschließlich aus Buchstaben. Wegen dieser vielfältigen Kombinationen ist es sinnvoll, die Zerlegung HAProxy zu überlassen, statt selbst einen komplexen oder ungenauen regulären Ausdruck zu schreiben.
Die URI kann verschiedene Formen haben:
- Eine relative URI:
- Eine absolute URI, auch URL genannt:
-
Ein Stern (’*’): Diese Form ist nur zusammen mit OPTIONS zulässig und kann nicht weitergeleitet werden. Sie dient dazu, die Fähigkeiten des nächsten Netzknotens abzufragen.
-
Eine Kombination aus Adresse und Port, etwa 192.168.0.12:80. Sie wird mit CONNECT verwendet, um TCP-Tunnel durch HTTP-Proxys aufzubauen, meist für HTTPS, gelegentlich auch für andere Protokolle.
Eine relative URI besteht aus zwei Teilen. Vor dem Fragezeichen steht der Pfad, normalerweise der relative Pfad zu statischen Objekten auf dem Server. Danach folgt die Abfragezeichenfolge. Sie wird hauptsächlich bei GET-Anfragen an dynamische Skripte verwendet und hängt stark von der eingesetzten Sprache, dem Framework oder der Anwendung ab.
HTTP/2 und HTTP/3 übertragen keine Versionsinformation mit der Anfrage. Daher wird die Version des zugrunde liegenden Protokolls angenommen, also “HTTP/2”. Außerdem senden diese Protokolle keine zusammenhängende Anfragezeile. Sie zerlegen sie in einzelne Pseudo-Header, deren Namen mit einem Doppelpunkt beginnen. HAProxy setzt daraus wieder eine entsprechende Anfragezeile zusammen. Deshalb können sich protokollierte Anfragezeilen zwischen HTTP/1.x und HTTP/2 oder HTTP/3 leicht unterscheiden.
1.3.2. Die Anfrage-Header
Die Header beginnen in der zweiten Zeile. Am Zeilenanfang steht ein Name, unmittelbar gefolgt von einem Doppelpunkt (’:’). Üblicherweise folgt danach LWS, vorgeschrieben ist das jedoch nicht. Anschließend stehen die Werte. Mehrere gleichnamige Header können in einer Zeile zusammengefasst und ihre Werte durch Kommas getrennt werden, sofern die Reihenfolge erhalten bleibt. Dies kommt häufig beim Feld “Cookie:” vor. Ein Header kann mehrere Zeilen umfassen, wenn die Folgezeilen mit LWS beginnen. Im Beispiel aus 1.3 enthalten die Zeilen 4 und 5 insgesamt 3 Werte für “Accept:”. Gemäß Spezifikation wird LWS am Anfang und Ende eines Headers ignoriert und gehört nicht zum Wert.
Entgegen einer verbreiteten Annahme wird bei Header-Namen nicht zwischen Groß- und Kleinschreibung unterschieden. Das gilt auch für Werte, die andere Header-Namen bezeichnen, etwa bei “Connection:”. HTTP/2 und HTTP/3 übertragen Header-Namen immer in Kleinbuchstaben, was im Debug-Modus zu sehen ist. Intern werden sämtliche Header-Namen in Kleinbuchstaben normalisiert, damit HTTP/1.x und HTTP/2 oder HTTP/3 dieselbe Darstellung verwenden. Auf der anderen Seite werden sie unverändert gesendet. Deshalb kommt eine mit Binnenmajuskeln geschriebene HTTP/1.x-Anfrage mit kleingeschriebenen Header-Namen an.
Die erste leere Zeile beendet die Header. Oft wird von einem doppelten Zeilenumbruch gesprochen. Das ist ungenau, auch wenn ein doppelter Zeilenumbruch eine gültige Form einer Leerzeile ist.
HAProxy berücksichtigt diese komplexen Kombinationen beim Indizieren, Prüfen und Zählen der Header-Werte. Über ihre mögliche Schreibweise muss man sich daher keine Gedanken machen. Eine Anwendung sollte aber nicht als fehlerhaft gelten, nur weil sie ungewöhnliche, jedoch gültige Konstrukte verwendet.
Wichtiger Hinweis:
1.4. HTTP-Antwort
Eine HTTP-Antwort ähnelt einer HTTP-Anfrage stark. Beide heißen HTTP-Nachrichten. Als Beispiel dient folgende Antwort:
Als Sonderfall unterstützt HTTP sogenannte Informationsantworten mit Statuscodes 1xx. Sie enthalten keinen Teil der eigentlichen Antwort, sondern dienen als Signalisierung, etwa um einen Client zum weiteren Senden seiner Anfrage aufzufordern. Bei einer Antwort mit Status 100 stehen die angeforderten Informationen in der nächsten folgenden Antwort, deren Status nicht 100 ist. Auf eine Anfrage können somit mehrere Antworten folgen. Das funktioniert nur mit aktiviertem Keep-Alive; 1xx-Nachrichten wurden mit HTTP/1.1 eingeführt. HAProxy kann diese Nachrichten korrekt weiterleiten und überspringen und verarbeitet nur die nächste Antwort mit einem anderen Status als 100. Sofern nicht ausdrücklich anders angegeben, werden diese Nachrichten weder protokolliert noch verändert. Status 101 bedeutet, dass das Protokoll auf derselben Verbindung wechselt. HAProxy muss dann wie nach CONNECT in den Tunnelmodus wechseln. Der Header Upgrade enthält zusätzliche Informationen zum neuen Protokoll.
1.4.1. Die Antwortzeile
Zeile 1 ist die Antwortzeile. Sie besteht immer aus 3 Feldern:
- einer Versionsangabe: HTTP/1.1
- einem Statuscode: 200
- einer Begründung: OK
Der Statuscode hat immer 3 Stellen. Die erste Ziffer bezeichnet die allgemeine Statusklasse:
- 1xx = zu überspringende Informationsnachricht, etwa 100 oder 101
- 2xx = OK, Inhalt folgt, etwa 200 oder 206
- 3xx = OK, kein Inhalt folgt, etwa 302 oder 304
- 4xx = vom Client verursachter Fehler, etwa 401, 403 oder 404
- 5xx = vom Server verursachter Fehler, etwa 500, 502 oder 503
Statuscodes über 599 dürfen nicht übertragen werden. Manche Implementierungen verwenden sie jedoch in Protokollen, um interne Zustände zu melden. Die genaue Bedeutung der Codes beschreibt RFC9110. HTTP/2 und neuere Versionen haben keine Versionsangabe und übermitteln den Statuscode im Pseudo-Header “:status”.
Das Feld “reason” ist nur ein Hinweis und wird von Clients nicht ausgewertet. Es kann beliebigen Inhalt haben; üblich sind jedoch die etablierten Meldungen. Das Feld kann aus einem oder mehreren Wörtern bestehen, etwa “OK”, “Found” oder “Authentication Required”. Ab HTTP/2 existiert es nicht und wird nicht übertragen. Leitet HAProxy eine Antwort von HTTP/2 oder neuer an einen HTTP/1-Client weiter, erzeugt es ein solches übliches, zum Statuscode passendes Begründungsfeld.
HAProxy kann selbst folgende Statuscodes ausgeben:
Die oben aufgeführten Fehlercodes 4xx und 5xx lassen sich anpassen; siehe “errorloc” in Abschnitt 4.2 . Andere Statuscodes können gezielt durch bestimmte Aktionen ausgegeben werden, etwa “deny”, “return” und “redirect” in Abschnitt 4.3 .
1.4.2. Die Antwort-Header
Antwort-Header funktionieren genauso wie Anfrage-Header. HAProxy verwendet daher dieselbe Analysefunktion für beide. Einzelheiten stehen in Abschnitt 1.3.2.
11 - 2. HAProxy konfigurieren
2.1. Format der Konfigurationsdatei
Die Konfiguration von HAProxy bezieht Parameter aus 3 wesentlichen Quellen:
- den Befehlszeilenargumenten, die immer Vorrang haben
- den Konfigurationsdateien, deren Format hier beschrieben wird
- der Umgebung des laufenden Prozesses, sofern bestimmte Umgebungsvariablen ausdrücklich referenziert werden
Die Konfigurationsdatei verwendet ein recht einfaches hierarchisches Format mit wenigen Grundregeln:
Mehr ist zum Schreiben eines einfachen, aber zuverlässigen Konfigurationsgenerators nicht nötig. Um jede beliebige Konfiguration zuverlässig auszuwerten oder bestimmte Grenzfälle zu behandeln, reicht dies jedoch nicht aus.
Aus den obigen Regeln ergeben sich zunächst einige Folgerungen. Nach Regel 6 und 7 gelten die Schlüsselwörter zum Definieren eines neuen Abschnitts überall und können in keinem bestimmten Abschnitt eine andere Bedeutung haben. Diese Schlüsselwörter bestehen stets aus einem einzelnen Wort, nicht aus einer Wortfolge. Der nachfolgende Abschnitt wird gewöhnlich mit demselben Namen bezeichnet. So meint „globaler Abschnitt“ den Konfigurationsabschnitt nach dem Schlüsselwort “global”. Diese Bezeichnung wird in Fehlermeldungen häufig verwendet, um die zu bearbeitenden Stellen leichter auffindbar zu machen.
Mehrere Abschnittstypen erzeugen ein internes Objekt oder einen Konfigurationsbereich, der von anderen unterscheidbar sein muss. Dafür nehmen sie ein zusätzliches Wort entgegen, das den Namen dieses Abschnitts festlegt. Bei einigen ist der Abschnittsname zwingend erforderlich. So erzeugt “frontend foo” einen neuen Abschnitt des Typs “frontend” mit dem Namen “foo”. Ein Name gilt gewöhnlich nur für seinen Abschnittstyp; zwei Abschnitte unterschiedlichen Typs können denselben Namen tragen. Davon wird jedoch abgeraten, da es die Konfigurationsverwaltung erschwert.
Aus Regel 7 folgt unmittelbar, dass beim Einlesen mehrerer Dateien jede davon mit einem neuen Abschnitt beginnen muss und jedes Dateiende einen Abschnitt beendet. Eine Datei kann weder Unterabschnitte enthalten noch einen bestehenden Abschnitt beenden und einen neuen beginnen.
Regel 1 besagt, dass die Reihenfolge wichtig ist. Manche Schlüsselwörter definieren Direktiven, die mehrfach wiederholt werden können, um eine geordnete Folge von Regeln zu bilden. Beispielsweise können mit “tcp-request” Regeln für “accept” und “reject” anhand verschiedener Kriterien abwechselnd angewendet werden. Ein Werkzeug zur Bearbeitung von Konfigurationsdateien muss deshalb beim Ändern einer Datei stets die Reihenfolge innerhalb eines Abschnitts erhalten. Die Reihenfolge der Abschnitte ist gewöhnlich unerheblich. Eine Ausnahme bildet der globale Abschnitt: Er muss vor den anderen stehen, kann aber bei Bedarf wiederholt werden. Außerdem können bestimmten erzeugten Objekten wie Proxys automatisch Kennungen zugewiesen werden, die sich beim Umordnen der Abschnitte ändern. Sie erscheinen beispielsweise in der Statistik. In der folgenden Konfiguration erhält “foo” daher eine kleinere ID als “bar”. Werden die beiden Abschnitte vertauscht, kehrt sich dies um:
Ein weiterer wichtiger Punkt: Nach den Regeln 2 und 3 gehören Leerzeilen, Leerzeichen, Tabulatoren und Kommentare nach einem ungeschützten “#” nicht zur Konfiguration, da sie nur als Begrenzungen dienen. Die folgenden Konfigurationen sind daher exakt gleichwertig:
und:
Üblicherweise wird nur das Schlüsselwort, das einen neuen Abschnitt beginnt, linksbündig angeordnet. Alle anderen Schlüsselwörter werden durch einen Tabulator oder einige vorangestellte Leerzeichen eingerückt. So ist sofort erkennbar, dass sie zu demselben Abschnitt gehören, wie im zweiten Beispiel oben. Kommentare vor einem neuen Abschnitt helfen beim Erkennen des gesuchten Abschnitts. Eine Leerzeile am Abschnittsende erleichtert es ebenfalls, beim Bearbeiten dessen Ende zu finden.
Tabulatoren eignen sich gut zum Einrücken, lassen sich aber schlecht kopieren und einfügen. Werden stattdessen Leerzeichen verwendet, werden nur wenige (2 bis 4) empfohlen. So bleibt die Bearbeitung vor Ort auch mit einfachen Editoren ohne automatische Einrückung handhabbar.
Früher wurden Argumente häufig an festen Tabulatorpositionen ausgerichtet, da die meisten Schlüsselwörter höchstens zwei Argumente annahmen. Für moderne Versionen mit komplexen Ausdrücken eignet sich dies nicht mehr und wird nicht empfohlen.
2.2. Anführungszeichen und Maskierung
In modernen Konfigurationen benötigen manche Argumente Zeichen, die zuvor ausschließlich als Trennzeichen dienten. HAProxy unterstützt deshalb die Maskierung eines Zeichens mit einem vorangestellten Backslash (’\’), schwaches Quoting mit doppelten Anführungszeichen ("") um einen Textabschnitt und starkes Quoting mit einfachen Anführungszeichen (’’) um einen Textabschnitt.
Dies ähnelt dem Vorgehen in verschiedenen Programmiersprachen und besonders dem üblichen Verhalten der Bourne-Shell. Beim Zerlegen der Zeilen in Wörter berücksichtigt der Konfigurationsparser auch Anführungszeichen und Backslashes. So entscheidet er, ob ein Zeichen als Trennzeichen oder als wörtliches Zeichen innerhalb des aktuellen Wortes gilt. Anschließend werden das Maskierungszeichen und die Anführungszeichen entfernt; das verbleibende Wort wird unverändert etwa als Schlüsselwort oder Argument verwendet.
Wird innerhalb eines Wortes ein Backslash benötigt, muss er entweder mit sich selbst maskiert werden, also durch einen doppelten Backslash, oder in einfache Anführungszeichen gesetzt werden.
Außerhalb von Anführungszeichen wird ein Sonderzeichen durch einen vorangestellten Backslash (’\’) maskiert:
Zusätzlich lassen sich einige nicht druckbare Zeichen mit der üblichen C-Schreibweise einfügen:
Für schwaches Quoting wird das zu schützende Zeichen oder die Zeichenfolge in doppelte Anführungszeichen ("") gesetzt. Dadurch werden folgende Interpretationen verhindert:
Schwaches Quoting ermöglicht die Auswertung von Umgebungsvariablen, denen ein Dollarzeichen (’$’) vorangestellt wird. Außerhalb von Anführungszeichen werden diese nicht ausgewertet. Wird innerhalb doppelter Anführungszeichen ein Dollarzeichen als solches benötigt, muss es mit einem Backslash maskiert werden.
Für starkes Quoting wird das zu schützende Zeichen oder die Zeichenfolge in einfache Anführungszeichen (’’) gesetzt. Darin wird nichts interpretiert; dies ist eine wirksame Methode, reguläre Ausdrücke zu schützen.
Die folgende Tabelle zeigt daraus abgeleitet, wie Sonderzeichen in verschiedenen Kontexten eingegeben werden können. Nicht druckbare Zeichen sind durch ihren Namen in spitzen Klammern ersetzt. Manche Zeichen lassen sich nur maskiert darstellen und besitzen innerhalb einfacher Anführungszeichen keine mögliche Darstellung; deshalb fehlen sie dort:
Beispiel:
In einem besonderen Fall kann eine zweite Ebene von Anführungszeichen oder Maskierung nötig sein. Manche Schlüsselwörter nehmen Argumente in runden Klammern entgegen, teilweise durch Kommas getrennt. Meist sind dies Ganzzahlen oder vordefinierte Wörter. Bei beliebigen Zeichenketten kann jedoch eine weitere Maskierungsebene erforderlich sein, um Zeichen des Arguments von dessen Begrenzungszeichen zu unterscheiden. Ein häufiges Beispiel ist der Konverter “regsub”. Er nimmt einen regulären Ausdruck als Argument entgegen. Wird darin eine schließende runde Klammer benötigt, muss sie eigene Anführungszeichen erhalten.
Für Anführungszeichen verhält sich der Parser für Schlüsselwortargumente genauso wie der Parser auf oberster Ebene. Lediglich die Escape-Sequenzen \#, \$ und \xNN werden nicht verarbeitet. Weniger offensichtlich ist, dass die innen verwendeten Begrenzungszeichen zunächst maskiert oder in Anführungszeichen gesetzt werden müssen, damit sie nicht bereits auf der obersten Ebene aufgelöst werden.
Das folgende Beispiel verwendet den Konverter “regsub” mit 3 Argumenten: einem regulären Ausdruck, einer Ersetzungszeichenkette und einer Menge von Flags:
Hier waren keine besonderen Anführungszeichen nötig. Soll nun aber sowohl “foo” als auch “bar” durch “blah” ersetzt werden, wird der reguläre Ausdruck “(foo|bar)” benötigt. Folgendes ist nicht möglich:
Denn die Zeichenkette soll so aufgeteilt werden:
Tatsächlich wird jedoch eine Zeichenkette zwischen öffnender und schließender Klammer übergeben, gefolgt von ungültigem Resttext:
Es scheint naheliegend, die schließende Klammer in Anführungszeichen zu setzen. Allein genügt dies aber nicht: Wie oben beschrieben, verarbeitet der Parser auf oberster Ebene die Anführungszeichen und löst sie vor der Verarbeitung dieses Wortes auf:
Für den Argumentparser auf der zweiten Ebene hat sich somit nichts geändert: Er sieht weiterhin einen abgeschnittenen regulären Ausdruck als einziges Argument und ungültigen Resttext am Ende. Werden die Anführungszeichen maskiert, gelangen sie unverändert auf die zweite Ebene:
Alternativ kann die gesamte Zeichenkette außen in einfache und innen in doppelte Anführungszeichen gesetzt werden, damit die doppelten Anführungszeichen nicht wieder entfernt werden:
Dabei ist zu beachten, dass Begrenzungszeichen innerhalb der übergeordneten Zeichenkette gewöhnliche Zeichen bleiben und keine Trennfunktion mehr haben. Insbesondere gehören Leerzeichen und Tabulatoren neben Kommas zur Zeichenkette. Das folgende Beispiel ist an mehreren Stellen falsch:
Allein die Leerzeichen um die Kommas führen dazu, dass diese Teil des Feldes selbst werden. Der Konverter " regsub" mit führendem Leerzeichen wird daher nicht gefunden und löst einen Fehler aus. Weniger offensichtlich ist, dass die Ersetzungszeichenkette " blah" ein Leerzeichen in die Ausgabe einfügt. Eine gute Faustregel lautet deshalb, niemals unnötige Leerzeichen in Ausdrücke einzufügen.
In regulären Ausdrücken kann das Dollarzeichen (’$’) auftreten oder ein Backslash (’\’) in der Ersetzungszeichenkette verwendet werden. Diese Zeichen werden innerhalb doppelter Anführungszeichen ebenfalls verarbeitet. Daher sind einfache Anführungszeichen oder eine doppelte Maskierung vorzuziehen. Beispiel:
Innerhalb einfacher Anführungszeichen sind Backslashes keine Maskierungszeichen. Das gesamte obige Wort ist bereits durch einfache Anführungszeichen vor ihrer Interpretation geschützt. Wäre dagegen der gesamte Ausdruck in doppelte Anführungszeichen gesetzt, würden das Dollarzeichen und die Backslashes bereits auf oberster Ebene aufgelöst und dadurch der Argumentinhalt auf der zweiten Ebene beschädigt.
Da einfache Anführungszeichen innerhalb von starkem Quoting nicht maskiert werden können, müssen sie bei Bedarf im Argument zweimal maskiert oder in Anführungszeichen gesetzt werden. Dafür gibt es mehrere Möglichkeiten:
Im Zweifelsfall zunächst ganz auf Anführungszeichen verzichten und nur Argumente mit Kommas oder schließenden runden Klammern in einfache oder doppelte Anführungszeichen setzen. Enthält die Zeichenkette ein Dollarzeichen oder einen Backslash, müssen diese Anführungszeichen gegebenenfalls mit einem Backslash maskiert werden. Dies ähnelt der doppelten Maskierung eines an “eval” übergebenen Befehls in einer Bourne-Shell. Für API-Autoren ist es vermutlich am besten, ausnahmslos jedes Argument unabhängig von seinem Inhalt mit maskierten Anführungszeichen zu umgeben. Für Anwender sind Konfigurationen wahrscheinlich besser lesbar, wenn der gesamte Ausdruck in einfachen und jedes Argument in doppelten Anführungszeichen steht.
2.3. Umgebungsvariablen
Die HAProxy-Konfiguration unterstützt Umgebungsvariablen. Sie werden ausschließlich innerhalb doppelter Anführungszeichen interpretiert und beim Einlesen der Konfiguration expandiert. Variablennamen müssen mit einem Dollarzeichen ("$") beginnen und können wie in der Bourne-Shell zusätzlich in geschweifte Klammern ("{}") eingeschlossen werden. Sie dürfen alphanumerische Zeichen und Unterstriche ("_") enthalten, sollten aber nicht mit einer Ziffer beginnen. Enthält eine Variable mehrere durch Leerzeichen getrennte Werte, lässt sie sich in einzelne Argumente expandieren: Dazu die Variable in geschweifte Klammern setzen und vor der schließenden Klammer das Suffix ‘[*]’ ergänzen. Ein Standardwert für nicht gesetzte Variablen kann nach einem Bindestrich ‘-’ hinter dem Variablennamen angegeben werden. Er ersetzt nur nicht vorhandene Variablen, keine leeren.
Beispiel:
Einige Variablen werden von HAProxy definiert und können in der Konfigurationsdatei verwendet werden. Sie sind in der folgenden Tabelle aufgeführt und in vier Kategorien eingeteilt:
-
verwendbar: Die Variable ist in der Konfiguration zugänglich. Sie kann direkt aufgelöst oder in bedingten Blöcken und Prädikaten zum Aktivieren oder Deaktivieren von Konfigurationsfragmenten verwendet werden, wie in Abschnitt 2.4 „Bedingte Blöcke“ beschrieben.
-
veränderbar: Die Variable kann in der Konfiguration mit “setenv”/“unsetenv” neu definiert oder entfernt werden.
-
aufgelistet: Die Variable erscheint in der Ausgabe des CLI-Befehls “show env”, der in Abschnitt 9.3 „Unix-Socket-Befehle“ des Verwaltungshandbuchs beschrieben ist.
Daneben gibt es die Unterkategorien „Master“ und „Worker“, die in der folgenden Tabelle mit ‘M’ bzw. ‘W’ gekennzeichnet sind. Sie zeigen die Unterschiede zwischen den beiden Prozessen beim Start von HAProxy im Master-Worker-Modus.
-
Master: Die Variable ist im Master-Prozess gesetzt und zugänglich. Sie erscheint daher in der Ausgabe von “show env” der Master-CLI und kann in bedingten Blöcken oder Direktiven spezielle Einstellungen für den Master aktivieren. Siehe die Beispiele in Abschnitt 2.4 „Bedingte Blöcke“.
-
Worker: Die Variable ist im Worker-Prozess gesetzt und zugänglich. Sie erscheint in “show env” der Worker-CLI oder in “@1 show env” der Master-CLI und kann ebenfalls Bedingungen für Parameter des Worker-Prozesses bilden. Siehe die Beispiele in Abschnitt 2.4 „Bedingte Blöcke“.
Im eigenständigen Betrieb ohne die Option “-W” und ohne das Schlüsselwort “master-worker” verhält sich der Prozess wie ein Worker. Ausgenommen sind die Variablen “HAPROXY_MASTER_CLI” und “HAPROXY_MWORKER”, die dann nicht definiert sind.
Einige Variablen sind als weder verwendbar noch veränderbar gekennzeichnet:
- HAPROXY_CFGFILES
- HAPROXY_MWORKER
- HAPROXY_CLI
- HAPROXY_MASTER_CLI
- HAPROXY_LOCALPEER
Ihre Werte sind beim Einlesen der Konfiguration undefiniert und werden erst später während der Initialisierung gesetzt. Daher wird empfohlen, diese Variablen weder in bedingten Blöcken noch in den Schlüsselwörtern “setenv”/“resetenv”/“unsetenv” des globalen Abschnitts zu referenzieren.
Die folgende Tabelle fasst den Status der Variablen für die verschiedenen Betriebsarten zusammen:
Im Einzelnen handelt es sich um folgende Variablen:
-
HAPROXY_LOCALPEER: beim Prozessstart definiert; enthält den Namen des lokalen Peers. Siehe “-L” im Verwaltungshandbuch.
-
HAPROXY_CFGFILES: durch Semikolons getrennte Liste der von HAProxy geladenen Konfigurationsdateien. Kann bei der Angabe eines Verzeichnisses nützlich sein.
-
HAPROXY_HTTP_LOG_FMT: enthält das HTTP-Standardprotokollformat aus Abschnitt 8.2.3 „HTTP-Protokollformat“. Damit lässt sich das Standardformat überschreiben, ohne die gesamte ursprüngliche Definition kopieren zu müssen.
-
HAPROXY_HTTP_CLF_LOG_FMT: enthält das HTTP-CLF-Standardprotokollformat aus Abschnitt 8.2.3 „HTTP-Protokollformat“. Damit lässt sich das Standardformat überschreiben, ohne die gesamte ursprüngliche Definition kopieren zu müssen.
Beispiel:
-
HAPROXY_HTTPS_LOG_FMT: wie HAPROXY_HTTP_LOG_FMT, jedoch für das HTTPS-Protokollformat aus Abschnitt 8.2.4 „HTTPS-Protokollformat“.
-
HAPROXY_TCP_LOG_FMT: wie HAPROXY_HTTP_LOG_FMT, jedoch für das TCP-Protokollformat aus Abschnitt 8.2.2 „TCP-Protokollformat“.
-
HAPROXY_TCP_CLF_LOG_FMT: wie HAPROXY_HTTP_CLF_LOG_FMT, jedoch für das TCP-CLF-Protokollformat aus Abschnitt 8.2.2 „TCP-Protokollformat“.
-
HAPROXY_KEYLOG_FC_LOG_FMT: enthält das Keylog-Format für die clientseitige TLS-Verbindung des Frontends. Schlüsseleinträge werden durch Zeilenumbrüche getrennt; das Format ist daher möglicherweise nicht mit dem verwendeten syslog-Server kompatibel. “tune.ssl.keylog on” ist erforderlich.
-
HAPROXY_KEYLOG_BC_LOG_FMT: wie HAPROXY_KEYLOG_FC_LOG_FMT, jedoch für die serverseitige TLS-Verbindung des Backends. Schlüsseleinträge werden durch Zeilenumbrüche getrennt; das Format ist daher möglicherweise nicht mit dem verwendeten syslog-Server kompatibel. “tune.ssl.keylog on” ist erforderlich.
-
HAPROXY_MWORKER: Diese Variable wird im Master-Worker-Modus auf 1 gesetzt.
-
HAPROXY_CLI: konfigurierte Listener-Adressen des Statistik-Sockets jedes Prozesses, durch Semikolons getrennt.
-
HAPROXY_MASTER_CLI: im Master-Worker-Modus die durch Semikolons getrennten Listener-Adressen der Master-CLI.
-
HAPROXY_STARTUP_VERSION: enthält die beim Start verwendete Version. Im Master-Worker-Modus ist dies die Version, mit der der Master gestartet wurde, auch nach Aktualisierung der ausführbaren Datei und anschließendem Neuladen.
-
HAPROXY_BRANCH: enthält die Version des HAProxy-Zweigs, etwa “2.8”, jedoch nicht die vollständige Versionsnummer. Dies kann bei einer Migration nützlich sein, wenn Ressourcen wie Maps oder Zertifikate in einem Pfad mit der Nummer des Versionszweigs liegen.
Zusätzlich werden einige Pseudovariablen intern aufgelöst und lassen sich wie gewöhnliche Variablen verwenden. Pseudovariablen beginnen immer mit einem Punkt (’.’); nur in ihnen ist ein Punkt zulässig. Derzeit gibt es folgende Pseudovariablen:
-
.FILE: Name der gerade eingelesenen Konfigurationsdatei.
-
.LINE: Zeilennummer in der gerade eingelesenen Konfigurationsdatei, beginnend bei eins.
-
.SECTION: Name des gerade eingelesenen Abschnitts oder dessen Typ, wenn der Abschnitt keinen Namen hat, etwa “global”. Vor dem ersten Abschnitt ist dies eine leere Zeichenkette.
Diese Variablen werden an der Stelle aufgelöst, an der sie eingelesen werden. Wird beispielsweise “.LINE” in einer “log-format”-Direktive eines defaults-Abschnitts verwendet, steht die Zeilennummer bereits vor dem Parsen und Kompilieren der “log-format”-Direktive fest. Nachfolgende Proxys verwenden daher dieselbe Zeilennummer.
So lassen sich in Variablen, Protokollen, Fehlerstatus, Health Checks und Header-Werten Informationen zum Auffinden einer Regel ausgeben. Zeilennummern können sogar zur Benennung von Konfigurationsobjekten wie Servern dienen.
2.4. Bedingte Blöcke
Manchmal ist es praktisch, beliebige Teile der Konfiguration abhängig von Bedingungen ein- oder auszuschalten. So lassen sich beispielsweise SSL oder Cipher sowie Listener einer Vorproduktionsumgebung ohne Änderung der Konfiguration aktivieren oder deaktivieren. Auch die Konfigurationssyntax kann während einer Migration zwei verschiedene HAProxy-Versionen unterstützen. HAProxy bietet dafür verschachtelbare Direktiven nach Art eines Präprozessors, die Textblöcke einbeziehen oder ignorieren. Diese Direktiven müssen in einer eigenen Zeile stehen und wirken auf die folgenden Zeilen. Zwei davon unterstützen einen Ausdruck; die anderen wechseln lediglich zu einem alternativen Block oder schließen die aktuelle Ebene ab. Bedingte Blöcke werden mit folgenden 4 Direktiven gebildet:
- .if
<condition> - .elif
<condition> - .else
- .endif
“.if” eröffnet eine neue verschachtelte Ebene, “.elif” und “.else” bleiben auf derselben Ebene, und “.endif” schließt eine Ebene. Jedes “.if” muss mit einem zugehörigen “.endif” abgeschlossen werden. “.elif” darf nur auf “.if” oder “.elif” folgen; beliebig viele “.elif” können aufeinanderfolgen. Je “.if” ist nur ein “.else” zulässig. Es muss immer nach dem “.if” oder dem letzten “.elif” eines Blocks stehen.
Kommentare können bei Bedarf nach einem ‘#’ in derselben Zeile stehen und werden ignoriert. Die Direktiven werden wie andere Konfigurationsdirektiven in Tokens zerlegt; daher können Bedingungen Umgebungsvariablen verwenden.
Bedingungen lassen sich auch beim Start mit dem Parameter -cc auswerten. Siehe „3. HAProxy starten“ im Verwaltungshandbuch.
Eine Bedingung ist entweder eine leere Zeichenkette, die falsch ergibt, oder ein Ausdruck aus einer beliebigen Kombination folgender Elemente:
- die Ganzzahl null (‘0’), die immer “false” ergibt
- eine Ganzzahl ungleich null, etwa ‘1’, die immer “true” ergibt
- ein Prädikat, optional gefolgt von Argumenten in runden Klammern
- eine Bedingung in einem Paar runder Klammern ‘(’ und ‘)’
- ein Ausrufezeichen (’!’) vor einem der obigen nicht leeren Elemente, das dessen Wert negiert
- mit logischem AND (’&&’) verknüpfte Ausdrücke, die von links nach rechts ausgewertet werden, bis einer falsch ergibt
- mit logischem OR (’||’) verknüpfte Ausdrücke, die von rechts nach links ausgewertet werden, bis einer wahr ergibt
Dabei werden derselbe Zeilen-Tokenizer und Argumentparser wie in der übrigen Konfigurationssprache verwendet. Wörter werden an Folgen eines oder mehrerer ungeschützter Leerzeichen oder Tabulatoren getrennt und vor der Auswertung mit jeweils einem Leerzeichen wieder zusammengesetzt. So muss nicht die gesamte Zeile in Anführungszeichen gesetzt werden. Allerdings gehören dadurch Leerzeichen um Kommas oder Klammern tatsächlich zum Wert, was nicht immer erwartet wird. Beispielsweise prüft der folgende Ausdruck:
ob die Variable " HAPROXY_MWORKER " mit den Leerzeichen existiert. Dieser Ausdruck:
vergleicht dagegen die Umgebungsvariable “ENABLE_SSL” mit dem Wert " 1", der ein einzelnes führendes Leerzeichen enthält. Denn die Zeile wird zunächst wie folgt in Wörter zerlegt:
Anschließend wird das schwache Quoting verarbeitet und die Umgebungsvariable “$ENABLE_SSL” aufgelöst, beispielsweise mit ENABLE_SSL=0. Schließlich werden die Wörter mit jeweils einem Leerzeichen dazwischen zu einer einzigen Zeichenkette zusammengesetzt:
Erst danach wird diese als einzelner Ausdruck ausgewertet. Das zwischen Komma und “1” eingefügte Leerzeichen gehört weiterhin zum Argumentwert, sodass das Argument " 1" lautet:
Selbst wenn ENABLE_SSL den Wert “1” hätte, würde dieser also nicht mit " 1" übereinstimmen, da sich die Zeichenketten um ein Leerzeichen unterscheiden.
Hinweis: Wie in Abschnitt „2.2. Anführungszeichen und Maskierung“ erläutert, ist es eine gute Faustregel, niemals unnötige Leerzeichen in Ausdrücke einzufügen.
Wie in anderen Sprachen hat AND Vorrang vor OR. Daher wird “A && B || C && D” als “(A && B) || (C && D)” ausgewertet.
Derzeit werden folgende Prädikate unterstützt:
-
awslc_api_atleast(
<ver>): ergibt wahr, wenn die aktuelle awslc-API-Nummer mindestens so neu wie<ver>ist, andernfalls falsch. Beispiel: awslc_api_atleast(35) -
awslc_api_before(
<ver>): ergibt wahr, wenn die aktuelle awslc-API-Nummer strikt älter als<ver>ist, andernfalls falsch. Beispiel: awslc_api_before(26) -
defined(
<name>) : ergibt wahr, wenn die Umgebungsvariable<name>existiert, unabhängig von ihrem Inhalt -
feature(
<name>) : ergibt wahr, wenn die Funktion<name>in der Funktionsliste von “haproxy -vv” als vorhanden aufgeführt ist, also<name>nach einem ‘+’ erscheint -
openssl_version_atleast(
<ver>): ergibt wahr, wenn die aktuelle openssl-Version mindestens so neu wie<ver>ist, andernfalls falsch. Bibliotheken wie LibreSSL, AWS-LC und WolfSSL geben ebenfalls eine Pseudo-OpenSSL-Version an. Beispiel:
-
openssl_version_before(
<ver>): ergibt wahr, wenn die aktuelle openssl-Version strikt älter als<ver>ist, andernfalls falsch. Bibliotheken wie LibreSSL, AWS-LC und WolfSSL geben ebenfalls eine Pseudo-OpenSSL-Version an. Beispiel: openssl_version_before(3.5.0) -
ssllib_name_startswith(
<name>) : ergibt wahr, wenn der Name der mit HAProxy eingebundenen SSL-Bibliothek mit<name>beginnt. Beispiel: ssllib_name_startswith(wolfSSL) -
streq(
<str1>,<str2>) : ergibt nur dann wahr, wenn beide Zeichenketten gleich sind -
strneq(
<str1>,<str2>): ergibt nur dann wahr, wenn sich beide Zeichenketten unterscheiden -
strstr(
<str1>,<str2>): ergibt nur dann wahr, wenn die zweite Zeichenkette in der ersten vorkommt. -
version_atleast(
<ver>): ergibt wahr, wenn die aktuelle haproxy-Version mindestens so neu wie<ver>ist, andernfalls falsch. Die Versionssyntax entspricht der Ausgabe von “haproxy -v”; fehlende Bestandteile werden als null angenommen. -
version_before(
<ver>): ergibt wahr, wenn die aktuelle haproxy-Version strikt älter als<ver>ist, andernfalls falsch. Die Versionssyntax entspricht der Ausgabe von “haproxy -v”; fehlende Bestandteile werden als null angenommen. -
enabled(
<opt>) : ergibt wahr, wenn die Option<opt>zur Laufzeit aktiviert ist. Nur ein Teil der Optionen wird unterstützt:
Beispiel:
Vier weitere Direktiven dienen der Ausgabe von Statusmeldungen:
- .diag “message” : gibt diese Meldung nur im Diagnosemodus (-dD) aus
- .notice “message” : gibt diese Meldung auf der Stufe NOTICE aus
- .warning “message”: gibt diese Meldung auf der Stufe WARNING aus
- .alert “message” : gibt diese Meldung auf der Stufe ALERT aus
Meldungen auf der Stufe WARNING können den Prozessstart verhindern, wenn “zero-warning” aktiviert ist. Meldungen auf der Stufe ALERT führen immer zu einem schwerwiegenden Fehler. Damit lassen sich ungeeignete Bedingungen erkennen und Hinweise für den Anwender ausgeben.
Beispiel:
2.5. Zeitformat
Manche Parameter enthalten Zeitwerte, etwa Zeitüberschreitungen. Sofern nicht ausdrücklich anders angegeben, werden sie gewöhnlich in Millisekunden ausgedrückt. Durch Anhängen einer Einheit an den Zahlenwert können aber auch andere Einheiten verwendet werden. Dies ist zu beachten, da es nicht bei jedem Schlüsselwort wiederholt wird. Unterstützt werden:
- us: Mikrosekunden. 1 Mikrosekunde = 1/1000000 Sekunde
- ms: Millisekunden. 1 Millisekunde = 1/1000 Sekunde. Dies ist der Standard.
- s : Sekunden. 1s = 1000ms
- m : Minuten. 1m = 60s = 60000ms
- h : Stunden. 1h = 60m = 3600s = 3600000ms
- d : Tage. 1d = 24h = 1440m = 86400s = 86400000ms
2.6. Größenformat
Manche Parameter enthalten Größenwerte, etwa Bandbreitengrenzen. Sofern nicht ausdrücklich anders angegeben, werden sie gewöhnlich in Bytes ausgedrückt. Durch Anhängen einer Einheit an den Zahlenwert können aber auch andere Einheiten verwendet werden. Dies ist zu beachten, da es nicht bei jedem Schlüsselwort wiederholt wird. Die folgenden Einheiten werden unabhängig von der Groß-/Kleinschreibung unterstützt:
- k: Kilobytes. 1 Kilobyte = 1024 Bytes
- m: Megabytes. 1 Megabyte = 1048576 Bytes
- g: Gigabytes. 1 Gigabyte = 1073741824 Bytes
Zeit- und Größenformate erfordern Ganzzahlen; Nachkommastellen sind nicht zulässig.
2.7. Namensformat für Maps und ACLs
Für Maps und ACLs können Musterlisten verwendet werden. Eine Musterliste wird durch ihren Namen identifiziert und kann an verschiedenen Stellen der Konfiguration zum Einsatz kommen. Je nach Namensformat gibt es drei Kategorien:
-
Musterlisten aus regulären Dateien: Dies ist der Standardfall. Der absolute oder relative Dateiname dient als Name. Die Datei muss existieren, andernfalls tritt ein Fehler auf; sie darf jedoch leer sein. Das Präfix “file@” kann angegeben werden, gehört aber nicht zum Namen der Liste. Ein Dateiname verweist mit und ohne dieses Präfix auf dieselbe Musterliste.
-
Musterlisten aus optionalen Dateien: Vor dem Dateinamen muss das Präfix “opt@” stehen. Die Datei muss nicht existieren. Ist sie vorhanden, wird ihr Inhalt geladen; fehlt sie, wird kein Fehler gemeldet. Das Präfix gehört nicht zum Namen der Liste. Bei gleichem Dateinamen verweisen optionale und reguläre Dateien daher auf dieselbe Musterliste.
-
Musterlisten aus virtuellen Dateien: Der Name ist lediglich eine Kennung und verweist auf keine Datei. Das Präfix “virt@” muss verwendet werden und gehört zum Namen. Diese Listen lassen sich daher nicht mit den anderen Arten vermischen.
Virtuelle Dateien eignen sich für vollständig dynamisch verwaltete Muster, die beim Start und Neuladen noch nicht vorhanden sind. Optionale Dateien können unter denselben Bedingungen verwendet werden. Muster lassen sich jedoch in die Datei schreiben, etwa mit einem externen Skript auf Basis des CLI-Befehls “show map”. Dadurch können sie beim Neuladen erhalten bleiben.
Hinweis: Auch wenn solche Namen unwahrscheinlich sind, können damit keine regulären Dateien geladen werden, deren Name mit “file@”, “opt@” oder “virt@” beginnt. Dazu muss ausdrücklich “./” vor den Dateinamen gesetzt werden, beispielsweise “file@./virt@map”.
2.8. Variablen
In der HAProxy-Konfiguration lassen sich Variablen in Sample-Abruffunktionen, Konvertern, log-format-Zeichenketten und TCP/HTTP-Aktionen verwenden. Prozessweite Variablen sind während der gesamten Prozesslebensdauer global zugänglich; andere haben eine kürzere Lebensdauer. Wie in Shell-Skripten ist eine Variable ein symbolischer Name für einen Speicherbereich. Ihre Größe ist unbegrenzt, und der Speicher wird dynamisch reserviert. Deshalb müssen Variablen besonders bei intensiver Nutzung mit Vorsicht eingesetzt werden. Über die globalen Parameter “tune.vars” lässt sich jedoch der maximale Speicherverbrauch der Variablen begrenzen.
Variablen müssen im Format “<scope>.<name>” bezeichnet werden. <scope> ist ein einzelnes Wort für die Lebensdauer der Variablen. Der Teil <name> darf innerhalb eines Geltungsbereichs nur ‘a-z’, ‘A-Z’, ‘0-9’ und ‘_’ enthalten. Er ist dort eindeutig. Derselbe Name kann jedoch in verschiedenen Geltungsbereichen vorkommen und bezeichnet dann unterschiedliche Variablen. Unterstützt werden folgende Geltungsbereiche:
-
proc : Variablen, die während der gesamten Prozesslebensdauer bekannt und global zugänglich sind. “proc”-Variablen lassen sich über die CLI mit “get var” und “set var” bearbeiten. In Abschnitten des Typs “global” können sie außerdem mit “set-var” und “set-var-fmt” gesetzt werden.
-
sess : Variablen, die während der gesamten Sitzungslebensdauer bekannt sind. “sess”-Variablen gehören ausschließlich zu einer Sitzung, sind außerhalb davon unsichtbar und werden nicht mit anderen Sitzungen geteilt.
-
txn : Variablen, die während der gesamten Transaktionslebensdauer bekannt sind. “txn”-Variablen gehören ausschließlich zu einem Stream, sind außerhalb davon unsichtbar und werden nicht mit anderen Streams geteilt.
-
req : Variablen, die während der Anfrageverarbeitung eines bestimmten Streams bekannt sind. “req”-Variablen sind vom Erzeugen des Streams bis zum ersten Verbindungsversuch zum Server sichtbar. Sie gehören ausschließlich zu einem Stream, sind außerhalb davon unsichtbar und werden nicht mit anderen Streams geteilt. Zwischen “req”- und “res”-Variablen gibt es keinerlei Überschneidung.
-
res : Variablen, die während der Antwortverarbeitung eines bestimmten Streams bekannt sind. “res”-Variablen sind vom ersten Verbindungsversuch zum Server bis zur Zerstörung des Streams sichtbar. Sie gehören ausschließlich zu einem Stream, sind außerhalb davon unsichtbar und werden nicht mit anderen Streams geteilt. Zwischen “req”- und “res”-Variablen gibt es keinerlei Überschneidung.
-
check: Variablen, die während eines Health Checks bekannt sind. “check”-Variablen gehören ausschließlich zu einem Health Check, sind außerhalb davon unsichtbar und werden nicht mit anderen Health Checks geteilt. Sie können mit speziellen “tcp-check”- oder “http-check”-Direktiven gesetzt werden.
Je nach Kontext können zusätzliche Geltungsbereiche verwendet werden, die auf den Elternstream des aktuellen Streams verweisen:
-
psess: wie “sess”, verwendet jedoch die Sitzung des Elternstreams, sofern vorhanden.
-
ptxn : wie “txn”, verwendet jedoch die Transaktion des Elternstreams, sofern vorhanden.
-
preq : wie “req”, verwendet jedoch den Elternstream, sofern vorhanden. “preq”-Variablen sind nur während der Anfrageverarbeitung des Elternstreams zugänglich.
-
pres : wie “res”, verwendet jedoch den Elternstream, sofern vorhanden. “pres”-Variablen sind nur während der Antwortverarbeitung des Elternstreams zugänglich.
Auf den Elternstream verweisende Geltungsbereiche sind nutzbar, sobald dieser definiert ist. Meist gibt es keinen Elternstream; andernfalls wird dies ausdrücklich angegeben. Derzeit können nur Werte von Variablen aus einem Geltungsbereich des Elternstreams gelesen werden. Solche Variablen lassen sich weder setzen noch entfernen. Ein Kindstream übernimmt gewöhnlich zu einem bestimmten Zeitpunkt eine Verarbeitung für den Elternstream und hält diesen an, bis der Vorgang abgeschlossen ist. Der Elternstream kann daher beispielsweise mitten in der Anfrage- oder Antwortverarbeitung pausieren. Bestimmte Geltungsbereiche sind dann vom Kindstream aus nicht verfügbar. Untersucht etwa ein Kindstream eine Anfrage, findet er keine Variablen im Geltungsbereich “pres”: Der Elternstream verarbeitet gerade keine Antwort und hat deshalb keine Variablen im Bereich “res”.
Der Inhalt einer Variablen ist das Ergebnis eines Sample-Abrufausdrucks und übernimmt dessen Ausgabetyp. Dieser muss zur Verwendung der Variablen passen. Enthält eine Variable beispielsweise eine Zeichenkette und wird im Konverter “add()” verwendet, muss sie für einen erfolgreichen Aufruf in eine gültige Ganzzahl umwandelbar sein. Das ist besonders beim Vergleich von Variablen mit statischen Werten wichtig: Es muss die passende Abgleichmethode verwendet werden.
2.9. Adressformate
Mehrere Direktiven wie “bind”, “server”, “nameserver” und “log” benötigen eine Adresse.
Dies kann ein Hostname, eine IPv4- oder IPv6-Adresse oder ‘’ sein. ‘’ entspricht der speziellen Adresse “0.0.0.0” und kann bei “bind” oder “dgram-bind” verwendet werden, um auf allen IPv4-Adressen des Systems zu lauschen. Die IPv6-Entsprechung ist ‘::’.
Je nach Direktive folgt auf die IP-Adresse ein Port oder Portbereich. Bei ‘bind’ ist dies zwingend erforderlich, bei ‘server’ optional.
Die Adresse kann auch mit einem Schrägstrich ‘/’ beginnen. Dann gehört sie zur Familie “unix”, und ‘/’ mit den folgenden Zeichen muss den Pfad angeben.
Ob standardmäßig der Socket-Typ beziehungsweise die Transportmethode “datagram” oder “stream” verwendet wird, hängt von der Direktive mit der Adresse ab. ‘bind’ und ‘server’ verwenden standardmäßig “stream”, während ’log’, ’nameserver’ und ‘dgram-bind’ “datagram” verwenden.
Optional kann ein Präfix die Adressfamilie und/oder den Socket-Typ sowie die Transportmethode erzwingen.
2.9.1. Präfixe für Adressfamilien
‘abns@<name>’: Der folgende <name> bezeichnet einen abstrakten Namensraum (nur unter Linux).
‘abnsz@<name>’: Der folgende <name> bezeichnet einen nullterminierten abstrakten Namensraum (nur unter Linux).
‘fd@<n>’: Die folgende Adresse ist ein vom Elternprozess geerbter Dateideskriptor <n>. Er muss gebunden sein, kann aber bereits lauschen oder noch nicht.
‘ip@<address>[:port1[-port2]]’: Die folgende <address> gilt je nach Syntax als IPv4- oder IPv6-Adresse. Je nach verwendender Direktive kann oder muss ein Port oder Portbereich angegeben werden.
‘ipv4@<address>[:port1[-port2]]’: Die folgende <address> gilt immer als IPv4-Adresse. Je nach verwendender Direktive kann oder muss ein Port oder Portbereich angegeben werden.
‘ipv6@<address>[:port1[-port2]]’: Die folgende <address> gilt immer als IPv6-Adresse. Je nach verwendender Direktive kann oder muss ein Port oder Portbereich angegeben werden.
‘sockpair@<n>’: Die folgende Adresse ist der Dateideskriptor eines verbundenen Unix-Sockets oder eines Socket-Paars. Beim Verbindungsaufbau erzeugt der Initiator ein Paar verbundener Sockets und übergibt einen davon über den FD an die Gegenstelle. Der Listener wartet auf den FD über den Unix-Socket und verwendet ihn wie den FD eines accept(). Mit Vorsicht verwenden.
Fehler: Dieses Protokoll ist unter macOS bekanntermaßen
unzuverlässig, da die sendmsg(2)-Implementierung von macOS
fehlerhaft ist. Die Verbindung wird möglicherweise nicht korrekt angenommen.
‘unix@<path>’: Die folgende Zeichenkette gilt als UNIX-Socket <path>. Das Präfix eignet sich zur Angabe eines UNIX-Socket-Pfads, der nicht mit ‘/’ beginnt.
2.9.2. Präfixe für Socket-Typen
Den obigen Präfixen für Adressfamilien kann ein weiteres Präfix vorangestellt werden, um Socket-Typ und Transportmethode zu erzwingen. Der Standard hängt von der Direktive mit der Adresse ab, kann aber in manchen Fällen überschrieben werden. So verwendet “log” standardmäßig syslog über UDP, lässt sich aber auf syslog über TCP zwingen.
Diese Präfixe wurden für interne Zwecke entworfen. Anwender sollten stattdessen die Aliase aus dem folgenden Abschnitt „2.9.3. Protokollpräfixe“ verwenden. Gelegentlich sind sie dennoch praktisch, etwa bei geerbten Sockets, die über ihre Dateideskriptornummer bekannt sind. In diesem Fall ist die Adressfamilie “fd”, und der Socket-Typ muss angegeben werden.
Wer eines dieser Präfixe benötigt, weil sich das gewünschte Verhalten nicht mit Protokollpräfixen konfigurieren lässt, sollte dies den Betreuern melden.
‘stream+<family>@<address>’ erzwingt “stream” als Socket-Typ und Transportmethode.
‘dgram+<family>@<address>’ erzwingt “datagram” als Socket-Typ und Transportmethode.
‘quic+<family>@<address>’ erzwingt den Socket-Typ “datagram” und die Transportmethode “stream”.
2.9.3. Protokollpräfixe
‘quic4@<address>[:port1[-port2]]’: Die folgende <address> gilt immer als IPv4-Adresse; der Socket-Typ wird jedoch auf “datagram” und die Transportmethode auf “stream” festgelegt. Je nach verwendender Direktive kann oder muss ein UDP-Port oder -Portbereich angegeben werden. Dies entspricht “quic+ipv4@”.
‘quic6@<address>[:port1[-port2]]’: Die folgende <address> gilt immer als IPv6-Adresse; der Socket-Typ wird jedoch auf “datagram” und die Transportmethode auf “stream” festgelegt. Je nach verwendender Direktive kann oder muss ein UDP-Port oder -Portbereich angegeben werden. Dies entspricht “quic+ipv6@”.
’tcp@<address>[:port1[-port2]]’: Die folgende <address> gilt je nach Syntax als IPv4- oder IPv6-Adresse; Socket-Typ und Transportmethode werden jedoch auf “stream” festgelegt. Je nach verwendender Direktive kann oder muss ein Port oder Portbereich angegeben werden. Dies ist ein Alias für ‘stream+ip@’.
’tcp4@<address>[:port1[-port2]]’: Die folgende <address> gilt immer als IPv4-Adresse; Socket-Typ und Transportmethode werden jedoch auf “stream” festgelegt. Je nach verwendender Direktive kann oder muss ein Port oder Portbereich angegeben werden. Dies ist ein Alias für ‘stream+ipv4@’.
’tcp6@<address>[:port1[-port2]]’: Die folgende <address> gilt immer als IPv6-Adresse; Socket-Typ und Transportmethode werden jedoch auf “stream” festgelegt. Je nach verwendender Direktive kann oder muss ein Port oder Portbereich angegeben werden. Dies ist ein Alias für ‘stream+ipv6@’.
‘mptcp@<address>[:port1[-port2]]’: Die folgende <address> gilt je nach Syntax als IPv4- oder IPv6-Adresse; Socket-Typ und Transportmethode werden jedoch mit dem MPTCP-Protokoll auf “stream” festgelegt. Je nach verwendender Direktive kann oder muss ein Port oder Portbereich angegeben werden.
‘mptcp4@<address>[:port1[-port2]]’: Die folgende <address> gilt immer als IPv4-Adresse; Socket-Typ und Transportmethode werden jedoch mit dem MPTCP-Protokoll auf “stream” festgelegt. Je nach verwendender Direktive kann oder muss ein Port oder Portbereich angegeben werden.
‘mptcp6@<address>[:port1[-port2]]’: Die folgende <address> gilt immer als IPv6-Adresse; Socket-Typ und Transportmethode werden jedoch mit dem MPTCP-Protokoll auf “stream” festgelegt. Je nach verwendender Direktive kann oder muss ein Port oder Portbereich angegeben werden.
‘udp@<address>[:port1[-port2]]’: Die folgende <address> gilt je nach Syntax als IPv4- oder IPv6-Adresse; Socket-Typ und Transportmethode werden jedoch auf “datagram” festgelegt. Je nach verwendender Direktive kann oder muss ein Port oder Portbereich angegeben werden. Dies ist ein Alias für ‘dgram+ip@’.
‘udp4@<address>[:port1[-port2]]’: Die folgende <address> gilt immer als IPv4-Adresse; Socket-Typ und Transportmethode werden jedoch auf “datagram” festgelegt. Je nach verwendender Direktive kann oder muss ein Port oder Portbereich angegeben werden. Dies ist ein Alias für ‘dgram+ipv4@’.
‘udp6@<address>[:port1[-port2]]’: Die folgende <address> gilt immer als IPv6-Adresse; Socket-Typ und Transportmethode werden jedoch auf “datagram” festgelegt. Je nach verwendender Direktive kann oder muss ein Port oder Portbereich angegeben werden. Dies ist ein Alias für ‘dgram+ipv6@’.
‘uxdg@<path>’: Die folgende Zeichenkette gilt als Unix-Socket <path>; die Transportmethode wird jedoch auf “datagram” festgelegt. Dies ist ein Alias für ‘dgram+unix@’.
‘uxst@<path>’: Die folgende Zeichenkette gilt als Unix-Socket <path>; die Transportmethode wird jedoch auf “stream” festgelegt. Dies ist ein Alias für ‘stream+unix@’.
In künftigen Versionen könnten weitere Präfixe für Protokolle wie QUIC verwendet werden, das einen Stream-Transport auf Sockets des Typs “datagram” bereitstellt.
2.10. Beispiele
Ist haproxy über $PATH erreichbar, lassen sich diese Konfigurationen in einer Shell wie folgt prüfen:
12 - 3. Globaler Abschnitt
Parameter im Abschnitt “global” gelten für den gesamten Prozess und sind häufig vom Betriebssystem (OS) abhängig. Sie werden in der Regel einmalig festgelegt und müssen nach korrekter Konfiguration nicht mehr geändert werden. Für einige gibt es entsprechende Befehlszeilenoptionen.
Im Abschnitt “global” werden die folgenden Schlüsselwörter unterstützt:
-
Prozessverwaltung und Sicherheit
- 51degrees-allow-unmatched
- 51degrees-cache-size
- 51degrees-data-file
- 51degrees-difference
- 51degrees-drift
- 51degrees-property-name-list
- 51degrees-property-separator
- 51degrees-use-performance-graph
- 51degrees-use-predictive-graph
- ca-base
- chroot
- cluster-secret
- cpu-affinity
- cpu-map
- cpu-policy
- cpu-set
- crt-base
- daemon
- default-path
- description
- deviceatlas-json-file
- deviceatlas-log-level
- deviceatlas-properties-cookie
- deviceatlas-separator
- dns-accept-family
- expose-deprecated-directives
- expose-experimental-directives
- external-check
- fd-hard-limit
- gid
- grace
- group
- h1-accept-payload-with-any-method
- h1-case-adjust
- h1-case-adjust-file
- h1-do-not-close-on-insecure-transfer-encoding
- h2-workaround-bogus-websocket-clients
- hard-stop-after
- harden.reject-privileged-ports.tcp
- harden.reject-privileged-ports.quic
- insecure-fork-wanted
- insecure-setuid-wanted
- issuers-chain-path
- jwt.allow_none_alg
- jwt.decrypt_alg_list
- jwt.decrypt_enc_list
- key-base
- limited-quic
- localpeer
- log
- log-send-hostname
- log-tag
- lua-load
- lua-load-per-thread
- lua-prepend-path
- max-threads-per-group
- mworker-max-reloads
- nbthread
- node
- numa-cpu-mapping
- ocsp-update.disable
- ocsp-update.maxdelay
- ocsp-update.mindelay
- ocsp-update.httpproxy
- ocsp-update.mode
- pidfile
- pp2-never-send-local
- presetenv
- prealloc-fd
- resetenv
- set-dumpable
- set-var
- setenv
- ssl-default-bind-ciphers
- ssl-default-bind-ciphersuites
- ssl-default-bind-client-sigalgs
- ssl-default-bind-curves
- ssl-default-bind-options
- ssl-default-bind-sigalgs
- ssl-default-server-ciphers
- ssl-default-server-ciphersuites
- ssl-default-server-client-sigalgs
- ssl-default-server-curves
- ssl-default-server-options
- ssl-default-server-sigalgs
- ssl-dh-param-file
- ssl-propquery
- ssl-provider
- ssl-provider-path
- ssl-security-level
- ssl-server-verify
- ssl-skip-self-issued-ca
- stats
- stats-file
- strict-limits
- uid
- ulimit-n
- unix-bind
- unsetenv
- user
- wurfl-cache-size
- wurfl-data-file
- wurfl-information-list
- wurfl-information-list-separator
-
Leistungsoptimierung
- busy-polling
- max-spread-checks
- maxcompcpuusage
- maxcomprate
- maxconn
- maxconnrate
- maxpipes
- maxsessrate
- maxsslconn
- maxsslrate
- maxzlibmem
- no-memory-trimming
- noepoll
- noevports
- nogetaddrinfo
- nokqueue
- noktls
- nopoll
- noreuseport
- nosplice
- profiling.memory
- profiling.tasks
- server-state-base
- server-state-file
- spread-checks
- ssl-engine
- ssl-mode-async
- tune.applet.zero-copy-forwarding
- tune.buffers.limit
- tune.buffers.reserve
- tune.bufsize
- tune.bufsize.large
- tune.bufsize.small
- tune.cli.max-payload-size
- tune.comp.maxlevel
- tune.defaults.purge
- tune.disable-fast-forward
- tune.disable-zero-copy-forwarding
- tune.epoll.mask-events
- tune.events.max-events-at-once
- tune.fail-alloc
- tune.fd.edge-triggered
- tune.h1.be.glitches-threshold
- tune.h1.fe.glitches-threshold
- tune.h1.zero-copy-fwd-recv
- tune.h1.zero-copy-fwd-send
- tune.h2.be.glitches-threshold
- tune.h2.be.initial-window-size
- tune.h2.be.max-concurrent-streams
- tune.h2.be.max-frames-at-once
- tune.h2.be.rxbuf
- tune.h2.fe.glitches-threshold
- tune.h2.fe.initial-window-size
- tune.h2.fe.max-concurrent-streams
- tune.h2.fe.max-frames-at-once
- tune.h2.fe.max-rst-at-once
- tune.h2.fe.max-total-streams
- tune.h2.fe.rxbuf
- tune.h2.header-table-size
- tune.h2.initial-window-size
- tune.h2.max-concurrent-streams
- tune.h2.max-frame-size
- tune.h2.zero-copy-fwd-send
- tune.http.cookielen
- tune.http.logurilen
- tune.http.maxhdr
- tune.idle-pool.shared
- tune.idletimer
- tune.lua.bool-sample-conversion
- tune.lua.burst-timeout
- tune.lua.forced-yield
- tune.lua.log.loggers
- tune.lua.log.stderr
- tune.lua.maxmem
- tune.lua.openlibs
- tune.lua.service-timeout
- tune.lua.session-timeout
- tune.lua.task-timeout
- tune.max-checks-per-thread
- tune.maxaccept
- tune.maxpollevents
- tune.maxrewrite
- tune.max-rules-at-once
- tune.memory.hot-size
- tune.pattern.cache-size
- tune.peers.max-updates-at-once
- tune.pipesize
- tune.pool-high-fd-ratio
- tune.pool-low-fd-ratio
- tune.pt.zero-copy-forwarding
- tune.quic.be.cc.cubic-min-losses
- tune.quic.be.cc.hystart
- tune.quic.be.cc.max-frame-loss
- tune.quic.be.cc.max-win-size
- tune.quic.be.cc.reorder-ratio
- tune.quic.be.max-idle-timeout
- tune.quic.be.sec.glitches-threshold
- tune.quic.be.stream.data-ratio
- tune.quic.be.stream.max-concurrent
- tune.quic.be.stream.rxbuf
- tune.quic.be.tx.pacing
- tune.quic.be.tx.udp-gso
- tune.quic.cc.cubic.min-losses (veraltet)
- tune.quic.cc-hystart (veraltet)
- tune.quic.disable-tx-pacing (veraltet)
- tune.quic.disable-udp-gso (veraltet)
- tune.quic.fe.cc.cubic-min-losses
- tune.quic.fe.cc.hystart
- tune.quic.fe.cc.max-frame-loss
- tune.quic.fe.cc.max-win-size
- tune.quic.fe.cc.reorder-ratio
- tune.quic.fe.max-idle-timeout
- tune.quic.fe.sec.glitches-threshold
- tune.quic.fe.sec.retry-threshold
- tune.quic.fe.sock-per-conn
- tune.quic.fe.stream.data-ratio
- tune.quic.fe.stream.max-concurrent
- tune.quic.fe.stream.max-total
- tune.quic.fe.stream.rxbuf
- tune.quic.fe.tx.pacing
- tune.quic.fe.tx.udp-gso
- tune.quic.frontend.max-data-size (veraltet)
- tune.quic.frontend.max-idle-timeout (veraltet)
- tune.quic.frontend.max-streams-bidi (veraltet)
- tune.quic.frontend.max-tx-mem (veraltet)
- tune.quic.frontend.stream-data-ratio (veraltet)
- tune.quic.frontend.default-max-window-size (veraltet)
- tune.quic.listen
- tune.quic.max-frame-loss (veraltet)
- tune.quic.mem.tx-max
- tune.quic.reorder-ratio (veraltet)
- tune.quic.retry-threshold (veraltet)
- tune.quic.socket-owner (veraltet)
- tune.quic.zero-copy-fwd-send
- tune.renice.runtime
- tune.renice.startup
- tune.rcvbuf.backend
- tune.rcvbuf.client
- tune.rcvbuf.frontend
- tune.rcvbuf.server
- tune.recv_enough
- tune.ring.queues
- tune.runqueue-depth
- tune.sched.low-latency
- tune.sndbuf.backend
- tune.sndbuf.client
- tune.sndbuf.frontend
- tune.sndbuf.server
- tune.streams-elasticity
- tune.stick-counters
- tune.ssl.cachesize
- tune.ssl.capture-buffer-size
- tune.ssl.capture-cipherlist-size (veraltet)
- tune.ssl.certificate-compression
- tune.ssl.default-dh-param
- tune.ssl.force-private-cache
- tune.ssl.hard-maxrecord
- tune.ssl.keylog
- tune.ssl.keyupdate-rate-limit
- tune.ssl.lifetime
- tune.ssl.maxrecord
- tune.ssl.ssl-ctx-cache-size
- tune.ssl.ocsp-update.maxdelay (veraltet)
- tune.ssl.ocsp-update.mindelay (veraltet)
- tune.takeover-other-tg-connections
- tune.vars.global-max-size
- tune.vars.proc-max-size
- tune.vars.reqres-max-size
- tune.vars.sess-max-size
- tune.vars.txn-max-size
- tune.zlib.memlevel
- tune.zlib.windowsize
-
Fehlerbehebung
- anonkey
- debug.counters
- force-cfg-parser-pause
- quiet
- warn-blocked-traffic-after
- zero-warning
-
HTTPClient
- httpclient.resolvers.disabled
- httpclient.resolvers.id
- httpclient.resolvers.prefer
- httpclient.retries
- httpclient.ssl.ca-file
- httpclient.ssl.verify
- httpclient.timeout.connect
3.1. Prozessverwaltung und Sicherheit
51degrees-data-file <file path>
Der Pfad der 51Degrees-Datendatei für die Geräteerkennung. Die Datei sollte entpackt und für HAProxy mit den erforderlichen Berechtigungen zugänglich sein.
Beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_51DEGREES kompiliert wurde.
51degrees-property-name-list [<string> ...]
Eine Liste von 51Degrees-Eigenschaftsnamen, die aus dem Datensatz geladen werden sollen. Eine vollständige Liste ist auf der 51Degrees-Website verfügbar: https://51degrees.com/resources/property-dictionary
Bitte beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_51DEGREES kompiliert wurde.
51degrees-property-separator <char>
Ein Zeichen, das an jeden Eigenschaftswert in einem Antwortheader angehängt wird, der 51Degrees-Ergebnisse enthält. Wenn nicht gesetzt, wird als Standardwert ‘,’ verwendet.
Bitte beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_51DEGREES kompiliert wurde.
51degrees-cache-size <number>
Legt die Größe des 51Degrees-Konverter-Caches auf <number> Einträge fest. Dies ist ein LRU-Cache, der vorherige Geräteerkennungen und deren Ergebnisse speichert. Standardmäßig ist dieser Cache deaktiviert.
Bitte beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_51DEGREES kompiliert wurde.
51degrees-use-performance-graph { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) die Verwendung des Leistungsgraphen im Erkennungsprozess. Der Standardwert hängt von der 51Degrees-Bibliothek ab.
Bitte beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_51DEGREES und 51DEGREES_VER=4 kompiliert wurde.
51degrees-use-predictive-graph { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) die Verwendung des Vorhersagegraphen im Erkennungsprozess. Der Standardwert hängt von der 51Degrees-Bibliothek ab.
Bitte beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_51DEGREES und 51DEGREES_VER=4 kompiliert wurde.
51degrees-drift <number>
Legt den zulässigen Driftwert für eine Erkennung fest.
Bitte beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_51DEGREES und 51DEGREES_VER=4 kompiliert wurde.
51degrees-difference <number>
Legt den zulässigen Differenzwert für eine Erkennung fest.
Bitte beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_51DEGREES und 51DEGREES_VER=4 kompiliert wurde.
51degrees-allow-unmatched { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) die Verwendung von nicht übereinstimmenden Knoten im Erkennungsprozess. Der Standardwert hängt von der 51Degrees-Bibliothek ab.
Bitte beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_51DEGREES und 51DEGREES_VER=4 kompiliert wurde.
acme.scheduler { auto | off }
Aktiviert oder deaktiviert den ACME-Scheduler.
Der ACME-Scheduler startet beim Start von HAProxy und durchläuft die Zertifikate. Er startet eine ACME-Erneuerungsaufgabe, wenn der notAfter-Wert gegenüber curtime + (notAfter - notBefore) / 12 bereits verstrichen ist; ist notBefore nicht definiert, gilt ein Zeitraum von 7 Tagen. Anschließend schläft der Scheduler und wacht nach 12 Stunden wieder auf.
Der Standardwert ist “auto”.
Siehe auch: acme
ca-base <dir>
Weist ein Standardverzeichnis zum Abrufen von SSL-CA-Zertifikaten und CRLs zu, wenn mit den Anweisungen “ca-file”, “ca-verify-file” oder “crl-file” ein relativer Pfad verwendet wird. Absolute Pfade, die in “ca-file”, “ca-verify-file” und “crl-file” angegeben sind, haben Vorrang und ignorieren “ca-base”.
chroot { <jail dir> | auto }
Wechselt in das Verzeichnis <jail dir> und führt dort chroot() aus, bevor Privilegien abgegeben
werden. Dies erhöht die Sicherheit bei Ausnutzung einer unbekannten Schwachstelle, da ein Angriff
auf das System dadurch sehr erschwert wird. Es ist wichtig sicherzustellen, dass <jail dir> leer
und für niemanden beschreibbar ist. Wird der Prozess mit Superuser-Rechten gestartet, wird chroot()
direkt ausgeführt. Unter Linux versucht haproxy bei einem Start ohne Privilegien, dies innerhalb
eines mit unshare(CLONE_NEWUSER) neu erzeugten Benutzernamensraums auszuführen. Ist dieser Mechanismus
nicht verfügbar, schlägt chroot() mit der üblichen Fehlermeldung fehl.
Als Sonderfall kann <jail dir> auf “auto” gesetzt werden. Dann erzeugt haproxy ein anonymes
temporäres Verzeichnis, entfernt dessen Verzeichniseintrag und führt darin chroot() aus. Das
resultierende Jail hat keinen Namen im Dateisystem, ist leer und schreibgeschützt. Ein eigenes
Jail-Verzeichnis muss daher nicht vorbereitet werden.
Wenn mit Superuser-Berechtigungen gestartet wird, wird eine Warnung ausgegeben, wenn kein chroot verwendet wird, um Benutzer dazu zu ermutigen, stets dieses Verfahren zu nutzen. Falls aus irgendeinem Grund ein zwingender Grund besteht, chroot nicht zu verwenden (z. B. Zugriff auf einen Server über einen Unix-Socket mit unpassendem Pfad), bleibt es möglich, die Warnung zu unterdrücken, indem explizit “chroot /” hinzugefügt wird. Dies hat den Vorteil, dass es in der Konfiguration sichtbar ist.
close-spread-time <time>
Definiert ein Zeitfenster, über das beim geordneten Herunterfahren das Schließen ungenutzter und
aktiver Verbindungen verteilt wird. Nach Empfang von SIGUSR1 und Ablauf einer gegebenenfalls
vorhandenen Schonfrist werden ohne diese Option alle ungenutzten Verbindungen auf einmal geschlossen.
Aktive HTTP- oder HTTP2-Verbindungen werden nach Empfang der nächsten Anfrage beendet, entweder
mit einer zusätzlichen Zeile “Connection:
close” in der HTTP-Antwort oder einem GOAWAY-Frame bei HTTP2. Ist die Option gesetzt, wird das
Schließen über die angegebene Zeit <time> verteilt. Bei close-spread-time “infinite” wird das
aktive Schließen von Verbindungen während des geordneten Herunterfahrens deaktiviert. Der Header
“Connection: close” wird HTTP-Antworten nicht mehr hinzugefügt (ebenso wenig GOAWAY bei HTTP2).
Ungenutzte Verbindungen werden erst bei Erreichen ihrer Zeitüberschreitung geschlossen, entsprechend
den verschiedenen konfigurierten Zeitüberschreitungen.
Argumente:
Es wird empfohlen, diesen Wert niedriger als den Wert in der “hard-stop-after”-Option einzustellen, falls diese verwendet wird, damit alle Verbindungen die Möglichkeit haben, vor dem Prozessende ordnungsgemäß zu schließen.
Siehe auch: grace, hard-stop-after, idle-close-on-response
cluster-secret <secret>
Definiert eine ASCII-Zeichenkette als Geheimnis, das zwischen mehreren Knoten desselben Clusters geteilt wird. Es kann für verschiedene Zwecke verwendet werden. Es wird mindestens verwendet, um zustandslose Reset-Tokens für alle von diesem Prozess instanziierten QUIC-Verbindungen abzuleiten. Ebenso dient es zur Ableitung von Geheimnissen zum Verschlüsseln von Retry-Tokens.
Wenn dieser Parameter nicht gesetzt ist, wird beim Prozessstart ein zufälliger Wert gewählt. Dies ermöglicht die Nutzung von Funktionen, die darauf basieren, wenn auch mit gewissen Einschränkungen.
cpu-map [auto:]<thread-group>[/<thread-set>] <cpu-set>[,...] [...]
Auf einigen Betriebssystemen ist es möglich, eine Thread-Gruppe oder einen Thread einer bestimmten CPU-Menge zuzuordnen. Das bedeutet, dass die zugewiesenen Threads niemals auf anderen CPUs ausgeführt werden. Die Anweisung “cpu-map” legt CPU-Mengen für einzelne Threads oder Thread-Gruppen fest. Das erste Argument ist ein Thread-Gruppenbereich, optional gefolgt von einem Thread-Menge. Diese Bereiche haben folgendes Format:
<number> muss je nach Wortbreite des Rechners zwischen 1 und 32 oder 64 liegen. Gruppen-IDs
oberhalb von ’thread-groups’ und Thread-IDs oberhalb der Wortbreite des Rechners werden ignoriert.
Alle Thread-Nummern sind relativ zu ihrer jeweiligen Gruppe. Ein Bereich kann mit zwei durch einen
Bindestrich (’-’) getrennten Nummern angegeben werden. Wie bei der bind-Direktive “thread” wählt
“all” alle Threads, “odd” nur ungerade und “even” nur gerade Nummern aus. Das zweite und alle
weiteren Argumente sind CPU-Mengen. Jede CPU-Menge ist entweder eine einzelne Nummer, beginnend
bei 0 für die erste CPU, oder ein Bereich aus zwei durch einen Bindestrich (’-’) getrennten Nummern.
CPU-Nummern und Bereiche können durch Kommas getrennt oder als weitere Argumente in derselben
Zeile mehrfach angegeben werden. Außerhalb von Linux und BSD kann der maximale CPU-Index auf 31
oder 63 begrenzt sein. Mehrere “cpu-map”-Direktiven sind zulässig; jede ersetzt jedoch frühere
“cpu-map”-Angaben, soweit sie sich überschneiden.
Bereiche können teilweise definiert werden: Die obere Grenze darf fehlen. Dann wird sie durch den entsprechenden Höchstwert ersetzt, je nach Wortbreite des Rechners 32 oder 64.
Vor die Thread-Menge kann das Präfix “auto:” gesetzt werden. HAProxy bindet die Threads dann automatisch an CPUs, indem es die Thread- und CPU-Mengen schrittweise durchläuft. Dafür müssen beide Mengen gleich groß sein. Unabhängig von der Deklarationsreihenfolge der CPU-Mengen erfolgt die Bindung von der niedrigsten zur höchsten Grenze. Mit “auto:” werden nicht gleichzeitig ein Gruppenbereich und ein Thread-Bereich unterstützt. Nur einer darf ein Bereich sein; der andere muss eine feste Nummer sein.
Gruppenbereiche werden aus historischen Gründen unterstützt. Heute bezeichnet eine einzelne Nummer eine Thread-Gruppe und muss 1 sein, wenn keine Thread-Gruppen verwendet werden. Ohne Thread-Gruppen muss einem Thread-Bereich oder einer Thread-Nummer “1/” vorangestellt werden. Schließlich ist “1” genau gleichbedeutend mit “1/all” und bezeichnet alle Threads der Gruppe.
Beispiele:
cpu-affinity <affinity>
Legt fest, wie Threads an CPUs gebunden werden sollen. Derzeit werden folgende Werte akzeptiert:
- per-core: Jeder Thread wird an alle Hardware-Threads eines Kerns gebunden.
- per-group: Jeder Thread wird an alle Hardware-Threads der Gruppe gebunden. Dies ist der Standard,
sofern nicht “threads-per-core 1” in “cpu-policy” verwendet wird. “per-group” akzeptiert ein
optionales Argument zur CPU-Zuweisung. Ist eine CPU-Liste größer als die maximal zulässige Anzahl
von CPUs pro Gruppe und muss auf mehrere Gruppen aufgeteilt werden, bestimmt eine zusätzliche
Option, wie die Gruppen an diese CPUs gebunden werden:
- auto: Jede Thread-Gruppe erhält nur einen gleich großen Anteil zusammenhängender CPU-Kerne, die ausschließlich ihr zugeordnet sind und nicht mit anderen Gruppen geteilt werden. Dies ist der Standard, da es im Allgemeinen günstiger ist.
- loose: Jede Gruppe darf weiterhin jede CPU der Liste verwenden. Das führt im Allgemeinen zu mehr Konkurrenz um Ressourcen, kann aber gelegentlich helfen, mit störender Zusatzlast auf denselben CPUs besser umzugehen.
- auto: Verwendet “per-group”, sofern nicht “threads-per-core 1” in “cpu-policy” gesetzt ist; dann wird “per-core” verwendet. Dies ist der Standard.
- per-thread: Bindet einen Thread an genau einen Hardware-Thread. Bei “threads-per-core 1” in “cpu-policy” wird jeder Thread an einen Hardware-Thread eines anderen Kerns gebunden.
- per-ccx: Jeder Thread wird an alle Hardware-Threads eines CCX gebunden.
cpu-policy <policy> [threads-per-core 1 | auto]
Wählt die zu verwendende Richtlinie für die CPU-Zuweisung.
Auf Systemen mit mehreren CPUs gibt es viele Gründe, nicht alle verfügbaren CPU-Kerne zu verwenden oder sie auf verschiedene Thread-Gruppen aufzuteilen: Leistung, Latenz, Kosten oder die systemweite Ressourcenverwaltung. Mit “cpu-set” können bereits einige Kerne ausgeschlossen werden. Anschließend muss aber entschieden werden, wie die übrigen auf Threads und Thread-Gruppen verteilt werden.
Diese Zuordnung erfolgt normalerweise mit “cpu-map”, kann auf heterogenen Systemen jedoch besonders schwer zu pflegen sein.
Die Direktive “cpu-policy” wählt stattdessen eine von wenigen Zuweisungsrichtlinien aus, wenn “cpu-map” nicht verwendet wird. Derzeit werden die folgenden Richtlinien unterstützt; “performance” ist der Standard:
-
none Es erfolgt keine besondere nachgelagerte Auswahl. Alle aktivierten CPUs sind nutzbar. Ist die Thread-Anzahl nicht gesetzt, entspricht sie der Anzahl verfügbarer CPUs, jedoch pro Thread-Gruppe höchstens 32 auf 32-Bit-Systemen oder 64 auf 64-Bit-Systemen. Ist die Anzahl der Thread-Gruppen nicht gesetzt, wird sie auf 1 gesetzt.
-
efficiency Wie “group-by-ccx” unten, allerdings werden CPU-Cluster ausgeschlossen, deren Kerne mehr als 25% leistungsfähiger sind als die des nächstleistungsschwächeren Typs. Dies sind typischerweise “big”- oder “performance”-Kerne. Werden mehrere CPU-Kerntypen erkannt, wird also nur der effiziente Typ verwendet. Bei mäßiger Last kann dies sinnvoll sein, wenn die leistungsstärksten Kerne für die Anwendung oder eine Sicherheitskomponente verfügbar bleiben sollen. Einige moderne CPUs haben viele solcher effizienten Kerne, die zusammen bei geringerem Energieverbrauch eine angemessene Leistung liefern können.
-
first-usable-node Wenn die CPUs beim Start nicht bereits eingeschränkt wurden (etwa mit “taskset”) und “nbthread” nicht gesetzt ist, wird der erste NUMA-Knoten mit aktivierten CPUs verwendet. Die Anzahl seiner CPUs wird zur Thread-Anzahl. Für alle wird eine einzige Thread-Gruppe aktiviert, innerhalb der systemabhängigen Grenze von 32 oder 64.
-
group-by-2-ccx Wie “group-by-ccx” unten, erstellt aber für je zwei CCX eine Gruppe. Bei CPUs mit vielen CCX aus jeweils wenigen Kernen kann dies sinnvoll sein, um viele Gruppen zu vermeiden oder die Verteilung etwas zu glätten, wenn nicht alle Kerne verwendet werden. Beachten Sie, dass langsame Kommunikation zwischen CCX die Leistung dabei sehr stark beeinträchtigen kann. Im Allgemeinen wird davon abgeraten.
-
group-by-2-clusters Wie “group-by-cluster”, erstellt aber für je zwei Cluster eine Gruppe. Bei CPUs mit vielen Clustern aus jeweils wenigen Kernen kann dies sinnvoll sein, um viele Gruppen zu vermeiden oder die Verteilung etwas zu glätten, wenn nicht alle Kerne verwendet werden. Beachten Sie, dass langsame Kommunikation zwischen Clustern die Leistung dabei sehr stark beeinträchtigen kann. Im Allgemeinen wird davon abgeraten.
-
group-by-3-ccx Wie “group-by-ccx” unten, erstellt aber für je drei CCX eine Gruppe. Bei CPUs mit vielen CCX aus jeweils wenigen Kernen kann dies sinnvoll sein, um viele Gruppen zu vermeiden oder die Verteilung etwas zu glätten, wenn nicht alle Kerne verwendet werden. Beachten Sie, dass langsame Kommunikation zwischen CCX die Leistung dabei sehr stark beeinträchtigen kann. Im Allgemeinen wird davon abgeraten.
-
group-by-3-clusters Wie “group-by-cluster”, erstellt aber für je drei Cluster eine Gruppe. Bei CPUs mit vielen Clustern aus jeweils wenigen Kernen kann dies sinnvoll sein, um viele Gruppen zu vermeiden oder die Verteilung etwas zu glätten, wenn nicht alle Kerne verwendet werden. Beachten Sie, dass langsame Kommunikation zwischen Clustern die Leistung dabei sehr stark beeinträchtigen kann. Im Allgemeinen wird davon abgeraten.
-
group-by-4-ccx Wie “group-by-ccx” unten, erstellt aber für je vier CCX eine Gruppe. Bei CPUs mit vielen CCX aus jeweils wenigen Kernen kann dies sinnvoll sein, um viele Gruppen zu vermeiden oder die Verteilung etwas zu glätten, wenn nicht alle Kerne verwendet werden. Beachten Sie, dass langsame Kommunikation zwischen CCX die Leistung dabei sehr stark beeinträchtigen kann. Im Allgemeinen wird davon abgeraten.
-
group-by-4-clusters Wie “group-by-cluster”, erstellt aber für je vier Cluster eine Gruppe. Bei CPUs mit vielen Clustern aus jeweils wenigen Kernen kann dies sinnvoll sein, um viele Gruppen zu vermeiden oder die Verteilung etwas zu glätten, wenn nicht alle Kerne verwendet werden. Beachten Sie, dass langsame Kommunikation zwischen Clustern die Leistung dabei sehr stark beeinträchtigen kann. Im Allgemeinen wird davon abgeraten.
-
group-by-ccx Wenn weder “nbthread” noch “nbtgroups” gesetzt ist, wird für jeden CPU Core Complex (“CCX”) mit verfügbaren CPUs eine Thread-Gruppe erzeugt, mit ebenso vielen Threads wie CPUs. Ein CCX fasst CPUs mit ähnlich schnellem Zugriff auf den Last Level Cache (“LLC”) zusammen, typischerweise den L3-Cache. Auf den meisten modernen Rechnern ist es für die Leistung entscheidend, CPUs aus entfernten CCX nicht in derselben Thread-Gruppe zu mischen. Alle Threads einer Gruppe werden an alle CPUs des CCX gebunden. So bleibt die Kommunikation innerhalb der Gruppe lokal im CCX, ohne eine zu enge Bindung zu erzwingen. Die Grenzen für Threads pro Gruppe und für die Anzahl der Thread-Gruppen werden eingehalten. Dies wird für Systeme mit mehreren Sockeln und NUMA-Systeme sowie für CPUs mit hohen Latenzen zwischen CCX empfohlen.
-
group-by-cluster Wenn weder “nbthread” noch “nbtgroups” gesetzt ist, wird für jeden CPU-Cluster mit verfügbaren CPUs eine Thread-Gruppe erzeugt, mit ebenso vielen Threads wie CPUs. Alle Threads einer Gruppe werden an alle CPUs des Clusters gebunden. So bleibt die Kommunikation innerhalb der Gruppe lokal im Cluster, ohne eine zu enge Bindung zu erzwingen. Die Grenzen für Threads pro Gruppe und für die Anzahl der Thread-Gruppen werden eingehalten. Dies wird für Systeme mit mehreren Sockeln und NUMA-Systeme sowie für CPUs mit hohen Latenzen zwischen CCX empfohlen. Auf den meisten Servern sind Cluster und CCX identisch. Auf heterogenen Rechnern (“performance” gegenüber “efficiency” oder “big” gegenüber “little”) besteht ein Cluster dagegen meist nur aus einem Teil eines CCX mit sehr ähnlichen CPUs (gleicher Typ, maximal +/-5% Frequenzunterschied). Der Unterschied zeigt sich auf modernen Laptops und Desktop-Rechnern, auf denen Entwickler und Administratoren Konfigurationen prüfen.
-
performance Wie “group-by-ccx” oben, allerdings werden CPU-Cluster ausgeschlossen, deren Kerne weniger als 80% der Leistung des nächstleistungsstärkeren Typs erreichen. Das sind typischerweise “little”- oder “efficient”-Kerne. Ihr Hinzufügen bringt im Allgemeinen wenig und kann leicht nachteilig sein (z. B. bei TLS-Handshakes). Häufig ist es deutlich wirksamer, solche Kerne für andere Aufgaben wie die Netzwerkverarbeitung freizuhalten. Auf Entwicklungssystemen können sie auch Hilfsprogramme wie Lastgeneratoren und Überwachungswerkzeuge ausführen. Dies ist die Standardrichtlinie.
-
resource Wie “group-by-cluster” oben, allerdings wird nur der kleinste und effizienteste CPU-Cluster verwendet; alle anderen werden ignoriert. Damit lässt sich der Ressourcenverbrauch auf das kleinste Maß begrenzen, das noch angemessene Leistung liefert. Beispielsweise kann so der Energieverbrauch weiter gesenkt oder bei einer Sidecar-Konfiguration auf gemieteten Systemen die Zahl benötigter Kerne minimiert werden, um das System leichter verkleinern zu können. Ist nur ein Cluster vorhanden, wird dieser weiterhin vollständig verwendet.
Optional kann das Schlüsselwort “threads-per-core” hinzugefügt werden. Es akzeptiert “1” und “auto”. Bei 1 wird pro Kern nur ein Thread erzeugt, unabhängig von der Anzahl der Hardware-Threads des Kerns. Bei auto wird pro Hardware-Thread ein Thread erzeugt. Ist keine Affinität angegeben und wird threads-per-core 1 verwendet, ist die Affinität standardmäßig per-core.
Siehe auch: “cpu-map”, “cpu-set”, “nbthread”
cpu-set <directive>...
Erlaubt eine symbolische Beschreibung der CPU-Mengen, auf denen ausgeführt werden soll. Die
Direktive unterstützt folgende Schlüsselwörter: - reset hebt frühere Einschränkungen auf, die
beispielsweise von einem Dienstmanager oder einem “taskset”-Befehl geerbt wurden. - drop-cpu
<set> bindet nicht an CPUs dieser Menge - only-cpu <set> bindet nicht an CPUs außerhalb dieser
Menge - drop-node <set> bindet nicht an CPUs dieses NUMA-Knotens - only-node <set> bindet nicht
an CPUs außerhalb dieses NUMA-Knotens - drop-cluster <set> bindet nicht an CPUs mit dieser
Hardware-Cluster-Nummer - only-cluster <set> bindet nicht an CPUs mit anderen
Hardware-Cluster-Nummern - drop-core <set> bindet nicht an CPUs mit dieser Hardware-Kernnummer -
only-core <set> bindet nicht an CPUs mit anderen Hardware-Kernnummern - drop-thread <set>
bindet nicht an CPUs mit dieser Hardware-Thread-Nummer - only-thread <set> bindet nicht an CPUs
mit anderen Hardware-Thread-Nummern. Siehe auch: “cpu-policy”
crt-base <dir>
Legt ein Standardverzeichnis zum Laden von SSL-Zertifikaten fest, wenn “crtfile” oder “crt” einen relativen Pfad verwendet. Angegebene absolute Pfade haben Vorrang und ignorieren “crt-base”.
daemon
Lässt den Prozess per fork in den Hintergrund wechseln. Dies ist die empfohlene Betriebsart und entspricht dem Befehlszeilenargument “-D”. Mit “-db” in der Befehlszeile kann sie deaktiviert werden. Im systemd-Modus wird diese Option ignoriert.
default-path { current | config | parent | origin <path> }
Standardmäßig lädt HAProxy Dateien mit relativen Pfaden aus dem Verzeichnis, in dem der Prozess gestartet wurde. Manchmal sollen alle relativen Pfade stattdessen von einem anderen Verzeichnis ausgehen, als wäre der Prozess dort gestartet worden. Dafür ist diese Direktive vorgesehen. Technisch führt sie während der Verarbeitung jeder Konfigurationsdatei vorübergehend chdir() zum angegebenen Verzeichnis aus und kehrt nach jeder Datei in das ursprüngliche Verzeichnis zurück. Ihr Argument legt die Richtlinie zum Laden von Dateien fest, deren Pfad nicht mit einem Schrägstrich (’/’) beginnt: - “current” lädt alle relativen Dateien aus dem Startverzeichnis des Prozesses; dies ist der Standard.
- "config" lädt alle relativen Dateien aus dem Verzeichnis der
Konfigurationsdatei. Enthält deren Pfad einen Schrägstrich ('/'), wird
der längste Teil bis zum letzten Schrägstrich als Zielverzeichnis
verwendet, andernfalls das aktuelle Verzeichnis. Damit lassen sich
Maps, Fehlerdateien, Zertifikate und Lua-Skripte als verschiebbare
Pakete bündeln. Werden mehrere Konfigurationsdateien geladen, wird
das Verzeichnis für jede Datei aktualisiert.
- "parent" lädt alle relativen Dateien aus dem übergeordneten Verzeichnis
des Verzeichnisses der Konfigurationsdatei. Enthält deren Pfad einen
Schrägstrich ('/'), wird ".." an den längsten Teil bis zum letzten
Schrägstrich angehängt und als Zielverzeichnis verwendet; andernfalls
ist das Verzeichnis "..". So lassen sich Maps, Fehlerdateien,
Zertifikate und Lua-Skripte als verschiebbare Pakete bündeln, deren
Bestandteile in verschiedenen Unterverzeichnissen liegen
(z. B. "config/", "certs/", "maps/", ...).
- "origin" lädt alle relativen Dateien aus dem angegebenen (erforderlichen)
Pfad. Dies kann die Verwaltung verschiedener HAProxy-Instanzen
erleichtern, die parallel auf einem System laufen. Jede Instanz
verwendet dabei ein anderes Präfix, während die übrigen Abschnitte
leicht verschiebbar bleiben.
Jede Direktive “default-path” ersetzt sofort jede frühere und kann einen Wechsel in ein anderes Verzeichnis bewirken. Auch wenn dies stets das gewünschte Verhalten ergeben sollte, ist die Verwendung mehrerer default-path-Direktiven keine gute Praxis. Werden dennoch mehrere verwendet, sollte die Richtlinie in allen Konfigurationsdateien einheitlich bleiben.
Warnung: Einige Konfigurationselemente wie Maps oder Zertifikate werden eindeutig über ihren konfigurierten Pfad identifiziert. Bei einer verschiebbaren Verzeichnisstruktur können mehrere davon denselben eindeutigen Namen erhalten. Das erschwert Aktualisierungen zur Laufzeit, insbesondere wenn mehrere Konfigurationsdateien aus verschiedenen Verzeichnissen geladen werden. Vor der Verwendung relativer Pfade ist ein strikt kollisionsfreies Schema für Dateinamen unbedingt erforderlich. Ein robuster Ansatz wäre, allen Dateinamen den jeweiligen Standortnamen voranzustellen oder dies auf Verzeichnisebene zu tun.
description <text>
Fügt einen Text hinzu, der die Instanz beschreibt.
Bestimmte Zeichen (beispielsweise #) müssen maskiert werden. Da der Text in eine HTML-Seite eingefügt wird, sollten Sie die Zeichen “<” und “>” vermeiden.
deviceatlas-json-file <path>
Legt den Pfad der DeviceAtlas-JSON-Datendatei fest, die über die API geladen wird. Der Pfad muss auf eine gültige JSON-Datendatei verweisen, auf die der HAProxy-Prozess zugreifen kann.
deviceatlas-log-level <value>
Legt den Informationsumfang fest, den die API zurückgibt. Diese Direktive ist optional; ohne Angabe gilt der Standardwert 0.
deviceatlas-properties-cookie <name>
Legt den Namen des Client-Cookies für die Erkennung fest, wenn bei der Anfrage die clientseitige DeviceAtlas-Komponente verwendet wurde. Diese Direktive ist optional; ohne Angabe gilt der Standardwert DAPROPS.
deviceatlas-separator <char>
Legt das Trennzeichen für die Ergebnisse der API-Eigenschaften fest. Diese Direktive ist optional; ohne Angabe gilt der Standardwert |.
dns-accept-family <family>[,...]
Standardmäßig akzeptieren DNS-Resolver sowohl IPv4- als auch IPv6-Adressen. Dies lässt sich mit “resolve-prefer” in server-Zeilen und dem Adressfamilienargument der Aktion “do-resolve” beeinflussen. Es ist jedoch nur eine Präferenz: Ist ausschließlich die andere Familie vorhanden, bleibt ihre Verwendung möglich. In Umgebungen ohne nutzbares Dual-Stack kann ein unerreichbarer, nur auf IPv6 verweisender DNS-Eintrag erhebliche Probleme verursachen. Er ersetzt einen früheren IPv4-Eintrag, der bis zur nächsten Anfrage möglicherweise weiter funktioniert hätte. Die globale Option “dns-accept-family” kann die Verwendung nur einer oder beider Adressfamilien erzwingen. Ihr Argument ist eine durch Kommas getrennte Liste folgender Wörter: - “ipv4”: IPv4-Adressen abfragen und akzeptieren (“A”-Einträge) - “ipv6”: IPv6-Adressen abfragen und akzeptieren (“AAAA”-Einträge) - “auto”: IPv4 verwenden; IPv6 zusätzlich verwenden, wenn das System dafür ein Standardgateway besitzt. Das Ergebnis der letzten Prüfung wird 30 Sekunden lang zwischengespeichert.
Wird nur eine Familie verwendet, werden für die andere weder Anfragen an Resolver gesendet noch Antworten berücksichtigt. Seit 3.3 ist “auto” der Standardwert. Damit werden tatsächlich erst dann beide Familien aktiviert, wenn die Routbarkeit von IPv6 feststeht; andernfalls bleibt es bei IPv4. Siehe auch: “resolve-prefer”, “do-resolve”
expose-deprecated-directives
Diese Anweisung muss vor einigen als veraltet gekennzeichneten Direktiven stehen, damit Warnungen unterdrückt werden und die Konfigurationsdatei nicht abgewiesen wird. Betroffen sind nicht alle veralteten Direktiven, sondern nur solche ohne alternative Lösung.
expose-experimental-directives
Diese Anweisung muss vor als experimentell gekennzeichneten Direktiven stehen, sonst wird die Konfigurationsdatei abgewiesen. Die von dieser Option erfassten Funktionen arbeiten nicht garantiert zuverlässig und können während des Wartungszyklus funktionsunfähig werden. Während der Arbeit an der nächsten Version pflegen die Entwickler sie nach bestem Bemühen und unternehmen angemessene Anstrengungen, ihre Funktionsfähigkeit zu erhalten, geben aber keine Garantie. Deshalb ist für diese Funktionen keine Unterstützung über das Erscheinen der nächsten LTS-Version hinaus zu erwarten. Von Benutzern, die experimentelle Funktionen erproben möchten, wird erwartet, dass sie zeitnah aktualisieren, um deren Verbesserungen zu erhalten. Ob diese Direktive noch benötigt wird, lässt sich leicht erkennen: Ist sie aktiviert, ohne von einer solchen Funktion verwendet zu werden, weist eine Warnung darauf hin, sie zu deaktivieren. Bleibt die Warnung aus, wird sie also noch benötigt.
external-check [preserve-env]
Erlaubt einen externen Agenten für Health Checks. Als Sicherheitsmaßnahme ist dies standardmäßig deaktiviert. Selbst bei Aktivierung können Prüfungen weiterhin fehlschlagen, wenn nicht auch “insecure-fork-wanted” aktiviert ist. Verwendet das gestartete Programm eine ausführbare Datei mit setuid (was es wirklich nicht tun sollte), muss möglicherweise auch “insecure-setuid-wanted” im globalen Abschnitt gesetzt werden. Standardmäßig starten Prüfungen mit einer bereinigten Umgebung, die nur Variablen aus dem Befehl “external-check” im Backend-Abschnitt enthält. Manchmal soll die Umgebung dennoch erhalten bleiben, etwa wenn komplexe Skripte daraus zusätzliche Pfade oder Informationen beziehen. Dafür kann das Schlüsselwort “preserve-env” angehängt werden. Dann wird jedoch dringend davon abgeraten, setuid-Programme auszuführen oder Prüfungen unter einem privilegierten Benutzer laufen zu lassen, da das Prüfprogramm sonst möglichen Angriffen ausgesetzt ist. Weitere Einzelheiten finden Sie bei “option external-check”, “insecure-fork-wanted” und “insecure-setuid-wanted”.
fd-hard-limit <number>
Setzt unabhängig von Systemgrenzen eine Obergrenze für die Anzahl der vom Prozess verwendeten
Dateideskriptoren. Mit “ulimit-n” und “maxconn” kann ein Wert erzwungen werden. Sind beide nicht
gesetzt, gilt die harte Grenze von RLIMIT_NOFILE, wie sie “ulimit -n -H” ausgibt. Einige moderne
Betriebssysteme erlauben hier jedoch extrem große Werte (in der Größenordnung von 1 Milliarde),
die im normalen Betrieb viel zu viel RAM verbrauchen würden. Mit fd-hard-limit kann eine
gegebenenfalls niedrigere Obergrenze durchgesetzt werden. Systemgrenzen unterhalb von <number>
werden also immer eingehalten; bei höheren Systemgrenzen gilt der angegebene Wert. Standardmäßig
ist fd-hard-limit auf 1048576 gesetzt. Dieser Standard kann beim Kompilieren über DEFAULT_MAXFD
geändert werden. Der Wert kann als maximale Systemgrenze (des Kernels) dienen, wenn die harte
RLIMIT_NOFILE-Grenze extrem groß ist. fd-hard-limit im globalen Abschnitt kann den beim Bauen über
DEFAULT_MAXFD vorgegebenen Wert vorübergehend überschreiben. Im folgenden Beispiel ist keine andere
Einstellung gesetzt; maxconn passt sich automatisch dem kleineren Wert aus “fd-hard-limit” und
der RLIMIT_NOFILE-Grenze an:
Siehe auch: ulimit-n, maxconn
gid <number>
Ändert die Gruppen-ID des Prozesses auf <number>. Es wird empfohlen, diese Gruppen-ID
HAProxy oder einer kleinen Gruppe ähnlicher Daemons vorzubehalten. HAProxy muss unter einem
Benutzer dieser Gruppe oder mit Superuser-Rechten gestartet werden. Hat der startende Benutzer
zusätzliche Gruppen, kann HAProxy diese nur ablegen, wenn es mit Superuser-Rechten gestartet wurde.
Siehe auch “group” und “uid”.
grace <time>
Definiert eine Verzögerung zwischen SIGUSR1 und dem tatsächlichen geordneten Herunterfahren.
Argumente:
Dies dient der Kompatibilität mit älteren Umgebungen, in denen der haproxy-Prozess gestoppt werden muss, externe Komponenten den Status aber noch vor dem Freigeben der Listener erkennen müssen. Dabei wird die interne Variable “stopping” (ausgegeben von der Sample-Abruffunktion “stopping”) auf true gesetzt, während die Listener weiterhin ungestört Verbindungen annehmen. Erst nach Ablauf der Verzögerung beginnt das normale geordnete Herunterfahren. Dies darf nicht für Prozesse verwendet werden, die neu geladen werden: Der alte Prozess wird seine Bindungen sonst nicht freigeben; der neue kann möglicherweise nicht starten, oder es können andere Probleme entstehen.
Beispiel:
Ein flexiblerer und dauerhafterer Ansatz wäre, dass ein Orchestrierungssystem über die CLI eine globale Variable setzt, diese für Antworten auf externe Prüfungen verwendet und erst nach einer Verzögerung SIGUSR1 sendet.
Beispiel:
Siehe auch: hard-stop-after, monitor
group <group name>
Ähnlich wie “gid”, verwendet aber die GID des Gruppennamens <group name> aus /etc/group.
Siehe auch “gid” und “user”.
h1-accept-payload-with-any-method
Weist HTTP/1.0-Anfragen mit GET/HEAD/DELETE und einer Nutzlast nicht mit der HTTP-Antwort 413 Payload Too Large zurück.
Während HTTP/1.1 dies ausdrücklich erlaubt, ist HTTP/1.0 hier nicht eindeutig. Einige ältere Server erwarten keine Nutzlast und prüfen niemals die Länge des Inhalts (über Content-Length- oder Transfer-Encoding-Header). Manche Zwischenstationen verarbeiten die Nutzlast von HTTP/1.0-GET/HEAD/DELETE-Anfragen daher korrekt, andere ignorieren sie vollständig. Das kann Sicherheitsprobleme verursachen, da Request-Smuggling-Angriffe möglich sind. Standardmäßig weist HAProxy HTTP/1.0-GET/HEAD/DELETE-Anfragen mit Nutzlast deshalb zurück.
Bei einigen alten Clients kann dies jedoch Probleme verursachen. In diesem Fall kann diese globale Option gesetzt werden.
h1-do-not-close-on-insecure-transfer-encoding
Nach der HTTP/1.1-Spezifikation (RFC9112#6.1) stellt das gleichzeitige Vorhandensein von Transfer-Encoding und Content-Length in derselben Nachricht ein erhebliches Risiko für Content-Smuggling-Angriffe dar, wenn sich irgendwo in der vor- oder nachgelagerten Kette ein HTTP/1.0-Agent befindet. Ein Agent muss die Verbindung in diesem Fall nach der Antwort unbedingt schließen, um jede Ausnutzung zu verhindern. Das kann bei sehr alten Clients jedoch die Leistung beeinträchtigen, insbesondere wenn sie für jede Anfrage eine TLS-Verbindung neu aushandeln müssen. Diese Option weist HAProxy an, die Regel nicht durchzusetzen, sondern die Nachricht lediglich zu bereinigen und die Verbindung nach der Antwort offen zu halten. Dies darf nur erfolgen, wenn absolut sicher ist, dass keine HTTP/1.0-Agenten in der Kette vorhanden sind und alle Implementierungen vor HAProxy die HTTP/1.1-Regeln zu diesen Header-Feldern vollständig einhalten. In jedem Fall ignoriert und entfernt HAProxy weiterhin den überflüssigen Content-Length-Header, um die nächste Station nicht zu verwirren.
Wird diese Option wegen eines alten fehlerhaften Clients oder Servers aktiviert, ist Folgendes wichtig: Unabhängig davon, ob die Option nötig ist, riskiert ein Agent, der diese Regel verletzt, dass ältere Agenten seine Nachrichten abschneiden. Diese würden Content-Length berücksichtigen und Transfer-Encoding ignorieren, obwohl die summierte Größe der codierten Chunk-Längenangaben nicht darin enthalten ist. Die obige Regel dient also nicht nur der Sicherheit, sondern auch dazu, Agenten auszusondern, die wegen Inkompatibilitäten mit älteren Agenten Kommunikationsprobleme haben können.
h1-case-adjust <from> <to>
Definiert die Anpassung der Groß- und Kleinschreibung für den Header-Namen <from>, sofern
aktiviert. Vor dem Senden an HTTP/1-Clients oder -Server wird er in <to> geändert. <from> muss
kleingeschrieben sein; <from> und <to> dürfen sich nur in der Groß- und Kleinschreibung
unterscheiden. Für mehrere Header-Namen kann die Direktive wiederholt werden. Doppelte Einträge
sind nicht zulässig. Müssen viele Header-Namen angepasst werden, ist “h1-case-adjust-file”
möglicherweise praktischer. Beachten Sie, dass ohne “option h1-case-adjust-bogus-client” oder
“option h1-case-adjust-bogus-server” in einem Proxy keine Umwandlung erfolgt.
Es gibt keine standardisierte Groß- und Kleinschreibung für Header-Namen, da sie gemäß RFC7230 unabhängig davon verglichen werden. Anwendungen müssen sie daher ohne Unterscheidung der Groß- und Kleinschreibung verarbeiten. Einige fehlerhafte Anwendungen verletzen jedoch die Standards und verlassen sich auf die von Browsern meist verwendete Schreibweise. Bei HTTP/2 wird dies kritisch, da alle Header-Namen kleingeschrieben übertragen werden müssen. HAProxy folgt derselben Konvention: Unabhängig von der HTTP-Version werden alle Header-Namen kleingeschrieben an Clients und Server gesendet.
Anwendungen, die Anfragen oder Antworten nicht korrekt verarbeiten, benötigen solche Umgehungslösungen möglicherweise vorübergehend, um die an sie gesendeten Header-Namen bis zur Fehlerbehebung anzupassen. Beachten Sie, dass eine Anwendung, die dies benötigt, für Content-Smuggling-Angriffe anfällig sein könnte und unbedingt korrigiert werden muss.
Beispiel:
Siehe “h1-case-adjust-file”, “option h1-case-adjust-bogus-client” und “option h1-case-adjust-bogus-server”.
h1-case-adjust-file <hdrs-file>
Definiert eine Datei mit Schlüssel-Wert-Paaren, um die Groß- und Kleinschreibung bestimmter
Header-Namen vor dem Senden an HTTP/1-Clients oder -Server anzupassen. Die Datei <hdrs-file> muss
pro Zeile 2 Header-Namen enthalten. Der erste muss kleingeschrieben sein; beide dürfen sich nur in
der Groß- und Kleinschreibung unterscheiden. Zeilen mit ‘#’ am Anfang und Leerzeilen werden
ignoriert. Führende und abschließende Tabulatoren und Leerzeichen werden entfernt. Doppelte
Einträge sind nicht zulässig. Ohne “option h1-case-adjust-bogus-client” oder
“option h1-case-adjust-bogus-server” in einem Proxy erfolgt keine Umwandlung.
Wird diese Direktive wiederholt, wird nur die letzte verarbeitet. Sie ist eine Alternative zu “h1-case-adjust”, wenn viele Header-Namen angepasst werden müssen. Bitte lesen Sie die Hinweise zu den damit verbundenen Risiken.
Siehe “h1-case-adjust”, “option h1-case-adjust-bogus-client” und “option h1-case-adjust-bogus-server”.
h2-workaround-bogus-websocket-clients
Deaktiviert die Bekanntgabe der Unterstützung für h2-Websockets an Clients. Dies kann Probleme mit Clients umgehen, die Schwierigkeiten mit der Implementierung des noch relativ neuen RFC8441 haben, etwa Firefox 88. Damit Clients für den Websocket-Tunnel automatisch auf http/1.1 zurückfallen können, geben Sie h2-Unterstützung in der bind-Zeile mit “alpn” ohne explizites Schlüsselwort “proto” an. Wurde diese Anweisung zuvor aktiviert, lässt sie sich mit dem vorangestellten Schlüsselwort “no” deaktivieren.
hard-stop-after <time>
Definiert die maximal zulässige Zeit für ein sauberes, geordnetes Herunterfahren.
Argumente:
Damit lässt sich sicherstellen, dass die Instanz auch dann beendet wird, wenn während eines Soft-Stops Verbindungen offen bleiben (beispielsweise bei langen Zeitüberschreitungen für einen Proxy im TCP-Modus). Dies gilt sowohl im TCP- als auch im HTTP-Modus.
Beispiel:
Siehe auch: grace
harden.reject-privileged-ports.tcp { on | off }
Schaltet für jedes Protokoll einen Schutz ein oder aus, der die Kommunikation mit Clients verbietet, die privilegierte Ports als Quellport verwenden. Dieser Portbereich ist in RFC 6335 definiert. Standardmäßig ist der Schutz für das QUIC-Protokoll aktiv, da dieses Verhalten verdächtig ist und für Spoofing- oder DNS/NTP-Amplifikationsangriffe genutzt werden kann.
http-err-codes [+-]<range>[,...] [...]
Ersetzt, verkleinert oder erweitert die Liste der Statuscodes, die für die Beendigungscodes und den Zähler “http_err_cnt” in Stick-Tabellen einen Fehler kennzeichnen. Der Standardbereich für Fehler reicht von 400 bis 499. In bestimmten Situationen ziehen es jedoch einige Benutzer vor, bestimmte Codes auszuschließen, insbesondere beim Erfassen von Clientfehlern (z. B. 404 auf Systemen mit dynamisch erzeugten Inhalten). Siehe auch “http-fail-codes” und “http_err_cnt”.
Ein Bereich ohne vorangestelltes ‘+’ oder ‘-’ ersetzt den vorhandenen Bereich durch den neuen. Ein Bereich mit vorangestelltem ‘+’ erweitert den vorhandenen Bereich um den angegebenen Bereich; dieser darf sich mit dem vorhandenen Bereich überschneiden, muss es aber nicht. Ein Bereich mit vorangestelltem ‘-’ entfernt den angegebenen Bereich aus dem vorhandenen. Ein Bereich besteht aus einer Zahl von 100 bis 599, auf die optional “-” und eine weitere Zahl folgen, die mindestens so groß wie die erste ist und die Obergrenze des Bereichs angibt. Mehrere Bereiche für dieselbe Operation zum Hinzufügen, Entfernen oder Ersetzen können durch Kommas getrennt werden.
Beispiel:
http-fail-codes [+-]<range>[,...] [...]
Ersetzt, verkleinert oder erweitert die Liste der Statuscodes, die für die Beendigungscodes und den Zähler “http_fail_cnt” in Stick-Tabellen einen Fehlschlag kennzeichnen. Der Standardbereich für Fehlschläge reicht von 500 bis 599, mit Ausnahme von 501 und 505, die durch Clients ausgelöst werden können. Diese Codes zeigen normalerweise an, dass der Server die Anfrage nicht verarbeiten konnte. Einige Benutzer ziehen es vor, bestimmte Codes in Situationen auszuschließen, in denen diese bekanntermaßen nicht relevant sind, beispielsweise 500 in bestimmten SOAP-Umgebungen, wo dieser Code keinen Serverfehler ausdrückt. Die Syntax ist genau dieselbe wie bei http-err-codes oben. Siehe auch “http-err-codes” und “http_fail_cnt”.
insecure-fork-wanted
Standardmäßig versucht HAProxy mit allen verfügbaren Mitteln zu verhindern, dass nach dem Start weitere Threads oder Prozesse erzeugt werden. Dies ist besonders wichtig bei Lua-Dateien unklarer Herkunft und beim Experimentieren mit Entwicklungsversionen, die noch Fehler enthalten können, deren Ausnutzbarkeit unklar ist. Generell ist es eine sinnvolle Vorsichtsmaßnahme, sicherzustellen, dass Datenverkehr keine unerwarteten Hintergrundaktivitäten auslösen kann. Allerdings verhindert dies die Ausführung externer Prüfungen und kann bestimmte, sehr spezielle Lua-Skripte beeinträchtigen, die ausdrücklich auf die Möglichkeit zum Forken angewiesen sind. Diese Option dient dazu, den Schutz zu deaktivieren. Beachten Sie, dass dies keine gute Idee ist: Eine Schwachstelle in einer Bibliothek oder in HAProxy selbst lässt sich bei deaktiviertem Schutz leichter ausnutzen. Außerdem ist das Forken aus Lua oder an anderer Stelle unzuverlässig, da der durch Fork erzeugte Prozess zufällig eine von einem anderen Thread gesetzte Sperre übernehmen kann und dann einen Vorgang niemals abschließen kann. Daher wird dringend empfohlen, diese Option niemals zu verwenden und jede Arbeitslast, die einen solchen Fork benötigt, zu überdenken und auf eine sicherere Lösung umzustellen (beispielsweise Agenten anstelle externer Prüfungen). Diese Option unterstützt das Präfix “no”, um sie zu deaktivieren. Sie kann auch mit “-dI” in der haproxy-Befehlszeile aktiviert werden.
insecure-setuid-wanted
HAProxy muss zur Laufzeit keine ausführbaren Programme aufrufen (außer bei externen Prüfungen, von denen dringend abgeraten wird) und soll sich sogar in einer leeren chroot-Umgebung isolieren. Daher gibt es grundsätzlich keinen triftigen Grund, den Aufruf eines ausführbaren setuid-Programms zu erlauben, ohne dass sich der Benutzer der Risiken vollständig bewusst ist. Wenn HAProxy externe Prüfungen aufrufen und/oder chroot deaktivieren muss, könnte das Ausnutzen einer Schwachstelle in einer Bibliothek oder in HAProxy selbst zur Ausführung eines externen Programms führen. Unter Linux lässt sich der Prozess so einschränken, dass ein auf einem solchen Programm gesetztes setuid-Bit ignoriert wird. Dies verringert das Risiko einer Rechteausweitung in dieser Situation erheblich. HAProxy tut dies standardmäßig. Falls dies bei einer externen Prüfung Probleme verursacht (beispielsweise wenn sie den Befehl “ping” benötigt), kann dieser Schutz durch explizites Hinzufügen dieser Direktive im globalen Abschnitt deaktiviert werden. Ist die Direktive aktiviert, lässt sie sich durch Voranstellen des Schlüsselworts “no” wieder deaktivieren.
issuers-chain-path <dir>
Legt ein Verzeichnis fest, aus dem Zertifikatsketten zur Vervollständigung der Ausstellerkette geladen werden. Alle Dateien müssen im PEM-Format vorliegen. Wenn bei Zertifikaten, die mit “crt” oder “crt-list” geladen werden, die Zertifikatskette (auch als Zwischenzertifikat bekannt) nicht in der PEM-Datei enthalten ist, vervollständigt HAProxy die Kette, sofern der Aussteller des Zertifikats dem ersten Zertifikat der mit “issuers-chain-path” geladenen Kette entspricht. Eine “crt”-Datei mit PrivateKey+Certificate+IntermediateCA2+IntermediateCA1 könnte durch PrivateKey+Certificate ersetzt werden. HAProxy vervollständigt die Kette, wenn im Verzeichnis “issuers-chain-path” eine Datei mit IntermediateCA2+IntermediateCA1 vorhanden ist. Alle anderen Zertifikate mit demselben Aussteller teilen sich die Kette im Speicher.
Die OCSP-Funktionen können die vervollständigte Kette verwenden, wenn keine .issuer-Datei verwendet wurde oder keine Kette in der PEM-Datei enthalten war.
jwt.allow_none_alg
Erlaubt JWT-Token mit dem Algorithmus “none” im Konverter ‘jwt_verify’. Wenn diese Option gesetzt ist, gelten diese Token immer als gültig. Standardmäßig werden unsignierte Token abgelehnt, da sie als unsicher gelten (siehe RFC8725 Abschnitt 3.1 ).
jwt.decrypt_alg_list <list>
Legt die Liste der in den Konvertern jwt_decrypt_XXX erlaubten Algorithmen fest. JWT-Tokens mit einem nicht unterstützten oder deaktivierten Algorithmus werden niemals entschlüsselt. Die angegebenen Algorithmen müssen dasselbe Format wie in Abschnitt 4.1 von RFC7518 haben und durch Doppelpunkte getrennt werden. Mit dem besonderen Namen “ALL” können alle unterstützten Algorithmen aktiviert werden (eine vollständige Liste finden Sie beim Konverter “jwt_decrypt_jwk”); einem Algorithmusnamen kann ein ‘!’ hinzugefügt werden, um ihn ausdrücklich zu deaktivieren. Beachten Sie, dass diese Option alle Algorithmen deaktiviert, die nicht ausdrücklich in der angegebenen Liste aufgeführt sind, sofern nicht “ALL” angegeben wird.
Beispiele:
jwt.decrypt_enc_list <list>
Legt die Liste der in den Konvertern jwt_decrypt_XXX erlaubten Verschlüsselungsalgorithmen fest. JWT-Tokens mit einem nicht unterstützten oder deaktivierten Verschlüsselungsalgorithmus werden niemals entschlüsselt. Die angegebenen Algorithmen müssen dasselbe Format wie in Abschnitt 5.1 von RFC7518 haben und durch Doppelpunkte getrennt werden. Mit dem besonderen Namen “ALL” können alle unterstützten Algorithmen aktiviert werden (eine vollständige Liste finden Sie beim Konverter “jwt_decrypt_jwk”); einem Algorithmusnamen kann ein ‘!’ hinzugefügt werden, um ihn ausdrücklich zu deaktivieren. Beachten Sie, dass diese Option alle Algorithmen deaktiviert, die nicht ausdrücklich in der angegebenen Liste aufgeführt sind, sofern nicht “ALL” angegeben wird.
Beispiele:
key-base <dir>
Legt ein Standardverzeichnis fest, aus dem private SSL-Schlüssel geladen werden, wenn bei “key”-Direktiven ein relativer Pfad verwendet wird. Angegebene absolute Pfade haben Vorrang und ignorieren “key-base”. Diese Option funktioniert nur mit einer load-Zeile in einem crt-store.
limited-quic
Diese Einstellung muss verwendet werden, um QUIC-Listener-Bindungen ausdrücklich zu aktivieren, wenn haproxy mit einer OpenSSL-Version ohne QUIC-Unterstützung kompiliert wurde. Sie aktiviert eine interne Kompatibilitätsschicht von haproxy, die beim Kompilieren mit USE_QUIC_OPENSSL_COMPAT=1 ausgewählt worden sein muss. Diese Kompatibilitätsschicht unterstützt die meisten erforderlichen TLS-Operationen, allerdings ohne QUIC 0-RTT.
Diese Funktion richtet sich hauptsächlich an OpenSSL vor Version 3.5.2, wo die QUIC-API noch nicht oder nur teilweise implementiert war. Die Kompatibilitätsschicht lässt sich auch für Version 3.5.2 und höher aktivieren, was aber vermutlich unnötig ist.
Wenn limited-quic gesetzt ist, die Kompatibilitätsschicht beim Kompilieren aber nicht ausgewählt wurde, wird die Option ohne Meldung ignoriert, und die QUIC-TLS-Operationen verwenden die TLS-Bibliothek.
localpeer <name>
Legt den Peer-Namen der lokalen Instanz fest. Die Option wird ignoriert, wenn das Befehlszeilenargument “-L” angegeben wurde oder wenn sie nach “peers”-Abschnittsdefinitionen verwendet wird. In diesen Fällen wird beim Einlesen der Konfiguration eine Warnung ausgegeben.
Diese Option setzt außerdem die Umgebungsvariable HAPROXY_LOCALPEER. Siehe auch “-L” im Verwaltungshandbuch und den Abschnitt “peers” weiter unten.
log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>]
Fügt einen globalen Syslog-Server hinzu. Es können mehrere globale Server definiert werden. Sie erhalten Protokollmeldungen zu Starts und Beendigungen sowie alle Protokollmeldungen von Proxys, die mit “log global” konfiguriert sind. Weitere Einzelheiten finden Sie bei der Option “log” für Proxys.
log-send-hostname [<string>]
Legt das Hostnamenfeld im Syslog-Header fest. Wenn der optionale Parameter “string” gesetzt ist, erhält das Feld den Inhalt dieser Zeichenfolge; andernfalls wird der Hostname des Systems verwendet. Dies wird meist verwendet, wenn Protokollmeldungen nicht über einen zwischengeschalteten Syslog-Server weitergeleitet werden oder wenn lediglich der in den Protokollen ausgegebene Hostname angepasst werden soll.
log-tag <string>
Setzt das Tag-Feld im Syslog-Header auf diese Zeichenfolge. Standardmäßig wird der Programmname verwendet, mit dem das Programm über die Befehlszeile gestartet wurde; dieser ist üblicherweise “haproxy”. Manchmal kann es sinnvoll sein, damit mehrere auf demselben Host laufende Prozesse zu unterscheiden. Siehe auch die pro Proxy einstellbare Direktive “log-tag”.
lua-load <file> [ <arg1> [ <arg2> [ ... ] ] ]
Diese globale Direktive lädt eine Lua-Datei und führt sie im gemeinsamen Kontext aus, der für alle Threads sichtbar ist. Jede in diesem Kontext gesetzte Variable ist für jeden Thread sichtbar. Dies ist die einfachste und empfohlene Methode, Lua-Programme zu laden, skaliert bei vielen Lua-Aufrufen jedoch nicht gut, da jeweils nur ein Thread mit dem globalen Zustand arbeiten kann. Ein so geladenes Programm sieht in der Variablen “core.thread” immer den Wert 0. Diese Direktive kann mehrfach verwendet werden.
Die Argumente sind in der Lua-Datei über den folgenden Code im Dateirumpf verfügbar. Denken Sie daran, dass Lua-Arrays mit dem Index 1 beginnen. Eine in einer Datei deklarierte “local”-Variable ist in der gesamten Datei verfügbar, in anderen Dateien jedoch nicht.
local args = table.pack(...)
lua-load-per-thread <file> [ <arg1> [ <arg2> [ ... ] ] ]
Diese globale Direktive lädt eine Lua-Datei in jeden gestarteten Thread und führt sie dort aus. Globale Variablen sind nur innerhalb des jeweiligen Threads sichtbar, sodass jeder Thread einen anderen Wert sehen kann. Daher wird dringend empfohlen, in so geladenen Programmen keine globalen Variablen zu verwenden. Für jeden Thread wird eine unabhängige Kopie geladen und initialisiert; alles erfolgt nacheinander und in der numerischen Reihenfolge der Threads von 1 bis nbthread. Falls bestimmte Operationen nur einmal ausgeführt werden müssen, sollte das Programm anhand der Variablen “core.thread” prüfen, welcher Thread gerade initialisiert wird. So geladene Programme laufen gleichzeitig auf allen Threads und sind sehr gut skalierbar. Dies ist die empfohlene Methode zum Laden einfacher Funktionen, die Sample-Fetches, Konverter, Aktionen oder Dienste registrieren, sobald feststeht, dass das Programm nicht von globalen Variablen abhängt. Der Einfachheit halber steht die Direktive auch dann zur Verfügung, wenn nur ein Thread verwendet wird oder Threads deaktiviert sind (in diesem Fall entspricht sie lua-load). Diese Direktive kann mehrfach verwendet werden.
Zur Verwendung von Argumenten siehe lua-load.
lua-prepend-path <string> [<type>]
Stellt die angegebene Zeichenfolge, gefolgt von einem Semikolon, der Lua-Variablen package.<type> voran. <type> muss entweder “path” oder “cpath” sein. Wenn <type> nicht angegeben wird, ist der Standardwert “path”.
Die Pfade von Lua sind durch Semikolons getrennte Listen von Mustern, die bestimmen, wie die Funktion require nach der Quelldatei einer Bibliothek sucht. Fragezeichen (?) innerhalb eines Musters werden durch den Modulnamen ersetzt. Der Pfad wird von links nach rechts ausgewertet. Somit werden später vorangestellte Pfade früher geprüft.
Beispielsweise bei Angabe des folgenden Pfads:
Beim Aufruf von require "example" versucht Lua zunächst, das Skript /usr/share/haproxy-lua/example.lua zu laden. Falls es nicht vorhanden ist, wird /usr/share/haproxy-lua/example/init.lua versucht. Falls auch dieses nicht vorhanden ist, werden die Standardpfade geprüft.
Einzelheiten finden Sie in der Lua-Dokumentation unter https://www.lua.org/pil/8.1.html .
master-worker (deprecated)
Master-Worker-Modus. Er entspricht dem Befehlszeilenargument “-W”.
Dieses Schlüsselwort ist veraltet. Starten Sie den Master-Worker-Modus stattdessen mit “-W” oder “-Ws”.
Dieser Modus startet einen “master”, der nach dem Einlesen der Konfiguration mittels Fork einen “worker” zur Verarbeitung des Datenverkehrs erzeugt. Der Master dient als Prozessmanager, der die “workers” überwacht.
In diesem Modus können Sie HAProxy direkt neu laden, indem Sie dem Master das Signal SIGUSR2 senden. Beim Neuladen wird der Master aufgefordert, die Konfiguration erneut einzulesen und mittels Fork einen neuen Worker zu erzeugen. Der bisherige Worker bleibt bis zum Ende seiner Aufgaben erhalten.
Der Master-Worker-Modus ist sowohl mit dem Vordergrund- als auch mit dem Daemon-Modus kompatibel.
Wenn ein Worker mit einem Fehlercode beendet wird, etwa wegen eines Segmentierungsfehlers, werden standardmäßig alle Worker beendet, und der Master wird ebenfalls beendet. Es bietet sich an, dieses Verhalten mit Restart=on-failure in einer systemd-Unit-Datei zu kombinieren, um den gesamten Prozess neu zu starten. Falls Sie dieses Verhalten nicht wünschen, müssen Sie das Schlüsselwort “no-exit-on-failure” verwenden.
Siehe auch “-W” im Verwaltungshandbuch.
master-worker no-exit-on-failure
Wenn im Master-Worker-Modus ein Worker mit einem Fehlercode beendet wird, etwa wegen eines Segmentierungsfehlers, werden standardmäßig alle Worker beendet, und der Master wird ebenfalls beendet. Es bietet sich an, dieses Verhalten mit Restart=on-failure in einer systemd-Unit-Datei zu kombinieren, um den gesamten Prozess neu zu starten.
Dieses Schlüsselwort ermöglicht es, die übrigen Prozesse nach dem Absturz eines Workers weiterlaufen zu lassen, anstatt alle zu beenden. Es muss mit Vorsicht verwendet werden, da es ausschließlich zur Fehlerdiagnose vorgesehen ist und den Master-Prozess in einen abnormen Zustand versetzen könnte.
max-threads-per-group <number>
Legt die maximale Anzahl von Threads in einer Thread-Gruppe fest. Sofern die Anzahl der Thread-Gruppen nicht mit der Direktive “thread-groups” festgelegt ist, erstellt haproxy so viele Thread-Gruppen wie nötig, um die angeforderte Thread-Anzahl zu erreichen. Der Mindestwert ist 1, der Höchstwert 64 (auf 64-Bit-Systemen beziehungsweise 32 auf 32-Bit-Systemen). Niedrigere Werte verringern die Konkurrenz bei atomaren Operationen auf gemeinsam genutzten Zuständen, können jedoch die Anzahl der Sockets erhöhen, die zum Erstellen aller Listener und zum Vorhalten ungenutzter Backend-Verbindungen benötigt werden. Höhere Werte verringern diesen Aufwand, verursachen bei Konkurrenz jedoch eine höhere CPU-Auslastung und niedrigere Verbindungsraten. Der Standardwert ist 16. In Tests auf verschiedenen Systemen erwies sich dies als der beste Kompromiss, darunter x86_64-Prozessoren mehrerer Hersteller und große Arm64-Systeme, sowohl auf physischer Hardware als auch unter Hypervisoren.
mworker-max-reloads <number>
Im Master-Worker-Modus begrenzt diese Option, wie viele Neuladungen ein Worker überleben kann. Wenn der Worker nach einer Neuladung nicht beendet wurde und die Anzahl seiner Neuladungen diesen Wert überschreitet, erhält er ein SIGTERM-Signal. Diese Option hilft, die Anzahl der Worker unter Kontrolle zu halten. Siehe auch “show proc” im Verwaltungshandbuch.
Standardmäßig ist dieser Wert auf 50 gesetzt.
nbthread <number>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für Threads einkompiliert wurde. Sie lässt HAProxy mit <number> Threads laufen. “nbthread” funktioniert auch, wenn HAProxy im Vordergrund gestartet wird. Auf einigen Plattformen mit Unterstützung für CPU-Affinität wird der Standardwert von “nbthread” automatisch auf die Anzahl der CPUs gesetzt, an die der Prozess beim Start gebunden ist. Dadurch lässt sich die Thread-Anzahl vom aufrufenden Prozess aus mit Befehlen wie “taskset” oder “cpuset” einfach anpassen. Andernfalls ist der Standardwert 1. Der Standardwert wird in der Ausgabe von “haproxy -vv” angezeigt. Beachten Sie, dass sowohl hier gesetzte als auch automatisch ermittelte Werte der durch “thread-hard-limit” festgelegten Grenze unterliegen (sofern diese gesetzt ist).
numa-cpu-mapping
Auf einer NUMA-fähigen Plattform ermöglicht dies der Direktive “cpu-policy”, die Topologie zu untersuchen und die beste Auswahl an CPUs sowie die dazugehörige Thread-Anzahl zu ermitteln. Falls die angewendete Bindung auf einer bestimmten Architektur jedoch nicht optimal ist, kann sie mit der Anweisung ’no numa-cpu-mapping’ deaktiviert werden. Diese automatische Bindung wird auch dann nicht angewendet, wenn eine ’nbthread’-Anweisung in der Konfiguration vorhanden ist, wenn die Prozessaffinität bereits festgelegt wurde, beispielsweise über die Direktive ‘cpu-map’ oder das Dienstprogramm taskset, oder wenn cpu-policy auf einen anderen Wert gesetzt ist. Siehe auch “cpu-map”, “cpu-policy”, “cpu-set”.
ocsp-update.disable [ on | off ]
Deaktiviert ocsp-update in HAProxy vollständig. Sämtliche ocsp-update-Konfiguration wird ignoriert. Der Standardwert ist “off”. Weitere Informationen zum automatischen Aktualisierungsmechanismus finden Sie bei der Option “ocsp-update”.
ocsp-update.httpproxy <address>[:port]
Ermöglicht die Verwendung eines HTTP-Proxys für die OCSP-Aktualisierungen. Dies funktioniert nur mit HTTP; HTTPS wird nicht unterstützt. Mit dieser Option kann der OCSP-Aktualisierer eine absolute URI in der Anfrage an den Proxy senden.
ocsp-update.maxdelay <number>
Legt das maximale Intervall zwischen zwei automatischen Aktualisierungen derselben OCSP-Antwort fest. Die Zeit wird in Sekunden angegeben und beträgt standardmäßig 3600 (1 Stunde). Der Wert muss höher als “ocsp-update.mindelay” sein. Weitere Informationen zum automatischen Aktualisierungsmechanismus finden Sie bei der Option “ocsp-update”.
ocsp-update.mindelay <number>
Legt das minimale Intervall zwischen zwei automatischen Aktualisierungen derselben OCSP-Antwort fest. Die Zeit wird in Sekunden angegeben und beträgt standardmäßig 300 (5 Minuten). Dies ist besonders bei OCSP-Antworten ohne ausdrücklichen Ablaufzeitpunkt nützlich. Der Wert muss niedriger als “ocsp-update.maxdelay” sein. Weitere Informationen zum automatischen Aktualisierungsmechanismus finden Sie bei der Option “ocsp-update”.
ocsp-update.mode [ on | off ]
Legt den standardmäßigen ocsp-update-Modus für alle in der Konfiguration verwendeten Zertifikate fest. Diese globale Option kann durch die crt-list-Option “ocsp-update” überschrieben werden. Standardmäßig ist sie auf “off” gesetzt. Weitere Informationen zum automatischen Aktualisierungsmechanismus finden Sie bei der Option “ocsp-update”.
pidfile <pidfile>
Schreibt im Daemon-Modus die PIDs aller Daemons in die Datei <pidfile> beziehungsweise im Master-Worker-Modus die PID des Master-Prozesses in die Datei <pidfile>. Diese Option entspricht dem Befehlszeilenargument “-p”. Die Datei muss für den Benutzer zugänglich sein, der den Prozess startet. Siehe auch “daemon” und “master-worker”.
pp2-never-send-local
Bis einschließlich Version 2.1 enthielt HAProxy einen Fehler in der Implementierung des PROXY-Protokolls v2, durch den bei Zustandsprüfungen ein PROXY-Befehl anstelle eines LOCAL-Befehls gesendet wurde. Dies ist zwar geringfügig, führt aber in den Protokollen einiger Server zu Verwirrung. Leider wurde der Fehler erst sehr spät entdeckt. Dabei zeigte sich, dass einige Server, deren PROXY-Protokollimplementierung möglicherweise nur mit HAProxy getestet wurde, den LOCAL-Befehl nicht korrekt verarbeiten und dauerhaft im Zustand “down” verbleiben, wenn HAProxy sie prüft. In diesem Fall kann diese globale Option aktiviert werden, um zum alten (fehlerhaften) Verhalten zurückzukehren, bis die Hersteller der betroffenen Komponenten kontaktiert und die Komponenten korrigiert wurden. Diese Option ist standardmäßig deaktiviert und wirkt auf alle Server mit der Anweisung “send-proxy-v2”.
presetenv <name> <value>
Setzt die Umgebungsvariable <name> auf den Wert <value>. Wenn die Variable bereits existiert, wird sie NICHT überschrieben. Die Änderungen werden sofort wirksam, sodass bereits die nächste Zeile in der Konfigurationsdatei den neuen Wert sieht. Siehe auch “setenv”, “resetenv” und “unsetenv”.
prealloc-fd
Öffnet einmalig den höchsten Dateideskriptor und bewirkt damit eine Vorabzuweisung der Datenstrukturen des Kernels. Dies verhindert kurze Pausen, wenn nbthread>1 gilt und HAProxy einen Dateideskriptor öffnet, für den der Kernel seine Datenstrukturen erweitern muss.
resetenv [<name> ...]
Entfernt alle Umgebungsvariablen außer den als Argument angegebenen. Dies ermöglicht eine bereinigte, kontrollierte Umgebung, bevor mit setenv oder unsetenv neue Werte gesetzt werden. Beachten Sie, dass einige interne Funktionen Umgebungsvariablen verwenden können, etwa Funktionen zur Zeitverarbeitung, aber auch OpenSSL oder sogar externe Prüfungen. Dies darf nur mit äußerster Vorsicht und nach vollständiger Validierung verwendet werden. Die Änderungen werden sofort wirksam, sodass bereits die nächste Zeile in der Konfigurationsdatei die neue Umgebung sieht. Siehe auch “setenv”, “presetenv” und “unsetenv”.
server-state-base <directory>
Legt das Verzeichnispräfix fest, das allen Namen von Serverzustandsdateien vorangestellt wird, die nicht mit ‘/’ beginnen. Siehe auch “server-state-file”, “load-server-state-from-file” und “server-state-file-name”.
server-state-file <file>
Gibt den Pfad zur Datei mit den Serverzuständen an. Beginnt der Pfad mit einem Schrägstrich (’/’), gilt er als absolut; andernfalls wird er relativ zu dem mit “server-state-base” festgelegten Verzeichnis (falls gesetzt) oder zum aktuellen Verzeichnis interpretiert. Vor dem Neuladen von HAProxy können die aktuellen Serverzustände mit dem Statistikbefehl “show servers state” gespeichert werden. Die Ausgabe dieses Befehls muss in die durch <file> bezeichnete Datei geschrieben werden. Beim Start liest, lädt und übernimmt HAProxy vor der Verarbeitung von Datenverkehr den Zustand jedes Servers, der sowohl in der Datei als auch in der aktuellen laufenden Konfiguration vorhanden ist. Siehe auch “server-state-base” und “show servers state”, “load-server-state-from-file” und “server-state-file-name”
set-dumpable [ on | off | libs ]
Mit dieser Option lässt sich das Verhalten bei der Erstellung eines Speicherabbilds nach einem Prozessabsturz festlegen. Verfügbare Optionen sind:
-
on aktiviert die Erstellung von Speicherabbildern auf Prozessebene, falls sie zuvor deaktiviert war.
-
off deaktiviert eine zuvor aktivierte Erstellung von Speicherabbildern.
-
libs aktiviert die Erstellung von Speicherabbildern mit einer eingebetteten Kopie der für die Fehlerdiagnose benötigten Programmdateien und Bibliotheken. Entwickler können dies anfordern. In diesem Fall versucht haproxy, die Bibliotheken, von denen es abhängt, in den Speicher zu laden und dort sorgfältig aufzubewahren. Falls der Prozess abstürzt, werden sie in das Speicherabbild aufgenommen, sodass sie nicht mehr aus dem Dateisystem beschafft werden müssen und keine Gefahr besteht, dass sie nicht zum Speicherabbild passen. Dafür werden einige bis einige zehn Megabyte zusätzlicher RAM benötigt, weshalb dies auf kleinen Systemen besser nicht verwendet werden sollte.
Diese Option sollte standardmäßig deaktiviert bleiben und nur auf Anforderung eines Entwicklers aktiviert werden. Standardmäßig ist sie deaktiviert. Ohne Argument ist der Standardwert “on”. Wenn sie aktiviert wurde, kann sie dennoch durch Voranstellen des Schlüsselworts “no” oder durch Setzen auf “off” ausdrücklich deaktiviert werden. Sie hat keine Auswirkungen auf Leistung oder Stabilität, versucht aber mit allen verfügbaren Mitteln, Speicherabbilder wieder zu aktivieren, die möglicherweise durch Dateigrößenlimits (ulimit -f), Größenlimits für Speicherabbilder (ulimit -c) oder die Fähigkeit eines Prozesses zur Erstellung von Speicherabbildern nach Änderung seiner UID/GID (etwa /proc/sys/fs/suid_dumpable unter Linux) deaktiviert wurden. Speicherabbilder können weiterhin durch die Berechtigungen des aktuellen Verzeichnisses (prüfen Sie, aus welchem Verzeichnis die Datei gestartet wird), die Berechtigungen des chroot-Verzeichnisses (möglicherweise muss die chroot-Direktive vorübergehend deaktiviert oder das Verzeichnis an einen eigenen beschreibbaren Ort verlegt werden) oder andere systemspezifische Einschränkungen begrenzt sein. Einige Linux-Varianten sind beispielsweise dafür bekannt, die standardmäßige core-Datei durch den Pfad zu einem Programm zu ersetzen, das nicht einmal auf dem System installiert ist (prüfen Sie /proc/sys/kernel/core_pattern). Häufig lässt sich das Problem einfach durch Eintragen von “core”, “core.%p” oder “/var/log/core/core.%p” beheben. Wenn Sie diese Option aktivieren und auf das erneute Auftreten eines seltenen Problems warten, ist es oft sinnvoll, zunächst ein solches Speicherabbild zu erzeugen, beispielsweise durch Senden von “kill -11” an den “haproxy”-Prozess, und zu prüfen, ob dieser beim Beenden ein Speicherabbild am erwarteten Ort hinterlässt.
set-var <var-name> <expr>
Setzt die prozessweite Variable ‘<var-name>’ auf das Ergebnis der Auswertung des Sample-Ausdrucks <expr>. Die Variable ‘<var-name>’ darf nur eine prozessweite Variable sein (mit dem Präfix ‘proc.’). Dies funktioniert genau wie die Aktion ‘set-var’ in TCP- oder HTTP-Regeln, mit dem Unterschied, dass der Ausdruck beim Einlesen der Konfiguration ausgewertet und die Variable sofort gesetzt wird. Im Ausdruck sind nur Sample-Fetch-Funktionen und Konverter erlaubt, die interne Daten verwenden, typischerweise ‘int(value)’ oder ‘str(value)’. Auch bereits angelegte Variablen können referenziert werden. Diese Variablen können anschließend aus den regulären Regelsätzen gelesen und geändert werden.
Beispiel:
set-var-fmt <var-name> <fmt>
Setzt die prozessweite Variable ‘<var-name>’ auf die Zeichenfolge, die sich aus der Auswertung des Protokollformats <fmt> ergibt. Die Variable ‘<var-name>’ darf nur eine prozessweite Variable sein (mit dem Präfix ‘proc.’). Dies funktioniert genau wie die Aktion ‘set-var-fmt’ in TCP- oder HTTP-Regeln, mit dem Unterschied, dass der Ausdruck beim Einlesen der Konfiguration ausgewertet und die Variable sofort gesetzt wird. Im Ausdruck sind nur Sample-Fetch-Funktionen und Konverter erlaubt, die interne Daten verwenden, typischerweise ‘int(value)’ oder ‘str(value)’. Auch bereits angelegte Variablen können referenziert werden. Diese Variablen können anschließend aus den regulären Regelsätzen gelesen und geändert werden. Einzelheiten zur Syntax benutzerdefinierter Protokollformate finden Sie in Abschnitt 8.2.6
.
Beispiel:
setcap <name>[,<name>...]
Legt eine Liste von Capabilities fest, die erhalten bleiben müssen, wenn der Prozess entweder als Benutzer ohne Root-Rechte (uid > 0) gestartet und ausgeführt wird oder zunächst mit uid 0 (root) startet und anschließend zu einem Benutzer ohne Root-Rechte wechselt. Standardmäßig gehen beim Wechsel der uid alle Berechtigungen verloren. Einige davon werden jedoch oft benötigt, etwa um sich beim transparenten Proxying von einer fremden Adresse aus mit einem Server zu verbinden oder einen Port unterhalb von 1024 zu binden, beispielsweise bei Verwendung von “tune.quic.fe.sock-per-conn default-on”. Dies führt zu Konfigurationen, die vollständig unter uid 0 laufen. Das Setzen von Capabilities ist im Allgemeinen eine sicherere Alternative, da nur die benötigten Capabilities erhalten bleiben. Die Funktion ist OS-spezifisch und nur unter Linux aktiviert, wenn beim Kompilieren USE_LINUX_CAP=1 gesetzt wurde. Die Liste der unterstützten Capabilities hängt ebenfalls vom OS ab und wird in der Fehlermeldung aufgeführt, die bei Angabe eines ungültigen oder leeren Capability-Namens erscheint. Mehrere Capabilities können durch Kommas getrennt angegeben werden. Zu den häufig verwendeten gehören “cap_net_raw”, das die transparente Bindung an eine fremde Adresse erlaubt, und “cap_net_bind_service”, das die Bindung an einen privilegierten Port erlaubt und von QUIC verwendet werden kann. Wenn der Prozess unter demselben Benutzer ohne Root-Rechte gestartet und ausgeführt wird, sollten die benötigten Capabilities zusätzlich zu diesem Schlüsselwort mit setcap auf der haproxy-Programmdatei gesetzt werden. Weitere Einzelheiten zum Setzen von Capabilities auf der haproxy-Programmdatei finden Sie in Kapitel 13.1 zur Unterstützung von Linux-Capabilities im Verwaltungshandbuch.
Beispiel:
setenv <name> <value>
Setzt die Umgebungsvariable <name> auf den Wert <value>. Wenn die Variable bereits existiert, wird sie überschrieben. Die Änderungen werden sofort wirksam, sodass bereits die nächste Zeile in der Konfigurationsdatei den neuen Wert sieht. Siehe auch “presetenv”, “resetenv” und “unsetenv”.
shm-stats-file <name>
Wenn diese Direktive gesetzt ist, aktiviert sie die Verwendung gemeinsamen Speichers zum Speichern von Statistikzählern. <name> wird als Argument an shm_open() übergeben, um den gemeinsamen Speicher an einem eindeutigen Ort zu öffnen. Die Direktive ist daher nur auf Systemen verfügbar, die shm_open() unterstützen. Wenn SHM für Statistiken verwendet wird, werden alle gemeinsam nutzbaren Zähler für Frontends, Backends, Listener und Server im SHM gespeichert, sofern für diese Objekte eine GUID gesetzt ist. Beim Neuladen von haproxy versucht der neue Prozess, den SHM nach Objekten zu durchsuchen, die sich anhand ihrer GUID und ihres Typs den in der Konfiguration definierten Objekten zuordnen lassen. Damit sollen die Werte einiger Zähler beim Neuladen erhalten bleiben. Wird haproxy hingegen ordnungsgemäß beendet, werden die SHM-Objekte freigegeben, wodurch die Zähler tatsächlich zurückgesetzt werden. Die Datei kann auch vor dem Start eines neuen Prozesses manuell entfernt werden, um ein Zurücksetzen zu erzwingen.
Siehe auch “guid”, “guid-prefix” und “shm-stats-file-max-objects”
shm-stats-file-max-objects <number>
Diese Einstellung legt fest, wie viele Objekte der für gemeinsame Zähler verwendete gemeinsame Speicher pro Thread-Gruppe maximal aufnehmen kann. Sie steht in direktem Zusammenhang mit der maximalen Speichergröße des shm und dient dazu, den shm vorab auf eine bestimmte Größe abzubilden, damit zur Laufzeit keine erneute Speicherabbildung nötig ist. Der Standardwert ist 2k. Dies sollte für die meisten Konfigurationen ausreichen, ohne einen unangemessenen Speicherverbrauch zu riskieren, lässt sich bei Bedarf aber einfach ändern. haproxy meldet beim Start, wenn der Wert zu niedrig ist, um alle Objekte zu registrieren, die im gemeinsamen Speicher abgelegt werden sollen. Diese Einstellung ist nur relevant, wenn “shm-stats-file” definiert wurde.
Siehe auch “thread-groups”
ssl-default-bind-ciphers <ciphers>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde. Sie legt für alle “bind”-Zeilen ohne eigene ausdrückliche Definition die standardmäßige Zeichenfolge fest, die die Liste der Verschlüsselungsalgorithmen (“cipher suite”) beschreibt, die beim SSL/TLS-Handshake bis einschließlich TLSv1.2 ausgehandelt werden. Das Format der Zeichenfolge ist in “man 1 ciphers” der OpenSSL-Handbuchseiten definiert. Hintergrundinformationen und Empfehlungen finden Sie beispielsweise unter (https://wiki.mozilla.org/Security/Server_Side_TLS ) und (https://mozilla.github.io/server-side-tls/ssl-config-generator/ ). Zur Konfiguration von TLSv1.3-Verschlüsselungsalgorithmen siehe das Schlüsselwort “ssl-default-bind-ciphersuites”. Weitere Informationen finden Sie beim Schlüsselwort “bind”.
ssl-default-bind-ciphersuites <ciphersuites>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde und HAProxy mit OpenSSL 1.1.1 oder höher erstellt wurde. Sie legt für alle “bind”-Zeilen ohne eigene ausdrückliche Definition die standardmäßige Zeichenfolge fest, die die Liste der Verschlüsselungsalgorithmen (“cipher suite”) beschreibt, die beim TLSv1.3-Handshake ausgehandelt werden. Das Format der Zeichenfolge ist in “man 1 ciphers” der OpenSSL-Handbuchseiten im Abschnitt “ciphersuites” definiert. Zur Konfiguration von Verschlüsselungsalgorithmen für TLSv1.2 und frühere Versionen siehe das Schlüsselwort “ssl-default-bind-ciphers”. Diese Einstellung akzeptiert möglicherweise auch TLSv1.2-Cipher-Suites. Dieses Verhalten ist jedoch nicht dokumentiert und wird nicht empfohlen, da es inkonsistent oder fehlerhaft sein könnte. Die standardmäßigen TLSv1.3-Cipher-Suites von OpenSSL sind: “TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256”
TLSv1.3 unterstützt nur 5 Cipher-Suites:
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_AES_128_CCM_SHA256
- TLS_AES_128_CCM_8_SHA256
Weitere Informationen finden Sie beim Schlüsselwort “bind”.
Beispiel:
ssl-default-bind-client-sigalgs <sigalgs>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde. Sie legt für alle “bind”-Zeilen ohne eigene ausdrückliche Definition die standardmäßige Zeichenfolge fest, die die Liste der Signaturalgorithmen für die Client-Authentifizierung beschreibt. Das Format ist eine durch Doppelpunkte getrennte Liste von Signaturalgorithmen. Jeder Signaturalgorithmus kann in einer von zwei Formen angegeben werden: als Name eines TLS1.3-Signaturschemas (“rsa_pss_rsae_sha256”) oder als Kombination aus Public-Key-Algorithmus + Digest (“ECDSA+SHA256”). Eine Liste kann beide Formen enthalten. Weitere Informationen zum Format finden Sie unter SSL_CTX_set1_client_sigalgs(3). Eine Liste der Signaturalgorithmen ist außerdem in RFC8446, Abschnitt 4.2.3 , sowie in der OpenSSL-Datei ssl/t1_lib.c verfügbar. Diese Einstellung gilt nicht für TLSv1.1 und frühere Protokollversionen, da die Signaturalgorithmen in diesen Versionen nicht gesondert ausgehandelt werden. Es wird nicht empfohlen, diese Einstellung zu ändern, sofern keine Kompatibilität mit einer Middlebox erforderlich ist.
ssl-default-bind-curves <curves>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde. Sie legt die standardmäßige Zeichenfolge fest, die die Liste der Algorithmen für elliptische Kurven (“curve suite”) beschreibt, die beim SSL/TLS-Handshake mit ECDHE ausgehandelt werden. Das Format ist eine durch Doppelpunkte getrennte Liste von Kurvennamen. Weitere Informationen finden Sie beim Schlüsselwort “bind”.
ssl-default-bind-options [<option>]...
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde. Sie legt standardmäßige ssl-options fest, die für alle “bind”-Zeilen erzwungen werden. Die verfügbaren Optionen finden Sie beim Schlüsselwort “bind”.
Beispiel:
ssl-default-bind-sigalgs <sigalgs>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde. Sie legt für alle “bind”-Zeilen ohne eigene ausdrückliche Definition die standardmäßige Zeichenfolge fest, die die Liste der Signaturalgorithmen beschreibt, die beim TLSv1.2- und TLSv1.3-Handshake ausgehandelt werden. Das Format ist eine durch Doppelpunkte getrennte Liste von Signaturalgorithmen. Jeder Signaturalgorithmus kann in einer von zwei Formen angegeben werden: als Name eines TLS1.3-Signaturschemas (“rsa_pss_rsae_sha256”) oder als Kombination aus Public-Key-Algorithmus + Digest (“ECDSA+SHA256”). Eine Liste kann beide Formen enthalten. Weitere Informationen zum Format finden Sie unter SSL_CTX_set1_sigalgs(3). Eine Liste der Signaturalgorithmen ist außerdem in RFC8446, Abschnitt 4.2.3 , sowie in der OpenSSL-Datei ssl/t1_lib.c verfügbar. Diese Einstellung gilt nicht für TLSv1.1 und frühere Protokollversionen, da die Signaturalgorithmen in diesen Versionen nicht gesondert ausgehandelt werden. Es wird nicht empfohlen, diese Einstellung zu ändern, sofern keine Kompatibilität mit einer Middlebox erforderlich ist.
ssl-default-server-ciphers <ciphers>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde. Sie legt für alle “server”-Zeilen ohne eigene ausdrückliche Definition die standardmäßige Zeichenfolge fest, die die Liste der Verschlüsselungsalgorithmen beschreibt, die beim SSL/TLS-Handshake bis einschließlich TLSv1.2 mit dem Server ausgehandelt werden. Das Format der Zeichenfolge ist in “man 1 ciphers” der OpenSSL-Handbuchseiten definiert. Hintergrundinformationen und Empfehlungen finden Sie beispielsweise unter (https://wiki.mozilla.org/Security/Server_Side_TLS ) und (https://mozilla.github.io/server-side-tls/ssl-config-generator/ ). Zur Konfiguration von TLSv1.3-Verschlüsselungsalgorithmen siehe das Schlüsselwort “ssl-default-server-ciphersuites”. Weitere Informationen finden Sie beim Schlüsselwort “server”.
ssl-default-server-ciphersuites <ciphersuites>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde und HAProxy mit OpenSSL 1.1.1 oder höher erstellt wurde. Sie legt für alle “server”-Zeilen ohne eigene ausdrückliche Definition die standardmäßige Zeichenfolge fest, die die Liste der Verschlüsselungsalgorithmen beschreibt, die beim TLSv1.3-Handshake mit dem Server ausgehandelt werden. Das Format der Zeichenfolge ist in “man 1 ciphers” der OpenSSL-Handbuchseiten im Abschnitt “ciphersuites” definiert. Zur Konfiguration von Verschlüsselungsalgorithmen für TLSv1.2 und frühere Versionen siehe das Schlüsselwort “ssl-default-server-ciphers”. Weitere Informationen finden Sie beim Schlüsselwort “server”.
ssl-default-server-client-sigalgs <sigalgs>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde. Sie legt für alle “server”-Zeilen ohne eigene ausdrückliche Definition die standardmäßige Zeichenfolge fest, die die Liste der Signaturalgorithmen für die Client-Authentifizierung beschreibt. Das Format ist eine durch Doppelpunkte getrennte Liste von Signaturalgorithmen. Jeder Signaturalgorithmus kann in einer von zwei Formen angegeben werden: als Name eines TLS1.3-Signaturschemas (“rsa_pss_rsae_sha256”) oder als Kombination aus Public-Key-Algorithmus + Digest (“ECDSA+SHA256”). Eine Liste kann beide Formen enthalten. Weitere Informationen zum Format finden Sie unter SSL_CTX_set1_client_sigalgs(3). Eine Liste der Signaturalgorithmen ist außerdem in RFC8446, Abschnitt 4.2.3 , sowie in der OpenSSL-Datei ssl/t1_lib.c verfügbar. Diese Einstellung gilt nicht für TLSv1.1 und frühere Protokollversionen, da die Signaturalgorithmen in diesen Versionen nicht gesondert ausgehandelt werden. Es wird nicht empfohlen, diese Einstellung zu ändern, sofern keine Kompatibilität mit einer Middlebox erforderlich ist.
ssl-default-server-curves <curves>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde. Sie legt die standardmäßige Zeichenfolge fest, die die Liste der Algorithmen für elliptische Kurven (“curve suite”) beschreibt, die beim SSL/TLS-Handshake mit ECDHE ausgehandelt werden. Das Format ist eine durch Doppelpunkte getrennte Liste von Kurvennamen. Weitere Informationen finden Sie beim Schlüsselwort “server”.
ssl-default-server-options [<option>]...
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde. Sie legt standardmäßige ssl-options fest, die für alle “server”-Zeilen erzwungen werden. Die verfügbaren Optionen finden Sie beim Schlüsselwort “server”.
ssl-default-server-sigalgs <sigalgs>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde. Sie legt für alle “server”-Zeilen ohne eigene ausdrückliche Definition die standardmäßige Zeichenfolge fest, die die Liste der Signaturalgorithmen beschreibt, die beim TLSv1.2- und TLSv1.3-Handshake ausgehandelt werden. Das Format ist eine durch Doppelpunkte getrennte Liste von Signaturalgorithmen. Jeder Signaturalgorithmus kann in einer von zwei Formen angegeben werden: als Name eines TLS1.3-Signaturschemas (“rsa_pss_rsae_sha256”) oder als Kombination aus Public-Key-Algorithmus + Digest (“ECDSA+SHA256”). Eine Liste kann beide Formen enthalten. Weitere Informationen zum Format finden Sie unter SSL_CTX_set1_sigalgs(3). Eine Liste der Signaturalgorithmen ist außerdem in RFC8446, Abschnitt 4.2.3 , sowie in der OpenSSL-Datei ssl/t1_lib.c verfügbar. Diese Einstellung gilt nicht für TLSv1.1 und frühere Protokollversionen, da die Signaturalgorithmen in diesen Versionen nicht gesondert ausgehandelt werden. Es wird nicht empfohlen, diese Einstellung zu ändern, sofern keine Kompatibilität mit einer Middlebox erforderlich ist.
ssl-dh-param-file <file>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde. Sie legt für alle “bind”-Zeilen ohne eigene ausdrückliche Definition die standardmäßigen DH-Parameter fest, die beim SSL/TLS-Handshake mit ephemerem Diffie-Hellman-Schlüsselaustausch (DHE) verwendet werden. Benutzerdefinierte DH-Parameter in einer bind-Zertifikatsdatei haben, sofern vorhanden, Vorrang. Wenn weder mit ssl-dh-param-file noch direkt in der Zertifikatsdatei benutzerdefinierte DH-Parameter angegeben sind, werden keine DHE-Verschlüsselungsverfahren verwendet, es sei denn, tune.ssl.default-dh-param ist gesetzt. Im letzteren Fall werden vordefinierte DH-Parameter der angegebenen Größe verwendet. Benutzerdefinierte Parameter gelten als sicherer, daher wird ihre Verwendung empfohlen. Sie können mit dem OpenSSL-Befehl “openssl dhparam <size>” erzeugt werden. Dabei sollte die Größe mindestens 2048 betragen, da DH-Parameter mit 1024 Bit nicht mehr als sicher gelten sollten.
ssl-passphrase-cmd <cmd> <args> ...
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde. Sie ermöglicht die Definition einer vollständigen Befehlszeile, die aufgerufen wird, wenn während der Initialisierung ein verschlüsseltes Zertifikat geladen wird. Der Befehl kann ein Skript oder ein anderes Programm sein. Er erhält als ersten Parameter den Pfad des verschlüsselten privaten Schlüssels und anschließend die benutzerdefinierten “args”-Parameter. Er sollte die Passphrase zum Entschlüsseln des privaten Schlüssels auf der Standardausgabe ausgeben. Für jeden während der Initialisierung neu geladenen verschlüsselten privaten Schlüssel versucht HAProxy zunächst alle bereits bekannten Passphrasen zur Entschlüsselung und ruft den Passphrasenbefehl erst dann erneut auf, wenn keine davon funktioniert.
ssl-propquery <query>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde und die OpenSSL-Version mindestens 3.0 ist. Sie ermöglicht die Definition einer standardmäßigen Eigenschaftszeichenfolge, die beim Abrufen von Algorithmen aus Providern verwendet wird. Sie verhält sich wie die openssl-Option propquery und verwendet dieselbe Syntax (beschrieben unter https://www.openssl.org/docs/man3.0/man7/property.html ). Wenn beispielsweise zwei Provider geladen sind, foo und der Standardprovider, ermöglicht die propquery “?provider=foo”, standardmäßig die vom Provider foo bereitgestellten Algorithmusimplementierungen auszuwählen und auf die des Standardproviders zurückzugreifen, wenn sie nicht gefunden wurden.
ssl-provider <name>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde und die OpenSSL-Version mindestens 3.0 ist. Sie ermöglicht das Laden eines Providers während der Initialisierung. Bei erfolgreichem Laden kann HAProxy die vom geladenen Provider bereitgestellten Funktionen verwenden. In einer Konfigurationsdatei können mehrere ‘ssl-provider’-Optionen angegeben werden. Die Provider werden in der Reihenfolge ihres Auftretens geladen.
Beachten Sie, dass das explizite Laden eines Providers verhindert, dass OpenSSL den Provider ‘default’ automatisch lädt. OpenSSL erlaubt es auch, die zu ladenden Provider direkt in seiner Konfigurationsdatei (beispielsweise openssl.cnf) festzulegen. Daher ist diese Option ‘ssl-provider’ zum Laden von Providern nicht erforderlich. Mit dem CLI-Befehl “show ssl providers” können alle erfolgreich geladenen Provider angezeigt werden.
Der Standardsuchpfad für OpenSSL-Provider ist in der Ausgabe des Befehls “openssl version -a” zu finden. Befindet sich der Provider in einem anderen Verzeichnis, können Sie die Umgebungsvariable OPENSSL_MODULES auf das Verzeichnis setzen, in dem der Provider liegt.
Siehe auch “ssl-propquery” und “ssl-provider-path”.
ssl-provider-path <path>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für OpenSSL einkompiliert wurde und die OpenSSL-Version mindestens 3.0 ist. Sie ermöglicht die Angabe des Suchpfads, den OpenSSL bei der Suche nach Providern verwenden soll. Sie verhält sich wie die Umgebungsvariable OPENSSL_MODULES. Sie gilt für alle folgenden ‘ssl-provider’-Optionen, bis ein neuer ‘ssl-provider-path’ definiert wird. Siehe auch “ssl-provider”.
ssl-load-extra-del-ext
Diese Einstellung konfiguriert, wie HAProxy nach zusätzlichen SSL-Dateien sucht. Standardmäßig fügt HAProxy dem Dateinamen eine neue Erweiterung hinzu (beispielsweise wird für “foobar.crt” die Datei “foobar.crt.key” geladen). Wenn diese Option aktiviert ist, entfernt HAProxy die Erweiterung, bevor es die neue hinzufügt (beispielsweise wird für “foobar.crt” die Datei “foobar.key” geladen).
Die crt-Datei muss die Erweiterung “.crt” haben, damit diese Option funktioniert.
Diese Option ist nicht mit Bundle-Erweiterungen (.ecdsa, .rsa. .dsa) kompatibel und versucht nicht, diese zu entfernen.
Diese Option ist standardmäßig deaktiviert. Siehe auch “ssl-load-extra-files”.
ssl-load-extra-files <none|all|bundle|sctl|ocsp|issuer|key>*
Diese Einstellung verändert, wie HAProxy beim Laden von SSL-Zertifikaten nach nicht ausdrücklich angegebenen Dateien sucht. Die Option gilt sowohl für Zertifikate von “bind”-Zeilen als auch für solche von “server”-Zeilen. Einige der zusätzlichen Dateien haben bei Zertifikaten von “server”-Zeilen jedoch keine funktionalen Auswirkungen.
Standardmäßig erkennt HAProxy automatisch zahlreiche Dateien, die nicht in der Konfiguration angegeben sind. Wenn Sie die Startzeit optimieren möchten, können Sie dieses Verhalten deaktivieren.
“none”: Lädt nur die in der Konfiguration angegebenen Dateien. Wenn eine Datei nicht existiert, wird nicht versucht, ein Zertifikatsbundle zu laden. Bei einem Verzeichnis wird nicht versucht, Zertifikate mit demselben Basisnamen zu einem Bundle zusammenzufassen.
“all”: Dies ist das Standardverhalten. Es wird versucht, alles zu laden: Zertifikatsbundles, sctl, ocsp, issuer, key.
“bundle”: Wenn eine in der Konfiguration angegebene Datei nicht existiert, versucht HAProxy, ein “Zertifikatsbundle” zu laden. Zertifikatsbundles werden nur auf der Frontend-Seite verwaltet und funktionieren nicht für Backend-Zertifikate.
Seit HAProxy 2.3 werden die Bundles nicht mehr in denselben OpenSSL-Zertifikatsspeicher geladen. Stattdessen wird jedes Zertifikat in einen eigenen Speicher geladen, was der Angabe mehrerer “crt” entspricht. Dafür ist OpenSSL 1.1.1 erforderlich. Bundles dienen somit nur noch der Abwärtskompatibilität und sind für eine hybride RSA/ECC-bind-Konfiguration nicht mehr erforderlich.
Damit HAProxy diese PEM-Dateien als “Zertifikatsbundle” erkennt, müssen sie wie folgt benannt werden: Alle zu einem Bundle zusammenzufassenden PEM-Dateien müssen denselben Basisnamen und ein Suffix haben, das den Schlüsseltyp angibt. Derzeit werden drei Suffixe unterstützt: rsa, dsa und ecdsa. Wenn beispielsweise www.example.com zwei PEM-Dateien hat, eine RSA-Datei und eine ECDSA-Datei, müssen sie “example.pem.rsa” und “example.pem.ecdsa” heißen. Der erste Teil des Dateinamens ist beliebig; nur das Suffix ist entscheidend. Um dieses Bundle in HAProxy zu laden, geben Sie nur den Basisnamen an:
Beispiel: bind :8443 ssl crt example.pem
Beachten Sie, dass das Suffix nicht an HAProxy übergeben wird. Dadurch wird HAProxy angewiesen, nach einem Zertifikatsbundle zu suchen.
HAProxy lädt alle PEM-Dateien des Bundles so, als wären sie einzeln mit mehreren “crt” konfiguriert worden.
Das Laden von Bundles hat keine Auswirkungen mehr auf das Laden von Verzeichnissen, da die Dateien einzeln geladen werden.
In der CLI werden Bundles als separate Dateien behandelt. Für ihren Commit ist die Bundle-Erweiterung erforderlich.
OCSP-Dateien (.ocsp), Ausstellerdateien (.issuer), Certificate Transparency (.sctl) sowie private Schlüssel (.key) werden beim Bündeln mehrerer Zertifikate unterstützt.
“sctl”: Versucht, für jedes Schlüsselwort crt die Datei “<basename>.sctl” zu laden. Wenn sie für ein Backend-Zertifikat bereitgestellt wird, wird sie zwar geladen, hat aber keine funktionalen Auswirkungen.
“ocsp”: Versucht, für jedes Schlüsselwort crt die Datei “<basename>.ocsp” zu laden. Wenn sie für ein Backend-Zertifikat bereitgestellt wird, wird sie zwar geladen, hat aber keine funktionalen Auswirkungen.
“issuer”: Versucht, die Datei “<basename>.issuer” zu laden, wenn der Aussteller der OCSP-Datei nicht in der PEM-Datei enthalten ist. Wenn sie für ein Backend-Zertifikat bereitgestellt wird, wird sie zwar geladen, hat aber keine funktionalen Auswirkungen.
“key”: Wenn die PEM-Datei keinen privaten Schlüssel enthält, wird versucht, eine Datei “<basename>.key” mit einem privaten Schlüssel zu laden.
Das Standardverhalten ist “all”.
Beispiel:
Siehe auch: “crt”, Abschnitt 5.1 zu bind-Optionen und Abschnitt 5.2 zu Serveroptionen.
ssl-security-level <number>
Diese Direktive ermöglicht die Auswahl der OpenSSL-Sicherheitsstufe, wie unter https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_security_level.html beschrieben. Die Sicherheitsstufe wird auf alle SSL-Kontexte in HAProxy angewendet. Es werden nur Werte zwischen 0 und 5 unterstützt.
Der Standardwert hängt von Ihrer OpenSSL-Version, der Distribution und davon ab, wie die Bibliothek kompiliert wurde.
Diese Direktive erfordert mindestens OpenSSL 1.1.1.
ssl-server-verify [none|required]
Legt das Standardverhalten für die SSL-Verifizierung auf der Serverseite fest. Bei ’none’ werden Serverzertifikate nicht geprüft. Der Standardwert ist ‘required’, sofern das Verhalten nicht mit der Befehlszeilenoption ‘-dV’ erzwungen wird.
ssl-skip-self-issued-ca
Eine selbstausgestellte CA, auch x509-Root-CA genannt, bildet den Vertrauensanker für die Kettenvalidierung. Sie als Server zu senden ist nutzlos; der Client muss sie bereits besitzen. In einer Standardkonfiguration darf eine solche CA nicht in der PEM-Datei enthalten sein. Mit dieser Option können Sie sie in der PEM-Datei behalten, ohne sie an den Client zu senden. Ein Anwendungsfall ist die Bereitstellung des Ausstellers für ocsp ohne eine ‘.issuer’-Datei, wobei er über ‘issuers-chain-path’ gemeinsam genutzt werden kann. Dies betrifft alle Zertifikate ohne Zwischenzertifikate. Für BoringSSL ist diese Option nutzlos; .issuer wird ignoriert, da die ocsp-Funktionen dies nicht benötigen. Erfordert mindestens OpenSSL 1.0.2.
stats calculate-max-counters [on|off]
Aktiviert oder deaktiviert die Berechnung der Maximalwertzähler für die Statistik. Wenn Sie diese nicht benötigen, kann ihre Deaktivierung die Leistung etwas erhöhen. Der Standardwert ist on.
stats maxconn <connections>
Standardmäßig ist der Statistik-Socket auf 10 gleichzeitige Verbindungen begrenzt. Dieser Wert kann mit “stats maxconn” geändert werden.
stats socket [<address:port>|<path>] [param*]
Bindet einen UNIX-Socket an <path> oder eine TCPv4/v6-Adresse an <address:port>. Verbindungen zu diesem Socket liefern verschiedene Statistikausgaben und ermöglichen sogar die Ausführung einiger Befehle, um bestimmte Laufzeiteinstellungen zu ändern. Weitere Einzelheiten finden Sie in Abschnitt 9.3
“Unix-Socket-Befehle” des Verwaltungshandbuchs.
Alle von “bind”-Zeilen unterstützten Parameter werden unterstützt, beispielsweise um den Zugriff auf bestimmte Benutzer zu beschränken oder deren Zugriffsrechte einzuschränken. Weitere Informationen finden Sie in Abschnitt 5.1 .
stats timeout <timeout, in milliseconds>
Die standardmäßige Zeitüberschreitung des Statistik-Sockets beträgt 10 Sekunden. Dieser Wert kann mit “stats timeout” geändert werden. Der Wert muss in Millisekunden angegeben werden oder mit einer Zeiteinheit aus { us, ms, s, m, h, d } versehen sein.
stats-file <path>
Pfad zu einer erzeugten haproxy-Statistikdatei. Beim Start lädt haproxy die Werte in seine internen Zähler. Mit dem CLI-Befehl “dump stats-file” wird eine solche Statistikdatei erzeugt. Weitere Einzelheiten finden Sie im Verwaltungshandbuch.
stress-level <level>
Aktiviert alternativen Code, um die haproxy-Programmdatei gezielt zu belasten. Die Stufe ist eine ganze Zahl von 0 bis 9. Der Standardwert 0 deaktiviert jede belastende Ausführung. Die Stufen von 1 bis 9 erhöhen den Belastungsdruck auf die haproxy-Programmdatei. Beachten Sie, dass jede positive Stufe die Leistung erheblich beeinträchtigen kann. Daher sollte dies ausschließlich zur Fehlerdiagnose und auf Anforderung eines Entwicklers aktiviert werden.
strict-limits
Lässt den Prozessstart fehlschlagen, wenn ein setrlimit-Aufruf fehlschlägt. HAProxy versucht, auf Grundlage seiner Berechnungen das bestmögliche setrlimit zu setzen. Schlägt dies fehl, wird eine Warnung ausgegeben. Diese Option stellt sicher, dass HAProxy ausdrücklich fehlschlägt, wenn das Setzen dieser Limits scheitert. Sie ist standardmäßig aktiviert. Durch Voranstellen des Schlüsselworts “no” kann sie dennoch ausdrücklich deaktiviert werden.
thread-group <group> [<thread-range>...]
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für Threads einkompiliert wurde. Sie führt die Threads auf, aus denen die Thread-Gruppe <group> bestehen soll. Thread- und Gruppennummern beginnen bei 1. Thread-Bereiche werden entweder durch einzelne Thread-Nummern oder durch eine Unter- und Obergrenze angegeben, die durch einen Bindestrich ‘-’ getrennt sind (z. B. “1-16”). Nicht zugewiesene Threads werden automatisch nicht zugewiesenen Thread-Gruppen zugeordnet. Mit dieser Direktive definierte Thread-Gruppen erhalten niemals mehr Threads als angegeben. Wird dieselbe Gruppe mehrfach definiert, überschreibt die neue Definition die vorherigen. Siehe auch “nbthread” und “thread-groups”.
thread-groups <number>
Diese Einstellung ist nur verfügbar, wenn die Unterstützung für Threads einkompiliert wurde. Sie teilt die Threads von HAProxy in <number> unabhängige Gruppen auf. Derzeit ist der Standardwert 1. Mit Thread-Gruppen lässt sich die gemeinsame Nutzung von Ressourcen zwischen Threads verringern, um Konkurrenz zu begrenzen; dies erfordert allerdings etwas zusätzlichen Konfigurationsaufwand. Es ist auch die einzige Möglichkeit, mehr als 64 Threads zu verwenden, da pro Gruppe bis zu 64 Threads konfiguriert werden können. Die maximale Anzahl von Gruppen wird beim Kompilieren festgelegt und beträgt standardmäßig 16. Siehe auch “nbthread”.
thread-hard-limit <number>
Diese Einstellung erzwingt eine Obergrenze für die Anzahl der Threads, unabhängig davon, ob diese ermittelt oder konfiguriert wurde. Dies ist besonders auf Betriebssystemen mit automatischer Ermittlung der Thread-Anzahl nützlich, wenn in allgemeinen und portablen Konfigurationen weniger Threads als CPUs gewünscht sind. Während “nbthread” eine feste Thread-Anzahl erzwingt, die bei Überschreiten der verfügbaren CPUs zu einer Warnung und schlechter Leistung führt, begrenzt thread-hard-limit nur den Höchstwert. Es beschränkt die Thread-Anzahl automatisch auf diesen Wert, erhöht aber niedrigere Werte nicht. Wird “nbthread” auf einen höheren Wert festgelegt, hat thread-hard-limit Vorrang, und eine Warnung wird ausgegeben, damit die Unstimmigkeit in der Konfiguration behoben werden kann. Standardmäßig gibt es keine Begrenzung. Siehe auch “nbthread”.
uid <number>
Ändert die Benutzer-ID des Prozesses auf <number>. Es wird empfohlen, diese Benutzer-ID ausschließlich für HAProxy oder eine kleine Gruppe ähnlicher Daemons zu verwenden. HAProxy muss mit Superuser-Rechten gestartet werden, um zu einer anderen Benutzer-ID wechseln zu können. Siehe auch “gid” und “user”.
ulimit-n <number>
Setzt die maximale Anzahl von Dateideskriptoren pro Prozess auf <number>. Standardmäßig wird sie automatisch berechnet, weshalb empfohlen wird, diese Option nicht zu verwenden. Wenn lediglich die Anzahl der Dateideskriptoren begrenzt werden soll, verwenden Sie besser “fd-hard-limit”.
Beachten Sie, dass dynamische Server bei dieser automatischen Ressourcenberechnung nicht berücksichtigt werden. Bei einer großen Anzahl solcher Server kann es erforderlich sein, den Wert manuell anzugeben.
Siehe auch: fd-hard-limit, maxconn
unix-bind [ prefix <prefix> ] [ mode <mode> ] [ user <user> ] [ uid <uid> ] [ group
<group> ] [ gid <gid> ]
Legt gemeinsame Einstellungen für UNIX-Listener-Sockets fest, die in “bind”-Anweisungen deklariert werden. Dies dient hauptsächlich dazu, die Deklaration dieser UNIX-Sockets zu vereinfachen und das Fehlerrisiko zu verringern, da diese Einstellungen meist erforderlich, aber zugleich prozessspezifisch sind. Mit <prefix> lässt sich erzwingen, dass alle Socket-Pfade relativ zu diesem Verzeichnis angegeben werden. Dies kann für den Zugriff auf die chroot-Umgebung einer anderen Komponente erforderlich sein. Beachten Sie, dass diese Pfade aufgelöst werden, bevor HAProxy selbst chroot ausführt; sie sind daher absolut. <mode>, <user>, <uid>, <group> und <gid> haben dieselbe Bedeutung wie die gleichnamigen Parameter der “bind”-Anweisung. Wenn beide angegeben sind, hat die “bind”-Anweisung Vorrang. Die “unix-bind”-Einstellungen können somit als prozessweite Standardwerte betrachtet werden.
unsetenv [<name> ...]
Entfernt die als Argumente angegebenen Umgebungsvariablen. Dies kann nützlich sein, um vertrauliche Informationen zu verbergen, die bei bestimmten Vorgängen gelegentlich aus der Umgebung des Benutzers übernommen werden. Nicht vorhandene Variablen werden ohne Meldung ignoriert, sodass nach dem Vorgang sicher keine dieser Variablen mehr vorhanden ist. Die Änderungen werden sofort wirksam, sodass bereits die nächste Zeile in der Konfigurationsdatei diese Variablen nicht mehr sieht. Siehe auch “setenv”, “presetenv” und “resetenv”.
user <user name>
Ähnlich wie “uid”, verwendet jedoch die UID des Benutzernamens <user name> aus /etc/passwd. Siehe auch “uid” und “group”.
node <name>
Wie bei DNS-Namen sind nur Buchstaben, Ziffern, Bindestriche und Unterstriche erlaubt.
Diese Anweisung ist in HA-Konfigurationen nützlich, in denen mindestens zwei Prozesse oder Server dieselbe IP-Adresse nutzen. Durch unterschiedliche Knotennamen auf allen Knoten lässt sich sofort erkennen, welcher Server den Datenverkehr verarbeitet.
wurfl-cache-size <size>
Legt die Größe des WURFL-User-Agent-Caches fest. Für schnellere Abfragen werden bereits verarbeitete User-Agents in einem LRU-Cache vorgehalten:
- “0” : Es wird kein Cache verwendet.
<size>: Größe des lru-Caches in Elementen.
Beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_WURFL=1 kompiliert wurde.
wurfl-data-file <file path>
Der Pfad der WURFL-Datendatei zur Bereitstellung von Geräteerkennungsdiensten. Die Datei sollte mit den entsprechenden Berechtigungen für HAProxy zugänglich sein.
Beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_WURFL=1 kompiliert wurde.
wurfl-information-list [<capability>]*
Eine durch Leerzeichen getrennte Liste von WURFL-Capabilities, virtuellen Capabilities und Eigenschaftsnamen, die in eingefügten Headern verwendet werden sollen. Eine vollständige Liste der Namen von Capabilities und virtuellen Capabilities ist auf der Website von Scientiamobile verfügbar:
Gültige WURFL-Eigenschaften sind:
-
wurfl_id Enthält die Geräte-ID des gefundenen Geräts.
-
wurfl_root_id Enthält die Root-Geräte-ID des gefundenen Geräts.
-
wurfl_isdevroot Gibt an, ob das gefundene Gerät ein Root-Gerät ist. Mögliche Werte sind “TRUE” oder “FALSE”.
-
wurfl_useragent Der ursprüngliche User-Agent dieser konkreten Webanfrage.
-
wurfl_api_version Enthält eine Zeichenfolge, die die aktuell verwendete Libwurfl-API-Version darstellt.
-
wurfl_info Eine Zeichenfolge mit Informationen zur eingelesenen wurfl.xml und ihrem vollständigen Pfad.
-
wurfl_last_load_time Enthält den UNIX-Zeitstempel des letzten erfolgreichen Ladens von WURFL.
-
wurfl_normalized_useragent Der normalisierte User-Agent.
Beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_WURFL=1 kompiliert wurde.
wurfl-information-list-separator <char>
Ein Zeichen, das Werte in einem Antwort-Header mit WURFL-Ergebnissen trennt. Falls es nicht gesetzt ist, wird standardmäßig ein Komma (’,’) verwendet.
Beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_WURFL=1 kompiliert wurde.
wurfl-patch-file [<file path>]
Eine Liste von Pfaden zu WURFL-Patchdateien. Beachten Sie, dass Patches beim Start und somit vor chroot geladen werden.
Beachten Sie, dass diese Option nur verfügbar ist, wenn HAProxy mit USE_WURFL=1 kompiliert wurde.
3.2. Leistungsoptimierung
busy-polling
In manchen Situationen, insbesondere bei niedrigen Latenzanforderungen auf Prozessoren mit variabler Taktfrequenz oder beim Betrieb in virtuellen Maschinen, geht der Prozessor jedes Mal in den Ruhezustand oder wird für längere Zeit einer anderen VM zugeteilt, wenn der Prozess mit dem Poller auf I/O wartet. Dies verursacht übermäßig hohe Latenzen. Diese Option verhindert, dass der Prozessor in den Ruhezustand wechselt, indem sie für die Poller stets eine Zeitüberschreitung von null verwendet. Dies verringert die Latenz erheblich (beobachtet wurden 30 bis 100 Mikrosekunden), birgt jedoch das Risiko einer Überhitzung des Prozessors. Die Option kann auch mit Threads verwendet werden. In diesem Fall können falsch gebundene Threads stark miteinander konkurrieren, was zu schlechterer Leistung und hohen Werten in den Feldern für entzogene CPU-Zeit in der Ausgabe von “show info” führt; daran lassen sich die falsch konfigurierten Threads erkennen. Bei Verwendung dieser Option darf der Prozess nicht auf demselben Prozessor wie die Netzwerk-Interrupts laufen. Außerdem sollte die Option möglichst nicht auf mehreren CPU-Threads verwendet werden, die sich denselben Kern teilen. Sie ist standardmäßig deaktiviert. Wenn sie aktiviert wurde, kann sie dennoch durch Voranstellen des Schlüsselworts “no” ausdrücklich deaktiviert werden. Die Poller “select” und “poll” ignorieren sie.
Bei einem nahtlosen Neuladen wird diese Option für alte Prozesse automatisch deaktiviert. Dadurch wird übermäßige CPU-Konkurrenz vermieden, wenn mehrere Prozesse noch eine Zeit lang auf das Ende ihrer bestehenden Verbindungen warten.
max-spread-checks <delay in milliseconds>
Standardmäßig versucht HAProxy, den Beginn der Zustandsprüfungen über das kleinste Prüfintervall aller Server einer Serverfarm zu verteilen. Damit soll eine geballte Belastung der auf demselben Server laufenden Dienste vermieden werden. Bei großen Prüfintervallen (10 Sekunden oder mehr) dauert es jedoch einige Zeit, bis die letzten Server der Serverfarm erstmals geprüft werden, was problematisch sein kann. Dieser Parameter erzwingt eine Obergrenze für die Verzögerung zwischen der ersten und der letzten Prüfung, auch wenn die Prüfintervalle der Server größer sind. Kürzere Prüfintervalle der Server werden jedoch weiterhin eingehalten.
maxcompcpuusage <number>
Legt die maximale CPU-Auslastung fest, die HAProxy erreichen darf, bevor die Komprimierung für neue Anfragen eingestellt oder die Komprimierungsstufe laufender Anfragen verringert wird. Dies funktioniert wie ‘maxcomprate’, misst jedoch die CPU-Auslastung anstelle der Bandbreite eingehender Daten. Der Wert wird als Prozentsatz der von HAProxy genutzten CPU angegeben. Der Wert 100 deaktiviert die Begrenzung. Der Standardwert ist 100. Ein niedrigerer Wert verhindert, dass die Komprimierungsarbeit den gesamten Prozess verlangsamt und hohe Latenzen verursacht.
maxcomprate <number>
Setzt die maximale Eingaberate für die Komprimierung pro Prozess auf <number> Kilobyte pro Sekunde. Wird das Maximum erreicht, wird die Komprimierungsstufe jedes Streams während seiner Verarbeitung verringert. Ist das Maximum bereits zu Beginn eines Streams erreicht, wird dieser überhaupt nicht komprimiert. Ist das Maximum nicht erreicht, wird die Komprimierungsstufe bis auf tune.comp.maxlevel erhöht. Der Wert null bedeutet, dass es keine Begrenzung gibt; dies ist der Standardwert.
maxconn <number>
Setzt die maximale Anzahl gleichzeitiger Verbindungen pro Prozess auf <number>. Dies entspricht dem Befehlszeilenargument “-n”. Der über “-n” angegebene Wert hat Vorrang vor dem im globalen Abschnitt gesetzten maxconn-Wert. Der Haproxy-Prozess kann auch mit der Kompilierungsvariablen SYSTEM_MAXCONN erstellt werden, die dann als systemweiter Höchstwert für maxconn dient. Auch diese Grenze kann zur Laufzeit mit dem Befehlszeilenargument “-n” überschritten werden, falls SYSTEM_MAXCONN gesetzt ist. Proxys nehmen keine weiteren Verbindungen an, sobald maxconn erreicht ist. Das weiche Dateideskriptorlimit des Prozesses (abrufbar mit dem Befehl “ulimit -n”) wird anhand des angegebenen maxconn-Werts automatisch angepasst. Siehe auch “ulimit-n”. Hinweis: Der Poller “select” kann auf einigen Plattformen nicht zuverlässig mehr als 1024 Dateideskriptoren verwenden. Wenn Ihre Plattform nur select unterstützt und beim Start “select FAILED” meldet, müssen Sie maxconn so weit verringern, bis es funktioniert (im Allgemeinen auf etwas unter 500). Wenn maxconn nicht gesetzt ist, wird der Wert anhand der aktuellen Dateideskriptorlimits automatisch berechnet, die der Befehl “ulimit -nH” meldet (verwendet wird der größere der harten und weichen Werte). Anschließend wird der automatische Wert gegebenenfalls durch “fd-hard-limit” und durch ein mit der Befehlszeilenoption “-m” erzwungenes Speicherlimit verringert. Der automatische Wert hängt außerdem von der Puffergröße, dem für die Komprimierung zugewiesenen Speicher, der SSL-Cachegröße sowie der Verwendung von SSL und dem zugehörigen maxsslconn ab (das ebenfalls automatisch bestimmt werden kann).
Siehe auch: fd-hard-limit, ulimit-n
maxconnrate <number>
Setzt die maximale Anzahl von Verbindungen pro Sekunde und Prozess auf <number>. Proxys nehmen keine weiteren Verbindungen an, sobald diese Grenze erreicht ist. Damit lässt sich die Gesamtkapazität unabhängig von der Kapazität jedes einzelnen Frontends begrenzen. Beachten Sie, dass dies nur als Schutzmaßnahme für den Dienst eingesetzt werden kann: Bei Erreichen der Grenze ist eine faire Aufteilung zwischen den Frontends nicht unbedingt gewährleistet. Daher ist es sinnvoll, jedes Frontend zusätzlich auf einen Wert nahe seinem erwarteten Anteil zu begrenzen. Auch eine Verringerung von tune.maxaccept kann die Verteilung gerechter machen.
maxpipes <number>
Setzt die maximale Anzahl von Pipes pro Prozess auf <number>. Derzeit werden Pipes nur für kernelbasiertes TCP-Splicing verwendet. Da eine Pipe zwei Dateideskriptoren enthält, wird der Wert von “ulimit-n” entsprechend erhöht. Der Standardwert ist maxconn/4, was selbst für die meisten hohen Belastungen mehr als ausreichend erscheint. Der Splice-Code weist Pipes dynamisch zu, gibt sie wieder frei und kann auf normales Kopieren zurückfallen. Ein zu niedriger Wert kann daher lediglich die Leistung beeinträchtigen.
maxsessrate <number>
Setzt die maximale Anzahl von Sitzungen pro Sekunde und Prozess auf <number>. Proxys nehmen keine weiteren Verbindungen an, sobald diese Grenze erreicht ist. Damit lässt sich die Gesamtkapazität unabhängig von der Kapazität jedes einzelnen Frontends begrenzen. Beachten Sie, dass dies nur als Schutzmaßnahme für den Dienst eingesetzt werden kann: Bei Erreichen der Grenze ist eine faire Aufteilung zwischen den Frontends nicht unbedingt gewährleistet. Daher ist es sinnvoll, jedes Frontend zusätzlich auf einen Wert nahe seinem erwarteten Anteil zu begrenzen. Auch eine Verringerung von tune.maxaccept kann die Verteilung gerechter machen.
maxsslconn <number>
Setzt die maximale Anzahl gleichzeitiger SSL-Verbindungen pro Prozess auf <number>. Standardmäßig gibt es keine SSL-spezifische Begrenzung; die globale Einstellung maxconn gilt somit für alle Verbindungen. Diese Begrenzung verhindert, dass openssl zu viel Speicher verwendet und abstürzt, wenn malloc NULL zurückgibt (da dieser Fall leider nicht zuverlässig geprüft wird). Beachten Sie, dass die Grenze sowohl für eingehende als auch für ausgehende Verbindungen gilt. Eine Verbindung, die entschlüsselt und anschließend wieder verschlüsselt wird, zählt daher als 2 SSL-Verbindungen. Wenn dieser Wert nicht gesetzt ist, aber ein Speicherlimit erzwungen wird, wird er automatisch anhand des Speicherlimits, von maxconn, der Puffergröße, des für die Komprimierung zugewiesenen Speichers, der SSL-Cachegröße und der Verwendung von SSL in Frontends, Backends oder beiden berechnet. Wenn bei vorhandenem Speicherlimit weder maxconn noch maxsslconn angegeben sind, passt HAProxy diese Werte automatisch so an, dass 100% der Verbindungen gefahrlos über SSL erfolgen können. Dabei werden die Seiten berücksichtigt, auf denen SSL aktiviert ist (Frontend, Backend oder beide).
maxsslrate <number>
Setzt die maximale Anzahl von SSL-Sitzungen pro Sekunde und Prozess auf <number>. SSL-Listener nehmen keine weiteren Verbindungen an, sobald diese Grenze erreicht ist. Damit lässt sich die gesamte SSL-CPU-Auslastung unabhängig von der Kapazität jedes einzelnen Frontends begrenzen. Beachten Sie, dass dies nur als Schutzmaßnahme für den Dienst eingesetzt werden kann: Bei Erreichen der Grenze ist eine faire Aufteilung zwischen den Frontends nicht unbedingt gewährleistet. Daher ist es sinnvoll, jedes Frontend zusätzlich auf einen Wert nahe seinem erwarteten Anteil zu begrenzen. Beachten Sie außerdem, dass Sitzungen vor dem Eintritt in den SSL-Stack gezählt werden, nicht danach. Dies schützt den Stack auch vor fehlerhaften Handshakes. Auch eine Verringerung von tune.maxaccept kann die Verteilung gerechter machen.
maxzlibmem <number>
Legt die maximale Menge an RAM in Megabyte fest, die zlib pro Prozess verwenden darf. Sobald diese Menge erreicht ist, werden neue Streams nicht komprimiert, solange kein RAM verfügbar ist. Bei 0 gibt es keine Begrenzung. Der Standardwert ist 0. Der Wert kann in Byte über den UNIX-Socket mit “show info” in der Zeile “MaxZlibMemUsage” abgefragt werden; der von zlib verwendete Speicher wird unter “ZlibMemUsage” ebenfalls in Byte angezeigt.
no-memory-trimming
Deaktiviert das Freigeben ungenutzten Speichers (“malloc_trim”) zu den wenigen Zeitpunkten, an denen versucht wird, große Speichermengen zurückzugewinnen (bei Speichermangel oder beim Neuladen). Dabei wird der Speicherzuweiser des Systems gezwungen, alle ungenutzten Bereiche zu durchsuchen und freizugeben. Dies gilt im Allgemeinen als sinnvolle Maßnahme, um einem neuen Prozess mehr Speicher zu überlassen, den der alte voraussichtlich kaum noch nutzen wird. Auf einigen Systemen mit Zehntausenden bis Hunderttausenden gleichzeitigen Verbindungen kann jedoch starke Speicherfragmentierung auftreten, wodurch die Freigabe extrem lange dauert. Währenddessen fließt kein Datenverkehr mehr durch den Prozess, neue Verbindungen werden nicht mehr angenommen, einige Zustandsprüfungen können sogar fehlschlagen, und der Watchdog kann den nicht reagierenden Prozess beenden, wodurch ein riesiges Speicherabbild entsteht. Falls dies auftritt, wird empfohlen, mit dieser Option die Speicherbereinigung zu deaktivieren und nicht länger zu versuchen, dem neuen Prozess Speicher zu überlassen. Fortschrittliche Speicherzuweiser sind von diesem Problem normalerweise nicht betroffen.
noepoll
Deaktiviert die Verwendung des Ereignisabfragesystems “epoll” unter Linux. Dies entspricht dem Befehlszeilenargument “-de”. Als nächstes Abfragesystem wird im Allgemeinen “poll” verwendet. Siehe auch “nopoll”.
noevports
Deaktiviert die Verwendung des Ereignisabfragesystems event ports auf SunOS-Systemen, die von Solaris 10 oder höher abgeleitet sind. Dies entspricht dem Befehlszeilenargument “-dv”. Als nächstes Abfragesystem wird im Allgemeinen “poll” verwendet. Siehe auch “nopoll”.
nogetaddrinfo
Deaktiviert die Verwendung von getaddrinfo(3) zur Namensauflösung. Dies entspricht dem Befehlszeilenargument “-dG”. Stattdessen wird das veraltete gethostbyname(3) verwendet.
nokqueue
Deaktiviert die Verwendung des Ereignisabfragesystems “kqueue” unter BSD. Dies entspricht dem Befehlszeilenargument “-dk”. Als nächstes Abfragesystem wird im Allgemeinen “poll” verwendet. Siehe auch “nopoll”.
noktls
Deaktiviert die Verwendung von ktls. Dies entspricht dem Befehlszeilenargument “-dT”.
nopoll
Deaktiviert die Verwendung des Ereignisabfragesystems “poll”. Dies entspricht dem Befehlszeilenargument “-dp”. Als nächstes Abfragesystem wird “select” verwendet. Es sollte niemals erforderlich sein, “poll” zu deaktivieren, da es auf allen von HAProxy unterstützten Plattformen verfügbar ist. Siehe auch “nokqueue”, “noepoll” und “noevports”.
noreuseport
Deaktiviert die Verwendung von SO_REUSEPORT; siehe socket(7). Dies entspricht dem Befehlszeilenargument “-dR”.
nosplice
Deaktiviert kernelbasiertes TCP-Splicing zwischen Sockets unter Linux. Dies entspricht dem Befehlszeilenargument “-dS”. Daten werden dann mit herkömmlichen und portableren recv/send-Aufrufen kopiert. Kernelbasiertes TCP-Splicing ist auf einige sehr neue Varianten des Kernels 2.6 beschränkt. Die meisten Versionen zwischen 2.6.25 und 2.6.28 sind fehlerhaft und leiten beschädigte Daten weiter; sie dürfen daher nicht verwendet werden. Diese Option erleichtert es, Kernel-Splicing im Zweifelsfall global zu deaktivieren. Siehe auch “option splice-auto”, “option splice-request” und “option splice-response”.
profiling.memory { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) die Speicherprofilierung pro Funktion. Dabei werden Nutzungsstatistiken der malloc/calloc/realloc/free-Aufrufe im gesamten Prozess einschließlich der Bibliotheken erfasst und über den CLI-Befehl “show profiling” ausgegeben. Dies ist vor allem für Fälle gedacht, in denen eine ungewöhnliche Speichernutzung beobachtet wird, die sich nicht durch die Pools erklären lässt, und weitere Informationen benötigt werden. Die Leistungseinbuße liegt typischerweise bei etwa 1%, auf Rechnern mit vielen Threads möglicherweise etwas höher; daher eignet sich dies normalerweise für den Produktionseinsatz. Dasselbe lässt sich zur Laufzeit mit dem CLI-Befehl “set profiling memory” erreichen; siehe das Verwaltungshandbuch.
profiling.tasks { auto | on | off | lock | no-lock | memory | no-memory }*
Aktiviert (‘on’) oder deaktiviert (‘off’) die CPU-Profilierung pro Task. Bei ‘auto’ wird die Profilierung auf einem Thread automatisch aktiviert, sobald dessen durchschnittliche Latenz im Aktivitätsfeld “avg_loop_us” 1000 Mikrosekunden oder mehr erreicht. Sie wird automatisch deaktiviert, wenn die Latenz wieder unter 990 Mikrosekunden fällt (dieser Wert ist ein Mittelwert über die letzten 1024 Schleifendurchläufe, verändert sich also nicht schnell und glättet kurze Spitzen deutlich). Die Profilierung kann sich auf überlasteten Systemen, in Containern oder virtuellen Maschinen auch gelegentlich von selbst aktivieren, ebenso wenn das System auslagert (was auf einem Load-Balancer unter keinen Umständen geschehen darf).
Bei aktivierter Task-Profilierung kann HAProxy zusätzlich erfassen, wie lange jeder Task eine Sperre hält oder auf eine Sperre wartet, sowie die Wartezeit auf eine erfolgreiche Speicherzuweisung bei einem Cache-Miss im Pool. Dies kann helfen, bestimmte Latenzursachen zu verstehen. Dazu können zusätzlich die Schlüsselwörter “lock” (Erfassung von Sperrzeiten aktivieren), “no-lock” (deaktivieren), “memory” (Erfassung der Speicherzuweisungszeiten aktivieren) oder “no-memory” (deaktivieren) angegeben werden. Standardmäßig sind diese nicht aktiviert, da sie auf stark ausgelasteten Systemen einen nicht unerheblichen CPU-Aufwand verursachen können (3-10%). Beachten Sie, dass dieser Zusatzaufwand nur entsteht, wenn die Profilierung tatsächlich läuft. Im Modus “auto” tritt er somit nur auf, wenn HAProxy die Profilierung aktiviert.
Die CPU-Profilierung pro Task kann sehr hilfreich sein, um festzustellen, wofür Zeit aufgewendet wird und welche Anfragen welche Auswirkungen auf andere Anfragen haben. Ihre Aktivierung beeinträchtigt die Gesamtleistung typischerweise um weniger als 1%. Daher wird empfohlen, den Standardwert ‘auto’ beizubehalten, sodass sie nur arbeitet, wenn ein Problem erkannt wird. Diese Funktion erfordert ein System, das den Systemaufruf clock_gettime(2) mit den Uhrenkennungen CLOCK_MONOTONIC und CLOCK_THREAD_CPUTIME_ID unterstützt; andernfalls beträgt die gemeldete Zeit null. Diese Option kann zur Laufzeit mit “set profiling” in der CLI geändert werden.
spread-checks <0..50, in percent>
Manchmal ist es sinnvoll, Agenten- und Zustandsprüfungen nicht in exakt gleichmäßigen Abständen an Server zu senden, beispielsweise wenn sich viele logische Server auf demselben physischen Server befinden. Mit diesem Parameter kann dem Prüfintervall eine zufällige Abweichung zwischen 0 und +/- 50% hinzugefügt werden. Werte zwischen 2 und 5 scheinen gute Ergebnisse zu liefern. Der Standardwert bleibt 0.
ssl-engine <name> [algo <comma-separated list of algorithms>]
Setzt die OpenSSL-Engine auf <name>. Eine Liste gültiger Werte für <name> erhalten Sie mit dem Befehl “openssl engine”. Diese Anweisung kann mehrfach verwendet werden; dadurch werden mehrere Kryptografie-Engines aktiviert. Die Angabe einer nicht unterstützten Engine verhindert den Start von HAProxy. Beachten Sie, dass viele Engines eine niedrigere HTTPS-Leistung liefern als reine Software auf modernen Prozessoren. Der optionale Befehl “algo” legt mit der OPENSSL-Funktion ENGINE_set_default_string() die Standardalgorithmen fest, die eine ENGINE bereitstellt. Der Wert “ALL” verwendet die Engine für sämtliche kryptografischen Operationen. Wird keine algo-Liste angegeben, wird “ALL” verwendet. Es kann eine durch Kommas getrennte Liste verschiedener Algorithmen angegeben werden, darunter RSA, DSA, DH, EC, RAND, CIPHERS, DIGESTS, PKEY, PKEY_CRYPTO, PKEY_ASN1. Dies ist dasselbe Format wie in der openssl-Konfigurationsdatei:
https://www.openssl.org/docs/man1.0.2/apps/config.html
Mit HAProxy Version 2.6 wurde die Engine-Unterstützung im Standard-Build deaktiviert. Diese Option ist nur verfügbar, wenn HAProxy mit entsprechender Unterstützung erstellt wurde. Falls ssl-engine benötigt wird, kann HAProxy mit dem Flag USE_ENGINE=1 neu kompiliert werden.
ssl-mode-async
Fügt dem SSL-Kontext den Modus SSL_MODE_ASYNC hinzu. Dies ermöglicht asynchrone TLS-I/O-Operationen, wenn SSL-Engines mit entsprechender Unterstützung verwendet werden. Die aktuelle Implementierung unterstützt maximal 32 Engines. Die Openssl-ASYNC-API unterstützt keine verschiebbaren Lese-/Schreibpuffer und ist nicht mit der Pufferverwaltung von HAProxy vereinbar. Daher ist der asynchrone Modus für Lese-/Schreiboperationen deaktiviert (er ist nur während des anfänglichen Handshakes und bei Handshakes zur Neuverhandlung aktiviert).
tune.applet.zero-copy-forwarding { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) die kopierfreie Datenweiterleitung für Applets. Sie ist standardmäßig aktiviert.
Siehe auch: tune.disable-zero-copy-forwarding.
tune.buffers.limit <number>
Legt eine harte Obergrenze für die Anzahl der Puffer fest, die pro Prozess zugewiesen werden dürfen. Der Standardwert ist null und bedeutet unbegrenzt. Die Grenze wird automatisch so angepasst, dass die für Notfälle reservierten Puffer berücksichtigt werden; der Benutzer muss daher keine komplizierten Berechnungen durchführen. Das Erzwingen dieses Werts kann besonders nützlich sein, um den Speicherverbrauch eines Prozesses zu begrenzen und zugleich ein vernünftiges Verhalten beizubehalten. Wird diese Grenze erreicht, wartet ein Task, der einen Puffer anfordert, zunächst auf die Freigabe eines anderen Puffers. Solange die Grenzen sinnvoll gewählt sind, ist die Wartezeit meist sehr kurz und nicht wahrnehmbar. Einige historische Einschränkungen haben diesen Mechanismus jedoch über mehrere Versionen hinweg geschwächt. Es ist bekannt, dass manche Tasks bei anhaltendem Mangel in bestimmten Situationen bis zum Ablauf ihrer Zeitüberschreitung blockieren können. Daher ist es sicherer, diese Einstellung nur zu verwenden, wenn sie unbedingt erforderlich ist.
tune.buffers.reserve <number>
Legt die Anzahl der Puffer pro Thread fest, die vorab zugewiesen und ausschließlich für Situationen mit Speichermangel reserviert werden, in denen Speicherzuweisungen fehlschlagen. Der Mindestwert ist 0, der Standardwert 4. Es gibt keinen Grund für Benutzer, diesen Wert zu ändern, sofern nicht ein Entwickler des Kernteams dies aus einem sehr speziellen Grund empfiehlt.
tune.bufsize <size>
Setzt die Puffergröße auf diesen Wert (in Byte). Niedrigere Werte ermöglichen mehr gleichzeitige Streams bei derselben RAM-Menge, höhere Werte ermöglichen den Betrieb einiger Anwendungen mit sehr großen Cookies. Der Standardwert ist 16384 und kann beim Kompilieren geändert werden. Es wird dringend empfohlen, den Standardwert beizubehalten: Sehr niedrige Werte führen dazu, dass einige Dienste wie die Statistikfunktion nicht mehr funktionieren, während höhere Werte den Speicherverbrauch erhöhen und möglicherweise den gesamten verfügbaren Systemspeicher aufbrauchen. Zumindest der globale Parameter maxconn sollte um denselben Faktor verringert werden, um den dieser Wert erhöht wird. Außerdem erfordert HTTP/2 einen Wert von mindestens 16384. Der Wert muss außerdem unter 256 MB (268435456 Byte) liegen. Ist der Headerblock einer HTTP-Anfrage größer als (tune.bufsize - tune.maxrewrite), gibt HAProxy den Fehler HTTP 400 (Bad Request) zurück. Ist entsprechend der Headerblock einer HTTP-Antwort größer als dieser Wert, gibt HAProxy HTTP 502 (Bad Gateway) zurück. Beachten Sie, dass der mit diesem Parameter gesetzte Wert auf 32-Bit-Rechnern automatisch auf das nächste Vielfache von 8 und auf 64-Bit-Rechnern auf das nächste Vielfache von 16 aufgerundet wird. Siehe auch: tune.bufsize.large, tune.bufsize.small.
tune.bufsize.large <size>
Legt die Größe großer Puffer in Byte fest. Standardmäßig ist die Unterstützung großer Puffer nicht aktiviert; sie muss ausdrücklich durch Setzen dieses Werts aktiviert werden.
Diese Puffer sind für bestimmte Situationen vorgesehen, in denen mehr Daten gepuffert werden müssen, ohne die Größe regulärer Puffer zu ändern. Große Puffer werden nicht implizit verwendet. Siehe auch: tune.bufsize.
Beachten Sie, dass bei konfigurierten großen Puffern beim Start für jeden Thread drei spezielle große Puffer zur internen Verwendung zugewiesen werden.
tune.bufsize.small <size>
Legt die Größe kleiner Puffer in Byte fest. Der Standardwert ist 1024.
Diese Puffer sind für bestimmte Situationen vorgesehen, in denen der Speicherverbrauch begrenzt ist, die Zuweisung eines vollständigen Puffers jedoch unnötig erscheint. Falls ein kleiner Puffer nicht ausreicht, wird automatisch eine erneute Zuweisung durchgeführt, um auf einen Puffer der Standardgröße zu wechseln.
Derzeit verwendet nur das HTTP/3-Protokoll kleine Puffer automatisch, um die Antwort-Header zu senden. Ansonsten kann ihre Unterstützung für bestimmte Proxys über die Option “use-small-buffers” aktiviert werden. Siehe auch: tune.bufsize.
Siehe auch: option use-small-buffers
tune.cli.max-payload-size <size>
Legt die maximal zulässige Größe der Nutzdaten fest, die einem Befehl in der CLI übergeben werden.
In der CLI ist eine Befehlszeile durch die Puffergröße begrenzt. Alle Befehle und ihre Argumente müssen daher zur Verarbeitung in einen Puffer passen. Ausgenommen sind die Nutzdaten, die dem letzten Befehl der Befehlszeile übergeben werden können. Für diese Nutzdaten kann bei Bedarf ein eigener Speicherbereich zugewiesen werden. Ihre Größe wird durch diesen Parameter begrenzt. Der Standardwert ist 128KB.
Obwohl dieser Wert für die meisten Anwendungen ausreichen sollte, muss ein neuer Wert bei einer Änderung sorgfältig gewählt werden. Ein sehr hoher Wert kann die Leistung von HAProxy beeinträchtigen. Je nach Befehl kann die Verarbeitung sehr großer Nutzdaten lange dauern und möglicherweise den Watchdog auslösen.
Einzelheiten zur CLI finden Sie im Verwaltungshandbuch.
tune.comp.maxlevel <number>
Legt die maximale Komprimierungsstufe fest. Die Komprimierungsstufe beeinflusst die CPU-Auslastung während der Komprimierung. Dieser Wert beeinflusst die CPU-Auslastung während der Komprimierung. Jeder Stream mit Komprimierung initialisiert den Komprimierungsalgorithmus mit diesem Wert. Der Standardwert ist 1.
tune.defaults.purge
Zur Unterstützung dynamischer Backends bleiben nun alle benannten defaults-Abschnitte nach dem Einlesen im Speicher. Dies ist erforderlich, da ein zur Laufzeit hinzugefügtes Backend seine Konfiguration auf einem benannten defaults-Abschnitt aufbauen muss.
Bei vielen defaults-Instanzen kann dies erheblichen Speicher beanspruchen. Wenn die Funktion für dynamische Backends nicht benötigt wird, kann in diesem Fall mit dieser Option das Löschen der defaults-Abschnitte nach dem Einlesen erzwungen werden. Referenzierte defaults-Abschnitte müssen jedoch weiterhin erhalten bleiben, wenn sie Einstellungen enthalten, die von den referenzierenden Proxys nicht kopiert werden können. Dies ist beispielsweise der Fall, wenn der defaults-Abschnitt TCP/HTTP-Regeln oder einen tcpcheck-Regelsatz definiert.
tune.disable-fast-forward
Deaktiviert die schnelle Datenweiterleitung. Dieser Mechanismus optimiert die Weiterleitung, indem Daten direkt von einer Seite zur anderen übertragen werden, ohne den Stream aufzuwecken. Mit dieser Direktive kann die Optimierung deaktiviert werden. Beachten Sie, dass dadurch auch jegliches kernelbasierte TCP-Splicing sowie die kopierfreie Weiterleitung deaktiviert werden. Dieser Befehl ist nicht für den regulären Einsatz vorgesehen und wird im Allgemeinen nur von Entwicklern bei komplexen Fehlerdiagnosen empfohlen.
tune.disable-zero-copy-forwarding
Deaktiviert die kopierfreie Datenweiterleitung global. Dieser Mechanismus optimiert die schnelle Datenweiterleitung, indem er die Verwendung des Kanalpuffers vermeidet. Mit dieser Direktive kann die Optimierung deaktiviert werden. Beachten Sie, dass dadurch auch jegliches kernelbasierte TCP-Splicing deaktiviert wird.
Siehe auch: tune.pt.zero-copy-forwarding, tune.applet.zero-copy-forwarding, tune.h1.zero-copy-fwd-recv, tune.h1.zero-copy-fwd-send, tune.h2.zero-copy-fwd-send, tune.quic.zero-copy-fwd-send
tune.epoll.mask-events <event[,...]>
Im Laufe der Entwicklung von HAProxy traten einige komplexe Probleme auf, die durch Fehler im epoll-Mechanismus des Linux-Kernels verursacht wurden. Diese Probleme sind üblicherweise sehr selten und außerhalb der Umgebung des Meldenden nicht reproduzierbar. Sie lassen sich mitunter nur umgehen, indem epoll deaktiviert und stattdessen poll verwendet wird, was für Hochleistungsumgebungen nicht zufriedenstellend ist. Die Probleme betreffen jeweils nur sehr spezielle und seltene Ereignistypen. Eine Möglichkeit, diese zu maskieren, kann daher eine akzeptablere Umgehungslösung bieten. Diese Option erlaubt es, einige ungewöhnliche Ereignisse ohne Meldung zu ignorieren und durch ein Eingabeereignis zu ersetzen, das ein nicht näher bestimmtes eingehendes Ereignis meldet. Dadurch werden an bestimmten Stellen die schnellen Fehlerverarbeitungspfade vermieden und nur die üblichen Verarbeitungspfade verwendet. Dies sollte niemals verwendet werden, sofern nicht ein Experte zur Diagnose oder Umgehung eines Kernel-Fehlers dazu auffordert.
Die Option erwartet ein einziges Argument: eine durch Kommas getrennte Liste von Wörtern, die jeweils ein zu maskierendes Ereignis bezeichnen. Derzeit werden folgende Ereignisse unterstützt: - “err”: maskiert das Ereignis EPOLLERR - “hup”: maskiert EPOLLHUP-Ereignisse - “rdhup”: maskiert EPOLLRDHUP-Ereignisse
Beispiel:
tune.events.max-events-at-once <number>
Legt die Anzahl von Ereignissen fest, die ein asynchroner Task-Handler (aus der event_hdl-API) auf einmal verarbeiten darf. <number> sollte zwischen 1 und 10000 liegen. Ein hoher Wert kann durch die ununterbrochene, umfangreiche Arbeit des Tasks zu Konkurrenz zwischen Threads führen. Ein niedriger Wert kann dagegen dazu führen, dass der Task ständig neu eingeplant wird, weil er pro Durchlauf nicht genügend Ereignisse verarbeiten kann und mit dem Ereigniserzeuger nicht Schritt hält. Der Standardwert kann beim Kompilieren festgelegt werden; andernfalls beträgt er 100.
tune.fail-alloc
Wenn mit DEBUG_FAIL_ALLOC kompiliert oder mit “-dMfail” gestartet wurde, gibt dies die prozentuale Wahrscheinlichkeit an, mit der ein Zuweisungsversuch fehlschlägt. Der Wert muss zwischen 0 (keine Fehlschläge) und 100 (keine Erfolge) liegen. Dies ist zur Fehlerdiagnose nützlich und stellt sicher, dass Fehler bei der Speicherzuweisung angemessen behandelt werden. Ohne Einstellung beträgt der Anteil 0. Die Befehlszeilenoption “-dMfail” setzt ihn jedoch automatisch auf eine Fehlerquote von 1%, sodass zum Testen keine Konfigurationsänderung erforderlich ist.
tune.fd.edge-triggered { on | off } [ EXPERIMENTAL ]
Aktiviert (‘on’) oder deaktiviert (‘off’) den flankengesteuerten Abfragemodus für FDs, die ihn unterstützen. Derzeit wird dies nur mit epoll unterstützt. Es kann die Anzahl der epoll_ctl()-Aufrufe deutlich verringern und in bestimmten Szenarien die Leistung leicht verbessern. Die Funktion ist noch experimentell, kann bei verbleibenden Fehlern zum Stillstand von Verbindungen führen und ist standardmäßig deaktiviert.
tune.glitches.kill.cpu-usage <number>
Legt die minimale CPU-Auslastung zwischen 0 und 100 fest, ab der Verbindungen mit zu vielen Unregelmäßigkeiten beendet werden. Dies gilt für Verbindungen, die ihre glitches-threshold-Grenze erreicht haben. In Umgebungen, in denen sehr lange bestehende Verbindungen häufig fehlerhaftes Verhalten zeigen, ohne die Leistung zu beeinträchtigen, kann es sinnvoll sein, sie trotz dieses Verhaltens beizubehalten, solange sie keinen Schaden verursachen, und sie erst bei zunehmender CPU-Auslastung zu beenden. Dieser Parameter legt fest, dass eine Verbindung, die ihre Unregelmäßigkeitsschwelle erreicht, aktiv beendet wird, wenn die CPU-Auslastung mindestens diesen Wert erreicht, niemals jedoch darunter. Beachten Sie, dass die CPU-Auslastung pro Thread gemessen wird, sodass auch eine einzelne fehlerhaft arbeitende Verbindung beendet werden kann. Der Standardwert ist null; eine Verbindung wird dann beim Erreichen ihrer glitches-threshold-Grenze automatisch beendet. Als Faustregel kann der Wert auf das Doppelte der üblichen CPU-Auslastung oder auf die übliche CPU-Auslastung zuzüglich der Hälfte des ungenutzten Anteils gesetzt werden (wenn die CPU üblicherweise 60% erreicht, kann hier beispielsweise 80 sinnvoll sein). Dieser Parameter hat ohne tune.h2.fe.glitches-threshold, tune.quic.fe.sec.glitches-threshold oder tune.h1.fe.glitches-threshold keine Wirkung. Siehe auch die globalen Parameter “tune.h2.fe.glitches-threshold”, “tune.h1.fe.glitches-threshold” und “tune.quic.fe.sec.glitches-threshold”.
tune.h1.be.glitches-threshold <number>
Legt die Schwelle für die Anzahl von Unregelmäßigkeiten auf einer HTTP/1-Backend-Verbindung fest, nach deren Überschreiten die Verbindung automatisch beendet wird. Dadurch lassen sich fehlerhaft arbeitende Verbindungen automatisch beenden, ohne dafür explizite Regeln schreiben zu müssen. Der Standardwert ist null: Es wird keine Schwelle gesetzt, sodass kein Ereignis zum Schließen einer Verbindung führt. Typische Ereignisse sind fehlerhaft formatierte Header, die dennoch durch “accept-unsafe-violations-in-http-response” akzeptiert wurden. Ein von null verschiedener Wert sollte vermutlich im Hunderter- oder Tausenderbereich liegen, um wirksam zu sein, ohne Server mit geringfügigen Fehlern zu beeinträchtigen. Mit “tune.glitches.kill.cpu-usage” können Verbindungen auch erst dann beendet werden, wenn die CPU-Auslastung einen bestimmten Wert überschreitet. Beachten Sie, dass bei 75% der konfigurierten Schwelle ein geordnetes Schließen versucht wird, indem auf den Verbindungsmodus zum Schließen umgeschaltet und gegebenenfalls “Connection: close” angekündigt wird. Dadurch wird eine leicht fehlerhafte Verbindung nach einiger Zeit nicht mehr verwendet, ohne laufende Übertragungen zu gefährden.
Siehe auch: tune.h1.fe.glitches-threshold, bc_glitches und tune.glitches.kill.cpu-usage
tune.h1.fe.glitches-threshold <number>
Legt die Schwelle für die Anzahl von Unregelmäßigkeiten auf einer HTTP/1-Frontend-Verbindung fest, nach deren Überschreiten die Verbindung automatisch beendet wird. Dadurch lassen sich fehlerhaft arbeitende Verbindungen automatisch beenden, ohne dafür explizite Regeln schreiben zu müssen. Der Standardwert ist null: Es wird keine Schwelle gesetzt, sodass kein Ereignis zum Schließen einer Verbindung führt. Typische Ereignisse sind fehlerhaft formatierte Header, die dennoch durch “accept-unsafe-violations-in-http-request” akzeptiert wurden. Ein von null verschiedener Wert sollte vermutlich im Hunderter- oder Tausenderbereich liegen, um wirksam zu sein, ohne Clients mit geringfügigen Fehlern zu beeinträchtigen. Mit “tune.glitches.kill.cpu-usage” können Verbindungen auch erst dann beendet werden, wenn die CPU-Auslastung einen bestimmten Wert überschreitet. Beachten Sie, dass bei 75% der konfigurierten Schwelle ein geordnetes Schließen versucht wird, indem auf den Verbindungsmodus zum Schließen umgeschaltet und gegebenenfalls “Connection: close” angekündigt wird. Dadurch kann ein Client mit geringfügigen Protokollabweichungen eine neue Verbindung aufbauen und unbeeinträchtigt weiterarbeiten, ohne jemals ein hartes Schließen auszulösen und damit laufende Übertragungen zu gefährden.
Siehe auch: tune.h1.be.glitches-threshold, fc_glitches und tune.glitches.kill.cpu-usage
tune.h1.zero-copy-fwd-recv { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) den kopierfreien Datenempfang für den H1-Multiplexer. Er ist standardmäßig aktiviert.
Siehe auch: tune.disable-zero-copy-forwarding, tune.h1.zero-copy-fwd-send
tune.h1.zero-copy-fwd-send { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) das kopierfreie Senden von Daten für den H1-Multiplexer. Es ist standardmäßig aktiviert.
Siehe auch: tune.disable-zero-copy-forwarding, tune.h1.zero-copy-fwd-recv
tune.h2.be.glitches-threshold <number>
Legt die Schwelle für die Anzahl von Unregelmäßigkeiten auf einer Backend-Verbindung fest, bei deren Erreichen die Verbindung automatisch beendet wird. Dadurch lassen sich fehlerhaft arbeitende Verbindungen automatisch beenden, ohne dafür explizite Regeln schreiben zu müssen. Der Standardwert ist null: Es wird keine Schwelle gesetzt, sodass kein Ereignis zum Schließen einer Verbindung führt. Beachten Sie, dass manche H2-Server auf lange bestehenden Verbindungen gelegentlich einige Unregelmäßigkeiten verursachen können. Ein von null verschiedener Wert sollte daher vermutlich im Hunderter- oder Tausenderbereich liegen, um wirksam zu sein, ohne Server mit geringfügigen Fehlern zu beeinträchtigen. Mit “tune.glitches.kill.cpu-usage” können Verbindungen auch erst dann beendet werden, wenn die CPU-Auslastung einen bestimmten Wert überschreitet. Beachten Sie, dass bei 75% der konfigurierten Schwelle ein geordnetes Schließen versucht wird, indem ein GOAWAY für einen zukünftigen Stream angekündigt wird. Dadurch wird eine leicht fehlerhafte Verbindung nach einiger Zeit nicht mehr verwendet, ohne laufende Übertragungen zu gefährden.
Siehe auch: tune.h2.fe.glitches-threshold, bc_glitches und tune.glitches.kill.cpu-usage
tune.h2.be.initial-window-size <number>
Legt die anfängliche HTTP/2-Fenstergröße für ausgehende Verbindungen fest, also die Anzahl von Bytes, die der Server als Antwort senden kann, bevor er auf eine Bestätigung von HAProxy warten muss. Diese Einstellung betrifft nur Nutzdaten, keine Header. Ohne Einstellung gilt der gemeinsame Standardwert von tune.h2.initial-window-size. Eine leichte Erhöhung kann sinnvoll sein, um schnellere Downloads zu ermöglichen oder die CPU-Auslastung der Server zu verringern, geht jedoch zulasten einer fairen Verteilung zwischen den Clients. Besser ist die Verwendung von tune.h2.be.rxbuf, das keine solche Ungleichverteilung verursacht. Die Einstellung hat keinen Einfluss auf den Ressourcenverbrauch.
Siehe auch: tune.h2.initial-window-size.
tune.h2.be.max-concurrent-streams <number>
Legt die maximale Anzahl gleichzeitiger HTTP/2-Streams pro ausgehender Verbindung fest (also die Anzahl ausstehender Anfragen auf einer einzelnen Verbindung zu einem Server). Ohne Einstellung gilt der Standardwert von tune.h2.max-concurrent-streams. Ein kleinerer Wert als der Standardwert 100 kann die Reaktionsfähigkeit einer Website verbessern, erfordert jedoch mehr bestehende Verbindungen zu den Servern. Wenn “http-reuse” auf “always” gesetzt ist, wird empfohlen, diesen Wert zu verringern, damit nicht zu viele verschiedene Clients dieselbe Verbindung nutzen. Ist ein Client langsamer als andere, führt ein als “Head-of-Line-Blocking” bekannter Mechanismus häufig zu einem Kaskadeneffekt auf die Downloadgeschwindigkeit aller Clients, die sich die Verbindung teilen (halten Sie tune.h2.be.initial-window-size in diesem Fall niedrig). Es wird dringend empfohlen, diesen Wert nicht zu erhöhen; für manche Anwendungen können niedrige Werte optimal sein (typischerweise 1..5).
tune.h2.be.max-frames-at-once <number>
Legt die maximale Anzahl eingehender HTTP/2-Frames fest, die auf einer Backend-Verbindung auf einmal verarbeitet werden. Bei sehr großen Puffern kann ein niedriger Wert (einige zehn bis einige hundert) sinnvoll sein, um geringe Latenz und eine gerechtere Verteilung zwischen mehreren Verbindungen zu gewährleisten. Der Standardwert ist null, das heißt, es wird keine Begrenzung erzwungen.
tune.h2.be.rxbuf <size>
Legt die Größe des HTTP/2-Empfangspuffers für ausgehende Verbindungen in Byte fest. Die Größe wird auf das nächste Vielfache von tune.bufsize aufgerundet und von allen Streams gemeinsam genutzt, die Daten hochladen (sowohl HEADERS- als auch DATA-Frames). Jeder Stream erhält in jedem Fall einen Puffer. Außerdem werden 7/8 der ungenutzten Puffer unter den Streams aufgeteilt, die Nutzdaten herunterladen. Dadurch lässt sich die Upload-Leistung deutlich verbessern und Head-of-Line-Blocking (HoL) auf Backend-Verbindungen vermeiden, die bei “always” für http-reuse von mehreren Clients gemeinsam genutzt werden. Das pro Stream angekündigte Fenster wird automatisch an den verfügbaren Platz angepasst, sodass es in der Praxis nicht nötig sein sollte, tune.h2.be.initial-window-size zu ändern. Wird weniger als die für alle Streams erforderliche Größe gesetzt, wird dieses Minimum verwendet. Der Standardwert beträgt etwa 1600k (100 Streams mit jeweils 16kB großen Puffern).
Siehe auch: tune.h2.be.initial-window-size, tune.h2.fe.rxbuf, http-reuse.
tune.h2.fe.glitches-threshold <number>
Legt die Schwelle für die Anzahl von Unregelmäßigkeiten auf einer Frontend-Verbindung fest, bei deren Erreichen die Verbindung automatisch beendet wird. Dadurch lassen sich fehlerhaft arbeitende Verbindungen automatisch beenden, ohne dafür explizite Regeln schreiben zu müssen. Der Standardwert ist null: Es wird keine Schwelle gesetzt, sodass kein Ereignis zum Schließen einer Verbindung führt. Beachten Sie, dass manche H2-Clients auf lange bestehenden Verbindungen gelegentlich einige Unregelmäßigkeiten verursachen können. Ein von null verschiedener Wert sollte daher vermutlich im Hunderter- oder Tausenderbereich liegen, um wirksam zu sein, ohne Clients mit geringfügigen Fehlern zu beeinträchtigen. Mit “tune.glitches.kill.cpu-usage” können Verbindungen auch erst dann beendet werden, wenn die CPU-Auslastung einen bestimmten Wert überschreitet. Beachten Sie, dass bei 75% der konfigurierten Schwelle ein geordnetes Schließen versucht wird, indem ein GOAWAY für einen zukünftigen Stream angekündigt wird. Dadurch kann ein Client mit geringfügigen Protokollabweichungen eine neue Verbindung aufbauen und unbeeinträchtigt weiterarbeiten, ohne jemals ein hartes Schließen auszulösen und damit laufende Übertragungen zu gefährden.
Siehe auch: tune.h2.be.glitches-threshold, fc_glitches und tune.glitches.kill.cpu-usage
tune.h2.fe.initial-window-size <number>
Legt die anfängliche HTTP/2-Fenstergröße für eingehende Verbindungen fest, also die Anzahl von Bytes, die der Client hochladen kann, bevor er auf eine Bestätigung von HAProxy warten muss. Diese Einstellung betrifft nur Nutzdaten (also den Body von POST-Anfragen), keine Header. Ohne Einstellung gilt der gemeinsame Standardwert von tune.h2.initial-window-size. Eine Erhöhung kann sinnvoll sein, um schnellere Uploads zu ermöglichen. Der Standardwert entspricht tune.bufsize (16384) und ermöglicht pro Stream eine Bandbreite von mindestens 1.25 Mbps bei 100 ms Ping-Zeit sowie 125 Mbps bei 1 ms Ping-Zeit. Die Einstellung hat keinen Einfluss auf den Ressourcenverbrauch. Zu hohe Werte können dazu führen, dass Clients eine schlechtere Reaktionsfähigkeit erleben, wenn Seiten parallel zu großen Uploads abgerufen werden. Besser ist die Verwendung von tune.h2.fe.rxbuf, das keine Ungleichverteilung verursacht.
Siehe auch: tune.h2.initial-window-size.
tune.h2.fe.max-concurrent-streams <number> [args...]
Legt die maximale Anzahl gleichzeitiger HTTP/2-Streams pro eingehender Verbindung fest (also die Anzahl ausstehender Anfragen auf einer einzelnen Verbindung von einem Client). Ohne Einstellung gilt der Standardwert von tune.h2.max-concurrent-streams. Ein höherer Wert als der Standardwert 100 kann die Ladezeit komplexer Websites mit vielen kleinen Objekten über Netzwerke mit hoher Latenz gelegentlich etwas verbessern. Er kann aber auch den Speicherverbrauch erhöhen, da ein Client mehr Ressourcen auf einmal zuweisen kann. Der Standardwert 100 ist im Allgemeinen gut geeignet; es wird empfohlen, ihn nicht zu ändern. Eine höhere Parallelität beeinflusst außerdem die Verarbeitungslast und Latenz bei einer großen Anzahl von Verbindungen, die jeweils viele Streams verwenden, und kann Denial-of-Service-Angriffe erleichtern. Der Befehl unterstützt nach der Zahl folgende optionale Argumente:
- rq-load {
<number>| auto | ignore }:
- min
<number>:
Beispiel:
tune.h2.fe.max-frames-at-once <number>
Legt die maximale Anzahl eingehender HTTP/2-Frames fest, die auf einer Frontend-Verbindung auf einmal verarbeitet werden. Bei sehr großen Puffern kann ein niedriger Wert (einige zehn bis einige hundert) sinnvoll sein, um geringe Latenz und eine gerechtere Verteilung zwischen mehreren Verbindungen zu gewährleisten. Der Standardwert ist null, das heißt, es wird keine Begrenzung erzwungen.
tune.h2.fe.max-rst-at-once <number>
Legt die maximale Anzahl eingehender HTTP/2-RST_STREAM-Frames fest, die auf einer Frontend-Verbindung auf einmal verarbeitet werden. Sobald die angegebene Anzahl von RST_STREAM-Frames empfangen wurde, wird der Verbindungshandler in eine Warteschlange mit niedriger Priorität gestellt und nach allen anderen Tasks verarbeitet. Ein sehr niedriger Wert (1 oder einige wenige) kann sinnvoll sein, um die Auswirkungen von RST_STREAM-Fluten deutlich zu verringern. RST_STREAM tritt auch auf, wenn ein Benutzer auf die Stopp-Schaltfläche seines Browsers klickt. Die wenigen zusätzlichen Millisekunden durch das erneute Einreihen sind jedoch im Allgemeinen nicht wahrnehmbar, verringern aber gewöhnlich die durch solche Fluten verursachte Last erheblich. Der Standardwert ist null, das heißt, es wird keine Begrenzung erzwungen.
tune.h2.fe.max-total-streams <number>
Legt die maximale Gesamtanzahl von HTTP/2-Streams fest, die pro eingehender Verbindung verarbeitet werden. Sobald diese Grenze erreicht ist, sendet HAProxy einen GOAWAY-Frame zum geordneten Schließen. Dieser informiert den Client darüber, dass die Verbindung geschlossen wird, sobald alle ausstehenden Streams geschlossen wurden. In der Praxis schließen Clients die Verbindung nach Empfang dieser Meldung meist so schnell wie möglich und bauen für weitere Anfragen eine neue auf. Dies ist in Situationen nützlich und erwünscht, in denen Clients sehr lange verbunden bleiben und ein Ungleichgewicht innerhalb einer Serverfarm verursachen. In manchen hochdynamischen Umgebungen werden beispielsweise zusätzliche Load-Balancer während des Betriebs instanziiert, um auf zunehmende Last zu reagieren. Wenn die Last wieder abnimmt, sollen sie beendet werden, ohne bestehende Verbindungen abzubrechen. Eine hier gesetzte Grenze beschränkt die Lebensdauer der Verbindungen und sorgt für ihre häufige Erneuerung. Einige neue Verbindungen können dabei zu anderen Knoten aufgebaut werden, sodass bestehende Ressourcen schnell freigegeben werden.
Beachten Sie den impliziten Zusammenhang zwischen dieser Grenze und “tune.h2.fe.max-concurrent-streams” oben. HAProxy akzeptiert stets die Verarbeitung möglicherweise ausstehender Streams, die sich noch auf dem Weg zwischen Client und Frontend befinden. Daher wird die angekündigte Grenze automatisch um den für max-concurrent-streams konfigurierten Wert erhöht. Dieser erhöhte Wert dient als harte Grenze; überschreitet ein nicht protokollkonformer Client sie, wird die Verbindung geschlossen. Beim Zählen der Anfragen pro Verbindung anhand der Protokolle kann daher je nach Geschwindigkeit, mit der der Client Streams erzeugt, jeder Wert zwischen max-total-streams und (max-total-streams + max-concurrent-streams) auftreten.
Der Standardwert ist null und erzwingt keine zusätzliche Grenze über die vom Protokoll vorgegebene hinaus (2^30 ~= 1.07 Milliarden). Werte um 1000 können bereits eine häufige Erneuerung der Verbindungen bewirken, ohne bei den meisten Clients eine wahrnehmbare Latenz zu verursachen. Ein zu niedriger Wert kann durch häufige TLS-Neuverbindungen die CPU-Auslastung erhöhen und zusätzlich die Ladezeit von Seiten verlängern. Beachten Sie, dass einige Lasttestwerkzeuge keine Neuverbindungen unterstützen und mit dieser Einstellung Fehler melden können. Daher kann es erforderlich sein, sie bei Leistungsmessungen zu deaktivieren. Siehe auch “tune.h2.fe.max-concurrent-streams”.
tune.h2.fe.rxbuf <size>
Legt die Größe des HTTP/2-Empfangspuffers für eingehende Verbindungen in Byte fest. Die Größe wird auf das nächste Vielfache von tune.bufsize aufgerundet und von allen Streams gemeinsam genutzt, die Daten hochladen (sowohl HEADERS- als auch DATA-Frames). Jeder Stream erhält in jedem Fall einen Puffer. Außerdem werden 7/8 der ungenutzten Puffer unter den Streams aufgeteilt, die Nutzdaten hochladen, wodurch sich die Upload-Leistung deutlich verbessern lässt. Das pro Stream angekündigte Fenster wird automatisch an den verfügbaren Platz angepasst, sodass es in der Praxis nicht nötig sein sollte, tune.h2.fe.initial-window-size zu ändern. Wird weniger als die für alle Streams erforderliche Größe gesetzt, wird dieses Minimum verwendet. Der Standardwert 1600k (100 Streams mit jeweils 16kB großen Puffern) ermöglicht einem Client mit einer RTT von 100ms ungefähr 130 Mbps Uploadgeschwindigkeit.
Siehe auch: tune.h2.fe.initial-window-size und tune.h2.be.rxbuf.
tune.h2.header-table-size <number>
Legt die Größe der dynamischen HTTP/2-Headertabelle fest. Der Standardwert beträgt 4096 Byte; der Wert darf nicht größer als 65536 Byte sein. Ein höherer Wert kann es bestimmten Clients je nach ihren Fähigkeiten ermöglichen, kompaktere Anfragen zu senden. Diese Speichermenge wird für jede HTTP/2-Verbindung benötigt. Es wird empfohlen, den Wert nicht zu ändern.
tune.h2.initial-window-size <number>
Legt den Standardwert für die anfängliche HTTP/2-Fenstergröße sowohl eingehender als auch ausgehender Verbindungen fest. Dieser Wert gilt für eingehende Verbindungen, wenn tune.h2.fe.initial-window-size nicht gesetzt ist, und für ausgehende Verbindungen, wenn tune.h2.be.initial-window-size nicht gesetzt ist. Er dient sowohl als Anfangswert als auch als Mindestwert pro Stream. Der Standardwert beträgt 16384 (tune.bufsize). Für Uploads ermöglicht dies pro Stream ungefähr mindestens 1.25 Mbps Bandbreite über ein Netzwerk mit 100 ms Ping-Zeit beziehungsweise 125 Mbps über ein lokales Netzwerk mit 1 ms. Wenn innerhalb der durch tune.h2.be.rxbuf und tune.h2.fe.rxbuf festgelegten Grenzen weniger als die maximale Anzahl von Empfangspuffern verwendet wird, werden ungenutzte Puffer unter den empfangenden Streams aufgeteilt. Daher gibt es normalerweise keinen Grund, diese Standardeinstellung zu ändern. Da eine Änderung des Standardwerts sowohl die Uploadgeschwindigkeit erhöht als auch die Downloadkapazität ungerechter zwischen den Clients verteilt, wird empfohlen, stattdessen die seitenspezifischen Einstellungen tune.h2.fe.initial-window-size und tune.h2.be.initial-window-size zu verwenden.
tune.h2.log-errors { none | connection | stream }
Legt fest, welche Fehler im H2-Demultiplexer einen Protokolleintrag erzeugen. Der Standardwert ist “stream”: Jeder beim Dekodieren im Demultiplexer auftretende Fehler führt zu einem Protokolleintrag. Der Wert “connection” bedeutet, dass nur Fehler protokolliert werden, die die Verbindung ungültig machen. “none” bedeutet schließlich, dass kein Dekodierfehler protokolliert wird. Es wird empfohlen, mindestens “connection” einzustellen, um Protokollabweichungen zu erkennen, auch wenn in schwierigen Phasen vorübergehend auf “none” umgeschaltet werden muss.
tune.h2.max-concurrent-streams <number>
Legt den Standardwert für die maximale Anzahl gleichzeitiger HTTP/2-Streams pro Verbindung fest (also die Anzahl ausstehender Anfragen auf einer einzelnen Verbindung). Dieser Wert gilt für eingehende Verbindungen, wenn tune.h2.fe.max-concurrent-streams nicht gesetzt ist, und für ausgehende Verbindungen, wenn tune.h2.be.max-concurrent-streams nicht gesetzt ist. Der Standardwert ist 100. Die Auswirkungen unterscheiden sich je nach Seite; Einzelheiten finden Sie daher bei den beiden oben genannten Einstellungen. Es wird empfohlen, diese Einstellung nicht zu verwenden und stattdessen zu den seitenspezifischen Einstellungen zu wechseln. Der Wert null deaktiviert die Begrenzung, sodass ein einzelner Client so viele Streams erzeugen kann, wie HAProxy zuweisen kann. Es wird dringend empfohlen, diesen Wert nicht zu ändern.
tune.h2.max-frame-size <number>
Legt die maximale HTTP/2-Framegröße fest, die HAProxy seinen Peers als akzeptierte Empfangsgröße ankündigt. Der Standardwert ist der größere Wert aus 16384 und der Puffergröße (tune.bufsize). HAProxy kündigt in keinem Fall Unterstützung für Frames an, die größer als seine Puffer sind. Diese Einstellung dient hauptsächlich dazu, bei großen Puffern die maximale Framegröße begrenzen zu können. Zu große Frames können die Leistung beeinträchtigen oder bei einigen Peers fehlerhaftes Verhalten auslösen. Es wird dringend empfohlen, diesen Wert nicht zu ändern.
tune.h2.zero-copy-fwd-send { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) das kopierfreie Senden von Daten für den H2-Multiplexer. Es ist standardmäßig aktiviert.
Siehe auch: tune.disable-zero-copy-forwarding
tune.http.cookielen <number>
Legt die maximale Länge erfasster Cookies fest. Dies ist der höchste Wert, den “capture cookie xxx len yyy” annehmen darf; jeder höhere Wert wird automatisch auf diesen gekürzt. Der Wert sollte keinesfalls zu hoch gesetzt werden, da bei jeder Cookie-Erfassung unabhängig vom konfigurierten Wert stets diese Größe zugewiesen wird (alle verwenden denselben Pool). Dieser Wert gilt jeweils für Anfrage und Antwort, sodass pro Verbindung das Doppelte dieses Werts an Speicher zugewiesen wird. Ohne Angabe ist die Grenze auf 63 Zeichen gesetzt. Es wird empfohlen, diesen Wert nicht zu ändern.
tune.http.logurilen <number>
Legt die maximale Länge der Anfrage-URI in Protokollen fest. Dadurch lässt sich verhindern, dass lange Anfrage-URIs mit wertvollen Abfragezeichenfolgen in Protokollzeilen abgeschnitten werden. Dies hängt nicht mit Syslog-Grenzen zusammen. Wenn Sie diese Grenze erhöhen, können Sie auch den Parameter ’log … len yyy’ erhöhen. Ihr Syslog-Daemon benötigt möglicherweise ebenfalls spezielle Konfigurationsdirektiven. Der Standardwert ist 1024.
tune.http.maxhdr <number>
Legt die maximale Anzahl von Headern fest, die in empfangenen HTTP-Nachrichten erlaubt ist. Enthält eine Nachricht mehr Header als dieser Wert (einschließlich der ersten Zeile), wird sie bei einer Anfrage mit dem Statuscode “400 Bad Request” beziehungsweise bei einer Antwort mit “502 Bad Gateway” abgelehnt. Der Standardwert ist 101 und reicht für alle Anwendungsfälle aus, da der weit verbreitete Apache-Server dieselbe Grenze verwendet. Es kann sinnvoll sein, die Grenze vorübergehend zu erhöhen, damit eine fehlerhafte Anwendung bis zu ihrer Korrektur funktioniert. Der zulässige Bereich ist 1..32767. Beachten Sie, dass jeder zusätzliche Header pro Stream 32 Bit Speicher benötigt; setzen Sie die Grenze daher nicht zu hoch.
HTTP/1.1 ist ein Textprotokoll, weshalb beim Senden einer Nachricht keine besondere Begrenzung gilt. Die Begrenzung beim Einlesen der Nachricht genügt. HTTP/2 und HTTP/3 sind Binärprotokolle und erfordern einen Kodierungsschritt. Auch beim Kodieren der Header wird eine Grenze gesetzt, um die Beschränkungen dieser Protokolle einzuhalten. Diese Grenze ist ausreichend hoch, wird aber absichtlich nicht dokumentiert. Aus demselben Grund gilt dieselbe Grenze auch bei den ersten Schritten der Dekodierung.
tune.idle-pool.shared { full | on | off }
Steuert die gemeinsame Nutzung von Pools ungenutzter Verbindungen zu demselben Server durch mehrere Threads. Sie kann für alle Threads derselben Thread-Gruppe aktiviert werden (‘on’), für alle Threads aktiviert werden (‘full’) oder deaktiviert werden (‘off’). Standardmäßig werden die Pools innerhalb derselben Thread-Gruppe gemeinsam genutzt (‘on’), um die Anzahl dauerhafter Verbindungen zu einem Server zu minimieren und die Wiederverwendungsrate zu optimieren. Die gemeinsame Nutzung mit Threads anderer Thread-Gruppen kann die Leistung beeinträchtigen und ist standardmäßig nicht aktiviert. Sie kann aber sinnvoll sein, wenn eine möglichst hohe Verbindungswiederverwendung Priorität hat. Zur Fehlerdiagnose oder bei Verdacht auf einen Fehler in HAProxy bei der Wiederverwendung von Verbindungen kann es hilfreich sein, die gemeinsame Nutzung dieser Pools durch mehrere Threads ausdrücklich zu deaktivieren und die Option auf “off” zu setzen. Es wird dringend davon abgeraten, diese Option zu deaktivieren, ohne für alle Server, die zur Erzielung hoher Leistung auf Verbindungswiederverwendung angewiesen sind, einen konservativen Wert für “pool-low-conn” zu setzen. Andernfalls können Verbindungen mit zunehmender Thread-Anzahl sehr häufig geschlossen werden.
tune.idletimer <timeout>
Legt die Zeitspanne fest, nach der HAProxy davon ausgeht, dass ein leerer Puffer wahrscheinlich zu einem inaktiven Stream gehört. Dies dient dazu, einige Paketgrößen optimal anzupassen, wenn abwechselnd große und kleine Datenmengen weitergeleitet werden. Der Parameter beeinflusst die Entscheidung, splice() zu verwenden oder große Puffer über SSL zu senden. Der Wert wird in Millisekunden zwischen 0 und 65535 angegeben. Der Wert null bedeutet, dass HAProxy nicht versucht, inaktive Streams zu erkennen. Der Standardwert ist 1000 und scheint Pausen von Endbenutzern korrekt zu erkennen (beispielsweise das Lesen einer Seite vor einem Klick). Es sollte keinen Grund geben, diesen Wert zu ändern. Siehe tune.ssl.maxrecord weiter unten.
tune.listener.default-shards { by-process | by-thread | by-group }
Normalerweise erzeugt jede “bind”-Zeile einen einzigen Shard, also einen Socket, an dem alle Threads des Prozesses lauschen. Bei vielen Threads ist dies nicht sehr effizient und kann im Kernel erheblichen Aufwand beim Aktualisieren des Abfragestatus oder beim Verteilen von Ereignissen auf die verschiedenen Threads verursachen. Moderne Betriebssysteme unterstützen die Verteilung eingehender Verbindungen: Mehrere Sockets dürfen an dieselbe Adresse und denselben Port gebunden werden, und alle eingehenden Verbindungen werden gleichmäßig auf diese Sockets verteilt. Jeder Thread sieht dadurch nur die Verbindungen, die in dem Socket warten, an den er gebunden ist. Dies verringert den Aufwand im Kernel erheblich und verbessert die Leistung bei der Verarbeitung eingehender Verbindungen. In HAProxy wird dies üblicherweise über “shards” in “bind”-Zeilen aktiviert. Der Standardwert ist 1, sodass jeder Listener im Prozess nur einmal vorhanden ist. Auf Systemen mit vielen Prozessoren kann es bequemer sein, den Standardwert auf “by-thread” zu setzen, um stets einen Listener-Socket pro Thread zu erzeugen, oder auf “by-group”, um stets einen Listener-Socket pro Thread-Gruppe zu erzeugen. Achten Sie bei “by-thread” auf den Dateideskriptorverbrauch, da jeder Listener so viele Sockets benötigt, wie Threads vorhanden sind. Einige Betriebssysteme (z. B. FreeBSD) erlauben außerdem höchstens 256 Sockets an derselben Adresse. “by-group” entspricht bei Standardkonfigurationen mit einer einzigen Thread-Gruppe weiterhin “by-process”. Auf Systemen ohne Unterstützung dieses Mechanismus wird auf die gemeinsame Nutzung desselben Sockets zurückgefallen. Der Standardwert ist “by-group”, mit Rückfall auf “by-process” für Systeme oder Socket-Familien, die keine Mehrfachbindungen unterstützen.
tune.listener.multi-queue { on | fair | off }
Aktiviert (‘on’ / ‘fair’) oder deaktiviert (‘off’) die Annahme von Verbindungen über mehrere Warteschlangen am Listener. Dabei wird eingehender Datenverkehr auf alle Threads verteilt, auf denen eine “bind”-Zeile laufen darf, anstatt ihn vollständig selbst zu übernehmen. Dies sorgt für eine gleichmäßigere Verteilung des Datenverkehrs und skaliert deutlich besser, insbesondere wenn Threads aufgrund externer Aktivitäten ungleich ausgelastet sein können (beispielsweise wenn Netzwerk-Interrupts mit einem Thread konkurrieren). Der Standardmodus “on” optimiert die Thread-Auswahl, indem innerhalb einer Stichprobe der Thread mit den wenigsten Verbindungen gewählt wird. Dies ist bei langlebigen Verbindungen häufig die beste Wahl, da so alle Threads beschäftigt bleiben. Der zweite Modus “fair” durchläuft dagegen alle Threads unabhängig von ihrer momentanen Auslastung. Er kann für kurzlebige Verbindungen besser geeignet sein oder auf Rechnern mit sehr vielen Threads, auf denen die Wahrscheinlichkeit gering ist, im ersten Modus den am wenigsten ausgelasteten Thread zu finden. Schließlich lässt sich der Umverteilungsmechanismus mit “off” ausdrücklich deaktivieren, etwa zur Fehlerdiagnose oder bei kurzlebigen Verbindungen, wenn das Betriebssystem bereits eine ausreichend gute Verteilung bereitstellt. Der Standardwert ist “on”.
tune.lua.bool-sample-conversion { normal | pre-3.1-bug }
Gibt haproxy ausdrücklich vor, wie seine Sample-Objekte bei der Übergabe an Lua behandelt werden sollen. Wenn beispielsweise native Konverter, Sample-Fetches oder Variablen aus einem Lua-Skript verwendet werden, konvertiert haproxy den internen smp-Typ in den entsprechenden Lua-Typ. Aufgrund der historischen Implementierung gibt es Unklarheiten beim Umgang mit booleschen Werten: Bei der Konvertierung Lua -> haproxy smp bleiben boolesche Werte korrekt erhalten, bei haproxy smp -> Lua wurden sie dagegen irrtümlich in Ganzzahlen umgewandelt. Ein Sample-Fetch oder Konverter mit booleschem Rückgabewert gab bei Verwendung aus Lua daher die Ganzzahl 0 oder 1 zurück. In Lua sind boolesche Werte und Ganzzahlen jedoch nicht austauschbar. Um Mehrdeutigkeiten zu vermeiden, muss “tune.lua.bool-sample-conversion” deshalb ausdrücklich auf “normal” (Aufgabe des historischen Verhaltens zugunsten besserer Konsistenz) oder “pre-3.1-bug” (Erzwingen des historischen Verhaltens, damit die Logik bestehender Skripte nicht fehlerhaft arbeitet) gesetzt werden. Wenn die Option nicht ausdrücklich gesetzt ist und ein Lua-Skript aus der Konfiguration geladen wird, gibt haproxy eine Warnung aus und verwendet implizit “pre-3.1-bug”, um das historische Verhalten beizubehalten. Es wird empfohlen, diese Option auf “normal” zu setzen, nachdem sichergestellt wurde, dass die verwendeten Lua-Skripte boolesche haproxy-Samples korrekt als boolesche Werte behandeln.
Diese Einstellung muss vor jeder “lua-load”- oder “lua-load-per-thread”-Direktive gesetzt werden, damit sie berücksichtigt wird; andernfalls wird sie ignoriert.
tune.lua.burst-timeout <timeout>
Das Ausführungszeitlimit “burst” gilt für jeden Lua-Handler. Wenn der Handler vor Erreichen des Limits weder fertig wird noch die Ausführung abgibt, wird er abgebrochen. Dies verhindert Thread-Konkurrenz, eine zu lange Unterbrechung der Datenverkehrsverarbeitung und letztlich einen Prozessabsturz durch den Watchdog. Anders als andere Lua-Zeitlimits, die die Laufzeit über mehrere durch Yield unterbrochene Ausführungsphasen aufsummieren, stellt burst-timeout sicher, dass die Zeit in einem einzelnen Lua-Ausführungsfenster das konfigurierte Limit nicht überschreitet.
Yield bedeutet hier, dass die Lua-Ausführung tatsächlich unterbrochen wird, entweder durch einen expliziten Aufruf einer entsprechenden Funktion wie core.(m)sleep() oder core.yield() oder durch eine automatische erzwungene Unterbrechung (siehe tune.lua.forced-yield). Sie wird später fortgesetzt, wenn der zugehörige Task erneut zur Ausführung eingeplant wird. Nicht alle Lua-Handler können ihre Ausführung abgeben: Es muss zwischen unterbrechbaren und nicht unterbrechbaren Handlern unterschieden werden.
Bei unterbrechbaren Handlern (Tasks, Aktionen usw.) kann das Erreichen des Zeitlimits bedeuten, dass “tune.lua.forced-yield” für das System zu hoch ist. Ein niedrigerer Wert könnte die Situation verbessern. Es kann aber auch sinnvoll sein zu prüfen, ob manuelle Yield-Aufrufe an wichtigen Stellen der Lua-Funktion helfen. Ebenso kann es darauf hinweisen, dass der Handler zu viel Zeit in einer bestimmten, nicht unterbrechbaren Lua-Bibliotheksfunktion verbringt.
Bei nicht unterbrechbaren Handlern (Lua-Konvertern, Sample-Fetches) kann es schlicht bedeuten, dass der Handler zu viele Berechnungen durchführt. Dies könnte auf einen ungeeigneten Entwurf zurückgehen, denn solche Handler blockieren häufig den Ablauf der Anfrageausführung und sollen schnell beendet werden, damit die Anfrageverarbeitung fortfahren kann. Ein üblicher Lösungsansatz ist, die Lua-Funktion stärker auf Geschwindigkeit zu optimieren, da eine Verringerung von “tune.lua.forced-yield” hier nicht hilft.
Dieses Zeitlimit zählt nur die reine Lua-Laufzeit. Führt Lua ein core.sleep aus, wird die Schlafzeit nicht berücksichtigt. Das Standardzeitlimit beträgt 1000ms.
Hinweis: Wenn der Handler einen Lua-GC-Zyklus auslöst (entweder explizit oder nach einiger Zeit automatisch durch Lua), wird dessen Dauer ebenfalls angerechnet.
Die Dauer des GC-Zyklus lässt sich nicht gesondert bestimmen. Daher kann dies auf ausgelasteten Systemen zu Fehlalarmen führen, wenn der GC kaum mit der Arbeit nachkommt und den größten Teil der verfügbaren Ausführungszeit verbraucht. In diesem Fall kommen folgende Lösungsansätze infrage:
- prüfen, ob sich das Skript zur Verringerung des Lua-Speicherverbrauchs optimieren lässt
- Lua-GC-Parameter feinabstimmen und/oder manuelle GC-Zyklen anfordern
(siehe: https://www.lua.org/manual/5.4/manual.html#pdf-collectgarbage)
- tune.lua.burst-timeout erhöhen
Der Wert 0 deaktiviert diesen Schutz vollständig.
tune.lua.forced-yield <number>
Diese Direktive zwingt die Lua-Engine, nach jeweils <number> ausgeführten Anweisungen die Ausführung abzugeben. Dadurch lässt sich ein langes Skript unterbrechen, sodass der HAProxy-Scheduler andere Tasks verarbeiten kann, etwa Verbindungen annehmen oder Datenverkehr weiterleiten. Der Standardwert beträgt 10000 Anweisungen für mit “lua-load-per-thread” geladene Skripte und MAX(500, 10000 / nbthread) Anweisungen für mit “lua-load” geladene Skripte. Dieser Wert erwies sich als optimal für die Leistung und vermeidet zugleich Konkurrenz zwischen mehreren Threads um die globale Lua-Sperre.
Wenn HAProxy häufig Lua-Code ausführt, aber eine höhere Reaktionsfähigkeit benötigt wird, kann dieser Wert verringert werden. Ist der Lua-Code recht lang und sein Ergebnis für die Datenverarbeitung unbedingt erforderlich, kann <number> erhöht werden. Der Wert sollte jedoch sorgfältig gewählt werden, da er bei mehreren Threads die Konkurrenz erhöhen kann.
tune.lua.log.loggers { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) die Protokollierung der Ausgabe von LUA-Skripten über die für den aktuellen Proxy geltenden Logger, sofern vorhanden.
Der Standardwert ist ‘on’.
tune.lua.log.stderr { on | auto | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) die Protokollierung der Ausgabe von LUA-Skripten über stderr. Bei ‘auto’ ist die Protokollierung über stderr unter folgenden Bedingungen aktiviert, wenn mindestens eine davon zutrifft:
- tune.lua.log.loggers ist auf 'off' gesetzt
- das Skript läuft außerhalb eines Proxy-Kontexts, und es gibt keinen globalen Logger
- das Skript läuft in einem Proxy-Kontext ohne zugeordneten Logger
Beachten Sie, dass diese Protokollierung, sofern aktiviert, zusätzlich zur über tune.lua.log.loggers konfigurierten Protokollierung erfolgt.
Der Standardwert ist ‘auto’.
tune.lua.maxmem <number>
Legt die maximale Menge an RAM in Megabyte fest, die Lua pro Prozess verwenden darf. Der Standardwert ist null und bedeutet unbegrenzt. Es ist wichtig, eine Grenze zu setzen, damit ein Skriptfehler nicht den gesamten verfügbaren Systemspeicher aufbraucht.
tune.lua.openlibs [all | none | <lib>[,<lib>...]]
Wählt aus, welche Lua-Standardbibliotheken beim Initialisieren des Lua-Zustands geladen werden. Das Argument ist eine durch Kommas getrennte Liste von Bibliotheksnamen aus folgender Menge: table, io, os, string, math, utf8, package, debug. Anstelle einer Liste können die besonderen Werte “all” und “none” verwendet werden. “none” lässt sich nicht mit Bibliotheksnamen kombinieren. Der Standardwert ist “all”.
Die Bibliotheken base und coroutine werden unabhängig von dieser Einstellung immer geladen: base stellt grundlegende Lua-Funktionen bereit, auf die HAProxy angewiesen ist, und coroutine ist erforderlich, weil HAProxy coroutine.create() durch eine eigene sichere Implementierung ersetzt.
Beachten Sie, dass fork() und die Erzeugung neuer Threads in HAProxy unabhängig von dieser Einstellung bereits standardmäßig blockiert sind. Sie können nur über die globale Direktive “insecure-fork-wanted” wieder aktiviert werden. Die Beschränkung der geladenen Bibliotheken verringert die für Lua-Skripte zugängliche Angriffsfläche weiter. Insbesondere gilt: - Das Weglassen von “os” verhindert os.execute() und os.exit() - Das Weglassen von “io” verhindert io.open() und io.popen() - Das Weglassen von “package” verhindert das Laden nativer C-Module über require() - Das Weglassen von “debug” verhindert die Untersuchung interner HAProxy-Strukturen über debug.getupvalue(), debug.getmetatable() oder debug.sethook()
Beispiele:
Diese Einstellung muss vor jeder “lua-load”-, “lua-load-per-thread”- oder “lua-prepend-path”-Direktive gesetzt werden; andernfalls wird ein Fehler beim Einlesen der Konfiguration ausgegeben.
tune.lua.service-timeout <timeout>
Dies ist das Ausführungszeitlimit für Lua-Dienste. Es hilft, Endlosschleifen oder übermäßig lange Lua-Ausführungen zu verhindern. Dieses Zeitlimit zählt nur die reine Lua-Laufzeit. Führt Lua einen Schlafvorgang aus, wird dessen Dauer nicht berücksichtigt. Das Standardzeitlimit beträgt 4s.
tune.lua.session-timeout <timeout>
Dies ist das Ausführungszeitlimit für Lua-Sitzungen. Es hilft, Endlosschleifen oder übermäßig lange Lua-Ausführungen zu verhindern. Dieses Zeitlimit zählt nur die reine Lua-Laufzeit. Führt Lua einen Schlafvorgang aus, wird dessen Dauer nicht berücksichtigt. Das Standardzeitlimit beträgt 4s.
tune.lua.task-timeout <timeout>
Dient demselben Zweck wie “tune.lua.session-timeout”, gilt jedoch speziell für Tasks. Standardmäßig ist dieses Zeitlimit nicht gesetzt, da ein Task während der gesamten Lebensdauer von HAProxy aktiv bleiben kann, beispielsweise ein Task zur Prüfung von Servern.
tune.max-checks-per-thread <number>
Legt die Anzahl aktiver Prüfungen pro Thread fest, ab deren Überschreiten ein Thread aktiv nach einem weniger ausgelasteten Thread für die Zustandsprüfung sucht oder sie in eine Warteschlange stellt, bis die Anzahl der auf ihm laufenden aktiven Prüfungen sinkt. Der Standardwert ist null, das heißt, es wird keine solche Grenze gesetzt. Dies kann in Umgebungen mit sehr vielen aufwendigen Prüfungen und vielen Threads erforderlich sein, wenn die Last ungleich verteilt erscheint und Zustandsprüfungen beim Start zufällig ihr Zeitlimit überschreiten. Dies tritt typischerweise mit OpenSSL 3.0 auf, das bei Zustandsprüfungen etwa 20-mal mehr CPU beansprucht als ältere Versionen. Die Einstellung versucht, die Arbeit für Zustandsprüfungen gleichmäßiger auf alle Threads zu verteilen. Die weitaus meisten Konfigurationen benötigen keine Änderung dieses Parameters. Beachten Sie, dass zu niedrige Werte die Zustandsprüfung erheblich verlangsamen können, wenn die Prüfungen lange dauern.
tune.maxaccept <number>
Legt fest, wie viele Verbindungen ein Prozess maximal unmittelbar nacheinander annehmen darf, bevor er sich anderer Arbeit zuwendet. Im Einzelprozessmodus lieferten höhere Werte bei hohen Verbindungsraten früher bessere Leistung; mit mehreren Warteschlangen gilt dies jedoch nicht mehr. Der Wert gilt für jeden Listener einzeln, wobei die Anzahl der Prozesse berücksichtigt wird, an die der Listener gebunden ist. Der Standardwert ist 4, womit die besten Ergebnisse erzielt wurden. Wurde ein deutlich höherer Wert aus einer sehr alten Konfiguration übernommen, kann es sich lohnen, ihn zu entfernen, da dies sowohl die Leistung verbessert als auch die Antwortzeit verringert. Im Mehrprozessmodus wird der Wert durch das Doppelte der Anzahl von Prozessen geteilt, an die der Listener gebunden ist. Der Wert -1 deaktiviert die Begrenzung vollständig. Normalerweise sollte es nicht nötig sein, diesen Wert anzupassen.
tune.maxpollevents <number>
Legt die maximale Anzahl von Ereignissen fest, die bei einem Aufruf des Abfragesystems auf einmal verarbeitet werden können. Der Standardwert wird an das Betriebssystem angepasst. Es wurde beobachtet, dass Werte unter 200 die Latenz tendenziell leicht verringern, jedoch zulasten der Netzwerkbandbreite. Werte über 200 erhöhen dagegen tendenziell die Latenz zugunsten etwas höherer Bandbreite. Der konfigurierte Wert muss kleiner oder gleich 1000000 sein.
tune.maxrewrite <number>
Setzt den reservierten Pufferbereich auf diese Größe in Byte. Der reservierte Bereich wird zum Umschreiben oder Hinzufügen von Headern verwendet. Die ersten Lesevorgänge auf Sockets füllen niemals mehr als bufsize-maxrewrite. Historisch war der Standardwert die Hälfte von bufsize, was jedoch wenig sinnvoll ist, da selten sehr viele Header hinzugefügt werden müssen. Ein zu hoher Wert verhindert die Verarbeitung großer Anfragen oder Antworten. Ein zu niedriger Wert verhindert das Hinzufügen neuer Header zu bereits großen Anfragen oder zu POST-Anfragen. Im Allgemeinen ist ein Wert von etwa 1024 sinnvoll. Ist er größer als die Hälfte von bufsize, wird er automatisch auf diese Hälfte angepasst. Daher müssen Sie sich bei einer Änderung von bufsize nicht darum kümmern.
tune.max-rules-at-once <number>
Legt die maximale Anzahl von Regeln fest, die Funktionen zur Regelsatzauswertung auf einmal auswerten dürfen, sofern diese Funktionen ihre Ausführung abgeben können. Konfigurationen mit vielen “tcp-request content”- oder “http-request”-Regeln sind beispielsweise nicht ungewöhnlich. Viele Regeln zusammen mit CPU-intensiven Aktionen (etwa Aktionen auf Inhalten) können Konkurrenz zwischen Threads verursachen, da ohne Unterbrechung alle Regeln eines Regelsatzes innerhalb desselben Abfrageschleifendurchlaufs ausgewertet werden. Diese Option stellt sicher, dass bei inhaltsbezogenen Regelsätzen (die wegen der Inhaltsprüfung bereits Yield unterstützen) höchstens <number> Regeln innerhalb desselben Abfrageschleifendurchlaufs ausgeführt werden. Dazu zwingt sie die auswertende Funktion, die Ausführung abzugeben und die Auswertung erst im nächsten Abfrageschleifendurchlauf fortzusetzen.
Betroffen sind folgende Regelsätze:
- “tcp-request content”
- “tcp-response content”
- “http-request”
- “http-response”
Der Standardwert ist 50.
tune.memory.hot-size <number>
Legt die Speichermenge pro Thread fest, die im lokalen Cache sofort verfügbar gehalten wird und niemals von anderen Threads zurückgewonnen werden kann. Der Zugriff auf diesen Speicher ist sehr schnell und benötigt keine Sperren. Eine ausreichende Menge ist entscheidend für gute Leistung bei extremer Konkurrenz zwischen Threads. Der Wert wird in Byte angegeben. Der Standardwert wird beim Kompilieren über CONFIG_HAP_POOL_CACHE_SIZE festgelegt und beträgt standardmäßig 524288 (512 kB). Ein höherer Wert kann die Leistung in bestimmten Szenarien verbessern, insbesondere wenn Leistungsprofile eine starke Belastung der Speicherzuweisung zeigen. Erfahrungsgemäß liegt ein guter Wert zwischen der einfachen und der doppelten Größe des L2-Caches pro CPU-Kern. Zu hohe Werte beeinträchtigen die Leistung durch ineffiziente Nutzung der L3-Caches der CPUs und verbrauchen mehr Speicher. Es wird empfohlen, den Wert nicht zu ändern oder nur in kleinen Schritten vorzugehen. Um die CPU-Caches pro Thread vollständig zu deaktivieren, könnte ein sehr kleiner Wert funktionieren; besser ist jedoch “-dMno-cache” in der Befehlszeile.
tune.notsent-lowat.client <size>
Passt die Pufferung des Kernels pro Socket so an, dass die Sendeseite eines Sockets als voll gemeldet wird, sobald die gepufferte Datenmenge diesem Wert zuzüglich der gemessenen Fenstergröße entspricht. Dabei sollen nur die unbedingt benötigten Bytes in den Socket-Puffern verbleiben, ergänzt um eine kleine Reserve für die Daten, die bis zum nächsten Sendeversuch von haproxy übertragen werden. Ein niedriger Wert (typischerweise etwa tune.bufsize) kann den Speicherverbrauch der Systempuffer erheblich verringern und die Latenz auf Anwendungsebene reduzieren, die durch das Leeren gepufferter Daten entsteht. Auf unterstützenden Systemen ist diese Einstellung im Allgemeinen wirksamer und genauer als tune.sndbuf.client und tune.sndbuf.client. Sie gilt pro Verbindung (je nach Einstellung für Verbindungen von einem Client oder zu einem Server) und wird nur für TCP-Verbindungen verwendet. Der Standardwert ist null und bedeutet unbegrenzt. Dies ist nur unter Linux verfügbar.
tune.pattern.cache-size <number>
Setzt die Größe des Caches für Mustersuchen auf <number> Einträge. Dieser LRU-Cache speichert frühere Suchen und deren Ergebnisse. Er wird von ACLs und Maps für langsame Mustersuchen verwendet, insbesondere mit den Vergleichsmethoden “sub”, “reg”, “dir”, “dom”, “end”, “bin” sowie für Zeichenfolgenvergleiche ohne Beachtung der Groß-/Kleinschreibung. Er arbeitet auf Musterausdrücken und kann daher das Ergebnis einer Suche über alle in einer Konfigurationszeile angegebenen Muster speichern (einschließlich aller aus Dateien geladenen Muster). Einträge, die über HTTP-Aktionen oder die CLI aktualisiert werden, werden automatisch ungültig gemacht. Die Standardgröße beträgt 10000 Einträge. Dadurch bleibt der Speicherbedarf bei etwa 5 MB pro Prozess/Thread auf 32-Bit-Systemen und 8 MB pro Prozess/Thread auf 64-Bit-Systemen, da die Caches thread- beziehungsweise prozesslokal sind. Das Kollisionsrisiko in diesem Cache ist sehr gering und liegt in der Größenordnung der Cachegröße geteilt durch 2^64. Bei 10000 Anfragen pro Sekunde und der Standardgröße von 10000 Einträgen besteht typischerweise eine Wahrscheinlichkeit von 1%, dass ein Brute-Force-Angriff nach 60 Jahren eine einzige Kollision erzeugt, beziehungsweise von 0.1% nach 6 Jahren. Dies gilt als deutlich geringer als das Risiko einer Speicherbeschädigung durch alternde Komponenten. Falls dies nicht akzeptabel ist, kann der Cache durch Setzen dieses Parameters auf 0 deaktiviert werden.
tune.peers.max-updates-at-once <number>
Legt die maximale Anzahl von Stick-Tabellen-Aktualisierungen fest, die haproxy beim Senden von Nachrichten auf einmal zu verarbeiten versucht. Das Abrufen der Daten für diese Aktualisierungen erfordert Sperroperationen, die ohne Begrenzung auf Rechnern mit vielen Threads CPU-intensiv sein können. Sie können außerdem während der anfänglichen gebündelten Übertragung zwischen einem älteren und einem neueren Prozess die Latenz des Datenverkehrs erhöhen. Umgekehrt können niedrige Werte ebenfalls höheren CPU-Aufwand und eine längere Gesamtdauer verursachen. Der Standardwert ist 200; es wird empfohlen, ihn nicht zu ändern.
tune.pipesize <size>
Setzt die Größe der Kernel-Pipe-Puffer auf diesen Wert (in Byte). Standardmäßig verwenden Pipes die Standardgröße des Systems. Bei TCP-Splicing kann eine größere Pipe jedoch manchmal die Leistung verbessern, insbesondere wenn vermutet wird, dass die Pipes nicht vollständig gefüllt werden und viele splice()-Aufrufe erfolgen. Dies beeinflusst den Speicherbedarf des Kernels; der Wert darf daher nur geändert werden, wenn die Auswirkungen verstanden werden.
tune.pool-high-fd-ratio <number>
Legt den maximalen Anteil der von HAProxy global verwendeten Dateideskriptoren an der maximal nutzbaren Anzahl in Prozent fest, ab dem ungenutzte Verbindungen beendet werden, wenn keine Verbindung wiederverwendet werden kann und eine neue erstellt werden muss. Der Standardwert ist 25. Ein Viertel der Dateideskriptoren bedeutet, dass ungefähr die Hälfte der maximalen Anzahl von Frontend-Verbindungen eine ungenutzte Verbindung zum Backend vorhalten kann. Darüber hinauszugehen ist im allgemeinen Fall bei angestrebter Verbindungswiederverwendung vermutlich wenig sinnvoll.
tune.pool-low-fd-ratio <number>
Legt den maximalen Anteil der von HAProxy global verwendeten Dateideskriptoren an der maximal nutzbaren Anzahl in Prozent fest, ab dem keine weiteren Verbindungen zur Wiederverwendung in den Pool ungenutzter Verbindungen aufgenommen werden. Der Standardwert ist 20.
tune.pt.zero-copy-forwarding { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) die kopierfreie Datenweiterleitung für den Pass-through-Multiplexer. Für ihre Verwendung muss auch Kernel-Splicing konfiguriert sein. Sie ist standardmäßig aktiviert.
Siehe auch: tune.disable-zero-copy-forwarding, option splice-auto, option splice-request und option splice-response
tune.quic.be.cc.cubic-min-losses <number>
Legt fest, wie viele verlorene Pakete erforderlich sind, damit der Cubic-Algorithmus zur Überlastungssteuerung tatsächlich ein Verlustereignis annimmt. Normalerweise gilt jedes Verlustereignis als Folge einer Überlastung und reicht aus, damit Cubic mit einem kleineren Fenster neu beginnt. Experimente zeigen jedoch zahlreiche Verlustursachen, die nichts mit Überlastung zu tun haben und als nicht überlastungsbedingte Verluste einzuordnen sind. Eine Anpassung des Fensters hat darauf keine Wirkung, außer die Kommunikation zu verlangsamen. Häufige Ursachen sind schwache Funksignale, Zustellung in falscher Reihenfolge, zufällige Verzögerungen durch hohe CPU-Auslastung auf einem Client oder ungenaue Systemzeitgeber. Diese Einstellung macht Cubic etwas toleranter gegenüber solchen Verlusten, indem sie die minimale Anzahl aufsummierter Verluste zwischen zwei ACKs ändert, die als Verlustereignis gilt. Der Standardwert ist 1. In Experimenten wurden teils deutliche Verbesserungen beobachtet, allerdings stets zusammen mit mehr durch erneute Übertragungen verschwendeter Bandbreite und einem erhöhten Risiko, bereits überlastete Verbindungen vollständig auszulasten. Der Wert 2 kann für kurze Zeit zum Vergleich einiger Messwerte verwendet werden. Überschreiten Sie niemals 2, ohne dass ein Experte die Situation zuvor analysiert hat. Standard- und Mindestwert sind 1. Verwenden Sie immer 1.
tune.quic.cc.cubic.min-losses <number> (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.be.cc.hystart { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) den Algorithmus HyStart++ (RFC 9406) für QUIC-Verbindungen. Er ersetzt die Slow-Start-Phase von Überlastungssteuerungsalgorithmen, die hohe Paketverluste verursachen kann. Standardmäßig ist er deaktiviert.
tune.quic.cc-hystart { on | off } (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.be.cc.max-frame-loss <number>
Legt fest, wie oft ein einzelner QUIC-Frame maximal als verloren markiert werden darf. Wird die Grenze überschritten, gilt die Verbindung als fehlerhaft und wird sofort geschlossen.
Der Standardwert ist 10.
tune.quic.max-frame-loss <number> (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.be.cc.max-win-size <size>
Legt die standardmäßige maximale Fenstergröße für die Überlastungssteuerung einer einzelnen QUIC-Verbindung auf der Frontend- oder Backend-Seite fest. Der Wert muss als ganze Zahl mit optionalem Suffix ‘k’, ’m’ oder ‘g’ angegeben werden. Er muss zwischen 10k und 4g liegen.
Der QUIC-Multiplexer verwendet außerdem die aktuelle Größe des Überlastungsfensters, um zu entscheiden, ob beim Senden von Daten neue Stream-Puffer zugewiesen werden können. Die maximale Größe des Überlastungsfensters begrenzt somit auch diese Zuweisung.
Der Standardwert ist 480k.
Siehe auch die bind- und Serveroptionen “quic-cc-algo”.
tune.quic.frontend.default-max-window-size <size> (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.be.cc.reorder-ratio <0..100, in percent>
Der Faktor, der auf die berechnete Schwelle für die Umordnung von Paketen angewendet wird. Ein zu kleiner Wert kann dazu führen, dass viele Pakete als verloren erkannt werden.
Der Standardwert ist 50.
tune.quic.reorder-ratio <0..100, in percent> (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.be.max-idle-timeout <timeout>
Legt den QUIC-Transportparameter max_idle_timeout auf der Frontend- oder Backend-Seite fest. Der Wert folgt dem HAProxy-Zeitformat und wird in Millisekunden angegeben. Er bestimmt die Zeitspanne, nach der eine Verbindung ohne Meldung geschlossen wird, wenn sie während der effektiven Zeitspanne inaktiv geblieben ist. Beide Endpunkte verwenden denselben ausgehandelten Wert: - den kleineren der beiden Parameter, wenn beide ungleich null sind, - den größeren, wenn nur einer ungleich null ist, - sind beide Parameter null, ist die Funktion deaktiviert.
Der Standardwert ist 30s.
tune.quic.frontend.max-idle-timeout <timeout> (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.be.sec.glitches-threshold <number>
Legt die Schwelle für die Anzahl von Unregelmäßigkeiten pro Verbindung auf der Frontend- oder Backend-Seite fest, bei deren Erreichen die Verbindung automatisch beendet wird. Dadurch lassen sich fehlerhaft arbeitende Verbindungen automatisch beenden, ohne dafür explizite Regeln schreiben zu müssen. Der Standardwert ist null: Es wird keine Schwelle gesetzt, sodass kein Ereignis zum Schließen einer Verbindung führt. Beachten Sie, dass manche QUIC-Clients auf lange bestehenden Verbindungen gelegentlich einige Unregelmäßigkeiten verursachen können. Ein von null verschiedener Wert sollte daher vermutlich im Hunderter- oder Tausenderbereich liegen, um wirksam zu sein, ohne Clients mit geringfügigen Fehlern zu beeinträchtigen. Mit “tune.glitches.kill.cpu-usage” können Verbindungen auch erst dann beendet werden, wenn die CPU-Auslastung einen bestimmten Wert überschreitet.
Siehe auch: fc_glitches, tune.glitches.kill.cpu-usage
tune.quic.frontend.glitches-threshold <number> (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.fe.sec.retry-threshold <number>
Aktiviert die Retry-Funktion für alle konfigurierten QUIC-Listener dynamisch, sobald diese Anzahl halb offener Verbindungen erreicht ist. Eine halb offene Verbindung ist eine Verbindung, deren Handshake weder erfolgreich abgeschlossen noch fehlgeschlagen ist. Diese Einstellung erfordert ein gesetztes Cluster-Geheimnis, um zu funktionieren. Andernfalls wird sie ohne Meldung ignoriert (siehe “cluster-secret”). Sie wird ebenfalls ohne Meldung ignoriert, wenn die Verwendung von QUIC Retry erzwungen wurde (siehe “quic-force-retry”).
Der Standardwert ist 100.
Weitere Informationen zu QUIC Retry finden Sie unter https://www.rfc-editor.org/rfc/rfc9000.html#section-8.1.2 .
tune.quic.retry-threshold <number> (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.fe.sock-per-conn { default-on | force-off }
Legt global fest, welche Sockets QUIC-Frontend-Verbindungen für Empfangs- und Sendeoperationen verwenden. Verbindungen können den Listener-Socket gemeinsam nutzen oder jeweils einen eigenen Socket anlegen.
Der Standardwert ist “default-on”. Dabei wird jeder QUIC-Verbindung ein eigener Socket zugewiesen. Dies ist die bevorzugte Option für bestmögliche Leistung bei hohem QUIC-Datenverkehr. Es ist auch die einzige Möglichkeit, einen ordnungsgemäßen Soft-Stop ohne Datenverlust für QUIC-Verbindungen sicherzustellen und vorübergehende Fehler bei sendto()-Operationen effizient zu behandeln. Dies setzt jedoch einige erweiterte Funktionen des UDP-Netzwerkstacks voraus. Wird Ihre Plattform als nicht kompatibel eingestuft, wechselt haproxy beim Start automatisch in den Modus “force-off”. Beachten Sie, dass QUIC-Listener an privilegierten Ports möglicherweise unter uid 0 laufen müssen oder OS-spezifische Anpassungen wie System-Capabilities erfordern, damit die Ziel-uid solche Ports binden darf. Siehe auch die globale Direktive “setcap”.
Der Wert “force-off” bedeutet, dass QUIC-Übertragungen über den gemeinsam genutzten Listener-Socket erfolgen. Bei geringem Datenverkehr kann dies ein guter Kompromiss sein, da der FD-Verbrauch sinkt. Die Leistung ist aufgrund höherer CPU-Auslastung jedoch nicht optimal, wenn viele Threads die Listener gemeinsam nutzen oder sehr viele QUIC-Verbindungen gleichzeitig verwendet werden können.
Diese Einstellung wirkt zusammen mit den jeweiligen bind-Optionen “quic-socket”. Wenn global “default-on” eingestellt ist, wird dieser Modus für jeden Listener aktiviert, außer für solche mit “quic-socket listener”. Wird dagegen global “force-off” verwendet, gilt dies für jede Listener-Instanz unabhängig von ihrer individuellen Konfiguration.
tune.quic.socket-owner { connection | listener } (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Die neuere Option heißt “tune.quic.fe.sock-per-conn”. Dabei entspricht der bisherige Wert “connection” dem neuen Wert “default-on” und “listener” dem Wert “force-off”.
tune.quic.be.stream.data-ratio <0..100, in percent>
Mit dieser Einstellung lässt sich die harte Obergrenze für die Anzahl der auf jedem Stream gleichzeitig unterwegs befindlichen Datenbytes festlegen. Sie wird als Prozentsatz der QUIC-Verbindungseinstellung stream rxbuf angegeben, wobei das Ergebnis auf bufsize aufgerundet wird.
Der Standardwert ist 90. Dies passt zum häufigsten Webszenario, in dem nur ein oder wenige Streams für Uploads verwendet werden, während die übrigen ausschließlich Downloads dienen. Bleibt die Verbindungsgrenze stream rxbuf auf einem angemessenen Niveau, stellt dies sicher, dass nur ein Teil der geöffneten Streams seine maximale Kapazität zuweisen kann.
Wenn eine Anwendung viele Upload-Streams parallel nutzt und diese ungleich bedient werden, kann eine Verringerung dieses Anteils sinnvoll sein, um die Verteilung gerechter zu machen und die Bandbreite pro Stream zu reduzieren.
Siehe auch: “tune.quic.be.stream.rxbuf”, “tune.quic.fe.stream.rxbuf”, “tune.quic.be.stream.max-concurrent”, “tune.quic.fe.stream.max-concurrent”
tune.quic.frontend.stream-data-ratio <0..100, in percent> (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.be.stream.max-concurrent <number>
Auf der Frontend-Seite wird dieser Wert für den angekündigten Transportparameter initial_max_streams_bidi verwendet. Er wird als maximale Anzahl bidirektionaler Streams erzwungen, die der entfernte Peer während der Lebensdauer der Verbindung gleichzeitig öffnen darf. Dadurch wird die Anzahl gleichzeitiger HTTP/3-Clientanfragen begrenzt.
Der Standardwert ist 100. Beachten Sie, dass eine Verringerung die Empfangspufferkapazität der Streams einschränken und dadurch den Uploaddurchsatz verschlechtern kann. Dies lässt sich durch Erhöhen der QUIC-Verbindungseinstellung stream rxbuf ausgleichen.
Auf der Backend-Seite erzwingt haproxy den Wert lokal, um die Anzahl gleichzeitiger Anfragen zu begrenzen, die über eine einzelne Verbindung gemultiplext werden. Die Flusskontrolle des Peers kann sie weiter einschränken. Es kann erforderlich sein, den Standardwert 100 zu verringern, um die Reaktionsfähigkeit einer Website zu verbessern, allerdings zulasten einer höheren Anzahl offener Backend-Verbindungen. Ähnlich wie auf der Frontend-Seite beeinflusst diese Einstellung direkt die Rx-Pufferkapazität, begrenzt hier jedoch die HTTP-Downloadkapazität. Die QUIC-Einstellung stream rxbuf kann erhöht werden, wenn überwiegend HTTP-Antworten verarbeitet werden, die größer als “tune.bufsize” sind.
Siehe auch: “tune.quic.be.stream.rxbuf”, “tune.quic.fe.stream.rxbuf”, “tune.quic.be.stream.data-ratio”, “tune.quic.fe.stream.data-ratio”
tune.quic.fe.stream.max-total <number>
Legt die maximale Anzahl von Anfragen fest, die eine einzelne QUIC-Verbindung verarbeiten kann. Sobald diese Gesamtzahl erreicht ist, wird die Verbindung geordnet beendet. Bei HTTP/3 geschieht dies durch einen GOAWAY-Frame. Endgültig geschlossen wird die Verbindung, wenn alle verbleibenden Übertragungen abgeschlossen sind.
Diese Einstellung wird über den QUIC-Flusskontrollmechanismus als harte Grenze für die Verbindung angewendet. Verletzt ein Peer sie, wird die Verbindung sofort geschlossen.
Mit dieser Einstellung können Clients dazu gezwungen werden, von Zeit zu Zeit neue Verbindungen zu öffnen, um weitere Anfragen zu senden, und Verbindungen nicht übermäßig lange aufrechtzuerhalten. Niedrige Werte erhöhen jedoch die Latenz auf Clientseite sowie den CPU-Verbrauch auf beiden Seiten durch TLS-Handshakes.
Der Standardwert ist 0. Damit gilt keine besondere Grenze außer der durch die Kodierung des QUIC-Protokolls vorgegebenen (2^60, mehr als eine Milliarde Milliarden).
tune.quic.frontend.max-streams-bidi <number> (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.be.stream.rxbuf <size>
Diese Einstellung ist die harte Obergrenze für die Anzahl der auf einer QUIC-Frontend-Verbindung gleichzeitig unterwegs befindlichen Datenbytes. Sie wird als Wert für den Transportparameter initial_max_data verwendet. Abhängig von der Latenz beeinflusst sie direkt die Uploadbandbreite des Peers sowie den Speicherverbrauch pro Verbindung in haproxy.
Standardmäßig ist der Wert auf 0 gesetzt. Das bedeutet, dass er automatisch als Produkt aus max-concurrent und bufsize berechnet werden muss. Er kann beispielsweise erhöht werden, wenn eine Backend-Anwendung auf umfangreiche Uploads über Netzwerke mit hoher Latenz angewiesen ist.
Siehe auch: “tune.quic.be.stream.max-concurrent”, “tune.quic.fe.stream.max-concurrent”, “tune.quic.be.stream.data-ratio”, “tune.quic.fe.stream.data-ratio”
tune.quic.frontend.max-data-size <size> (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.be.tx.pacing { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) die Unterstützung für Pacing beim Senden über QUIC. Standardmäßig ist sie aktiv. Pacing soll die Datenausgabe gleichmäßiger verteilen, um Netzwerkverluste zu verringern. In den meisten Szenarien verbessert es den Netzwerkdurchsatz deutlich, indem erneute Übertragungen vermieden werden. Auf Netzwerken mit sehr hoher Bandbreite und niedriger Latenz kann eine Deaktivierung jedoch sinnvoll sein, um unerwünschte Verzögerungen zu vermeiden und den CPU-Verbrauch zu verringern.
Siehe auch die bind- und Serveroptionen “quic-cc-algo”.
tune.quic.disable-tx-pacing (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.be.tx.udp-gso { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) die Unterstützung für UDP GSO beim Senden über QUIC. Standardmäßig ist sie aktiv. Diese Kernel-Funktion ermöglicht das Senden mehrerer Datagramme mit einem einzigen Systemaufruf, was bei großen Übertragungen effizienter ist. Bei Verdacht auf ein Sendeproblem kann es sinnvoll sein, sie auf Empfehlung der Entwickler zu deaktivieren.
tune.quic.disable-udp-gso (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.listen { on | off }
Deaktiviert das QUIC-Transportprotokoll auf der Frontend-Seite. Alle QUIC-Listener werden weiterhin erstellt, lauschen jedoch nicht auf eingehende Datagramme. Somit verarbeitet haproxy auf der Frontend-Seite keinen QUIC-Datenverkehr.
Der Standardwert ist “on”. Bei Verdacht auf ein Problem mit QUIC-Datenverkehr lassen sich die QUIC-Listener mit dieser Option einfach ein- oder ausschalten, ohne jede einzelne Konfigurationszeile ändern zu müssen.
Siehe auch den Sample-Fetch “quic_enabled”.
tune.quic.mem.tx-max <size>
Legt die maximale Speichermenge fest, die der QUIC-Stack auf der Transportschicht zum Senden verwenden darf. Dies begrenzt sowohl die gleichzeitig unterwegs befindlichen Bytes als auch die Ausgabepuffer des Multiplexers. Beachten Sie, dass diese Grenze zur Vermeidung von Konkurrenz zwischen Threads nicht strikt erzwungen wird und daher gelegentlich überschritten werden kann. Außerdem kann jede Verbindung stets ein Fenster von mindestens 2 Datagrammen verwenden. Daher sollte gleichzeitig ein passender maxconn-Wert gesetzt werden.
tune.quic.frontend.max-tx-mem <size> (deprecated)
Dieses Schlüsselwort ist seit 3.3 veraltet und wird in 3.5 entfernt. Dies ist Teil der Vereinheitlichung der QUIC-Konfiguration. Bei Verwendung gilt diese Einstellung nur für Frontend-Verbindungen.
tune.quic.zero-copy-fwd-send { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) das kopierfreie Senden von Daten für den QUIC-Multiplexer. Es ist standardmäßig aktiviert.
Siehe auch: tune.disable-zero-copy-forwarding
tune.renice.runtime <number>
Diese Konfigurationsoption nimmt einen Wert zwischen -20 und 19 an. Sie setzt eine Scheduling-Priorität, wie in man 2 setpriority beschrieben. Die Priorität wird nach dem Einlesen der Konfiguration angewendet, also nur vom Worker oder vom eigenständig laufenden Prozess. Üblicherweise wird damit eine höhere Priorität als für einen Prozess festgelegt, der gerade die Konfiguration einliest (tune.renice.startup).
Siehe auch: tune.renice.startup
tune.renice.startup <number>
Diese Konfigurationsoption nimmt einen Wert zwischen -20 und 19 an. Sie setzt eine Scheduling-Priorität, wie in man 2 setpriority beschrieben. Die Priorität wird vor der übrigen Konfiguration angewendet, was nützlich sein kann, wenn die Priorität beim Einlesen der Konfiguration verringert werden soll. Dies betrifft den eigenständig laufenden Prozess oder den Worker vor dem Einlesen der Konfiguration. Sobald die Konfiguration eingelesen ist, wird die vorherige Priorität wiederhergestellt, sofern tune.renice.runtime nicht verwendet wird.
Siehe auch: tune.renice.runtime
tune.rcvbuf.backend <size>
Setzt die Größe des Kernel-Empfangspuffers für nicht verbundene Sockets auf diesen Wert. Dies kann für QUIC im Listener-Modus und für log-forward im Frontend verwendet werden. Die Standardpuffer des Systems sind mitunter für Sockets mit viel gebündeltem Datenverkehr zu klein, was Verluste und gegebenenfalls erneute Übertragungen (bei QUIC) verursachen und den Verbindungsaufbau unter hoher Last verlangsamen kann. Der Wert wird in Byte angegeben und auf jeden Socket angewendet. Im Listener-Modus werden Sockets von allen Verbindungen gemeinsam genutzt; die Gesamtzahl der Sockets hängt vom “shards”-Wert der “bind”-Zeile ab. Es gibt keinen allgemeingültigen guten Wert. Ein geeigneter Wert entspricht der erwarteten Größe pro Verbindung multipliziert mit der erwarteten Anzahl von Verbindungen. Der Kernel kann große Werte begrenzen. Siehe auch “tune.rcvbuf.client” und “tune.rcvbuf.server” für die entsprechenden Einstellungen verbundener Sockets sowie “tune.sndbuf.backend” und “tune.sndbuf.frontend” für die Sendeseite.
tune.rcvbuf.client <size>
Erzwingt die angegebene Größe in Byte für den Kernel-Empfangspuffer von Sockets auf der Client- oder Serverseite. Dieser Wert gilt für alle TCP/HTTP-Frontends und -Backends. Er sollte normalerweise niemals gesetzt werden. Die Standardgröße (0) lässt den Kernel den Wert anhand der verfügbaren Speichermenge automatisch anpassen. Manchmal können jedoch sehr niedrige Werte (z. B. 4096) helfen, Kernel-Speicher zu sparen, indem die Pufferung übermäßig großer empfangener Datenmengen verhindert wird. Niedrigere Werte erhöhen allerdings die CPU-Auslastung erheblich.
tune.recv_enough <size>
HAProxy verwendet einige Hinweise, um zu erkennen, ob ein kurzer Lesevorgang das Ende der Socket-Puffer anzeigt. Einer davon ist, dass ein Lesevorgang mehr als <recv_enough> Bytes zurückgibt. Der Standardwert ist 10136 (7 Segmente mit jeweils 1448). Mit dieser Einstellung lässt sich der Standardwert ändern, um Arbeitslasten mit vielen kurzen Nachrichten wie telnet- oder SSH-Sitzungen besser zu verarbeiten.
tune.ring.queues <number>
Legt die Anzahl der Schreibwarteschlangen vor Ringpuffern fest. Dies kann den CPU-Verbrauch von Traces bei der Fehlerdiagnose beeinflussen; sowohl zu niedrige als auch zu hohe Werte können erhebliche Auswirkungen haben. Ein geeigneter Wert wurde von den Entwicklern experimentell bestimmt. Daher sollte es keinen Grund geben, ihn zu ändern, sofern dies nicht zur Behebung bestimmter Probleme angefordert wird. Eine solche Einstellung sollte bei Versionsupgrades nicht dauerhaft in der Konfiguration verbleiben, da sich ihr optimaler Wert im Laufe der Zeit ändern kann.
tune.runqueue-depth <number>
Legt die maximale Anzahl von Tasks fest, die bei der Task-Ausführung auf einmal verarbeitet werden können. Der Standardwert hängt von der Thread-Anzahl ab, liegt aber zwischen 35 und 280, womit tendenziell die höchsten Anfrageraten und niedrigsten Latenzen erzielt werden. Eine Erhöhung kann die Latenz bei I/O-Operationen erhöhen; ein zu niedriger Wert kann zusätzlichen Aufwand verursachen. Bei höherer Thread-Anzahl sind niedrigere Werte vorteilhaft. Beim Experimentieren mit deutlich höheren Werten kann es sinnvoll sein, zusätzlich tune.sched.low-latency und gegebenenfalls tune.fd.edge-triggered zu aktivieren, um die maximale Latenz möglichst gering zu halten.
tune.sched.low-latency { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) den Task-Scheduler für niedrige Latenz. Standardmäßig verarbeitet HAProxy Tasks aus mehreren Klassen jeweils klassenweise, da dies am effizientesten ist. Bei hohen Werten von tune.runqueue-depth kann dies jedoch messbare Auswirkungen auf die Anfrage- oder Verbindungslatenz haben. Ist diese Einstellung aktiviert, werden vorhandene Tasks aus Klassen mit niedrigerer Priorität immer vor den anderen ausgeführt. Dadurch lässt sich die maximale Latenz neuer Anfragen oder Verbindungen inmitten sehr hohen Datenverkehrs verringern, allerdings zulasten einer stärkeren Beeinträchtigung dieses umfangreichen Datenverkehrs. Für den regulären Einsatz sollte diese Option besser deaktiviert bleiben. Der Standardwert ist off.
tune.sndbuf.backend <size>
Setzt die Größe des Kernel-Sendepuffers für nicht verbundene Sockets auf diesen Wert. Dies kann für die Protokollierung über UNIX-Sockets und UDP auf der Backend-Seite sowie für QUIC im Listener-Modus auf der Frontend-Seite verwendet werden. Die Standardpuffer des Systems sind mitunter für Sockets, die von vielen Verbindungen oder Protokollsendern gemeinsam genutzt werden, zu klein. Dies verursacht Verluste und möglicherweise erneute Übertragungen und verlangsamt den Aufbau neuer Verbindungen bei hohem Datenverkehr. Der Wert wird in Byte angegeben und auf jeden Socket angewendet. Im Listener-Modus werden Sockets von allen Verbindungen gemeinsam genutzt; die Gesamtzahl der Sockets hängt vom “shards”-Wert der “bind”-Zeile ab. Es gibt keinen allgemeingültigen guten Wert. Ein geeigneter Wert entspricht der erwarteten Größe pro Verbindung multipliziert mit der erwarteten Anzahl von Verbindungen. Der Kernel kann große Werte begrenzen. Siehe auch “tune.sndbuf.client” und “tune.sndbuf.server” für die entsprechenden Einstellungen verbundener Sockets sowie “tune.rcvbuf.backend” und “tune.rcvbuf.frontend” für die Empfangsseite.
tune.sndbuf.client <size>
Erzwingt die angegebene Größe in Byte für den Kernel-Sendepuffer von Sockets auf der Client- oder Serverseite. Dieser Wert gilt für alle TCP/HTTP-Frontends und -Backends. Er sollte normalerweise niemals gesetzt werden. Die Standardgröße (0) lässt den Kernel den Wert anhand der verfügbaren Speichermenge automatisch anpassen. Manchmal können jedoch sehr niedrige Werte (z. B. 4096) helfen, Kernel-Speicher zu sparen, indem die Pufferung übermäßig großer empfangener Datenmengen verhindert wird. Niedrigere Werte erhöhen allerdings die CPU-Auslastung erheblich. Ein weiterer Anwendungsfall ist das Verhindern von Schreibzeitüberschreitungen bei extrem langsamen Clients, wenn der Kernel wartet, bis ein großer Teil des Puffers gelesen wurde, bevor er HAProxy erneut benachrichtigt. Siehe auch tune.notsent-lowat.client und tune.notsent-lowat.server für wirksamere Einstellungen, die unter Linux eine feinere Steuerung von Speicherverbrauch und Reaktionsfähigkeit ohne Leistungseinbußen ermöglichen.
tune.ssl.cachesize <number>
Legt die Größe des globalen SSL-Sitzungscaches in Blöcken fest. Ein Block ist groß genug, um eine kodierte Sitzung ohne Peer-Zertifikat aufzunehmen. Eine kodierte Sitzung mit Peer-Zertifikat wird abhängig von dessen Größe in mehreren Blöcken gespeichert. Ein Block benötigt ungefähr 200 Byte Speicher (basierend auf der Berechnung sizeof(struct sh_ssl_sess_hdr) + SHSESS_BLOCK_MIN_SIZE, die für die Funktion shctx_init verwendet wird). Der Standardwert kann beim Kompilieren festgelegt werden; andernfalls beträgt er 20000. Ist der Cache voll, werden die am längsten ungenutzten Einträge entfernt und neu vergeben. Höhere Werte verringern die Häufigkeit solcher Bereinigungen und damit die Anzahl CPU-intensiver SSL-Handshakes, indem die Sitzungen aller Benutzer möglichst lange erhalten bleiben. Alle Einträge werden beim Start vorab zugewiesen. Der Wert 0 deaktiviert den SSL-Sitzungscache.
tune.ssl.capture-buffer-size <number>
Legt die maximale Größe des Puffers zur Erfassung der Verschlüsselungsalgorithmenliste, Erweiterungsliste, Liste elliptischer Kurven und Punktformate elliptischer Kurven aus dem ClientHello fest. Bei 0 (dem Standardwert) ist die Erfassung deaktiviert; andernfalls wird für jede SSL/TLS-Verbindung ein Puffer zugewiesen.
tune.ssl.certificate-compression { auto | off }
Diese Einstellung konfiguriert die Unterstützung für Zertifikatskomprimierung, eine Erweiterung (RFC 8879) für TLS 1.3.
Bei “auto” wird der Standardwert der TLS-Bibliothek verwendet.
Bei “off” wird versucht, die Unterstützung für diese Funktion ausdrücklich zu deaktivieren. HAProxy versucht dann weder, komprimierte Zertifikate zu senden, noch akzeptiert es solche Zertifikate.
Konfiguriert sowohl die Backend- als auch die Frontend-Seite.
Dieses Schlüsselwort wird von OpenSSL >= 3.2.0 unterstützt.
Der Standardwert ist auto.
tune.ssl.default-dh-param <number>
Legt die maximale Größe der Diffie-Hellman-Parameter fest, die beim DHE-Schlüsselaustausch zur Erzeugung des ephemeren beziehungsweise temporären Diffie-Hellman-Schlüssels verwendet werden. Für die endgültige Größe wird versucht, die Größe des RSA- oder DSA-Schlüssels des Servers zu übernehmen (z. B. einen temporären DH-Schlüssel mit 2048 Bit für einen RSA-Schlüssel mit 2048 Bit), ohne jedoch diesen Höchstwert zu überschreiten. Es sind nur Werte ab 1024 erlaubt. Höhere Werte erhöhen die CPU-Last; Werte über 1024 Bit werden von Java 7 und älteren Clients nicht unterstützt. Dieser Wert wird nicht verwendet, wenn statische Diffie-Hellman-Parameter entweder direkt in der Zertifikatsdatei oder über ssl-dh-param-file bereitgestellt werden. Sind weder default-dh-param noch ssl-dh-param-file definiert und enthält die PEM-Datei des Servers für ein bestimmtes Frontend keine eigenen DH-Parameter, stehen DHE-Verschlüsselungsverfahren für dieses Frontend nicht zur Verfügung.
tune.ssl.force-private-cache
Diese Option deaktiviert die gemeinsame Nutzung des SSL-Sitzungscaches zwischen allen Prozessen. Sie sollte normalerweise nicht verwendet werden, da sie viele Neuverhandlungen erzwingt, wenn Clients zufällig bei unterschiedlichen Prozessen landen. Auf einigen Betriebssystemen, auf denen keine der Synchronisierungsmethoden für den SSL-Cache verwendet werden kann, ist sie jedoch möglicherweise erforderlich. In diesem Fall kann eine zusätzliche Ebene mit hashbasierter Lastverteilung vor der SSL-Ebene die Auswirkungen der fehlenden gemeinsamen Sitzungsnutzung begrenzen.
tune.ssl.hard-maxrecord <number>
Legt die maximale Anzahl von Bytes fest, die zu einem Zeitpunkt an SSL_write() übergeben werden. Der Standardwert 0 bedeutet, dass es keine Begrenzung gibt. Im Gegensatz zu tune.ssl.maxrecord wird diese Einstellung nicht dynamisch angepasst. Kleinere Records können den Durchsatz verringern, sind aber bei ressourcenarmen Clients möglicherweise erforderlich.
tune.ssl.keylog { on | off }
Diese Option aktiviert die Protokollierung der TLS-Schlüssel. Sie sollte mit Vorsicht verwendet werden, da sie pro SSL-Sitzung mehr Speicher verbraucht und die Leistung beeinträchtigen könnte. Standardmäßig ist sie deaktiviert.
Diese Sample-Fetches sollten verwendet werden, um die SSLKEYLOGFILE zu erzeugen, die zum Entschlüsseln des Datenverkehrs mit wireshark erforderlich ist.
https://tlswg.org/sslkeylogfile/draft-ietf-tls-keylogfile.html
SSLKEYLOG besteht aus einer Reihe von Zeilen mit folgendem Format:
ClientRandom wird vom Sample-Fetch %[ssl_fc_client_random,hex] bereitgestellt. Das Geheimnis und das Label finden Sie in der folgenden Tabelle. Sie müssen eine SSLKEYLOGFILE mit allen Labels dieser Tabelle erzeugen.
Die folgenden Sample-Fetches liefern hexadezimale Zeichenfolgen und müssen nicht konvertiert werden.
Diese Fetches stehen für die Frontend- (fc) und Backend-Seite (bc) zur Verfügung. Ersetzen Sie “xx” durch “fc” oder “bc”, um die gewünschte Seite zu verwenden.
Dies ist nur mit OpenSSL 1.1.1 verfügbar und für TLS1.3-Sitzungen nützlich.
Wenn Sie den Inhalt einer SSLKEYLOGFILE für TLS < 1.3 erzeugen möchten, benötigen Sie nur diese Zeile:
“CLIENT_RANDOM %[ssl_fc_client_random,hex] %[ssl_fc_session_key,hex]”
Ein vollständiges Schlüsselprotokoll lässt sich mit einem log-format wie folgt erzeugen, auch wenn dies für Syslog nicht ideal ist:
HAProxy stellt die obigen Formate auch als vordefinierte Umgebungsvariablen bereit, die direkt in einer “log-format”-Direktive verwendet werden können:
tune.ssl.keyupdate-rate-limit <limit>
Begrenzt die Anzahl von KeyUpdate-Nachrichten, die pro Sekunde akzeptiert werden, auf <limit>, bevor dies als Flut betrachtet und die Verbindung beendet wird. Die Verarbeitung von KeyUpdate ist CPU-intensiv, und es gibt kaum einen Grund, viele solcher Nachrichten zu empfangen. Der Wert “0” deaktiviert die Ratenbegrenzung. Der Standardwert ist 100.
tune.ssl.lifetime <timeout>
Legt fest, wie lange eine zwischengespeicherte SSL-Sitzung gültig bleiben darf. Die Zeit wird in Sekunden angegeben und beträgt standardmäßig 300 (5 Minuten). Dies garantiert nicht, dass Sitzungen so lange erhalten bleiben: Ist der Cache voll, werden die am längsten ungenutzten Sitzungen unabhängig von ihrer konfigurierten Lebensdauer entfernt. Der eigentliche Zweck dieser Einstellung besteht darin, eine zu lange Verwendung von Sitzungen zu verhindern.
tune.ssl.maxrecord <number>
Legt die maximale Anzahl von Bytes fest, die zu Beginn der Datenübertragung an SSL_write() übergeben werden. Der Standardwert 0 bedeutet, dass es keine Begrenzung gibt. Bei SSL/TLS kann der Client Daten erst entschlüsseln, nachdem er einen vollständigen Record empfangen hat. Bei großen Records müssen Clients daher möglicherweise bis zu 16kB herunterladen, bevor sie mit der Verarbeitung beginnen können. Eine Begrenzung kann die Seitenladezeiten in Browsern verbessern, die über Netzwerke mit hoher Latenz oder niedriger Bandbreite verbunden sind. Es wird empfohlen, optimale Werte zu finden, die in 1 oder 2 TCP-Segmente passen (im Allgemeinen 1448 Byte über Ethernet mit aktivierten TCP-Zeitstempeln beziehungsweise 1460 bei deaktivierten Zeitstempeln). Dabei muss der zusätzliche Aufwand durch SSL/TLS berücksichtigt werden. Typische Werte von 1419 und 2859 lieferten in Tests gute Ergebnisse. Verwenden Sie “strace -e trace=write”, um den besten Wert zu ermitteln. HAProxy wechselt automatisch zu dieser Einstellung, sobald ein inaktiver Stream erkannt wurde (siehe tune.idletimer oben). Siehe auch tune.ssl.hard-maxrecord.
tune.ssl.ssl-ctx-cache-size <number>
Setzt die Größe des Caches für erzeugte Zertifikate auf <number> Einträge. Dies ist ein LRU-Cache. Da die dynamische Erzeugung eines SSL-Zertifikats aufwendig ist, werden die Zertifikate zwischengespeichert. Die Standardgröße beträgt 1000 Einträge.
tune.streams-elasticity <number>
Definiert einen Zielprozentsatz für Streams pro Frontend-Verbindung im Verhältnis zur maximalen Anzahl gleichzeitiger Verbindungen (maxconn), wenn alle Verbindungen aufgebaut sind. Diese Kennzahl gilt für gemultiplexte Protokolle wie HTTP/2 oder QUIC, bei denen jede Verbindung mehrere Streams empfangen kann. Mindestens einer ist immer garantiert; der Prozentsatz muss daher mindestens 100% betragen. Während des Verbindungsaufbaus kündigt HAProxy dynamisch zusätzliche Streams bis zur konfigurierten Grenze an und hält dabei das Zielverhältnis ein. Beim Aufbau erhält jede Frontend-Verbindung mindestens einen Stream. Zusätzliche Streams werden anhand des Zielprozentsatzes und der konfigurierten Stream-Grenzen zugeteilt. Dies ermöglicht eine effiziente Stream-Zuweisung bei wechselnder Last: mehr Streams bei niedriger und weniger bei hoher Last.
Hochdynamische Websites mit vielen Objekten pro Seite profitieren von hohen Verhältnissen, die viele Streams pro Verbindung ermöglichen. Websites, die im Durchschnitt weniger Streams verwenden (WebSocket, Anwendungscode), können niedrigere Verhältnisse nahe 120 oder 150 bevorzugen (20 bis 50% mehr Streams als Verbindungen), um bei anhaltender Last übermäßige Stream-Anzahlen zu verhindern.
Der Standardwert ist 0 und bedeutet, dass auf dieser Ebene keine Begrenzung erzwungen wird. Es gelten nur die H2- und QUIC-Konfigurationen (bei der Standardeinstellung von 100 Streams pro Verbindung entspricht dies 10000%). Für kleine Installationen mit maxconn um tausend bleibt dies die empfohlene Einstellung. Mittelgroße Installationen mit einigen tausend bis einigen zehntausend Verbindungen setzen das Verhältnis typischerweise zwischen 1000 und 5000 und erlauben damit bei Volllast 10 bis 50 Streams pro Verbindung. Große Installationen mit Hunderttausenden bis Millionen Verbindungen können niedrigere Werte (120 bis 200) verwenden, um bei Volllast im Durchschnitt 1.2 bis 2 Streams pro Verbindung zu unterstützen.
Im Gegensatz zu HTTP/2 kann QUIC die Anzahl gleichzeitiger Streams während der Lebensdauer einer Verbindung dynamisch anpassen. Die QUIC-Flusskontrolle ist jedoch strenger als die von HTTP/2. Daher sollten bei ihrer Verwendung ausreichend hohe Werte angegeben werden, um zusätzliche Latenz auf der Verbindung zu vermeiden. Für QUIC-Listener mit aktiviertem 0-RTT gibt es eine weitere Einschränkung: Der dem Peer anfänglich angekündigte Wert ignoriert die Stream-Elastizität und richtet sich ausschließlich nach “tune.quic.fe.stream.max-concurrent”. Nach dieser ersten Ankündigung bleibt das Prinzip der Stream-Elastizität während der Lebensdauer der Verbindung jedoch wirksam.
Die Überwachung der Gesamtzahl aktiver Streams in Backends einschließlich der Warteschlangen liefert einen praktischen Anhaltspunkt für eine dauerhaft tragbare Ziellast und hilft, übermäßige Kapazitätsbereitstellung zu vermeiden.
tune.stick-counters <number>
Legt die Anzahl von Stick-Zählern fest, die eine Verbindung oder Anfrage gleichzeitig über “track-sc*"-Aktionen in “tcp-request”- oder “http-request”-Regeln verfolgen darf. Der Standardwert wird beim Kompilieren durch das Makro MAX_SESS_STK_CTR festgelegt und beträgt standardmäßig 3. Mit dieser Einstellung lässt sich der Wert ändern und der beim Kompilieren angegebene Wert ignorieren; er darf jedoch nicht größer als 100 sein. Eine Erhöhung kann beim Übertragen komplexer Konfigurationen auf haproxy erforderlich sein, verursacht jedoch Kosten: Jeder Eintrag benötigt 16 Byte pro Verbindung und 16 Byte pro Anfrage. Dieser Speicher muss für alle Anfragen zugewiesen und mit Nullen gefüllt werden, selbst wenn er nicht verwendet wird. Der Wert 10 erhöht daher den Speicherverbrauch pro Anfrage um 320 Byte und bewirkt, dass dieser Speicher für jede Anfrage gelöscht wird, was messbare CPU-Auswirkungen hat. Werden dagegen keine “track-sc”-Regeln verwendet, kann der Wert verringert werden (0 ist zulässig und deaktiviert Stick-Zähler vollständig).
tune.takeover-other-tg-connections <value>
Standardmäßig wird nicht versucht, ungenutzte Verbindungen aus anderen Thread-Gruppen zu verwenden. Dieses Verhalten lässt sich jedoch ändern. Gültige Werte für <value> sind: “none”, der Standardwert, bei dem kein Versuch unternommen wird, ungenutzte Verbindungen aus anderen Thread-Gruppen zu verwenden; “restricted”, bei dem nur dann eine ungenutzte Verbindung von einem anderen Thread angefordert wird, wenn Protokolle verwendet werden, die keine neuen Verbindungen aufbauen können, etwa Reverse HTTP, oder wenn strict-maxconn verwendet wird; und “full”, bei dem immer auch in anderen Thread-Gruppen nach ungenutzten Verbindungen gesucht wird. Beachten Sie, dass Verbindungen aus anderen Thread-Gruppen Leistungseinbußen verursachen können und daher nur verwendet werden sollten, wenn dies wirklich erforderlich ist. Dieses Verhalten wird inzwischen durch tune.idle-pool.shared gesteuert. Dieses Schlüsselwort dient nur noch der Kompatibilität mit älteren Konfigurationen und wird künftig als veraltet eingestuft.
tune.vars.global-max-size <size>
Diese fünf Einstellungen steuern die maximale Speichermenge, die das Variablensystem verwenden darf. “global” begrenzt den insgesamt für alle Gültigkeitsbereiche verfügbaren Speicher. “proc” begrenzt den Speicher für den Prozessbereich, “sess” für den Sitzungsbereich, “txn” für den Transaktionsbereich und “reqres” für die Verarbeitung jeder einzelnen Anfrage oder Antwort. Die Speicherabrechnung ist hierarchisch: Grenzen auf einer übergeordneten Ebene schließen die untergeordneten Ebenen ein. “proc” umfasst “sess”, “sess” umfasst “txn” und “txn” umfasst “reqres”.
Wenn beispielsweise “tune.vars.sess-max-size” auf 100 begrenzt ist, können auch “tune.vars.txn-max-size” und “tune.vars.reqres-max-size” den Wert 100 nicht überschreiten. Wird eine Variable “txn.var” angelegt, die 100 Bytes enthält, ist der gesamte verfügbare Platz verbraucht. Beachten Sie, dass eine Überschreitung der Grenzen zur Laufzeit keine Fehlermeldung auslöst, Werte aber abgeschnitten oder beschädigt werden können. Planen Sie deshalb den Platzbedarf für die Speicherung aller Variablen genau.
tune.zlib.memlevel <number>
Legt den Parameter memLevel bei der Initialisierung von zlib für jeden Stream fest. Er bestimmt, wie viel Speicher für den internen Kompressionszustand reserviert werden soll. Der Wert 1 verwendet am wenigsten Speicher, ist jedoch langsam und verschlechtert das Kompressionsverhältnis. Der Wert 9 verwendet für optimale Geschwindigkeit am meisten Speicher. Zulässig sind Werte zwischen 1 und 9. Der Standardwert ist 8.
tune.zlib.windowsize <number>
Legt die Fenstergröße (die Größe des Verlaufspuffers) als Parameter der zlib-Initialisierung für jeden Stream fest. Größere Werte verbessern die Kompression auf Kosten eines höheren Speicherverbrauchs. Zulässig sind Werte zwischen 8 und 15. Der Standardwert ist 15.
3.3. Fehlerbehebung
anonkey <key>
Legt den globalen Anonymisierungsschlüssel auf <key> fest. Dieser muss eine 32-Bit-Zahl zwischen 0 und 4294967295 sein. CLI-Befehle verwenden diesen Schlüssel standardmäßig, wenn der anonymisierte Modus aktiviert ist. Der Schlüssel kann auch zur Laufzeit mit dem CLI-Befehl “set anon global-key” gesetzt werden. Siehe auch das Kommandozeilenargument “-dC” im Verwaltungshandbuch.
debug.counters { on | off }
Aktiviert (‘on’) oder deaktiviert (‘off’) die Aktualisierung der Ereigniszähler im Code. Diese Zähler werden vom CLI-Befehl “debug counters” unter dem Typ “CNT” ausgegeben. Sie stehen nur zur Verfügung, wenn der Code mit DEBUG_COUNTERS auf einem Wert von mindestens 1 kompiliert wurde. Bei dem Wert 1 werden die Zähler standardmäßig nicht aktualisiert (“debug.counters off”), bei dem Wert 2 werden sie standardmäßig aktualisiert (“debug.counters on”). Normalerweise besteht kein Anlass, diese Einstellung zu ändern, sofern nicht ein Entwickler darum bittet oder der Verdacht besteht, dass sie ungewöhnlich viel CPU-Zeit beansprucht. Im letzteren Fall ist ein Bericht an die Entwickler mit einem Auszug der Zähler erforderlich. Der Zustand lässt sich auch zur Laufzeit mit dem CLI-Befehl “debug counters” ändern. Weitere Informationen finden Sie im Verwaltungshandbuch.
force-cfg-parser-pause <timeout>
Dieser Befehl hält den Konfigurationsparser für <timeout> Millisekunden an. Das ist bei der Entwicklung oder beim Testen von Zeitüberschreitungen in Init-Skripten hilfreich, insbesondere zur Simulation eines sehr langen Neuladens. Dafür muss expose-experimental-directives gesetzt sein.
<timeout> gibt die Wartezeit standardmäßig in Millisekunden an. Durch Anhängen einer Einheit an die Zahl kann jedoch auch jede andere Einheit verwendet werden, wie am Anfang dieses Dokuments erläutert.
Beispiel:
quick-exit
Beschleunigt beim Neuladen das Beenden des alten Prozesses, indem die Freigabe von Speicherobjekten und Listenern übersprungen wird. Diese Ressourcen werden beim Beenden des Prozesses ohnehin vom Betriebssystem zurückgewonnen. Der Zeitgewinn ist nur gering und beträgt selbst bei sehr großen Konfigurationen höchstens einige hundert Millisekunden. Der eigentliche Haupteinsatzzweck besteht darin, einen gefundenen Fehler im deinit()-Code zu umgehen. Verwenden Sie diese Option möglichst nur auf Anweisung der Entwickler.
quiet
Unterdrückt alle Meldungen während des Starts. Entspricht dem Kommandozeilenargument “-q”.
warn-blocked-traffic-after <time>
Legt fest, nach welcher Verzögerung eine festhängende Task, die den Datenverkehr blockiert, eine Warnung auf der Standardfehlerausgabe auslöst. Die Verzögerung wird in Millisekunden angegeben und beträgt standardmäßig 100 ms. Zulässig sind Werte von einschließlich 1 ms bis einschließlich 1000 ms. Niedrigere Werte führen häufig, höhere Werte selten zu Warnungen. Der Watchdog beendet ohnehin eine außer Kontrolle geratene Task, die zweimal jeweils eine Sekunde lang nicht reagiert. Eine Warnverzögerung von 1000 ms löst daher normalerweise keine Warnung aus. Empfohlen werden Werte zwischen 10 und 100ms, um Konfigurationsfehler zu erkennen, die durch lange Antwortzeiten oder ruckelnde interaktive Sitzungen die Nutzung beeinträchtigen können. Solche Probleme können beispielsweise eine schlecht entworfene Lua-Sample-Fetch-Funktion mit aufwendigen Berechnungen oder eine sehr große map_reg- oder map_regm-Map-Datei mit hohen Auswertungskosten verursachen. Zum Vergleich: Ein TLS-Handshake kann zwischen einer und zwei Millisekunden beanspruchen, die Kompression eines 16kB großen HTTP-Antwortpuffers etwa eine Millisekunde. Die Ausgabe enthält einen Thread-Dump der verantwortlichen Task mit einem Backtrace und etwas Kontext, anhand dessen sich ermitteln lässt, wo die Zeit verbraucht wird.
zero-warning
Wenn diese Option gesetzt ist, verweigert HAProxy den Start, sobald beim Verarbeiten und Anwenden der Konfiguration eine Warnung ausgegeben wurde. Warnungen über ungeeignete Parameterkombinationen, sehr hohe Grenzen, die nicht gesetzt werden konnten, und ähnliche Probleme führen dann dazu, dass sich der Prozess beim Start mit einem Fehler beendet. Einige spät beim Start auftretende Warnungen kann diese Option nicht erfassen, etwa wenn beim Ändern der Gruppen-ID im Modus “daemon” oder “master-worker” zusätzliche Gruppen nicht abgelegt werden können oder wenn der Prozess nach fork() nicht als dumpbar markiert werden kann. Die Option erfasst keine Warnungen, die zur Laufzeit ausgegeben werden. Für Konfigurationen, die selten geändert werden, wird diese Option nachdrücklich empfohlen: Sie hilft, subtile Fehler zu erkennen und die Konfiguration sauber und mit künftigen Versionen kompatibel zu halten. Beachten Sie, dass auch “haproxy -c” in diesem Fall Fehler meldet. Diese Option entspricht dem Kommandozeilenargument “-dW”.
3.4. HTTPClient-Abstimmung
HTTPClient ist eine interne HTTP-Bibliothek, die von verschiedenen Subsystemen verwendet werden kann, beispielsweise in LUA-Skripten. HTTPClient wird nicht im Datenpfad eingesetzt und hat daher nichts mit dem HTTP-Datenverkehr zu tun, der HAProxy durchläuft.
httpclient.resolvers.disabled <on|off>
Deaktiviert die DNS-Auflösung des httpclient. Verhindert die Erstellung des resolvers-Abschnitts “default”.
Der Standardwert ist off.
httpclient.resolvers.id <resolvers id>
Legt den resolvers-Abschnitt fest, mit dem der httpclient die Namensauflösung versucht.
Standardmäßig wird die resolvers-ID “default” verwendet. Wenn diese Option nicht gesetzt ist und der Abschnitt nicht gefunden wird, wird lediglich die Namensauflösung deaktiviert.
Wird diese Option hingegen ausdrücklich gesetzt, führt ein Fehler beim Laden zu einem Konfigurationsfehler.
httpclient.resolvers.prefer <ipv4|ipv6>
Mit dieser Option lässt sich die gewünschte IP-Adressfamilie für die Namensauflösung auswählen. Das ist nützlich, wenn IPv6 in Ihrem Netzwerk nicht verfügbar ist. Der Standardwert ist “ipv6”.
httpclient.retries <number>
Legt fest, wie oft der httpclient eine fehlgeschlagene Anfrage erneut versucht. Die Wirkung entspricht der des Schlüsselworts “retries” in einem Backend.
Der Standardwert ist 3.
httpclient.ssl.ca-file <cafile>
Legt die ca-file fest, die zur Überprüfung des Serverzertifikats verwendet werden soll. Die Option akzeptiert dieselben Parameter wie die Option “ca-file” in einer server-Zeile.
Wenn diese Option nicht gesetzt ist, gilt standardmäßig der Wert “@system-ca”, der versucht, die CA des Systems zu laden. Schlägt dies fehl, wird SSL für den httpclient deaktiviert.
Wird diese Option hingegen ausdrücklich gesetzt, führt ein Fehlschlag zu einem Konfigurationsfehler.
httpclient.ssl.verify [none|required]
Funktioniert wie die Option verify in server-Zeilen. Bei ’none’ werden Serverzertifikate nicht überprüft. Der Standardwert ist “required”.
Wenn diese Option nicht gesetzt ist, gilt standardmäßig der Wert “required”. Schlägt dies fehl, wird SSL für den httpclient deaktiviert.
Wird diese Option hingegen ausdrücklich gesetzt, führt ein Fehlschlag zu einem Konfigurationsfehler.
httpclient.timeout.connect <timeout>
Legt die standardmäßige maximale Wartezeit für einen Verbindungsversuch des httpclient fest.
Argumente:
Der Standardwert ist 5000ms.
13 - 4. Proxys
Die Proxy-Konfiguration kann in einer Reihe von Abschnitten definiert werden:
- defaults [
<name>] [ from<defaults_name>] - frontend
<name>[ from<defaults_name>] - backend
<name>[ from<defaults_name>] - listen
<name>[ from<defaults_name>]
Ein “frontend”-Abschnitt beschreibt eine Gruppe lauschender Sockets, die Clientverbindungen annehmen.
Ein “backend”-Abschnitt beschreibt eine Gruppe von Servern, mit denen der Proxy eine Verbindung herstellt, um eingehende Verbindungen weiterzuleiten.
Ein “listen”-Abschnitt definiert einen vollständigen Proxy, bei dem Frontend- und Backend-Teil in einem einzigen Abschnitt kombiniert sind. Dies ist im Allgemeinen für rein TCP-basierten Datenverkehr nützlich.
Ein “defaults”-Abschnitt setzt alle Einstellungen auf die dokumentierten Standardwerte zurück und legt neue Werte für die nachfolgenden Abschnitte fest. Alle “frontend”, “backend” und “listen”-Abschnitte beziehen ihre Anfangseinstellungen immer aus einem defaults-Abschnitt, standardmäßig den zuletzt vor dem neu erstellten Abschnitt definierten. Es ist möglich, explizit einen bestimmten “defaults”-Abschnitt anzugeben, von dem die Anfangseinstellungen geladen werden sollen, indem dessen Name in der Abschnittszeile nach dem optionalen Schlüsselwort “from” angegeben wird. Während “defaults”-Abschnitte keinen Namen erfordern, wird die Angabe eines Namens für bessere Lesbarkeit empfohlen. Dies ist auch die einzige Möglichkeit, einen bestimmten Abschnitt anstelle des Standardvorgängers anzugeben. Da “defaults”-Abschnittsnamen optional sind, wird standardmäßig eine sehr großzügige Prüfung auf deren Namen angewendet, und diese dürfen sogar überlappen. Wenn jedoch ein “defaults”-Abschnitt von einem anderen Abschnitt referenziert wird, muss dessen Name der Syntax entsprechen, die für alle Proxy-Namen gilt, und dieser Name muss innerhalb der defaults-Abschnitte eindeutig sein. Bitte beachten Sie, dass unabhängig davon, was derzeit erlaubt ist, generell von der Verwendung doppelter Abschnittsnamen abgeraten wird und die gleiche Syntax wie für Proxy-Namen eingehalten werden sollte. Diese Regel könnte in einer zukünftigen Version verbindlich werden. Zudem wird eine Warnung ausgegeben, wenn ein defaults-Abschnitt explizit von einem Proxy verwendet wird, während er gleichzeitig implizit von einem anderen Proxy verwendet wird, weil er der zuletzt definierte ist. Es wird dringend empfohlen, beide Verwendungsarten nicht zu mischen, sondern entweder stets explizite Referenzen zu verwenden oder einen letzten gemeinsamen defaults-Abschnitt bereitzustellen, der ausschließlich für implizite Verwendungen reserviert ist.
Beachten Sie, dass ein defaults-Abschnitt auch seine Anfangseinstellungen von einem anderen defaults-Abschnitt beziehen kann, und dadurch Einstellungen über mehrere Ebenen von defaults-Abschnitten vererbt werden können. Dies kann praktisch sein, um bestimmte Konfigurationsprofile zu erstellen, die Gruppen von Standardwerten enthalten (z. B. TCP oder HTTP sowie kurze oder lange Zeitüberschreitungen), kann aber schnell unübersichtlich werden.
Standardmäßig werden benannte defaults-Abschnitte nach der Konfigurationsanalyse beibehalten. Dies ermöglicht deren Wiederverwendung bei der dynamischen Erstellung von Backends. Dieses Verhalten kann global über das Schlüsselwort “tune.defaults.purge” geändert werden.
Alle Proxy-Namen müssen aus Groß- und Kleinbuchstaben, Ziffern, ‘-’ (Bindestrich), ‘_’ (Unterstrich), ‘.’ (Punkt) und ‘:’ (Doppelpunkt) gebildet werden. Bei ACL-Namen wird zwischen Groß- und Kleinschreibung unterschieden. Daher bezeichnen “www” und “WWW” zwei verschiedene Proxys.
Historisch gesehen konnten sich alle Proxy-Namen unter bestimmten Bedingungen überlappen (z. B. wenn sie nicht über dieselben Frontend- oder Backend-Funktionen verfügten), doch dies verursachte zu viele Probleme in den Protokollen sowie Verwirrung bei CLI-Operationen, Stick-Table-Namen und Statistikabfragen. Zwei Proxys müssen nun unabhängig von ihren jeweiligen Funktionen unterschiedliche Namen haben.
Derzeit werden zwei wesentliche Proxy-Modi unterstützt: “tcp”, auch bekannt als Schicht 4, und “http”, auch bekannt als Schicht 7. Im Modus für Schicht 4 leitet HAProxy bidirektionalen Datenverkehr einfach zwischen zwei Seiten weiter. Im Modus für Schicht 7 analysiert HAProxy das Protokoll und kann anhand beliebiger Kriterien damit interagieren, indem es beliebige Inhalte in Anfragen oder Antworten zulässt, blockiert, umschaltet, hinzufügt, ändert oder entfernt.
Im HTTP-Modus hängt die Verarbeitung von Anfragen und Antworten, die über eine Verbindung fließen, von der Kombination der HTTP-Optionen im Frontend und im Backend ab. HAProxy unterstützt 3 Verbindungsmodi:
-
KAL: Keep-Alive (“option http-keep-alive”), der Standardmodus: Alle Anfragen und Antworten werden verarbeitet, und die Verbindungen bleiben zwischen Antworten und neuen Anfragen offen, aber inaktiv.
-
SCL: Serververbindung schließen (“option http-server-close”): Die Verbindung zum Server wird geschlossen, nachdem das Ende der Antwort empfangen wurde; die Verbindung zum Client bleibt offen.
-
CLO: Verbindung schließen (“option httpclose”): Die Verbindung wird nach Ende der Antwort geschlossen, und in beiden Richtungen wird “Connection: close” angehängt.
Der effektive Modus, der auf eine Verbindung angewendet wird, die durch ein Frontend und ein Backend läuft, kann je nach Proxy-Modus anhand der folgenden Matrix bestimmt werden, aber kurz gesagt sind die Modi symmetrisch, Keep-Alive ist die schwächste Option und das Schließen der Verbindung die stärkste.
Backend-Modus
Es ist möglich, ein TCP-Frontend an ein HTTP-Backend anzuschließen. Dies ist sinnlos, wenn nur HTTP-Verkehr behandelt wird. Es kann jedoch genutzt werden, um mehrere Protokolle innerhalb desselben Frontends zu verarbeiten. In diesem Fall wird die Clientverbindung zunächst als rohe TCP-Verbindung behandelt, bevor sie auf HTTP umgestellt wird. Vor dem Protokollwechsel werden die Inhaltsverarbeitungen auf Rohdaten durchgeführt. Nach dem Protokollwechsel werden die Daten analysiert und intern als HTX gespeichert, wodurch die Verwendung der Rohdarstellung nicht mehr möglich ist. Es gibt keine Möglichkeit, zurückzukehren.
Es gibt zwei Arten von Protokollwechseln: In-Place-Protokollwechsel und destruktive Protokollwechsel. Erstere beinhalten einen TCP-zu-HTTP/1-Protokollwechsel. In HTTP/1 werden die Anfrageverarbeitungen serialisiert, wodurch der anwendungsbezogene Datenstrom erhalten bleiben kann. Letztere beinhalten einen TCP-zu-HTTP/2-Protokollwechsel. Da es sich um ein multiplextes Protokoll handelt, kann der anwendungsbezogene Datenstrom keinem HTTP/2-Datenstrom zugeordnet werden und wird zerstört. Neue anwendungsbezogene Datenströme werden dann erstellt, wenn HAProxy neue HTTP/2-Datenströme auf der unteren Ebene im H2-Multiplexer empfängt. Es ist wichtig, diesen Unterschied zu verstehen, da dies die Art und Weise, wie Daten verarbeitet werden, grundlegend verändert. Bei einem HTTP/1-Protokollwechsel gehen die bereits auf Rohdaten durchgeführten Inhaltsverarbeitungen weder verloren noch werden sie erneut ausgeführt, während bei einem HTTP/2-Protokollwechsel die anwendungsbezogenen Datenströme getrennt sind und alle Frontend-Regeln systematisch auf jeden einzelnen angewendet werden. Wie bereits erwähnt, wird der erste Datenstrom, der TCP-Datenstrom, zerstört, jedoch erst nachdem die Frontend-Regeln ausgewertet wurden.
Bei der HTTP-Verarbeitung aus einem TCP-Proxy heraus ist außerdem zu beachten: HAProxy kann HTTP/1 während der tcp-request content-Regeln analysieren, aber nicht HTTP/2. Es ist lediglich möglich, die HTTP/2-Verbindungspräambel zu analysieren. Dies stellt eine erhebliche Einschränkung bezüglich der HTTP-Inhaltsanalyse im TCP-Modus dar. Konkret ist es nur möglich festzustellen, ob empfangene Daten HTTP sind. Zum Beispiel ist es nicht möglich, aufgrund des Host-Headers ein Backend auszuwählen, was in HTTP/1 trivial ist. Glücklicherweise gibt es eine Lösung, um diesen Nachteil zu mildern.
Es gibt zwei Möglichkeiten, einen HTTP-Protokollwechsel durchzuführen. Die erste, historische Methode, besteht darin, ein HTTP-Backend auszuwählen. Der Protokollwechsel erfolgt, wenn das Backend festgelegt wird. Für In-Place-Protokollwechsel wird nur die Backend-Konfiguration bei der HTTP-Datenverarbeitung berücksichtigt. Bei destruktiven Protokollwechseln wird der anwendungsbezogene Datenstrom zerstört, wodurch die Verarbeitung gestoppt wird. Mit dieser Methode sind die Möglichkeiten, ein Backend mit einer HTTP/2-Verbindung auszuwählen, wirklich begrenzt, wie oben erwähnt, und etwas sinnlos, da der Datenstrom zerstört wird. Die zweite Methode besteht darin, während der Auswertung der tcp-request content-Regeln den Protokollwechsel durchzuführen, mithilfe der Aktion “switch-mode http”. In diesem Fall erfolgt der Protokollwechsel im Frontend-Kontext, und es ist möglich, HTTP-Direktiven in diesem Frontend zu definieren. Für In-Place-Protokollwechsel bietet dies sofort die volle Leistungsfähigkeit der HTTP-Analyse. Das Verhalten ähnelt damit stark dem eines HTTP-Frontends. Bei destruktiven Protokollwechseln ändert sich nichts, außer dass es sinnlos ist, ein Backend auf Basis begrenzter Informationen auszuwählen. Dies ist natürlich die empfohlene Methode. Daher ist es ausreichend, im Rahmen der tcp-request content-Regeln den Anfrageprotokolltyp zu prüfen, um einen HTTP-Protokollwechsel durchzuführen. Alle verbleibenden HTTP-Manipulationen können dann in die http-request-Regelmenge des Frontends verlegt werden. Behalten Sie jedoch im Hinterkopf, dass die tcp-request content-Regeln weiterhin auf jedem Datenstrom ausgewertet werden, was sich nicht ändern lässt.
4.1. Matrix der Proxy-Schlüsselwörter
Die folgende Liste von Schlüsselwörtern wird unterstützt. Die meisten davon können nur in einem begrenzten Satz von Abschnittstypen verwendet werden. Einige sind als „veraltet“ markiert, da sie aus einer alten Syntax stammen, die verwirrend oder funktional eingeschränkt sein kann, und es gibt neue empfohlene Schlüsselwörter, die sie ersetzen sollen. Schlüsselwörter, die mit “(*)” markiert sind, können optional mit dem Präfix “no” invertiert werden, z. B. “no option contstats”. Dies ist sinnvoll, wenn die Option standardmäßig aktiviert ist und für einen bestimmten Fall deaktiviert werden muss. Solche Optionen können auch mit “default” präfixiert werden, um die Standardwerte unabhängig von vorherigen “defaults”-Abschnitten wiederherzustellen. Schlüsselwörter, die in defaults-Abschnitten unterstützt werden und mit “(!)” markiert sind, sind nur in benannten defaults-Abschnitten, nicht in anonymen, unterstützt.
Hinweis: Einige gefährliche und nicht empfohlene Direktiven sind bewusst nicht in der folgenden Matrix aufgeführt. Das ist beabsichtigt. Diese Direktiven sind dokumentiert. Doch durch ihre Nicht-Aufnahme in dieser Liste wird noch ein weiterer Weg geschaffen, um von ihrer Verwendung abzuraten.
4.2. Alphabetisch sortierte Schlüsselwortreferenz
Dieser Abschnitt enthält eine Beschreibung jedes Schlüsselworts und seiner Verwendung.
acl <aclname> <criterion> [flags] [operator] <value> ...
Eine Zugriffskontrollliste anlegen oder ergänzen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja(!) | ja | ja | ja
Diese Anweisung ist nur in benannten defaults-Abschnitten verfügbar, nicht in anonymen. ACLs, die in einem defaults-Abschnitt definiert sind, sind aus anderen Abschnitten, die ihn verwenden, nicht sichtbar.
Beispiel:
Siehe Abschnitt 7 zur ACL-Verwendung.
backlog <conns>
Dem System Hinweise auf die ungefähre gewünschte Größe der Listen-Warteschlange geben
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Diese Option ist nur für Stream-Listener, einschließlich QUIC-Listener, von Bedeutung. Bei QUIC-Instanzen verhält sie sich jedoch anders.
Für alle Listener außer QUIC besteht eine Möglichkeit zum Schutz vor SYN-Flood-Angriffen darin, die Größe des SYN-Backlogs des Systems zu erhöhen. Je nach System ist dies manchmal über einen Systemparameter einstellbar, manchmal nicht einstellbar und manchmal richtet sich das System nach Hinweisen, die die Anwendung beim Aufruf von listen() bereitstellt. Standardmäßig übergibt HAProxy den Wert von maxconn des Frontends an den listen()-Aufruf. Auf Systemen, die diesen Wert nutzen können, kann es gelegentlich sinnvoll sein, einen anderen Wert anzugeben, weshalb dieser backlog-Parameter existiert.
Unter Linux 2.4 wird der Parameter vom System ignoriert. Unter Linux 2.6 wird er als Hinweis verwendet, und das System akzeptiert Werte bis zur nächstgrößeren Zweierpotenz, jedoch nie oberhalb bestimmter Grenzen (üblicherweise 32768).
Für QUIC-Listener legt backlog eine gemeinsame Grenze für die maximale Anzahl aktiver Handshakes und Verbindungen fest, die darauf warten, angenommen zu werden. Die Handshake-Phase hängt hauptsächlich von der Netzwerklatenz zum entfernten Peer ab, während die zweite Phase ausschließlich von der Last von haproxy abhängt. Wenn eine dieser Grenzen erreicht ist, beginnt haproxy, empfangene INITIAL-Pakete zu verwerfen, wodurch keine neuen Verbindungen mehr angelegt werden können, bis der Überschuss an Verbindungen abnimmt. Dieser Zustand kann dazu führen, dass Browser stillschweigend auf eine ältere HTTP-Version wechseln und auf TCP umschalten.
Siehe auch: “maxconn” und die Optimierungshilfe des Zielbetriebssystems.
balance <algorithm> [ <arguments> ]
Den in einem Backend zu verwendenden Lastverteilungsalgorithmus festlegen.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Der Lastverteilungsalgorithmus eines Backends wird auf “random” festgelegt, wenn weder ein anderer Algorithmus noch ein Modus oder eine Option festgelegt wurde. Der Algorithmus darf für jedes Backend nur einmal festgelegt werden.
Bei Authentifizierungsschemata, die dieselbe Verbindung erfordern, wie NTLM, dürfen URI-basierte Algorithmen nicht verwendet werden, da dies dazu führen würde, dass nachfolgende Anfragen an verschiedene Backend-Server weitergeleitet werden, wodurch die ungültigen Annahmen verletzt würden, auf denen NTLM beruht.
TCP/HTTP-Beispiele:
LOG-Backend-Beispiele:
Hinweis: Die folgenden Einschränkungen und Besonderheiten beim Einsatz der “check_post”-Erweiterung mit “url_param” müssen berücksichtigt werden:
- Alle POST-Anfragen kommen für die Prüfung infrage, da nicht feststellbar ist, ob die Parameter im Textkörper oder in der Entität enthalten sind, die binäre Daten enthalten kann. Daher kann eine andere Methode erforderlich sein, um die Prüfung von POST-Anfragen einzuschränken, die keine URL-Parameter im Textkörper enthalten. (siehe acl http_end)
- Die Verwendung eines `<max_wait>`-Werts, der größer als die Größe des Anfrage-Puffers ist, ergibt keinen Sinn und ist nutzlos. Die Puffergröße wird beim Kompilieren festgelegt und beträgt standardmäßig 16 kB.
- Content-Encoding wird nicht unterstützt, die Parametersuche wird wahrscheinlich fehlschlagen; die Lastverteilung fällt auf Round Robin zurück.
- Expect: 100-continue wird nicht unterstützt, die Lastverteilung fällt auf Round Robin zurück.
- Transfer-Encoding (RFC7230 3.3.1) wird nur im ersten Chunk unterstützt. Wenn der gesamte Parameterwert nicht im ersten Chunk enthalten ist, ist die Auswahl des Servers undefiniert (genauer gesagt wird sie dadurch bestimmt, wie wenig tatsächlich im ersten Chunk enthalten war).
- Diese Funktion unterstützt nicht die Erzeugung einer Antwort mit dem Status 100, 411 oder 501.
- In einigen Fällen kann die Aktivierung von "check_post" einen Versuch auslösen, den gesamten Inhalt eines Nachrichtenkörpers zu durchsuchen. Die Suche endet normalerweise, wenn lineare Leerraumzeichen oder Steuerzeichen gefunden werden, was auf das Ende einer möglichen Liste von URL-Parametern hinweist. Dies ist wahrscheinlich kein Problem bei SGML-artigen Nachrichtenkörpern.
Siehe auch: “dispatch”, “cookie”, “transparent”, “hash-type”.
be-unpublished
Das Backend im unveröffentlichten Zustand starten.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Dadurch werden alle use_backend- und default_backend-Regeln aus einem anderen Proxy, die auf den aktuellen Proxy verweisen, ignoriert, und die nächsten Regeln zur inhaltsabhängigen Umschaltung werden ausgewertet. Dies kann jedoch über eine “force-be-switch”-Regel umgangen werden.
Dieser Zustand ähnelt dem deaktivierten Zustand, unterscheidet sich jedoch in einigen Punkten. Erstens wird ein unveröffentlichtes Backend weiterhin vollständig initialisiert, einschließlich der Health Checks der Server, die weiterhin aktiv bleiben. Schließlich kann ein Backend mit dem Befehl “publish backend” über die CLI veröffentlicht werden. Siehe das Management-Handbuch.
Siehe auch: “force-be-switch”
bind [<address>]:<port_range> [, ...] [param*]
Eine oder mehrere Adressen und/oder Ports festlegen, an denen ein Frontend lauscht.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | nein
Argumente:
Es ist möglich, eine durch Kommas getrennte Liste von address:port-Kombinationen anzugeben. Das Frontend lauscht dann an allen diesen Adressen. Es gibt keine feste Grenze für die Anzahl der Adressen und Ports, an denen ein Frontend lauschen kann, ebenso wenig wie für die Anzahl der “bind”-Anweisungen in einem Frontend.
Beispiel:
Hinweis: Bei Sockets im abstrakten Namensraum von Linux verwenden HAProxy-Sockets der Familie “abns” die gesamte Länge von sun_path als Adresslänge. Andere Programme wie socat verwenden standardmäßig nur die Länge der Zeichenkette. Übergeben Sie der Definition eines abstrakten Sockets in socat die Option “,unix-tightsocklen=0”, um Kompatibilität mit HAProxy zu erreichen, oder verwenden Sie stattdessen die HAProxy-Socket-Familie “abnsz”.
Siehe auch: “source”, “option forwardfor”, “unix-bind” und die PROXY-Protokoll-Dokumentation sowie Abschnitt 5 zu Bind-Optionen.
capture cookie <name> len <length>
Ein Cookie in der Anfrage und in der Antwort erfassen und protokollieren.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | nein
Argumente:
Es wird nur das erste Cookie erfasst. Sowohl die “cookie”-Anfrage-Header als auch die “set-cookie”-Antwort-Header werden überwacht. Dies ist besonders nützlich, um Anwendungsfehler zu erkennen, die zu Sitzungsüberschneidungen oder -diebstahl zwischen Benutzern führen, da die Cookies eines Benutzers normalerweise nur auf der Anmeldeseite geändert werden können.
Wenn das Cookie vom Client nicht übermittelt wurde, wird die zugehörige Protokollspalte mit “-” angezeigt. Wenn eine Anfrage keine Zuweisung eines Cookies durch den Server verursacht, wird in der Antwortspalte “-” angezeigt.
Die Erfassung erfolgt nur im Frontend, da sichergestellt werden muss, dass das Protokollformat für ein bestimmtes Frontend nicht je nach Backend wechselt. Dies könnte sich in Zukunft ändern. Es kann nur eine “capture cookie”-Anweisung pro Frontend geben. Die maximale Erfassungslänge wird durch die globale Einstellung “tune.http.cookielen” festgelegt und beträgt standardmäßig 63 Zeichen. Es ist nicht möglich, eine Erfassung in einem “defaults”-Abschnitt anzugeben.
Beispiel:
Siehe auch: “capture request header”, “capture response header” sowie Abschnitt 8 zur Protokollierung.
capture request header <name> len <length>
Das letzte Vorkommen des angegebenen Anfrageheaders erfassen und protokollieren.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | nein
Argumente:
Der vollständige Wert des letzten Vorkommens des Headers wird erfasst. Der Wert wird in geschweiften Klammern (’{}’) in das Protokoll aufgenommen. Werden mehrere Header erfasst, werden sie durch einen senkrechten Strich (’|’) getrennt und in derselben Reihenfolge angezeigt, in der sie in der Konfiguration deklariert wurden. Nicht vorhandene Header werden als leere Zeichenkette protokolliert. Häufig erfasste Anfrageheader sind das Feld “Host” in Umgebungen mit virtuellem Hosting, “Content-length” bei Unterstützung von Uploads, “User-agent” zur schnellen Unterscheidung echter Benutzer von Robotern und “X-Forwarded-For” in Umgebungen mit vorgeschalteten Proxys, um den Ursprung der Anfrage festzustellen.
Beim Erfassen von Headern wie “User-agent” können auch Leerzeichen protokolliert werden, was die Protokollanalyse erschwert. Wählen Sie daher die protokollierten Werte sorgfältig aus, wenn Ihr Protokollparser die geschweiften Klammern nicht zuverlässig auswerten kann.
Weder die Anzahl noch die Länge der erfassten Anfrageheader ist begrenzt. Es ist jedoch sinnvoll, beide gering zu halten, um den Speicherbedarf pro Stream zu begrenzen. Damit das Protokollformat für ein bestimmtes Frontend einheitlich bleibt, kann die Headererfassung nur in einem Frontend deklariert werden. In einem “defaults”-Abschnitt kann keine Erfassung angegeben werden.
Beispiel:
Siehe auch: “capture cookie”, “capture response header” sowie Abschnitt 8 zur Protokollierung.
capture response header <name> len <length>
Das letzte Vorkommen des angegebenen Antwortheaders erfassen und protokollieren.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | nein
Argumente:
Der vollständige Wert des letzten Vorkommens des Headers wird erfasst. Das Ergebnis wird nach den erfassten Anfrageheadern in geschweiften Klammern (’{}’) in das Protokoll aufgenommen. Werden mehrere Header erfasst, werden sie durch einen senkrechten Strich (’|’) getrennt und in derselben Reihenfolge angezeigt, in der sie in der Konfiguration deklariert wurden. Nicht vorhandene Header werden als leere Zeichenkette protokolliert. Häufig erfasste Antwortheader sind “Content-length”, der die erwartete Anzahl zurückgegebener Bytes angibt, und “Location”, um Weiterleitungen nachzuverfolgen.
Weder die Anzahl noch die Länge der erfassten Antwortheader ist begrenzt. Es ist jedoch sinnvoll, beide gering zu halten, um den Speicherbedarf pro Stream zu begrenzen. Damit das Protokollformat für ein bestimmtes Frontend einheitlich bleibt, kann die Headererfassung nur in einem Frontend deklariert werden. In einem “defaults”-Abschnitt kann keine Erfassung angegeben werden.
Beispiel:
Siehe auch: “capture cookie”, “capture request header” sowie Abschnitt 8 zur Protokollierung.
clitcpka-cnt <count>
Die maximale Anzahl von Keepalive-Prüfungen festlegen, die TCP auf der Clientseite senden soll, bevor es die Verbindung trennt.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Dieses Schlüsselwort entspricht der Socket-Option TCP_KEEPCNT. Wird es nicht angegeben, wird der systemweite TCP-Parameter (tcp_keepalive_probes) verwendet. Die Verfügbarkeit dieser Einstellung hängt vom Betriebssystem ab. Unter Linux funktioniert sie bekanntermaßen.
Siehe auch: “option clitcpka”, “clitcpka-idle”, “clitcpka-intvl”.
clitcpka-idle <timeout>
Die Zeit festlegen, die eine Verbindung inaktiv bleiben muss, bevor TCP Keepalive-Prüfungen sendet, sofern das Senden von TCP-Keepalive-Paketen auf der Clientseite aktiviert ist.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Dieses Schlüsselwort entspricht der Socket-Option TCP_KEEPIDLE. Wird es nicht angegeben, wird der systemweite TCP-Parameter (tcp_keepalive_time) verwendet. Die Verfügbarkeit dieser Einstellung hängt vom Betriebssystem ab. Unter Linux funktioniert sie bekanntermaßen.
Siehe auch: “option clitcpka”, “clitcpka-cnt”, “clitcpka-intvl”.
clitcpka-intvl <timeout>
Den zeitlichen Abstand zwischen einzelnen Keepalive-Prüfungen auf der Clientseite festlegen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Dieses Schlüsselwort entspricht der Socket-Option TCP_KEEPINTVL. Wird es nicht angegeben, wird der systemweite TCP-Parameter (tcp_keepalive_intvl) verwendet. Die Verfügbarkeit dieser Einstellung hängt vom Betriebssystem ab. Unter Linux funktioniert sie bekanntermaßen.
Siehe auch: “option clitcpka”, “clitcpka-cnt”, “clitcpka-idle”.
compression algo <algorithm> ...
HTTP-Komprimierung aktivieren.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Derzeit werden folgende Algorithmen unterstützt:
Die Komprimierung wird abhängig vom Anfrageheader Accept-Encoding aktiviert. Bei identity wird dieser Header nicht berücksichtigt. Unterstützen die Backend-Server HTTP-Komprimierung, bleiben diese Direktiven wirkungslos: HAProxy erkennt die komprimierte Antwort und komprimiert sie nicht erneut. Unterstützen die Backend-Server keine HTTP-Komprimierung und enthält die Anfrage einen Accept-Encoding-Header, komprimiert HAProxy die zugehörige Antwort.
Die Komprimierung wird deaktiviert, wenn: * die Anfrage im Header “Accept-Encoding” keinen unterstützten Komprimierungsalgorithmus angibt * die Antwort nicht HTTP/1.1 oder höher verwendet * der HTTP-Statuscode keiner der Werte 200, 201, 202 oder 203 ist * die Antwort weder einen Header “Content-Length” noch einen Header “Transfer-Encoding” mit dem letzten Wert “chunked” enthält * die Antwort einen Header “Content-Type” enthält, dessen erster Wert mit “multipart” beginnt * die Antwort im Header “Cache-control” den Wert “no-transform” enthält * User-Agent auf “Mozilla/4” passt, sofern es sich nicht um MSIE 6 mit XP SP2 oder MSIE 7 und neuer handelt * die Antwort einen Header “Content-Encoding” enthält, der anzeigt, dass die Antwort bereits komprimiert ist (siehe compression offload) * die Antwort einen ungültigen Header “ETag” oder mehrere ETag-Header enthält * die Nutzdatengröße unter der Mindestgröße liegt (siehe compression minsize-res)
Hinweis: Die Komprimierung gibt keinen Warning-Header aus.
Beispiele:
Siehe auch: “compression offload”, “compression direction”, “compression minsize-req” und “compression minsize-res”
compression minsize-req <size>
Die Mindestgröße der Nutzdaten in Bytes festlegen, ab der die Komprimierung angewendet wird.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Nutzdaten unterhalb dieser Größe werden nicht komprimiert. Dadurch entfällt unnötiger CPU-Aufwand für Daten, die von der Komprimierung nicht wesentlich profitieren würden. “minsize-req” gilt für Anfragen und “minsize-res” für Antworten. Der Standardwert ist 0.
compression offload
HAProxy ausschließlich als Komprimierungsinstanz einsetzen.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | ja
Die Einstellung “offload” bewirkt, dass HAProxy den Accept-Encoding-Header entfernt, um zu verhindern, dass Backend-Server Antworten komprimieren. Es wird dringend empfohlen, dies nicht zu tun, da sonst die gesamte Komprimierungsarbeit an der einzigen Stelle durchgeführt wird, an der HAProxy installiert ist. In bestimmten Bereitstellungsszenarien kann HAProxy jedoch vor einem fehlerhaften Gateway installiert sein, dessen fehlerhafte HTTP-Komprimierung nicht abgeschaltet werden kann. In diesem Fall kann HAProxy verwendet werden, um zu verhindern, dass das Gateway ungültige Nutzdaten ausgibt. In diesem Fall funktioniert das einfache Entfernen des Headers in der Konfiguration nicht, da es vor der Analyse des Headers angewendet wird und dadurch HAProxy am Komprimieren hindert. In solchen Szenarien sollte stattdessen die Einstellung “offload” verwendet werden.
Wird diese Einstellung in einem defaults-Abschnitt verwendet, wird eine Warnung ausgegeben und die Option ignoriert.
Siehe auch: “compression type”, “compression algo”, “compression direction”
compression direction <direction> (deprecated)
Ermöglicht es HAProxy, sowohl Anfragen als auch Antworten zu komprimieren. Gültige Werte sind “request”, um nur Anfragen zu komprimieren, “response”, um nur Antworten zu komprimieren, oder “both”, wenn beide komprimiert werden sollen. Der Standardwert ist “response”.
Diese Anweisung ist nur relevant, wenn die veraltete “filter compression” aktiviert wurde. Bei expliziter Verwendung der Filter comp-req und comp-res ist die Komprimierungsrichtung redundant.
Kann in folgenden Kontexten verwendet werden: http
Siehe auch: “compression type”, “compression algo”, “compression offload”
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
Cookiebasierte Sitzungsbindung in einem Backend aktivieren.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
In einem HTTP-Backend kann nur ein einziges Cookie zur Sitzungsbindung vorhanden sein, das in einem defaults-Abschnitt deklariert werden kann. Der Wert des Cookies entspricht dem Wert, der nach dem Schlüsselwort “cookie” in einer “server”-Anweisung angegeben ist. Wenn für einen bestimmten Server kein Cookie deklariert ist, wird kein Cookie gesetzt.
Beispiele:
Siehe auch: “balance source”, “capture cookie”, “server” und “ignore-persist”
declare capture [ request | response ] len <length>
Einen Erfassungsplatz deklarieren.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | nein
Argumente:
Diese Deklaration ist nur im Frontend- oder listen-Abschnitt verfügbar, der reservierte Platz kann jedoch in Backends verwendet werden. Das Schlüsselwort “request” reserviert einen Erfassungsplatz für die Anfrage, “response” reserviert einen Erfassungsplatz für die Antwort.
Siehe auch: “capture-req”, “capture-res” (Sample-Konverter), “capture.req.hdr”, “capture.res.hdr” (Sample-Abrufe), “http-request capture” und “http-response capture”
default-server [param*]
Die Standardoptionen für einen Server in einem Backend ändern.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Beispiel:
Siehe auch: “server” und Abschnitt 5 über Server-Optionen
default_backend <backend>
Das Backend festlegen, das verwendet werden soll, wenn keine “use_backend”-Regel zutrifft.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Bei der inhaltsabhängigen Umschaltung zwischen Frontend und Backends unter Verwendung des Schlüsselworts “use_backend” ist es oft nützlich, anzugeben, welches Backend verwendet wird, wenn keine Regel zutrifft. In der Regel ist dies das dynamische Backend, das alle unbestimmten Anfragen empfängt.
Wenn ein Backend deaktiviert oder unveröffentlicht ist, werden default_backend-Regeln, die darauf verweisen, ignoriert, und die Verarbeitung des Streams verbleibt beim ursprünglichen Proxy.
Beispiel:
Siehe auch: “use_backend”
description <string>
Einen listen-, frontend- oder backend-Abschnitt beschreiben.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | ja
Argumente: Zeichenkette
Ermöglicht das Hinzufügen eines Satzes zur Beschreibung des zugehörigen Objekts auf der HAProxy-HTML-Statistikseite. Die Beschreibung wird rechts neben dem Objektnamen angezeigt. Es ist nicht notwendig, Leerzeichen im <string>-Argument durch einen Backslash zu maskieren.
disabled
Einen Proxy, ein Frontend oder ein Backend deaktivieren.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Das Schlüsselwort “disabled” dient zur Deaktivierung einer Instanz, hauptsächlich, um einen Listener-Port freizugeben oder einen Dienst vorübergehend zu deaktivieren. Die Instanz wird weiterhin erstellt und ihre Konfiguration überprüft, aber sie wird im Zustand “stopped” erstellt und erscheint in den Statistiken entsprechend. Sie empfängt keinen Datenverkehr und sendet weder Health Checks noch Protokollmeldungen. Es ist möglich, mehrere Instanzen gleichzeitig zu deaktivieren, indem das Schlüsselwort “disabled” in einem “defaults”-Abschnitt verwendet wird.
Standardmäßig kann ein deaktiviertes Backend nicht für die inhaltsabhängige Umschaltung ausgewählt werden. Mit “force-be-switch” kann ein Teil des Datenverkehrs diese Einschränkung jedoch umgehen.
Siehe auch: “enabled”, “force-be-switch”
dispatch <address>:<port> (deprecated)
Eine Standardserveradresse festlegen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Argumente:
Das Schlüsselwort “dispatch” bezeichnet einen Standardserver, der verwendet wird, wenn kein anderer Server die Verbindung übernehmen kann. Früher wurde es verwendet, um nicht persistente Verbindungen an einen zusätzlichen Load-Balancer weiterzuleiten. Aufgrund seiner einfachen Syntax wurde es auch für einfache TCP-Relais verwendet. Für eine klarere Konfiguration wird empfohlen, darauf zu verzichten und stattdessen die Direktive “server” zu verwenden.
Dieses Schlüsselwort wurde in 3.3 als veraltet markiert und wird wegen einiger interner Einschränkungen in 3.5 entfernt (keine Unterstützung für SSL oder inaktive Verbindungen usw.). Die Verwendung führt zu einer Warnung, die durch Aktivierung der Anweisung “expose-deprecated-directives” im global-Abschnitt unterdrückt werden kann.
Die korrekte Vorgehensweise ohne diese Anweisung ist, einfach einen Server mit derselben Adresse und demselben Port zu deklarieren. Wenn die Anweisung “dispatch” mit anderen Servern kombiniert wurde, sollten diese Server mit einem Gewicht von null konfiguriert werden, damit sie vom Lastverteilungsalgorithmus niemals ausgewählt werden.
Beispiel:
Siehe auch: “server”
dynamic-cookie-key <string>
Den geheimen Schlüssel für dynamische Cookies eines Backends festlegen.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: Der zu verwendende geheime Schlüssel.
Wenn dynamische Cookies aktiviert sind (siehe die Anweisung “dynamic” für Cookies), wird für jeden Server ein dynamisches Cookie erstellt (sofern nicht explizit auf der “server”-Zeile angegeben), das aus einem Hash der IP-Adresse des Servers, des TCP-Ports und des geheimen Schlüssels gebildet wird. Auf diese Weise kann sichergestellt werden, dass die Sitzungsbindung über mehrere Load-Balancer hinweg erhalten bleibt, selbst wenn Server dynamisch hinzugefügt oder entfernt werden.
enabled
Einen Proxy, ein Frontend oder ein Backend aktivieren.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Das Schlüsselwort “enabled” dient zur expliziten Aktivierung einer Instanz, wenn die Standardeinstellung auf “disabled” gesetzt wurde. Dies wird äußerst selten verwendet.
Siehe auch: “disabled”
errorfile <code> <file>
Anstelle von HAProxy erzeugter Fehler den Inhalt einer Datei zurückgeben.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Dieses Schlüsselwort dient zum Ersetzen von Fehlern, die HAProxy selbst erkennt und zurückgibt; vom Server zurückgegebene Fehler werden damit nicht umgeschrieben. Daher werden nur wenige Fehlercodes unterstützt.
Der Code 200 wird als Antwort auf Anfragen ausgegeben, die auf eine “monitor-uri”-Regel passen.
Die Dateien werden beim Start von HAProxy eingelesen und müssen der HTTP-Spezifikation entsprechen. Sie sollten die konfigurierte Puffergröße (BUFSIZE), üblicherweise 16 kB, nicht überschreiten, da andernfalls ein interner Fehler zurückgegeben wird. Außerdem ist es sinnvoll, keine Verweise auf lokale Inhalte (etwa Bilder) einzufügen: Wenn alle Server ausgefallen sind, könnte sonst anstelle eines Bildes ein Fehler zurückgegeben werden, wodurch eine Schleife zwischen Client und HAProxy entsteht. Schließlich darf die Antwort (tune.bufsize - tune.maxrewrite) nicht überschreiten, damit für “http-after-response”-Regeln noch genügend Platz bleibt (siehe “tune.maxrewrite”).
Die Dateien werden zusammen mit der Konfiguration gelesen und im Speicher gehalten. Daher werden die Fehler auch dann weiterhin zurückgegeben, wenn der Prozess in einer chroot-Umgebung läuft; Änderungen an den Dateien werden während der Laufzeit des Prozesses nicht berücksichtigt. Eine einfache Methode zur Entwicklung dieser Dateien besteht darin, sie dem Statuscode 403 zuzuordnen und eine gesperrte URL abzufragen.
Siehe auch: “http-error”, “errorloc”, “errorloc302”, “errorloc303”
Beispiel:
errorfiles <name> [<code> ...]
Die im http-errors-Abschnitt <name> definierten Fehlerdateien vollständig oder teilweise importieren.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Die im http-errors-Abschnitt mit dem Namen <name> definierten Fehler werden in den aktuellen Proxy importiert. Wird kein Statuscode angegeben, werden alle Fehlerdateien dieses http-errors-Abschnitts importiert. Andernfalls werden nur die Fehlerdateien für die aufgeführten Statuscodes importiert. Diese Fehlerdateien überschreiben die bereits für den Proxy definierten benutzerdefinierten Fehler. Sie können ihrerseits durch nachfolgende Definitionen überschrieben werden. Funktional entspricht dies genau der manuellen Deklaration aller Fehlerdateien mit “errorfile”-Direktiven.
Siehe auch: “http-error”, “errorfile”, “errorloc”, “errorloc302”, “errorloc303” und Abschnitt 12.4 zu http-errors.
Beispiel:
errorloc <code> <url>
Anstelle von HAProxy erzeugter Fehler eine HTTP-Weiterleitung zu einer URL zurückgeben
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Dieses Schlüsselwort dient zum Ersetzen von Fehlern, die HAProxy selbst erkennt und zurückgibt; vom Server zurückgegebene Fehler werden damit nicht umgeschrieben. Daher werden nur wenige Fehlercodes unterstützt.
Der Code 200 wird als Antwort auf Anfragen ausgegeben, die auf eine “monitor-uri”-Regel passen.
Beide Schlüsselwörter geben den HTTP-Statuscode 302 zurück, der den Client anweist, die angegebene URL mit derselben HTTP-Methode abzurufen. Bei anderen Methoden als GET, etwa POST, kann dies erhebliche Probleme verursachen, da die an den Client gesendete URL möglicherweise nur GET zulässt. Um dieses Problem zu umgehen, verwenden Sie “errorloc303”: Es sendet den HTTP-Statuscode 303 und weist den Client damit an, die URL mit einer GET-Anfrage abzurufen.
Siehe auch: “http-error”, “errorfile”, “errorloc303”
errorloc303 <code> <url>
Anstelle von HAProxy erzeugter Fehler eine HTTP-Weiterleitung zu einer URL zurückgeben
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Dieses Schlüsselwort dient zum Ersetzen von Fehlern, die HAProxy selbst erkennt und zurückgibt; vom Server zurückgegebene Fehler werden damit nicht umgeschrieben. Daher werden nur wenige Fehlercodes unterstützt.
Der Code 200 wird als Antwort auf Anfragen ausgegeben, die auf eine “monitor-uri”-Regel passen.
Beide Schlüsselwörter geben den HTTP-Statuscode 303 zurück, der den Client anweist, die angegebene URL mit derselben HTTP-Methode GET abzurufen. Dies löst die üblichen Probleme mit “errorloc” und dem Code 302. Möglicherweise unterstützen einige sehr alte, vor HTTP/1.1 entwickelte Browser dies nicht; bislang wurden jedoch keine solchen Probleme gemeldet.
Siehe auch: “http-error”, “errorfile”, “errorloc”, “errorloc302”
email-alert from <emailaddr>
Die Absenderadresse festlegen, die sowohl im Umschlag als auch im Header der E-Mail-Benachrichtigungen verwendet wird. Von dieser Adresse werden die E-Mail-Benachrichtigungen versendet.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Außerdem müssen “email-alert mailers” und “email-alert to” festgelegt sein. Dann wird der Versand von E-Mail-Benachrichtigungen für den Proxy aktiviert.
Siehe auch: “email-alert level”, “email-alert mailers”, “email-alert myhostname”, “email-alert to”, Abschnitt 12.3 zu Mailern.
email-alert level <level>
Die maximale Protokollstufe von Meldungen festlegen, für die E-Mail-Benachrichtigungen gesendet werden. Dies dient als Filter für den Versand der E-Mail-Benachrichtigungen.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Die Standardstufe ist alert
Außerdem müssen “email-alert from”, “email-alert mailers” und “email-alert to” festgelegt sein. Dann wird der Versand von E-Mail-Benachrichtigungen für den Proxy aktiviert.
Benachrichtigungen werden gesendet, wenn:
- ein nicht pausierter Server als ausgefallen markiert wird und
<level>alert oder niedriger ist - ein pausierter Server als ausgefallen markiert wird und
<level>notice oder niedriger ist - ein Server als verfügbar markiert wird oder in den Zustand drain wechselt und
<level>notice oder niedriger ist - “option log-health-checks” aktiviert ist,
<level>info oder niedriger ist und der Status eines Health Checks aktualisiert wird
Siehe auch: “email-alert from”, “email-alert mailers”, “email-alert myhostname”, “email-alert to”, Abschnitt 12.3 zu Mailern.
email-alert mailers <mailersect>
Die Mailer festlegen, die für den Versand von E-Mail-Benachrichtigungen verwendet werden
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Außerdem müssen “email-alert from” und “email-alert to” festgelegt sein. Dann wird der Versand von E-Mail-Benachrichtigungen für den Proxy aktiviert.
Siehe auch: “email-alert from”, “email-alert level”, “email-alert myhostname”, “email-alert to”, Abschnitt 12.3 zu Mailern.
email-alert myhostname <hostname>
Den Hostnamen festlegen, der bei der Kommunikation mit Mailern verwendet wird.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Standardmäßig wird der Hostname des Systems verwendet.
Außerdem müssen “email-alert from”, “email-alert mailers” und “email-alert to” festgelegt sein. Dann wird der Versand von E-Mail-Benachrichtigungen für den Proxy aktiviert.
Siehe auch: “email-alert from”, “email-alert level”, “email-alert mailers”, “email-alert to”, Abschnitt 12.3 zu Mailern.
email-alert to <emailaddr>
Sowohl die Empfängeradresse im Umschlag als auch die Zieladresse im Header von E-Mail-Benachrichtigungen festlegen. An diese Adresse werden die E-Mail-Benachrichtigungen gesendet.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Außerdem müssen “email-alert mailers” und “email-alert to” festgelegt sein. Dann wird der Versand von E-Mail-Benachrichtigungen für den Proxy aktiviert.
Siehe auch: “email-alert from”, “email-alert level”, “email-alert mailers”, “email-alert myhostname”, Abschnitt 12.3 zu Mailern.
error-log-format <fmt>
Die Formatzeichenkette für Protokolleinträge bei Verbindungsfehlern auf der Frontendseite festlegen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Diese Direktive legt die Formatzeichenkette für Protokolleinträge fest, die Informationen zu Fehlern, Zeitüberschreitungen, Wiederholungsversuchen, erneuten Zuweisungen oder HTTP-Statuscodes 5xx enthalten. Dieses Format gilt somit für jede Protokollzeile, auf die sich die Option “log-separate-errors” auswirken würde, einschließlich der in Abschnitt 8.2.5 beschriebenen Verbindungsfehler.
Wird die Direktive in einem defaults-Abschnitt verwendet, verwenden alle nachfolgenden Frontends dasselbe Protokollformat. Abschnitt 8.2.6 beschreibt benutzerdefinierte Formatzeichenketten für Protokolle ausführlich.
Die Direktive “error-log-format” überschreibt vorherige “error-log-format”-Direktiven.
force-persist { if | unless } <condition>
Eine Bedingung deklarieren, um die Sitzungsbindung an ausgefallene Server zu erzwingen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Standardmäßig werden Anfragen nicht an ausgefallene Server verteilt. Mit “option persist” lässt sich dies erzwingen, allerdings ohne Bedingung; bei gesetzter “option redispatch” erfolgt zudem eine erneute Zuweisung an einen funktionsfähigen Server. Damit bleiben nur wenige Möglichkeiten, bestimmte Anfragen gezielt an einen Server zu senden, der für Wartungsarbeiten künstlich als ausgefallen markiert wurde.
Mit der Anweisung “force-persist” können verschiedene ACL-basierte Bedingungen deklariert werden. Sind sie erfüllt, ignoriert eine Anfrage den Ausfallstatus eines Servers und versucht dennoch, eine Verbindung zu ihm herzustellen. So lässt sich ein Server starten, der auf Health Checks weiterhin einen Fehler zurückgibt, und der Dienst mit einem speziell konfigurierten Browser testen. Praktische Möglichkeiten sind beispielsweise eine bestimmte Quell-IP-Adresse oder ein bestimmtes Cookie. Das Cookie hat außerdem den Vorteil, dass es im Browser über eine Testseite einfach hinzugefügt oder entfernt werden kann. Sobald der Dienst überprüft ist, kann er allgemein zugänglich gemacht werden, indem er auf Health Checks eine gültige Antwort zurückgibt.
Die erzwungene Sitzungsbindung wird aktiviert, wenn eine “if”-Bedingung erfüllt ist oder eine “unless”-Bedingung nicht erfüllt ist. Die abschließende erneute Zuweisung ist dabei immer deaktiviert.
Siehe auch: “option redispatch”, “ignore-persist”, “persist” und Abschnitt 7 zur ACL-Verwendung.
external-check command <command>
Das bei einem external-check auszuführende Programm
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Dem Befehl werden folgende Argumente übergeben:
<proxy_address> <proxy_port> <server_address> <server_port>
Die Werte <proxy_address> und <proxy_port> werden vom ersten Listener abgeleitet, der IPv4, IPv6 oder ein UNIX-Socket verwendet. Bei einem UNIX-Socket-Listener ist proxy_address der Pfad des Sockets und <proxy_port> die Zeichenkette “NOT_USED”. In einem backend-Abschnitt lässt sich kein Listener bestimmen; daher haben sowohl <proxy_address> als auch <proxy_port> den Zeichenkettenwert “NOT_USED”.
Einige Werte werden auch über Umgebungsvariablen bereitgestellt.
Umgebungsvariablen:
Wird der Befehl ausgeführt und mit dem Status null beendet, gilt die Prüfung als erfolgreich; andernfalls gilt sie als fehlgeschlagen.
Beispiel:
Siehe auch: “external-check”, “option external-check”, “external-check path”
external-check path <path>
Der Wert der Umgebungsvariablen PATH bei der Ausführung eines external-check
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Der Standardpfad ist “”.
Beispiel:
Siehe auch: “external-check”, “option external-check”, “external-check command”
force-be-switch { if | unless } <condition>
Der inhaltsabhängigen Umschaltung erlauben, ein Backend auch dann auszuwählen, wenn es deaktiviert oder unveröffentlicht ist. Administratoren können mit dieser Regel den Datenverkehr zu Diensten testen, bevor sie diese nach außen zugänglich machen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | nein
Siehe auch: “be-unpublished”, “disabled”
filter <name> [param*]
Den Filter <name> zur Filterliste des Proxys hinzufügen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | ja
Argumente:
Die filter-Zeile kann für denselben Proxy mehrfach verwendet werden. Bei Bedarf kann derselbe Filter mehrmals referenziert werden.
Beispiel:
Siehe auch: Abschnitt 9 .
fullconn <conns>
Festlegen, bei welcher Backend-Last die Server ihren maxconn-Wert erreichen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Ist für einen Server der Parameter “maxconn” angegeben, überschreitet seine Anzahl gleichzeitiger Verbindungen diesen Wert niemals. Ist zusätzlich “minconn” angegeben, bezeichnet dies eine dynamische Grenze, die der Backend-Last folgt. Der Server akzeptiert dann stets mindestens <minconn> Verbindungen, aber nie mehr als <maxconn>. Hat das Backend weniger als <conns> gleichzeitige Verbindungen, steigt die Grenze linear zwischen den beiden Werten an. Dadurch lässt sich die Serverlast bei normalem Betrieb begrenzen und bei hoher Last weiter erhöhen, ohne die Server bei außergewöhnlich hoher Last zu überlasten.
Da sich dieser Wert nur schwer richtig bestimmen lässt, setzt HAProxy ihn automatisch auf 10% der Summe der maxconn-Werte aller Frontends, die zu diesem Backend verzweigen können (anhand der Regeln “use_backend” und “default_backend”). Daher kann die Angabe gefahrlos entfallen. “use_backend”-Regeln mit dynamischen Namen werden jedoch nicht berücksichtigt, da sich nicht feststellen lässt, ob sie auf dieses Backend verweisen könnten.
Beispiel:
Siehe auch: “maxconn”, “server”
guid <string>
Eine globale, eindeutige ID für diesen Proxy festlegen, bei der Groß- und Kleinschreibung unterschieden werden.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | ja
<string> muss in der gesamten haproxy-Konfiguration über alle Objekttypen hinweg eindeutig sein. Das Format ist nicht vorgegeben, damit Benutzer ihre eigene Namenskonvention wählen können. Die einzige Einschränkung ist die Länge, die 127 Zeichen nicht überschreiten darf. Zulässig sind alle alphanumerischen Zeichen sowie ‘.’, ‘:’, ‘-’ und ‘_’. Siehe auch “shm-stats-file”.
hash-balance-factor <factor>
Den Lastverteilungsfaktor für konsistentes Hashing mit begrenzter Last festlegen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | nein | ja
Argumente:
Die Angabe eines “hash-balance-factor” für einen Server mit “hash-type consistent” aktiviert einen Algorithmus, der verhindert, dass ein einzelner Server zu viele Anfragen gleichzeitig erhält, selbst wenn manche Hash-Buckets wesentlich mehr Anfragen erhalten als andere. Der Wert 0 für <factor> (der Standardwert) deaktiviert die Funktion. Andernfalls ist <factor> ein Prozentsatz größer als 100. Ist <factor> beispielsweise 150, darf kein Server eine Last von mehr als dem 1.5-Fachen des Durchschnitts haben. Werden Servergewichte verwendet, werden diese berücksichtigt.
Scheidet der zunächst ausgewählte Server aus, wählt der Algorithmus anhand des Anfragehashes einen anderen Server, bis ein Server mit freier Kapazität gefunden wird. Ein höherer <factor> erlaubt eine ungleichmäßigere Verteilung zwischen den Servern; ein niedrigerer <factor> bedeutet dagegen, dass im Durchschnitt mehr Server geprüft werden, was sich auf die Leistung auswirkt. Sinnvolle Werte liegen zwischen 125 und 200.
Diese Einstellung wird auch von “balance random” verwendet, das intern auf dem Verfahren des konsistenten Hashings beruht.
Siehe auch: “balance” und “hash-type”.
hash-preserve-affinity { always | maxconn | maxqueue }
Ein Verfahren für die Zuordnung von Streams zu Servern bei hashbasierter Lastverteilung festlegen, wenn Server ausgelastet sind oder eine volle Warteschlange haben.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Folgende Werte können angegeben werden:
- "always" : Dies ist die Standardstrategie. Ein Stream wird anhand des
Hashings einem Server zugeordnet, unabhängig davon, ob der
Server derzeit ausgelastet ist.
- "maxconn" : Bei dieser Auswahl werden Server übersprungen, für die
"maxconn" festgelegt ist und die derzeit ausgelastet sind.
Entlang des Hash-Rings wird ein anderer Server ausgewählt.
Dies wirkt sich nicht auf Server ohne "maxconn" aus. Sind
alle Server ausgelastet, wird die Anfrage in die Warteschlange
des letzten Servers im Hash-Ring vor dem ursprünglich
ausgewählten Server eingereiht.
- "maxqueue": Bei dieser Auswahl werden Server übersprungen, für die
"maxconn" festgelegt ist, "maxqueue" einen Wert ungleich null
hat (begrenzte Warteschlangengröße) und deren Warteschlange
derzeit voll ist. Entlang des Hash-Rings wird ein anderer
Server ausgewählt. Dies wirkt sich nicht auf Server aus,
bei denen nicht sowohl "maxconn" als auch "maxqueue"
festgelegt sind.
Siehe auch: “maxconn”, “maxqueue”, “hash-balance-factor”
hash-type <method> <function> <modifier>
Ein Verfahren zur Zuordnung von Hashes zu Servern festlegen
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Der Standard-Hash-Typ ist “map-based” und wird für die meisten Anwendungen empfohlen. Die Standardfunktion ist “sdbm”; die Funktion sollte anhand des Wertebereichs der zu hashenden Werte ausgewählt werden.
Siehe auch: “balance”, “hash-balance-factor”, “hash-preserve-affinity”, “server”
http-after-response <action> <options...> [ { if | unless } <condition> ]
Zugriffskontrolle für alle Antworten auf Schicht 7 (von Servern, Applets/Diensten und intern erzeugte Antworten).
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja(!) | ja | ja | ja
Die Anweisung http-after-response definiert Regeln für die Verarbeitung auf Schicht 7. Die Regeln werden in der Reihenfolge ihrer Deklaration ausgewertet, wenn sie in einem Abschnitt frontend, listen oder backend vorkommen. Da sie auf Antworten angewendet werden, werden zuerst die Regeln des Backends und anschließend die des Frontends angewendet. Auf jede Regel kann optional eine ACL-basierte Bedingung folgen; dann wird die Regel nur ausgewertet, wenn diese Bedingung wahr ist.
Anders als http-response-Regeln gelten diese Regeln für alle Antworten: sowohl für Serverantworten als auch für sämtliche von HAProxy erzeugten Antworten. Sie werden am Ende der Antwortanalyse und vor der Datenweiterleitung ausgewertet.
Die Bedingung wird unmittelbar vor der Ausführung der Aktion ausgewertet, und die Aktion wird genau einmal ausgeführt. Daher ist es unproblematisch, wenn eine Aktion ein Element ändert, das in der Bedingung geprüft wird. Das bedeutet auch, dass mehrere Aktionen dieselbe Bedingung verwenden können: Die erste Aktion, die das Ergebnis der Bedingung ändert, reicht dann aus, um die übrigen Aktionen implizit zu deaktivieren. Dies wird beispielsweise verwendet, wenn einer leeren Variablen ein Wert aus verschiedenen Quellen zugewiesen werden soll. Die Anzahl der “http-after-response”-Anweisungen pro Instanz ist nicht begrenzt.
Das erste Schlüsselwort nach “http-after-response” in der Syntax ist die Aktion der Regel, auf die optional unterschiedlich viele Argumente für die Aktion folgen. Die unterstützten Aktionen und ihre jeweilige Syntax sind in Abschnitt 4.3 „Aktionen“ aufgeführt (suchen Sie nach Aktionen mit einem Häkchen in der Spalte “HTTP Aft”).
Diese Direktive ist nur in benannten defaults-Abschnitten verfügbar, nicht in anonymen. Im defaults-Abschnitt definierte Regeln werden vor denen im zugehörigen Proxy-Abschnitt ausgewertet. Um Mehrdeutigkeiten zu vermeiden, darf derselbe defaults-Abschnitt in diesem Fall nicht zugleich von Proxys mit Frontend-Funktion und von Proxys mit Backend-Funktion verwendet werden. Ein listen-Abschnitt kann daher keinen defaults-Abschnitt verwenden, der solche Regeln definiert.
Hinweis: Fehler, die bereits früh beim Parsen der Anfrage auftreten, werden auf einer niedrigeren Ebene vom Multiplexer behandelt, noch vor jeder HTTP-Analyse. Für diese Fehler wird daher kein http-after-response-Regelsatz ausgewertet.
Beispiel:
http-check comment <string>
Einen Kommentar für die nachfolgende http-check-Regel definieren, der bei ihrem Fehlschlagen im Protokoll ausgegeben wird.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Dies funktioniert nur für die Regeln connect, send und expect. Es dient einer verständlichen Fehlermeldung.
Siehe auch: “option httpchk”, “http-check connect”, “http-check send” und “http-check expect”.
http-check connect [default] [port <expr>] [addr <ip>] [send-proxy]
Eine neue Verbindung für einen HTTP-Health-Check öffnen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Wie bei tcp-check-Health-Checks kann die Verbindung konfiguriert werden, die für einen HTTP-Health-Check verwendet wird. Diese Direktive sollte auch zur Beschreibung eines Szenarios mit mehreren Anfrage-Antwort-Wechseln verwendet werden, möglicherweise über unterschiedliche Ports oder mit unterschiedlichen Servern.
Wenn weder in der Serverzeile ein TCP-Port noch eine port-Direktive für den Server konfiguriert ist, muss im ersten Schritt der http-check-Sequenz der Port mit “http-check connect” angegeben werden.
In einem http-check-Regelsatz ist ein ‘connect’ erforderlich; außerdem muss der Regelsatz mit einer ‘connect’-Regel beginnen. Damit soll sichergestellt werden, dass Administratoren wissen, was sie tun.
Auch wenn der Regelsatz mit connect beginnen muss, dürfen diesem noch Regeln vom Typ set-var, unset-var oder comment vorausgehen.
Beispiele:
Siehe auch: “option httpchk”, “http-check send”, “http-check expect”
http-check disable-on-404
Bei einer HTTP/404-Antwort auf Health Checks einen Wartungsmodus aktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Wenn diese Option aktiviert ist, wird ein Server, der eine HTTP-Antwort 404 zurückgibt, aus der weiteren Lastverteilung ausgeschlossen, empfängt jedoch weiterhin Verbindungen mit Sitzungsbindung. Damit können Web-Administratoren ihre Server bequem geordnet herunterfahren. Es ist wichtig zu beachten, dass ein Server, der als ausgefallen erkannt wird, während er sich in diesem Modus befindet, keine alert-Meldung auslöst, sondern lediglich eine notice-Meldung. Wenn der Server erneut 2xx oder 3xx antwortet, wird er sofort wieder in die Farm eingefügt. Der Status auf der Statistikseite meldet “NOLB” für einen Server in diesem Modus. Es ist wichtig zu beachten, dass diese Option nur in Verbindung mit der “httpchk”-Option funktioniert. Wenn diese Option zusammen mit “http-check expect” verwendet wird, hat sie Vorrang, sodass 404-Antworten weiterhin als Soft-Stop betrachtet werden. Beachten Sie außerdem, dass ein gestoppter Server auch dann weiterhin gestoppt bleibt, wenn er mit 404 antwortet. Diese Option wird nur für laufende Server ausgewertet.
Siehe auch: “option httpchk” und “http-check expect”.
http-check expect [min-recv <int>] [comment <msg>]
HTTP-Health-Checks so konfigurieren, dass sie Antwortinhalte oder bestimmte Statuscodes berücksichtigen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Standardmäßig betrachtet “option httpchk” die Antwortstatuscodes 2xx und 3xx als gültig und alle anderen als ungültig. Wenn “http-check expect” verwendet wird, definiert es, was als gültig oder ungültig gilt. In einem Backend ist nur eine einzige “http-check”-Anweisung zulässig. Wenn ein Server nicht antwortet oder eine Zeitüberschreitung auftritt, schlägt die Prüfung selbstverständlich fehl. Die verfügbaren Musterabgleiche sind:
Es ist wichtig zu beachten, dass die Antworten auf eine bestimmte Größe begrenzt werden, die durch die globale Option “tune.bufsize” festgelegt ist, die standardmäßig 16384 Bytes beträgt. Daher enthalten zu große Antworten bei Verwendung von “string” oder “rstring” möglicherweise nicht das erforderliche Muster. Falls eine große Antwort unbedingt erforderlich ist, kann die Standardmaximalgröße durch Setzen der globalen Variablen geändert werden. Es ist jedoch ratsam, sich daran zu erinnern, dass die Analyse sehr großer Antworten CPU-Zyklen verschwenden kann, insbesondere wenn reguläre Ausdrücke verwendet werden, und dass es immer besser ist, die Prüfungen auf kleinere Ressourcen zu konzentrieren.
In einer http-check-Regelsatz kann die letzte expect-Regel implizit sein. Wenn nach der letzten “http-check send”-Anweisung keine expect-Regel angegeben ist, wird eine implizite expect-Regel definiert, die auf Statuscodes 2xx oder 3xx prüft. Das bedeutet, diese Regel ist auch dann definiert, wenn überhaupt keine “http-check”-Regel vorhanden ist, wenn nur “option httpchk” gesetzt ist.
Wenn “http-check expect” mit “http-check disable-on-404” kombiniert wird, hat schließlich die letztere Direktive Vorrang, wenn der Server mit 404 antwortet.
Beispiele:
Siehe auch: “option httpchk”, “http-check connect”, “http-check disable-on-404” und “http-check send”.
http-check send [meth <method>] [{ uri <uri> | uri-lf <fmt> }>] [ver <version>]
Der bei HTTP-Health-Checks gesendeten Anfrage eine optionale Liste von Headern und/oder einen Nachrichtenkörper hinzufügen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Neben der Anfragezeile, die durch die Anweisung “option httpchk” definiert wird, ist dies die gültige Methode, um einige Header und optional einen Nachrichtenkörper zur Anfrage hinzuzufügen, die während HTTP-Health-Checks gesendet wird. Wenn ein Nachrichtenkörper definiert ist, wird automatisch der zugehörige “Content-Length”-Header hinzugefügt. Daher sollte dieser Header oder der “Transfer-encoding”-Header nicht in der Anfrage enthalten sein, die durch “http-check send” bereitgestellt wird. Falls vorhanden, wird er ignoriert. Der alte Trick, Header nach der Versionszeichenkette in der “option httpchk”-Zeile hinzuzufügen, ist nun veraltet.
Außerdem unterstützt “http-check send” kein HTTP-Keep-Alive. Beachten Sie, dass automatisch ein “Connection: close”-Header angehängt wird, es sei denn, ein Connection-Header wurde bereits über einen hdr-Eintrag konfiguriert.
Beachten Sie außerdem, dass der Host-Header und der Authority-Teil der Anfrage, wenn beide definiert sind, automatisch synchronisiert werden. Das bedeutet, wenn beim Senden der HTTP-Anfrage ein Host-Header eingefügt wird, wird der Authority-Teil der Anfrage entsprechend aktualisiert. Seien Sie daher nicht überrascht, wenn der Host-Header-Wert den konfigurierten Authority-Teil der Anfrage überschreibt.
Beachten Sie außerdem, dass derzeit kein Host-Header automatisch in HTTP/1.1 oder höheren Anfragen hinzugefügt wird. Sie sollten ihn explizit hinzufügen.
Siehe auch: “option httpchk”, “http-check send-state” und “http-check expect”.
http-check send-state
Die Ausgabe eines Zustandsheaders bei HTTP-Health-Checks aktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Wenn diese Option aktiviert ist, sendet HAProxy systematisch einen speziellen Header “X-Haproxy-Server-State” mit einer Liste von Parametern, die jedem Server mitteilen, wie er von HAProxy wahrgenommen wird. Dies kann beispielsweise dann nützlich sein, wenn ein Server ohne Zugriff auf HAProxy verändert wird und der Betreiber wissen möchte, ob HAProxy ihn weiterhin als aktiv erkennt oder ob der Server der letzte in einer Farm ist.
Der Header besteht aus durch Semikolons getrennten Feldern, wobei das erste ein Wort (“UP”, “DOWN”, “NOLB”) ist, möglicherweise gefolgt von der Anzahl gültiger Prüfungen im Verhältnis zur insgesamt für den Zustandswechsel erforderlichen Anzahl, wie in der Statistikoberfläche. Die folgenden Felder haben die Form “<variable>=<value>” und geben in beliebiger Reihenfolge einige Werte an, die in der Statistikoberfläche verfügbar sind: – eine Variable “address”, die die Adresse des Backend-Servers enthält. Dies entspricht dem <address>-Feld in der Serverdeklaration. Bei Unix-Domain-Sockets wird “unix” angezeigt.
- eine Variable "port", die den Port des Backend-Servers enthält. Dies entspricht dem `<port>`-Feld in der Serverdeklaration. Bei Unix-Domain-Sockets wird "unix" angezeigt.
- eine Variable "name", die den Namen des Backends gefolgt von einem Schrägstrich ("/") und dem Namen des Servers enthält. Dies kann verwendet werden, wenn ein Server in mehreren Backends überprüft wird.
- eine Variable "node", die den Namen des HAProxy-Knotens enthält, wie in der globalen "node"-Variablen festgelegt, andernfalls den Hostnamen des Systems, falls nicht angegeben.
- eine Variable "weight", die das Gewicht des Servers, einen Schrägstrich ("/") und das Gesamtgewicht der Farm (wobei nur verwendbare Server gezählt werden) enthält. Dies hilft zu erkennen, ob andere Server zur Lastverteilung zur Verfügung stehen, wenn dieser ausfällt.
- eine Variable "scur", die die aktuelle Anzahl an gleichzeitigen Verbindungen auf dem Server, gefolgt von einem Schrägstrich ("/") und der Gesamtanzahl an Verbindungen auf allen Servern des gleichen Backends enthält.
- eine Variable "qcur", die die aktuelle Anzahl an Anfragen in der Warteschlange des Servers enthält.
Beispiel für einen vom Anwendungsserver empfangenen Header:
Siehe auch: “option httpchk”, “http-check disable-on-404” und “http-check send”.
http-check set-var(<var-name>[,<cond>...]) <expr>
Diese Operation legt den Inhalt einer Variablen fest. Die Variable wird inline deklariert.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Beispiele:
http-check unset-var(<var-name>)
Eine Referenz auf eine Variable innerhalb ihres Gültigkeitsbereichs freigeben.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Beispiele:
http-error status <code> [content-type <type>]
file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
[ hdr `<name>` `<fmt>` ]*
Eine benutzerdefinierte Fehlermeldung festlegen, die anstelle der von HAProxy erzeugten Fehler verwendet wird.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Diese Direktive kann anstelle von “errorfile” verwendet werden, um eine benutzerdefinierte Fehlermeldung festzulegen. Wie die Direktive “errorfile” gilt sie für Fehler, die HAProxy erkennt und zurückgibt. Ist eine Fehlerdatei definiert, wird sie beim Start von HAProxy eingelesen und muss den HTTP-Standards entsprechen. Die erzeugte Antwort darf die konfigurierte Puffergröße (BUFFSIZE) nicht überschreiten, da andernfalls ein interner Fehler zurückgegeben wird. Wenn Sie diese Fehler mit http-after-response-Regeln umschreiben möchten, sollte schließlich der reservierte Pufferbereich verfügbar sein (siehe “tune.maxrewrite”).
Die Dateien werden zusammen mit der Konfiguration gelesen und im Speicher gehalten. Daher werden die Fehler auch dann weiterhin zurückgegeben, wenn der Prozess in einer chroot-Umgebung läuft; Änderungen an den Dateien werden während der Laufzeit des Prozesses nicht berücksichtigt.
Hinweis: Fehler vom Typ 400/408/500, die früh beim Parsen der Anfrage auftreten, werden auf einer niedrigeren Ebene vom Multiplexer behandelt. Auf dieser Ebene wird keine benutzerdefinierte Formatierung unterstützt. Daher werden nur statische Fehlermeldungen unterstützt, die mit der Direktive “errorfile” definiert sind. Diese Einschränkung besteht jedoch nur beim Parsen der Anfrageheader oder zwischen zwei Transaktionen.
Siehe auch: “errorfile”, “errorfiles”, “errorloc”, “errorloc302”, “errorloc303” und Abschnitt 12.4 zu http-errors.
http-request <action> [options...] [ { if | unless } <condition> ]
Zugriffskontrolle für Anfragen auf Schicht 7
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja(!) | ja | ja | ja
Die Anweisung http-request definiert Regeln für die Verarbeitung auf Schicht 7. Die Regeln werden in der Reihenfolge ihrer Deklaration ausgewertet, wenn sie in einem Abschnitt frontend, listen oder backend vorkommen. Auf jede Regel kann optional eine ACL-basierte Bedingung folgen; dann wird die Regel nur ausgewertet, wenn diese Bedingung wahr ist.
Die Bedingung wird unmittelbar vor der Ausführung der Aktion ausgewertet, und die Aktion wird genau einmal ausgeführt. Daher ist es unproblematisch, wenn eine Aktion ein Element ändert, das in der Bedingung geprüft wird. Das bedeutet auch, dass mehrere Aktionen dieselbe Bedingung verwenden können: Die erste Aktion, die das Ergebnis der Bedingung ändert, reicht dann aus, um die übrigen Aktionen implizit zu deaktivieren. Dies wird beispielsweise verwendet, wenn einer leeren Variablen ein Wert aus verschiedenen Quellen zugewiesen werden soll. Die Anzahl der “http-request”-Anweisungen pro Instanz ist nicht begrenzt.
Das erste Schlüsselwort nach “http-request” in der Syntax ist die Aktion der Regel, auf die optional unterschiedlich viele Argumente für die Aktion folgen. Die unterstützten Aktionen und ihre jeweilige Syntax sind in Abschnitt 4.3 „Aktionen“ aufgeführt (suchen Sie nach Aktionen mit einem Häkchen in der Spalte “HTTP Req”).
Diese Direktive ist nur in benannten defaults-Abschnitten verfügbar, nicht in anonymen. Im defaults-Abschnitt definierte Regeln werden vor denen im zugehörigen Proxy-Abschnitt ausgewertet. Um Mehrdeutigkeiten zu vermeiden, darf derselbe defaults-Abschnitt in diesem Fall nicht zugleich von Proxys mit Frontend-Funktion und von Proxys mit Backend-Funktion verwendet werden. Ein listen-Abschnitt kann daher keinen defaults-Abschnitt verwenden, der solche Regeln definiert.
Beispiel:
Beispiel:
Beispiel:
Siehe auch: “stats http-request”, Abschnitt 12.2 zu Benutzerlisten und Abschnitt 7 zur ACL-Verwendung.
http-response <action> <options...> [ { if | unless } <condition> ]
Zugriffskontrolle für Antworten auf Schicht 7
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja(!) | ja | ja | ja
Die Anweisung http-response definiert Regeln für die Verarbeitung auf Schicht 7. Die Regeln werden in der Reihenfolge ihrer Deklaration ausgewertet, wenn sie in einem Abschnitt frontend, listen oder backend vorkommen. Da sie auf Antworten angewendet werden, werden zuerst die Regeln des Backends und anschließend die des Frontends angewendet. Auf jede Regel kann optional eine ACL-basierte Bedingung folgen; dann wird die Regel nur ausgewertet, wenn diese Bedingung wahr ist.
Die Bedingung wird unmittelbar vor der Ausführung der Aktion ausgewertet, und die Aktion wird genau einmal ausgeführt. Daher ist es unproblematisch, wenn eine Aktion ein Element ändert, das in der Bedingung geprüft wird. Das bedeutet auch, dass mehrere Aktionen dieselbe Bedingung verwenden können: Die erste Aktion, die das Ergebnis der Bedingung ändert, reicht dann aus, um die übrigen Aktionen implizit zu deaktivieren. Dies wird beispielsweise verwendet, wenn einer leeren Variablen ein Wert aus verschiedenen Quellen zugewiesen werden soll. Die Anzahl der “http-response”-Anweisungen pro Instanz ist nicht begrenzt.
Das erste Schlüsselwort nach “http-response” in der Syntax ist die Aktion der Regel, auf die optional unterschiedlich viele Argumente für die Aktion folgen. Die unterstützten Aktionen und ihre jeweilige Syntax sind in Abschnitt 4.3 „Aktionen“ aufgeführt (suchen Sie nach Aktionen mit einem Häkchen in der Spalte “HTTP Res”).
Diese Direktive ist nur in benannten defaults-Abschnitten verfügbar, nicht in anonymen. Im defaults-Abschnitt definierte Regeln werden vor denen im zugehörigen Proxy-Abschnitt ausgewertet. Um Mehrdeutigkeiten zu vermeiden, darf derselbe defaults-Abschnitt in diesem Fall nicht zugleich von Proxys mit Frontend-Funktion und von Proxys mit Backend-Funktion verwendet werden. Ein listen-Abschnitt kann daher keinen defaults-Abschnitt verwenden, der solche Regeln definiert.
Beispiel:
Beispiel:
Siehe auch: “http-request”, Abschnitt 12.2 zu Benutzerlisten und Abschnitt 7 zur ACL-Verwendung.
http-reuse { never | safe | aggressive | always }
Festlegen, wie inaktive HTTP-Verbindungen von mehreren Anfragen gemeinsam genutzt werden dürfen
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Um den Aufwand für den Aufbau einer neuen Verbindung zu den Backend-Servern bei jeder HTTP-Anfrage zu vermeiden, versucht HAProxy, solche inaktiven Verbindungen nach ihrer Verwendung offenzuhalten. Diese Verbindungen gehören jeweils zu einem bestimmten Server und werden in einer als Pool bezeichneten Liste gespeichert. Innerhalb dieser Liste werden sie anhand gemeinsamer Schlüsseleigenschaften gruppiert. Bei nachfolgenden HTTP-Anfragen wird im zugehörigen Pool nach einer kompatiblen Verbindung mit identischen Eigenschaften gesucht. Diese Verbindung wird dann wiederverwendet, statt eine neue aufzubauen.
Mit dem Server-Schlüsselwort “pool-max-conn” lässt sich die Anzahl inaktiver Verbindungen begrenzen, die zu einem Server offengehalten werden. Nicht verwendete Verbindungen werden regelmäßig gemäß dem Intervall “pool-purge-delay” entfernt.
Anhand folgender Verbindungseigenschaften wird entschieden, ob eine inaktive Verbindung für eine bestimmte Anfrage wiederverwendet werden kann:
- Quell- und Zieladressen
- Proxy-Protokoll
- die Socket-Optionen TOS und mark
- der Verbindungsname, der durch das Ergebnis der Auswertung des Ausdrucks “pool-conn-name” bestimmt wird, sofern dieser vorhanden ist, andernfalls durch den Ausdruck “sni”. Dessen Standardwert ist “req.hdr(host),field(1,:)”; er verwendet also das Feld “Host” aus dem Header der eingehenden Anfrage ohne Doppelpunkt und Portnummer.
In manchen Fällen finden aufgrund zusätzlicher Einschränkungen keine Verbindungssuche oder Wiederverwendung statt. Dies wird durch die Wiederverwendungsstrategie bestimmt, die als Argument des Schlüsselworts angegeben wird:
- "never" : Inaktive Verbindungen werden niemals von mehreren Sitzungen
gemeinsam genutzt. Dieser Modus kann erzwungen werden, um eine
aus einem defaults-Abschnitt geerbte andere Strategie aufzuheben
oder um Fehler zu untersuchen. Wenn beispielsweise eine alte,
fehlerhafte Anwendung annimmt, dass mehrere Anfragen über
dieselbe Verbindung vom selben Client stammen, und sich die
Anwendung nicht korrigieren lässt, kann es sinnvoll sein, die
gemeinsame Nutzung von Verbindungen in einem einzelnen Backend
zu deaktivieren. Ein Beispiel wäre eine alte HAProxy-Version,
die im Tunnelmodus Cookies einfügt und nach der ersten Anfrage
keine weiteren Anfragen prüft.
- "safe" : Dies ist die Standardstrategie und die empfohlene Strategie.
Die erste Anfrage einer Sitzung wird immer über eine eigene
Verbindung gesendet. Nur nachfolgende Anfragen dürfen über
andere bestehende Verbindungen verteilt werden. Damit ist
sichergestellt, dass der Browser die Anfrage unbemerkt erneut
versuchen kann, falls der Server die Verbindung während des
Sendens der Anfrage schließt. Da dies genau dem gewöhnlichen
Keepalive-Verhalten entspricht, sollte es keine Nebenwirkungen
geben. Verbindungen mit Protokollen, die von Head-of-Line-
Blockierung betroffen sind (Backends mit h2 oder fcgi), werden
außerdem gesondert behandelt. Sobald mindestens ein Stream
verarbeitet wird, ist die verwendete Verbindung für Streams
derselben Sitzung reserviert. Werden keine Streams mehr
verarbeitet, wird die Verbindung freigegeben und kann
wiederverwendet werden.
- "aggressive": Dieser Modus kann in Webservice-Umgebungen nützlich sein,
in denen nicht unbedingt alle Server bekannt sind und es von
Vorteil wäre, die meisten ersten Anfragen über bestehende
Verbindungen zu senden. Erste Anfragen werden dabei nur über
bestehende Verbindungen gesendet, die bereits mindestens einmal
wiederverwendet wurden. Damit ist nachgewiesen, dass der Server
die Wiederverwendung von Verbindungen korrekt unterstützt.
Dieser Modus sollte nur verwendet werden, wenn sichergestellt
ist, dass der Client gelegentlich eine fehlgeschlagene Anfrage
wiederholen kann, und der Vorteil der aggressiven
Wiederverwendung die Nachteile seltener Verbindungsfehler
deutlich überwiegt.
- "always": Dieser Modus wird nur empfohlen, wenn bekannt ist, dass der
Pfad zum Server bestehende Verbindungen niemals kurz nach
ihrer Freigabe unterbricht. Er erlaubt, die erste Anfrage einer
Sitzung über eine bestehende Verbindung zu senden. Gegenüber
der Strategie "safe" kann dies die Leistung erheblich steigern,
wenn das Backend eine Cache-Farm ist: Solche Komponenten zeigen
üblicherweise ein gleichmäßiges Verhalten und profitieren von
der gemeinsamen Verbindungsnutzung. Es wird empfohlen, die
Zeitüberschreitung "http-keep-alive" in diesem Modus niedrig zu
halten, damit keine toten Verbindungen weiter verwendbar
bleiben. Meist ergeben sich dieselben Leistungsgewinne wie mit
"aggressive", jedoch mit höheren Risiken. Dieser Modus sollte
nur verwendet werden, wenn er die Situation gegenüber
"aggressive" verbessert.
Verbindungen mit bestimmten fehlerhaften, auf der Verbindung beruhenden Authentifizierungsschemata wie NTLM werden nach Möglichkeit als privat markiert und niemals gemeinsam genutzt. Dies gilt jedoch nicht bei einem Protokoll mit Multiplexing-Unterstützung und einer Wiederverwendungsstufe oberhalb der Standardstrategie “safe”: In diesem Fall verhindert nichts, dass die Verbindung bereits gemeinsam genutzt wird.
Ob eine inaktive Verbindung nach der Verarbeitung offengehalten oder geschlossen wird, hängt außerdem von “tune.pool-low-fd-ratio” (Standard: 20%) und “tune.pool-high-fd-ratio” (Standard: 25%) ab. Diese Werte geben den Anteil der insgesamt verfügbaren Dateideskriptoren an, der von inaktiven Verbindungen belegt wird. Oberhalb des ersten Grenzwerts hält haproxy Verbindungen nach einer Antwort nicht mehr offen; oberhalb des zweiten beendet es inaktive Verbindungen aktiv. Konfigurationen mit einem sehr hohen Anteil inaktiver Verbindungen können eine geringere Wiederverwendungsrate aufweisen, weil zu wenige Verbindungen offenbleiben. Ursache kann ein zu niedriger globaler “maxconn”-Wert sein oder viel HTTP/2- beziehungsweise HTTP/3-Verkehr im Frontend (wenige Verbindungen) bei gleichzeitigen HTTP/1-Verbindungen im Backend. In diesem Fall kann es sinnvoll sein, diese Schwellenwerte anzupassen oder einfach den globalen “maxconn”-Wert zu erhöhen.
In seltenen Fällen wird der Hostname zur Unterscheidung ausgehender TLS-Verbindungen verwendet, etwa bei einem Forward Proxy, bei dem sich die meisten Anfragen an unterschiedliche Hosts richten. Dann ist die Wiederverwendungsrate sehr niedrig, und selten verwendete Verbindungen werden automatisch entfernt, bevor sie erneut verwendet werden können. Der Mechanismus misst nämlich fortlaufend die durchschnittliche Anzahl von Verbindungen, die benötigt wird, um den Dienst ohne Erschöpfung der Ressourcen bereitzustellen. In solchen Situationen kann ein Wert für “pool-low-conn” nahe der erwarteten durchschnittlichen Anzahl inaktiver Verbindungen helfen, mehr Verbindungen zu erhalten: Threads werden dadurch dazu angehalten, eigene Verbindungen aufzubauen, statt Verbindungen anderer Threads zu übernehmen und so den Pool verfügbarer Verbindungen zu verkleinern.
Wenn ein lokal gehosteter Server mehrere Websites betreibt und ein einziges Zertifikat mit mehreren Hostnamen oder Platzhaltern verwendet, kann es wirksamer sein, einfach “no-sni-auto” in der “server”-Zeile zu verwenden. Dadurch wird vermieden, eine Verbindung für einen einzelnen Host-Namen zu reservieren, und die Wiederverwendungsrate steigt erheblich. Manche Server führen jedoch übermäßig strenge Prüfungen zwischen Host und SNI durch und weisen deshalb nachfolgende Anfragen ab. Diese Option muss daher vorab überprüft werden. Das Standardverhalten (“sni-auto”) funktioniert auch mit solchen Servern sicher.
Wenn Thread-Gruppen ausdrücklich aktiviert sind, können inaktive Verbindungen nur zwischen Threads derselben Gruppe verwendet werden. Daher kann eine ungleichmäßige Lastverteilung zwischen den Gruppen dazu führen, dass mehr inaktive Verbindungen benötigt werden und die Wiederverwendungsrate sinkt. In diesem Fall kann dieselbe Lösung angewendet werden: den globalen “maxconn”-Wert oder die Pool-Anteile erhöhen.
Siehe auch: “option http-keep-alive”, “pool-conn-name”, “pool-max-conn”, “pool-purge-delay”, “server maxconn”, “sni”, “thread-groups”, “tune.pool-high-fd-ratio”, “tune.pool-low-fd-ratio”
http-send-name-header [<header>]
Den Servernamen in eine Anfrage einfügen. Dabei die durch <header> angegebene Headerzeichenkette verwenden
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Die Anweisung “http-send-name-header” setzt das Headerfeld mit dem Namen <header> unmittelbar vor dem Senden der Anfrage auf den Namen des Zielservers. Alle vorhandenen Vorkommen dieses Headers werden entfernt. Bei Wiederholungsversuchen und erneuten Zuweisungen wird das Headerfeld aktualisiert, sodass es stets den Server angibt, zu dem gerade eine Verbindung versucht wird. Da dieser Header erst sehr spät beim Verbindungsaufbau geändert wird, kann dies unerwartete Auswirkungen auf bereits geänderte Header haben. Wird die Anweisung beispielsweise mit transportbezogenen Headern wie connection, content-length oder transfer-encoding verwendet, werden wahrscheinlich ungültige Anfragen an den Server gesendet. Daher sind folgende Headernamen verboten: host, content-length, transfer-encoding und connection.
Siehe auch: “server”
id <value>
Einem Proxy eine dauerhafte ID zuweisen.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | ja
Argumente: keine
Eine dauerhafte ID für den Proxy festlegen. Diese ID muss eindeutig und positiv sein. Wird sie nicht festgelegt, wird automatisch eine unbenutzte ID zugewiesen. Aus historischen Gründen wird der Wert 1 nur bei ausdrücklicher Angabe verwendet. Der niedrigste automatisch zugewiesene Wert ist daher 2. Diese ID wird derzeit nur in den Statistiken zurückgegeben.
ignore-persist { if | unless } <condition>
Eine Bedingung zum Ignorieren der Sitzungsbindung deklarieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Wenn die cookiebasierte Sitzungsbindung aktiviert ist, gilt diese standardmäßig uneingeschränkt für jede Anfrage, die das Cookie enthält, vorausgesetzt, der Zielserver ist verfügbar und läuft.
Mit der Anweisung “ignore-persist” können verschiedene ACL-basierte Bedingungen deklariert werden. Sind sie erfüllt, ignoriert eine Anfrage die Sitzungsbindung. Dies ist gelegentlich für die Lastverteilung von Anfragen nach statischen Dateien nützlich, die häufig keine Sitzungsbindung benötigen. Auch für einen bestimmten User-Agent, etwa manche Webcrawler, lässt sich die Sitzungsbindung damit vollständig deaktivieren.
Die Sitzungsbindung wird ignoriert, wenn eine “if”-Bedingung erfüllt ist oder eine “unless”-Bedingung nicht erfüllt ist.
Beispiel:
Siehe auch: “force-persist”, “cookie” und Abschnitt 7 zur ACL-Verwendung.
load-server-state-from-file { global | local | none }
Ein unterbrechungsfreies Neuladen von HAProxy ermöglichen
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Diese Direktive verweist HAProxy auf eine Datei, in der die Serverzustände des zuvor laufenden Prozesses gespeichert wurden. So kann der neue Prozess beim Start vor der Verarbeitung von Datenverkehr die alten Zustände auf die Server anwenden, als hätte kein Neuladen stattgefunden. Die Direktive “load-server-state-from-file” legt fest, welche Datei HAProxy verwenden soll. Derzeit gibt es nur 2 Argumente: entweder das Laden von Zuständen verhindern oder Zustände aus einer Datei laden, die alle Backends und Server enthält. Die Zustandsdatei kann erzeugt werden, indem der Befehl “show servers state” über das Statistik-Socket ausgeführt und seine Ausgabe umgeleitet wird.
Das Dateiformat ist versioniert und sehr spezifisch. Erläuterungen enthält die Dokumentation des Befehls “show servers state” (Kapitel 9.3 des Verwaltungshandbuchs).
Argumente:
Hinweise: - Die IP-Adresse eines Servers bleibt beim Neuladen standardmäßig erhalten. Die Reihenfolge lässt sich jedoch mit der Servereinstellung “init-addr” ändern. Das bedeutet, dass eine zur Laufzeit über die CLI geänderte IP-Adresse erhalten bleibt und Änderungen am lokalen Resolver, etwa /etc/hosts, möglicherweise wirkungslos bleiben, wenn die Zustandsdatei verwendet wird.
- Das Servergewicht wird aus dem zuvor laufenden Prozess übernommen,
sofern es nicht zwischen der vorherigen und der neuen Konfigurationsdatei
geändert wurde.
Beispiel: Minimale Konfiguration
global
stats socket /tmp/socket
server-state-file /tmp/server_state
defaults
load-server-state-from-file global
backend bk
server s1 127.0.0.1:22 check weight 11
server s2 127.0.0.1:22 check weight 12
Anschließend kann Folgendes ausgeführt werden:
Der Inhalt der Datei /tmp/server_state sähe dann etwa so aus:
Beispiel: Minimale Konfiguration
global
stats socket /tmp/socket
server-state-base /etc/haproxy/states
defaults
load-server-state-from-file local
backend bk
server s1 127.0.0.1:22 check weight 11
server s2 127.0.0.1:22 check weight 12
Anschließend kann Folgendes ausgeführt werden:
Der Inhalt der Datei /etc/haproxy/states/bk sähe etwa so aus:
Siehe auch: “server-state-file”, “server-state-file-name” und “show servers state”
log global
Die Protokollierung von Ereignissen und Datenverkehr pro Instanz aktivieren.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Präfix:
Argumente:
Das Frontend entscheidet, welche Informationen einer Verbindung protokolliert werden. Bei inhaltsabhängiger Umschaltung werden die Protokolleinträge des Backends ignoriert. Verbindungen werden auf der Stufe “info” protokolliert.
Die Protokolldeklarationen im Backend legen jedoch fest, wie und wo Änderungen des Serverstatus protokolliert werden. Die Stufe “notice” zeigt an, dass ein Server verfügbar wird; “warning” wird für Beendigungssignale und die endgültige Beendigung eines Dienstes verwendet; “alert” wird verwendet, wenn ein Server ausfällt.
Hinweis: Gemäß RFC3164 werden Meldungen vor der Ausgabe auf 1024 Bytes gekürzt.
Beispiel:
log-format <fmt>
Die benutzerdefinierte Formatzeichenkette für die Protokollierung des Datenverkehrs festlegen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Diese Direktive legt die Formatzeichenkette für alle Protokolleinträge fest, die durch Datenverkehr über das Frontend mit dieser Zeile entstehen. Wird die Direktive in einem defaults-Abschnitt verwendet, verwenden alle nachfolgenden Frontends dasselbe Protokollformat. Abschnitt 8.2.6 beschreibt benutzerdefinierte Formatzeichenketten für Protokolle ausführlich.
Es kann auch ein besonderes log-format definiert werden, das nur bei Verbindungsfehlern verwendet wird; siehe die Option “error-log-format”.
Die Direktive “log-format” überschreibt vorherige Direktiven vom Typ “option tcplog”, “log-format”, “option httplog” und “option httpslog”.
log-format-sd <fmt>
Die benutzerdefinierte Formatzeichenkette zur Erzeugung strukturierter Daten gemäß RFC5424 festlegen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Diese Direktive legt die Formatzeichenkette für den Teil mit strukturierten Daten gemäß RFC5424 fest. Sie gilt für alle Protokolleinträge, die durch Datenverkehr über das Frontend mit dieser Zeile entstehen. Wird die Direktive in einem defaults-Abschnitt verwendet, verwenden alle nachfolgenden Frontends dasselbe Protokollformat. Abschnitt 8.2.6 beschreibt die Formatzeichenkette für Protokolle ausführlich.
Weitere Informationen zum Teil mit strukturierten Daten nach RFC5424 finden Sie unter https://tools.ietf.org/html/rfc5424#section-6.3 .
Hinweis: Diese Formatzeichenkette wird nur für Logger verwendet, deren Protokollformat auf “rfc5424” gesetzt ist.
Beispiel:
log-steps <steps>
Festlegen, bei welchen Schritten der Transaktionsverarbeitung Protokolleinträge erzeugt werden sollen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Bei der Verarbeitung von TCP-/HTTP-Transaktionen kann haproxy an verschiedenen Stellen Protokolleinträge erzeugen, etwa bei accept, connect, request, response und close.
Standardmäßig gibt HAProxy pro Transaktion einen einzigen Protokolleintrag aus, sobald alle im Protokollformatausdruck verwendeten Elemente verfügbar sind. In der Praxis wird der Eintrag daher gewöhnlich am Ende der Transaktion ausgegeben, also nach dem Ende der Antwort bei HTTP oder am Ende der Verbindung bei TCP, sofern “option logasap” nicht verwendet wird.
Mit der Direktive “log-steps” lassen sich die genauen Ausgabezeitpunkte festlegen und sogar mehrere Protokolleinträge für dieselbe Transaktion erzeugen. Der Sonderwert ‘all’ aktiviert sämtliche verfügbaren Protokollauslöser, sodass eine Transaktion von accept bis close verfolgt werden kann. Einzelne Protokollauslöser können auch über ihre durch Kommas getrennten Namen angegeben werden, um gezielt festzulegen, wann Protokolleinträge erzeugt werden.
Übliche Protokollauslöser sind: accept, connect, request, response und close.
Beispiel:
Als Protokollierungsschritte angegebene Protokollauslöser, etwa accept oder close, können unverändert in log-profiles nach der Direktive ‘on’ verwendet werden. Die Kombination von “log-steps” mit log-profiles ermöglicht eine genaue Steuerung der Protokolleinträge, die haproxy während der Transaktionsverarbeitung automatisch erzeugt.
Diese Einstellung ist nur für Frontends relevant; in Backends wird sie ignoriert.
Siehe auch: “log-profile”
log-tag <string>
Das Protokollkennzeichen für alle ausgehenden Protokollmeldungen festlegen
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Das tag-Feld im Syslog-Header wird auf diese Zeichenkette gesetzt. Standardmäßig wird das im global-Abschnitt festgelegte log-tag verwendet, andernfalls der Programmname beim Aufruf über die Befehlszeile, üblicherweise “HAProxy”. Dies kann hilfreich sein, um mehrere Prozesse auf demselben Host oder Kundeninstanzen innerhalb desselben Prozesses zu unterscheiden. Im Backend verwenden Protokollmeldungen über verfügbare oder ausgefallene Server dieses Kennzeichen. Es kann praktisch sein, in einem defaults-Abschnitt ein log-tag für einen gehosteten Kunden festzulegen, darauf alle Frontends und Backends dieses Kunden folgen zu lassen und dann für den nächsten Kunden einen neuen defaults-Abschnitt zu beginnen. Siehe auch die globale Direktive “log-tag”.
max-keep-alive-queue <value>
Die maximale Serverwarteschlangengröße für die Beibehaltung von Keepalive-Verbindungen festlegen
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
HTTP-Keepalive versucht nach Möglichkeit, dieselbe Serververbindung wiederzuverwenden. Gelegentlich kann dies jedoch nachteilig sein, etwa wenn ein Server viele Verbindungen hat, während andere untätig sind. Dies gilt besonders für Server mit statischen Inhalten.
Diese Einstellung legt einen Schwellenwert für die Anzahl wartender Verbindungen fest, ab dem HAProxy nicht mehr versucht, denselben Server wiederzuverwenden, sondern bevorzugt einen anderen sucht. Der Standardwert -1 bedeutet, dass es keine Grenze gibt. Der Wert null bedeutet, dass Keepalive-Anfragen niemals in eine Warteschlange eingereiht werden. Für sehr nahe Server, die mit geringer Latenz erreichbar sind und auf das Unterbrechen von Keepalive unempfindlich reagieren, wird ein niedriger Wert empfohlen; ein lokaler Server für statische Inhalte kann beispielsweise 10 oder weniger verwenden. Bei entfernten Servern mit hoher Latenz können höhere Werte nötig sein, um die Latenz und/oder den Aufwand für die Auswahl eines anderen Servers auszugleichen.
Dies hat keine Auswirkungen auf Antworten, die infolge einer 401-Antwort an denselben Server gebunden bleiben. Sie gehen weiterhin an denselben Server, selbst wenn sie dafür in eine Warteschlange eingereiht werden müssen.
Siehe auch: “option http-server-close”, “option prefer-last-server”, den Serverparameter “maxconn” und cookiebasierte Sitzungsbindung.
max-session-srv-conns <nb>
Die maximale Anzahl ausgehender Verbindungen festlegen, die für eine bestimmte Clientsitzung inaktiv offengehalten werden können. Der Standardwert ist 5; er entspricht genau dem beim Kompilieren definierten MAX_SRV_LIST.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
maxconn <conns>
Die maximale Anzahl gleichzeitiger Verbindungen eines Frontends festlegen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Wenn das System dies unterstützt, kann es bei großen Websites sinnvoll sein, diese Grenze sehr hoch zu setzen, damit HAProxy die Verbindungswarteschlangen verwaltet und Verbindungsversuche der Clients nicht unbeantwortet bleiben. Dieser Wert sollte den globalen maxconn-Wert nicht überschreiten. Außerdem enthält eine Verbindung zwei Puffer von jeweils tune.bufsize (standardmäßig 16kB) sowie weitere Daten. Dadurch werden pro aufgebauter Verbindung etwa 33 kB RAM benötigt. Ein mittelgroßes System mit 1GB RAM kann bei entsprechender Abstimmung also ungefähr 20000-25000 gleichzeitige Verbindungen bewältigen.
Wird <conns> sehr hoch gesetzt, sind die Server möglicherweise nicht für diese Last ausgelegt. Daher ist es im Allgemeinen sinnvoll, ihnen angemessene Verbindungsgrenzen zuzuweisen.
Ist dieser Wert null, was dem Standard entspricht, wird der globale “maxconn”-Wert verwendet.
Siehe auch: “server”, “maxconn” im global-Abschnitt, “fullconn”
mode { tcp|http|log|spop }
Den Betriebsmodus oder das Protokoll der Instanz festlegen. Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja Argumente:
Bei inhaltsabhängiger Umschaltung müssen Frontend und Backend im selben Modus arbeiten, üblicherweise HTTP. Andernfalls wird die Konfiguration abgelehnt.
Beispiel:
monitor fail { if | unless } <condition>
Eine Bedingung hinzufügen, um auf eine HTTP-Überwachungsanfrage einen Fehler zurückzugeben.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | nein
Argumente:
Diese Anweisung fügt eine Bedingung hinzu, die erzwingen kann, dass die Antwort auf eine Überwachungsanfrage einen Fehler meldet. Fragt eine externe Komponente die für die Überwachung vorgesehene URI ab, wird standardmäßig eine Antwort mit dem Status 200 zurückgegeben. Ist eine der obigen Bedingungen erfüllt, antwortet HAProxy mit 503 statt 200. Damit lässt sich der Ausfall eines Standorts an eine externe Komponente melden, die ihre Routing-Ankündigungen zwischen mehreren Standorten auf die von HAProxy gemeldete Verfügbarkeit stützen kann. In diesem Fall würde eine ACL mit dem Kriterium “nbsrv” verwendet. “monitor fail” funktioniert nur im HTTP-Modus. Beide Statusmeldungen können bei Bedarf mit “errorfile” oder “errorloc” angepasst werden.
Beispiel:
Siehe auch: “monitor-uri”, “errorfile”, “errorloc”
monitor-uri <uri>
Eine URI für Überwachungsanfragen externer Komponenten abfangen
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Wenn ein Frontend eine HTTP-Anfrage mit Bezug auf <uri> empfängt, leitet HAProxy sie weder weiter noch protokolliert es sie. Stattdessen gibt es abhängig von den mit “monitor fail” definierten Fehlerbedingungen entweder “HTTP/1.0 200 OK” oder “HTTP/1.0 503 Service unavailable” zurück. Dies reicht normalerweise für jede vorgeschaltete HTTP-Prüfung aus, um den Dienst als UP und betriebsbereit zu erkennen, ohne die Anfrage an einen Backend-Server weiterzuleiten. Die HTTP-Methode, die Version und alle Header werden ignoriert; die Anfrage muss jedoch zumindest auf HTTP-Ebene gültig sein. Dieses Schlüsselwort darf nur in einem Frontend im HTTP-Modus verwendet werden.
Überwachungsanfragen werden sehr früh verarbeitet, unmittelbar nach dem Parsen der Anfrage und noch vor jeder “http-request”-Regel. Davor werden nur die tcp-request-Regelsätze angewendet. Diese Anfragen können auch nicht protokolliert werden; dies ist beabsichtigt. Es kann nur eine URI zur Überwachung konfiguriert werden. Bei mehreren “monitor-uri”-Anweisungen legt die letzte die zu verwendende URI fest. Diese Anfragen dienen ausschließlich dazu, einer übergeordneten Komponente den Zustand von HAProxy zu melden. Mit “monitor fail” und ACLs lassen sich jedoch beliebig viele Bedingungen hinzufügen und das Ergebnis dadurch an jede denkbare Prüfung anpassen, meistens an die Anzahl verfügbarer Server in einem Backend.
Hinweis: Beginnt <uri> mit einem Schrägstrich (’/’), erfolgt der Abgleich mit dem Pfad der Anfrage anstelle ihrer URI. Dies ist eine Umgehungslösung, damit HTTP/2-Anfragen auf die monitor-uri passen. Bei HTTP/2 werden Clients nämlich dazu angehalten, ausschließlich absolute URIs zu senden.
Beispiel:
Siehe auch: “monitor fail”
option abortonclose
Den vorzeitigen Abbruch noch nicht begonnener Verarbeitung beim Schließen durch den Client aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
TCP-Verbindungen können in jeder Richtung unabhängig geschlossen werden. Eine nur in einer Richtung geschlossene Verbindung wird häufig als „halbgeschlossen“ bezeichnet. Als das HTTP-Umfeld noch überwiegend den Schließmodus verwendete, bei dem vor dem Schließen nur eine Anfrage und eine Antwort pro Verbindung übertragen wurden, war folgendes Verhalten skriptgesteuerter Clients verbreitet: Anfrage senden, die Senderichtung schließen, auf die Antwort warten, das Schließsignal empfangen und den Vorgang beenden. Mit Keepalive und fortschrittlicheren Protokollen ist dieses Vorgehen jedoch praktisch verschwunden. Wenn ein Client die Verbindung vor Empfang seiner Antwort schließt, liegt das im Wesentlichen daran, dass der Benutzer eine Übertragung abbrechen möchte oder eine Zeitüberschreitung eingetreten ist und die Verbindung geschlossen wird.
Diese beiden Situationen, halbgeschlossene Verbindung und Abbruch, lassen sich auf der Serverseite, hier am HAProxy-Listener, nicht unterscheiden. Das ist problematisch: Wird die Verbindung offengehalten und die Anfrage trotz eines Abbruchs durch den Client weiterverarbeitet, kann dies viele Ressourcen verbrauchen. Dies gilt besonders, wenn der Benutzer die Schaltfläche „Neu laden“ betätigt hat, da dann neue Anfragen eingereiht werden, ohne die vorherigen abzubrechen. Umgekehrt würde ein grundsätzlicher Abbruch bei solchen halbgeschlossenen Verbindungen zahlreiche TCP-Anwendungen beeinträchtigen, ebenso manche HTTP-Anwendungen in internen Netzen, die mit älteren Agenten kommunizieren.
Mit der Option “abortonclose” lässt sich das gewünschte Verhalten wählen: - In einem Frontend verhindert sie die Verarbeitung ausstehender TLS-Handshakes auf einer halbgeschlossenen Verbindung. Dazu kann es kommen, wenn ein Benutzer während einer HTTPS-Anfrage unter hoher Last „Neu laden“ betätigt, beispielsweise bei einem VRRP-Failover vom aktiven HAProxy-Knoten auf den Ersatzknoten: Alle Clients verbinden sich gleichzeitig neu und müssen jeweils einen aufwendigen, vollständigen TLS-Handshake durchführen. Dauert dies länger als einige Sekunden, geben wahrscheinlich manche Benutzer auf. CPU-Zyklen für deren Handshakes aufzuwenden, wäre sinnlos. Wegen des CPU-Aufwands von TLS-Handshakes wird empfohlen, diese Option auf aus dem Internet erreichbaren Frontends aktiviert zu lassen. Für eingehende TLS-Verbindungen ist dies der Standard.
- In einem Backend bewirkt sie bei halbgeschlossenen Verbindungen den
Versuch, eine noch nicht an einen Server gesendete Anfrage abzubrechen,
also während sie in der Warteschlange liegt oder eine Verbindung
hergestellt wird. Wird die Anfrage bereits von einem Server bearbeitet,
wird auch die Verbindung zum Server halbgeschlossen, um ihm denselben
Zustand zu signalisieren. Der Server entscheidet dann über das weitere
Vorgehen. Für Backends im HTTP-Modus ist dies der Standard.
Es wird empfohlen, diese Option für aus dem Internet erreichbare TLS-Endpunkte und HTTP-Dienste zu aktivieren und für reine TCP-Dienste sowie nicht öffentlich erreichbare ältere Umgebungen zu deaktivieren. In HTTP-Backends ist sie standardmäßig aktiviert. Sie kann ausdrücklich deaktiviert werden, indem ihr das Schlüsselwort “no” vorangestellt wird, entweder im Backend-Abschnitt selbst oder im “defaults”-Abschnitt, von dem er erbt. Auch für TLS-Listener ist sie standardmäßig aktiviert und kann ausdrücklich deaktiviert werden, indem “no option abortonclose” im Frontend oder im geerbten “defaults”-Abschnitt angegeben wird.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “timeout queue” sowie die Serverparameter “maxconn” und “maxqueue”
option accept-invalid-http-request (deprecated)
Weniger strenges Parsen von HTTP-Anfragen aktivieren oder deaktivieren
Das Schlüsselwort “accept-invalid-http-request” ist veraltet. Verwenden Sie stattdessen “option accept-unsafe-violations-in-http-request”.
option accept-invalid-http-response (deprecated)
Weniger strenges Parsen von HTTP-Antworten aktivieren oder deaktivieren
Das Schlüsselwort “accept-invalid-http-response” ist veraltet. Verwenden Sie stattdessen “option accept-unsafe-violations-in-http-response”.
option accept-unsafe-violations-in-http-request
Weniger strenges Parsen von HTTP-Anfragen aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
Standardmäßig hält sich HAProxy beim Parsen von Nachrichten an die verschiedenen HTTP-RFCs. Das Parsen ist daher recht streng, und bei fehlerhaften Nachrichten wird ein Fehler an den Client zurückgegeben. Dieses Verhalten ist beabsichtigt, da solche Nachrichten vor allem für Angriffe verwendet werden, die Schwächen von Servern ausnutzen und Sicherheitsfilter umgehen. Manchmal hält sich ein fehlerhafter Browser aus irgendeinem Grund, etwa wegen seiner Konfiguration oder Implementierung, nicht an diese RCFs, und das Problem wird nicht sofort behoben. In diesem Fall kann diese Option den HAProxy-Parser weniger streng machen, damit er bestimmte ungültige Anfragen akzeptiert. Aus historischen Gründen betreffen die meisten Regeln das Parsen von H1. Neuere HTTP-Versionen sind tendenziell sauberer, und Anwendungen halten sich strenger an diese Protokolle.
Ist diese Option gesetzt, gelten folgende Regeln:
* Nur bei H1 führen ungültige Zeichen, einschließlich des NULL-Zeichens,
im Headernamen nicht zur Ablehnung; der Header wird jedoch verworfen.
* Nur bei H1 wird das NULL-Zeichen im Headerwert akzeptiert;
* Nur bei H1 werden Zeichen oberhalb von 127 in der URI akzeptiert. RFC3986
legt die in einer URI erlaubten Zeichen genau fest. Die Zeichen 0-31,
32 (Leerzeichen), 34 ('"'), 60 ('<'), 62 ('>'), 92 ('\'), 94 ('^'),
96 ('`'), 123 ('{'), 124 ('|'), 125 ('}'), 127 (Löschzeichen) und alle
darüberliegenden Zeichen sind normalerweise nicht erlaubt. Bei H1 werden
alle Zeichen im Bereich (0..32) sowie 127 immer blockiert. Alle Zeichen
oberhalb von 127 (ausschließlich) werden ebenfalls blockiert, außer wenn
diese Option aktiviert ist. Andere Zeichen (33..126) werden überhaupt
nicht geprüft.
* Bei H1 und H2 werden URLs mit Fragmentverweisen ('#' nach dem Pfad)
akzeptiert;
* Nur bei H1 wird der Authority-Teil von CONNECT-Anfragen nicht geprüft;
* Nur bei H1 erfolgt keine Prüfung zwischen dem Authority-Teil und dem Wert
des Host-Headers.
* Nur bei H1 werden die Prüfungen der HTTP-Version gelockert. Dadurch werden
GET-Anfragen nach HTTP/0.9 ohne Versionsangabe, andere Protokollnamen wie RTSP
sowie mehrere Ziffern sowohl für die Haupt- als auch die Unterversion
zugelassen.
* Nur bei H1 werden WebSocket-Anfragen (RFC6455) akzeptiert, die kein
gültiges Headerfeld "Sec-Websocket-Key" enthalten.
Diese Option sollte niemals standardmäßig aktiviert werden, da sie Anwendungsfehler verdeckt und Sicherheitslücken öffnet. Sie sollte erst eingesetzt werden, nachdem ein Problem bestätigt wurde.
Ist diese Option aktiviert, werden ungültige, aber akzeptierte H1-Anfragen erfasst, um eine spätere Analyse mit der Anfrage “show errors” über das UNIX-Statistik-Socket zu ermöglichen. Dies hilft auch zu bestätigen, dass das Problem behoben wurde.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option accept-unsafe-violations-in-http-response” und “show errors” über das Statistik-Socket.
option accept-unsafe-violations-in-http-response
Weniger strenges Parsen von HTTP-Antworten aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Ähnlich wie “option accept-unsafe-violations-in-http-request” kann diese Option die Regeln für das Parsen von HTTP-Antworten lockern. Sie sollte nur für vertrauenswürdige ältere Server aktiviert werden, um bestimmte ungültige Antworten zu akzeptieren. Aus historischen Gründen betreffen die meisten Regeln das Parsen von H1. Neuere HTTP-Versionen sind tendenziell sauberer, und Anwendungen halten sich strenger an diese Protokolle.
Ist diese Option gesetzt, gelten folgende Regeln:
* Nur bei H1 werden Statuscodes mit mehr als 3 Ziffern nicht abgelehnt,
sofern ihr Wert in 16 Bit passt.
* Nur bei H1 führen ungültige Zeichen, einschließlich des NULL-Zeichens,
im Headernamen nicht zur Ablehnung; der Header wird jedoch verworfen.
* Nur bei H1 wird das NULL-Zeichen im Headerwert akzeptiert;
* Nur bei H1 werden leere Werte oder mehrere Vorkommen des Wertes "chunked"
im Header Transfer-Encoding akzeptiert;
* Nur bei H1 erfolgt keine Prüfung zwischen dem Authority-Teil und dem Wert
des Host-Headers.
* Nur bei H1 werden die Prüfungen der HTTP-Version gelockert. Dadurch werden
andere Protokollnamen wie RTSP sowie mehrere Ziffern sowohl für die Haupt-
als auch die Unterversion zugelassen.
* Nur bei H1 werden WebSocket-Antworten (RFC6455) akzeptiert, die kein
gültiges Headerfeld "Sec-Websocket-Accept" enthalten.
Diese Option sollte niemals standardmäßig aktiviert werden, da sie Anwendungsfehler verdeckt und Sicherheitslücken öffnet. Sie sollte erst eingesetzt werden, nachdem ein Problem bestätigt wurde.
Ist diese Option aktiviert, werden fehlerhafte Headernamen in Antworten weiterhin akzeptiert. Die vollständige Antwort wird jedoch erfasst, um eine spätere Analyse mit der Anfrage “show errors” über das UNIX-Statistik-Socket zu ermöglichen. Dies hilft auch zu bestätigen, dass das Problem behoben wurde.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option accept-unsafe-violations-in-http-request” und “show errors” über das Statistik-Socket.
option allbackups
Entweder alle Ersatzserver gleichzeitig oder nur den ersten verwenden
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Standardmäßig erhält der erste betriebsbereite Ersatzserver den gesamten Datenverkehr, wenn alle regulären Server ausgefallen sind. Manchmal ist es jedoch sinnvoll, mehrere Ersatzserver gleichzeitig zu verwenden, weil einer allein nicht ausreicht. Ist “option allbackups” aktiviert, erfolgt die Lastverteilung zwischen allen Ersatzservern, sobald alle regulären Server nicht verfügbar sind. Dabei wird derselbe Lastverteilungsalgorithmus verwendet, und die Servergewichte werden berücksichtigt. Zwischen den Ersatzservern besteht dann keine Prioritätsreihenfolge mehr.
Diese Option wird vorwiegend bei statischen Serverfarmen eingesetzt, die eine Entschuldigungsseite zurückgeben sollen, wenn eine Anwendung vollständig offline ist.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
option checkcache
Alle Serverantworten analysieren und Antworten mit zwischenspeicherbaren Cookies blockieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Manche übergeordneten Frameworks setzen überall Anwendungscookies und geben Entwicklern nicht immer genügend Kontrolle darüber, wie Antworten zwischengespeichert werden sollen. Wird ein Sitzungscookie zusammen mit einem zwischenspeicherbaren Objekt zurückgegeben, besteht ein hohes Risiko, dass Sitzungen zwischen Benutzern verwechselt oder gestohlen werden, wenn diese dieselben Caches verwenden. In manchen Situationen ist es besser, die Antwort zu blockieren, als sensible Sitzungsinformationen unkontrolliert weiterzugeben.
Die Option “checkcache” aktiviert eine eingehende Prüfung aller Serverantworten auf strikte Einhaltung der HTTP-Spezifikation zur Zwischenspeicherbarkeit. Sie prüft die Header “Cache-control”, “Pragma” und “Set-cookie” in der Serverantwort sorgfältig darauf, ob ein Cookie auf einem clientseitigen Proxy zwischengespeichert werden könnte. Bei aktivierter Option dürfen nur folgende Antworten an den Client ausgeliefert werden: - alle ohne “Set-Cookie”-Header; - alle mit einem anderen Rückgabecode als 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501, sofern der Server kein Headerfeld “Cache-control: public” gesetzt hat; - alle, die aus einer Anfrage mit einer anderen Methode als GET, HEAD, OPTIONS, TRACE hervorgehen, sofern der Server kein Headerfeld ‘Cache-Control: public’ gesetzt hat; - Antworten mit einem Header ‘Pragma: no-cache’ - Antworten mit einem Header ‘Cache-control: private’ - Antworten mit einem Header ‘Cache-control: no-store’ - Antworten mit einem Header ‘Cache-control: max-age=0’ - Antworten mit einem Header ‘Cache-control: s-maxage=0’ - Antworten mit einem Header ‘Cache-control: no-cache’ - Antworten mit einem Header ‘Cache-control: no-cache=“set-cookie”’ - Antworten mit einem Header ‘Cache-control: no-cache=“set-cookie,’ (wobei weitere Felder nach set-cookie zulässig sind) - Antworten, die weder Frischeinformationen (“Cache-control” mit “max-age” oder “s-maxage” oder einen “Expires”-Header) noch einen Validator (einen “ETag”- oder “Last-Modified”-Header) enthalten, da ein spezifikationskonformer Cache eine solche Antwort nicht speichert.
Erfüllt eine Antwort diese Anforderungen nicht, wird sie wie durch eine Regel “http-response deny” blockiert, mit “HTTP 502 bad gateway”. Der Sitzungsstatus zeigt “PH–” an. Dies bedeutet, dass der Proxy die Antwort während der Headerverarbeitung blockiert hat. Zusätzlich wird eine alert-Meldung protokolliert, damit Administratoren erfahren, dass etwas korrigiert werden muss.
Da dies die Anwendung erheblich beeinflusst, sollte sie vor dem Produktiveinsatz mit aktivierter Option gründlich getestet werden. Es ist auch sinnvoll, die Option bei Tests immer zu aktivieren, selbst wenn sie im Produktivbetrieb nicht verwendet wird, da sie potenziell gefährliches Anwendungsverhalten meldet.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
option clitcpka
Das Senden von TCP-Keepalive-Paketen auf der Clientseite aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
Befindet sich zwischen einem Client und einem Server eine Firewall oder eine andere Komponente, die Sitzungszustände verfolgt, und verwendet das Protokoll sehr lange Sitzungen mit langen inaktiven Phasen, etwa bei Remotedesktops, besteht ein Risiko: Eine zwischengeschaltete Komponente könnte eine zu lange inaktive Sitzung ablaufen lassen.
Werden TCP-Keepalives auf Socket-Ebene aktiviert, sendet das System regelmäßig Pakete an das andere Ende der Verbindung und hält diese damit aktiv. Der Abstand zwischen Keepalive-Prüfungen wird ausschließlich vom System gesteuert und hängt sowohl vom Betriebssystem als auch von dessen Abstimmungsparametern ab.
Keepalive-Pakete werden auf Anwendungsebene weder gesendet noch empfangen. Nur die Netzwerkstapel sehen sie. Selbst wenn also eine Seite des Proxys bereits Keepalives verwendet, um ihre Verbindung aktiv zu halten, werden diese Pakete nicht zur anderen Seite des Proxys weitergeleitet.
Dies hat nichts mit HTTP-Keepalive zu tun.
Die Option “clitcpka” aktiviert das Senden von TCP-Keepalive-Prüfungen auf der Clientseite einer Verbindung. Dies sollte helfen, wenn zwischen HAProxy und einem Client Sitzungen ablaufen.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option srvtcpka”, “option tcpka”
option contstats
Die kontinuierliche Aktualisierung der Datenverkehrsstatistiken aktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
Standardmäßig werden die Zähler für die Statistikberechnung erst erhöht, wenn ein Stream endet. Bei kleinen Objekten funktioniert dies recht gut. Bei großen Objekten, etwa großen Bildern oder Archiven, oder bei A/V-Streaming sieht ein aus den HAProxy-Zählern erzeugtes Diagramm jedoch wie ein Igel aus. Bei aktivierter Option werden die Zähler während des Streams häufig erhöht, typischerweise alle 5 Sekunden, was meist für gleichmäßige Diagramme ausreicht. Die erneute Zählung greift unmittelbar in einen häufig ausgeführten Verarbeitungspfad ein. Sie ist daher nicht standardmäßig aktiviert, da sie bei sehr vielen Sitzungen zahlreiche Aufweckvorgänge verursachen und die Leistung geringfügig senken kann.
option disable-h2-upgrade
Den impliziten Wechsel einer HTTP/1.x-Clientverbindung auf HTTP/2 aktivieren oder deaktivieren.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
Standardmäßig kann HAProxy eine HTTP/1.x-Clientverbindung implizit in eine HTTP/2-Verbindung umwandeln, wenn die erste über eine bestimmte HTTP-Verbindung empfangene Anfrage der HTTP/2-Verbindungspräambel entspricht, also der Zeichenkette “PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n”. So können HTTP/1.x- und HTTP/2-Clients über Verbindungen ohne SSL unterstützt werden. Diese Option muss verwendet werden, um den impliziten Protokollwechsel zu deaktivieren. Dieser implizite Wechsel wird nur bei HTTP-Proxys unterstützt, und die Option ist entsprechend nur dort verfügbar. HTTP/2 kann bei unverschlüsselten Verbindungen auch durch “proto h2” in der bind-Zeile erzwungen werden. Schließlich gilt diese Option für alle bind-Zeilen. Um implizite Wechsel auf HTTP/2 für eine bestimmte bind-Zeile zu deaktivieren, kann “proto h1” verwendet werden.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
option dontlog-normal
Die Protokollierung normaler, erfolgreicher Verbindungen aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
Große Websites verarbeiten mehrere Tausend Verbindungen pro Sekunde, wodurch die Protokollierung erheblichen Aufwand verursachen kann. Manche müssen Protokolle sogar abschalten und können dann Probleme im Produktivbetrieb nicht untersuchen. Diese Option sorgt dafür, dass normale Verbindungen ohne Fehler, Zeitüberschreitung, Wiederholungsversuch oder erneute Zuweisung nicht protokolliert werden. Dadurch bleibt Speicherplatz für Auffälligkeiten. Im HTTP-Modus wird der Antwortstatuscode geprüft; Rückgabecodes 5xx werden weiterhin protokolliert.
Von dieser Option wird dringend abgeraten: Der Schlüssel zur Lösung komplexer Probleme findet sich meist in den normalen Protokolleinträgen, die hier entfallen. Wenn Sie Protokolle trennen müssen, verwenden Sie stattdessen die Option “log-separate-errors”.
Siehe auch: “log”, “dontlognull”, “log-separate-errors” und Abschnitt 8 zur Protokollierung.
option dontlognull
Die Protokollierung von Verbindungen ohne Datenübertragung aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
In manchen Umgebungen verbinden sich Komponenten regelmäßig mit verschiedenen Systemen, um deren Erreichbarkeit zu prüfen. Dies können andere Load-Balancer oder Überwachungssysteme sein. Standardmäßig erzeugt selbst eine einfache Portprüfung oder ein Portscan einen Protokolleintrag. Wenn solche Verbindungen die Protokolle zu stark belasten, kann die Option “dontlognull” aktiviert werden. Dann werden Verbindungen, über die keine Daten übertragen wurden, nicht protokolliert, was typischerweise auf diese Prüfungen zutrifft. Fehler werden jedoch weiterhin an den Client zurückgegeben und in den Statistiken gezählt. Ist dies nicht gewünscht, kann stattdessen die Option http-ignore-probes verwendet werden.
Im Allgemeinen wird empfohlen, diese Option in nicht kontrollierten Umgebungen wie dem Internet nicht zu verwenden, da andernfalls Scans und andere bösartige Aktivitäten nicht protokolliert würden.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “log”, “http-ignore-probes”, “monitor-uri” und Abschnitt 8 zur Protokollierung.
option external-check
Externe Prozesse für Health Checks von Servern verwenden
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Der Zustand eines Servers kann mit einem externen Befehl geprüft werden. Dazu wird das mit “external-check command” festgelegte Programm ausgeführt.
Die globale Einstellung “external-check” muss aktiviert sein.
Siehe auch: “external-check”, “external-check command”, “external-check path”
option forwarded [ proto ]
Das Einfügen des forwarded-Headers gemäß rfc 7239 in an Server gesendete Anfragen aktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Da HAProxy als Reverse-Proxy arbeitet, geht den Servern ein Teil des Anfragekontexts verloren, etwa der Ursprung der Anfrage mit IP-Adresse des Clients und verwendetem Protokoll.
Diese Einschränkung wird häufig mit dem bekannten x-forward-for und verwandten x-forward-*-Headern umgangen, um Teile dieses Kontexts an die dahinterliegenden Server und Anwendungen weiterzugeben. Obwohl dies üblicherweise funktioniert und weit verbreitet ist, wird es nicht offiziell von der IETF unterstützt und kann Interoperabilitäts- und Sicherheitsprobleme verursachen.
Als Lösung hat die IETF eine neue HTTP-Erweiterung beschrieben: den forwarded-Header (RFC7239). Weitere Informationen: https://www.rfc-editor.org/rfc/rfc7239.html
Dieser einzelne Header kann zahlreiche Details übermitteln und löst vor allem das Problem verketteter Proxys. Der RFC erlaubt mehreren hintereinandergeschalteten Proxys, ihre eigenen Werte an einen bereits vorhandenen Header anzuhängen.
Diese Option kann in einem defaults-, listen- oder backend-Abschnitt angegeben werden; in frontend-Abschnitten wird sie ignoriert.
Wird option forwarded ohne Argumente gesetzt, gilt das implizite Standardverhalten. Dabei wird der Parameter proto aktiviert und die ursprüngliche IP-Adresse des Clients eingefügt.
Die entsprechende explizite, manuelle Konfiguration wäre:
Das Schlüsselwort ‘by’ aktiviert den Parameter ‘by’ (“nodename”) im forwarded-Header. Damit lassen sich Informationen zum Proxy der Anfrage einfügen. Der Wert von ‘by’ wird auf die IP-Adresse des Proxys, also die Zieladresse, gesetzt. Ist sie nicht verfügbar, etwa bei einem UNIX-Listener, wird ‘by’ auf “unknown” gesetzt.
Das Schlüsselwort ‘by-expr’ aktiviert den Parameter ‘by’ (“nodename”) im forwarded-Header. Damit lassen sich Informationen zum Proxy der Anfrage einfügen. Der Wert von ‘by’ wird auf das Ergebnis des Sample-Ausdrucks <by_expr> gesetzt, sofern dieses gültig ist, andernfalls auf “unknown”.
Das Schlüsselwort ‘for’ aktiviert den Parameter ‘for’ (“nodename”) im forwarded-Header. Damit lassen sich Informationen zum Client der Anfrage einfügen. Der Wert von ‘for’ wird auf die IP-Adresse des Clients, also die Quelladresse, gesetzt. Ist sie nicht verfügbar, etwa bei einem UNIX-Listener, wird ‘for’ auf “unknown” gesetzt.
Das Schlüsselwort ‘for-expr’ aktiviert den Parameter ‘for’ (“nodename”) im forwarded-Header. Damit lassen sich Informationen zum Client der Anfrage einfügen. Der Wert von ‘for’ wird auf das Ergebnis des Sample-Ausdrucks <for_expr> gesetzt, sofern dieses gültig ist, andernfalls auf “unknown”.
Das Schlüsselwort ‘by_port’ ergänzt den Parameter ‘by’ um die Information “nodeport”. ‘by_port’ erfordert, dass ‘by’ oder ‘by-expr’ gesetzt ist; andernfalls wird es ignoriert. “nodeport” wird auf den Port des Proxys, also den Zielport, gesetzt, sofern er verfügbar ist; andernfalls wird es ignoriert.
Das Schlüsselwort ‘by_port-expr’ ergänzt den Parameter ‘by’ um die Information “nodeport”. ‘by_port-expr’ erfordert, dass ‘by’ oder ‘by-expr’ gesetzt ist; andernfalls wird es ignoriert. “nodeport” wird auf das Ergebnis des Sample-Ausdrucks <by_port_expr> gesetzt, sofern dieses gültig ist; andernfalls wird es ignoriert.
Das Schlüsselwort ‘for_port’ ergänzt den Parameter ‘for’ um die Information “nodeport”. ‘for_port’ erfordert, dass ‘for’ oder ‘for-expr’ gesetzt ist; andernfalls wird es ignoriert. “nodeport” wird auf den Port des Clients, also den Quellport, gesetzt, sofern er verfügbar ist; andernfalls wird es ignoriert.
Das Schlüsselwort ‘for_port-expr’ ergänzt den Parameter ‘for’ um die Information “nodeport”. ‘for_port-expr’ erfordert, dass ‘for’ oder ‘for-expr’ gesetzt ist; andernfalls wird es ignoriert. “nodeport” wird auf das Ergebnis des Sample-Ausdrucks <for_port_expr> gesetzt, sofern dieses gültig ist; andernfalls wird es ignoriert.
Beispiele:
Siehe auch: “option forwardfor”, “option originalto”
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
Das Einfügen des Headers X-Forwarded-For in an Server gesendete Anfragen aktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Da HAProxy als Reverse-Proxy arbeitet, sehen die Server seine IP-Adresse als Clientadresse. Das ist manchmal störend, wenn in den Serverprotokollen die IP-Adresse des Clients erwartet wird. Als Lösung kann HAProxy allen an den Server gesendeten Anfragen den bekannten HTTP-Header “X-Forwarded-For” hinzufügen. Dessen Wert gibt die IP-Adresse des Clients an. Da dieser Header immer am Ende der vorhandenen Headerliste angehängt wird, muss der Server so konfiguriert sein, dass er ausschließlich das letzte Vorkommen dieses Headers verwendet. Wie die Verwendung dieses Standardheaders aktiviert wird, steht im Serverhandbuch. Es darf nur das letzte Vorkommen verwendet werden, da der Client durchaus bereits einen solchen Header mitgesendet haben kann.
Mit dem Schlüsselwort “header” kann anstelle von “X-Forwarded-For” ein anderer Headername angegeben werden. Dies kann nützlich sein, wenn bereits ein “X-Forwarded-For”-Header einer anderen Anwendung wie stunnel vorhanden ist und erhalten bleiben soll. Dasselbe gilt, wenn der Backend-Server “X-Forwarded-For” nicht verwendet und einen anderen Header verlangt; Zeus Web Servers benötigen beispielsweise “X-Cluster-Client-IP”.
Manchmal wird dieselbe HAProxy-Instanz sowohl für direkten Clientzugriff als auch für Zugriff über einen Reverse-Proxy verwendet, etwa wenn ein SSL-Reverse-Proxy den HTTPS-Verkehr entschlüsselt. Für eine bekannte Quelladresse oder ein bekanntes Netz lässt sich das Hinzufügen des Headers mit dem Schlüsselwort “except” und der nachfolgenden Netzadresse deaktivieren. Bei Quell-IP-Adressen, die zu diesem Netz passen, wird der Header dann nicht hinzugefügt. Dies wird am häufigsten mit privaten Netzen oder 127.0.0.1 verwendet. Sowohl IPv4 als auch IPv6 werden unterstützt.
Alternativ legt das Schlüsselwort “if-none” fest, dass der Header nur hinzugefügt wird, wenn er noch nicht vorhanden ist. Dies sollte nur in einer vollständig vertrauenswürdigen Umgebung verwendet werden, da ein Sicherheitsproblem entstehen kann, wenn die bei HAProxy eintreffenden Header vom Endbenutzer kontrolliert werden.
Diese Option kann im Frontend oder im Backend angegeben werden. Verwendet sie mindestens eines von beiden, wird der Header hinzugefügt. Wenn beide das Unterargument header definieren, hat dessen Einstellung im Backend Vorrang vor der im Frontend. Beim Argument “if-none” setzt sich dagegen die zwingende Hinzufügung durch, sobald mindestens eines von Frontend und Backend dieses Argument nicht angibt.
Beispiel:
Siehe auch: “option httpclose”, “option http-server-close”, “option http-keep-alive”
option h1-case-adjust-bogus-client
Die Anpassung der Groß- und Kleinschreibung von HTTP/1-Headern für fehlerhafte Clients aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
Für Headernamen gibt es keine vorgeschriebene Groß- und Kleinschreibung, da gemäß RFC7230 nicht zwischen ihnen unterschieden wird. Anwendungen müssen Headernamen daher ohne Unterscheidung der Groß- und Kleinschreibung verarbeiten. Einige fehlerhafte Anwendungen verletzen jedoch die Standards und verlassen sich fälschlicherweise auf die von Browsern am häufigsten verwendete Schreibweise. Mit HTTP/2 wird dies kritisch, weil sämtliche Headernamen in Kleinbuchstaben übertragen werden müssen und HAProxy dieselbe Konvention verwendet. Unabhängig von der HTTP-Version werden alle Headernamen in Kleinbuchstaben an Clients und Server gesendet.
Wenn HAProxy eine HTTP/1-Antwort empfängt, werden deren Headernamen in Kleinbuchstaben umgewandelt, so verarbeitet und an die Clients gesendet. Wenn bekannt ist, dass ein Client die HTTP-Standards verletzt und eine von HAProxy kommende Antwort nicht verarbeiten kann, lassen sich die kleingeschriebenen Headernamen beim Formatieren und Senden der Antwort in ein anderes Format umwandeln. Dazu wird diese Option aktiviert und mit den globalen Direktiven “h1-case-adjust” oder “h1-case-adjust-file” die Liste der umzuformatierenden Header angegeben. Dies darf nur eine vorübergehende Umgehungslösung sein, bis der Client korrigiert wurde: Clients, die solche Umgehungen benötigen, können für Content-Smuggling-Angriffe anfällig sein und müssen unbedingt korrigiert werden.
Diese Option hat keine Auswirkungen auf standardkonforme Clients.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option h1-case-adjust-bogus-server”, “h1-case-adjust”, “h1-case-adjust-file”.
option h1-case-adjust-bogus-server
Die Anpassung der Groß- und Kleinschreibung von HTTP/1-Headern für fehlerhafte Server aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Für Headernamen gibt es keine vorgeschriebene Groß- und Kleinschreibung, da gemäß RFC7230 nicht zwischen ihnen unterschieden wird. Anwendungen müssen Headernamen daher ohne Unterscheidung der Groß- und Kleinschreibung verarbeiten. Einige fehlerhafte Anwendungen verletzen jedoch die Standards und verlassen sich fälschlicherweise auf die von Browsern am häufigsten verwendete Schreibweise. Mit HTTP/2 wird dies kritisch, weil sämtliche Headernamen in Kleinbuchstaben übertragen werden müssen und HAProxy dieselbe Konvention verwendet. Unabhängig von der HTTP-Version werden alle Headernamen in Kleinbuchstaben an Clients und Server gesendet.
Wenn HAProxy eine HTTP/1-Anfrage empfängt, werden deren Headernamen in Kleinbuchstaben umgewandelt, so verarbeitet und an die Server gesendet. Wenn bekannt ist, dass ein Server die HTTP-Standards verletzt und eine von HAProxy kommende Anfrage nicht verarbeiten kann, lassen sich die kleingeschriebenen Headernamen beim Formatieren und Senden der Anfrage in ein anderes Format umwandeln. Dazu wird diese Option aktiviert und mit den globalen Direktiven “h1-case-adjust” oder “h1-case-adjust-file” die Liste der umzuformatierenden Header angegeben. Dies darf nur eine vorübergehende Umgehungslösung sein, bis der Server korrigiert wurde: Server, die solche Umgehungen benötigen, können für Content-Smuggling-Angriffe anfällig sein und müssen unbedingt korrigiert werden.
Diese Option hat keine Auswirkungen auf standardkonforme Server.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option h1-case-adjust-bogus-client”, “h1-case-adjust”, “h1-case-adjust-file”.
option http-buffer-request
Das Warten auf den vollständigen HTTP-Anfragekörper vor der weiteren Verarbeitung aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Manchmal ist es sinnvoll, vor einer Entscheidung auf den Körper einer HTTP-Anfrage zu warten. Dies geschieht beispielsweise bei “balance url_param”. Ein erster Anwendungsfall ist das Puffern von Anfragen langsamer Clients, bevor eine Verbindung zum Server aufgebaut wird. Ein weiterer ist eine Routing-Entscheidung anhand des Inhalts des Anfragekörpers. Im Frontend oder Backend erzwingt diese Option, dass die HTTP-Verarbeitung wartet, bis entweder der gesamte Anfragekörper empfangen wurde oder der Anfragepuffer voll ist. Dies kann bei Anwendungen unerwünschte Nebenwirkungen haben, die HTTP zweckwidrig verwenden und ungepufferte Übertragungen zwischen Frontend und Backend erwarten. Daher sollte diese Option keinesfalls standardmäßig verwendet werden.
Siehe auch: “option http-no-delay”, “timeout http-request”, “http-request wait-for-body”
option http-drop-request-trailers
HTTP-Trailer beim Senden einer Anfrage an den Server verwerfen
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | nein | ja
Argumente: keine
Ist diese Option aktiviert, werden sämtliche HTTP-Trailer einer Anfrage verworfen, bevor sie an den Server gesendet wird.
RFC9110#section-6.5.1 legt fest, dass Trailerfelder mit Headerfeldern zusammengeführt werden können. Dies sollte bewusst geschehen, kann jedoch für manche Anwendungen problematisch sein. Das gilt insbesondere dann, wenn bösartige Clients sensible Headerfelder im Trailerteil verstecken und zwischengeschaltete Komponenten sie ohne besondere Prüfung mit den Headern zusammenführen. In diesem Fall kann diese Option im Backend aktiviert werden, um alle Trailerfelder aus Anfragen zu entfernen, bevor sie an den Server gesendet werden.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option http-drop-response-trailers”
option http-drop-response-trailers
HTTP-Trailer beim Senden einer Antwort an den Client verwerfen
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
Diese Option ähnelt “option http-drop-request-trailers”, muss jedoch verwendet werden, um Trailerfelder aus Antworten zu verwerfen, bevor diese an Clients gesendet werden.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option http-drop-request-trailers”
option http-ignore-probes
Die Protokollierung von Verbindungen ohne Datenübertragung und Anfragezeitüberschreitungen aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
Einige Browser haben begonnen, eine “pre-connect”-Funktion zu implementieren: Sie verbinden sich vorsorglich mit kürzlich besuchten Websites, falls der Benutzer sie erneut aufrufen möchte. Dadurch entstehen viele Verbindungen zu Websites, die mit 408 Request Timeout enden, wenn zuerst die Zeitüberschreitung eintritt, oder mit 400 Bad Request, wenn der Browser sie vorher schließt. Diese Verbindungen füllen die Protokolle und erhöhen die Fehlerzähler. “option dontlognull” gab es bereits, reicht hier jedoch nicht aus. Diese Option bewirkt stattdessen Folgendes: - Sie verhindert, dass eine 400/408-Meldung an den Client gesendet wird, wenn vor dem Schließen der Verbindung nichts empfangen wurde; - sie verhindert in dieser Situation jeden Protokolleintrag; - sie verhindert die Erhöhung jedes Fehlerzählers.
Die leere Verbindung wird damit stillschweigend ignoriert. Diese Option sollte möglichst nur verwendet werden, wenn ihre Notwendigkeit feststeht, da sie tatsächliche Probleme verdeckt. Die häufigste Ursache dafür, dass keine Anfrage empfangen wird und ein Status 408 erscheint, ist eine abweichende MTU zwischen dem Client und einer zwischengeschalteten Komponente wie einem VPN, das zu große Pakete blockiert. Solche Probleme treten gewöhnlich bei POST-Anfragen sowie bei GET-Anfragen mit großen Cookies auf. Die Protokolle sind häufig die einzige Möglichkeit, sie zu erkennen.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “log”, “dontlognull”, “errorfile” und Abschnitt 8 zur Protokollierung.
option http-keep-alive
HTTP-Keepalive vom Client bis zum Server für HTTP/1.x-Verbindungen aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Standardmäßig arbeitet HAProxy bei dauerhaften HTTP/1.x-Verbindungen im Keepalive-Modus: Es verarbeitet jede Anfrage und Antwort einer Verbindung und lässt die Verbindung anschließend auf beiden Seiten inaktiv offen. Dieser Modus lässt sich durch verschiedene Optionen wie “option http-server-close” oder “option httpclose” ändern. Mit dieser Option kann wieder zum Keepalive-Modus zurückgekehrt werden, etwa wenn in einem defaults-Abschnitt ein anderer Modus verwendet wurde.
“option http-keep-alive” aktiviert den HTTP-Keepalive-Modus sowohl auf der Client- als auch auf der Serverseite. Dies bietet die geringste Latenz auf der Clientseite mit ihrem langsameren Netz und die schnellste Sitzungswiederverwendung auf der Serverseite, erfordert jedoch das Offenhalten inaktiver Verbindungen zu den Servern. Bei kleinen Objekten lässt sich mit dieser Option im Allgemeinen ungefähr die doppelte Anfragerate gegenüber der Option “http-server-close” erreichen. Sie kann vor allem in zwei Situationen nützlich sein:
- wenn der Server nicht HTTP-konform ist und die Verbindung statt der
Anfragen authentifiziert, etwa bei NTLM-Authentifizierung
- wenn der Aufbau der Verbindung zum Server im Verhältnis zum Abruf des
zugehörigen Objekts vom Server erheblichen Aufwand verursacht.
Letzteres kann bei einem schnellen Server für statische Inhalte oder einem Cache auftreten.
Derzeit zeigen die Protokolle nicht an, ob Anfragen aus derselben Sitzung stammen. Der im Protokoll angegebene Annahmezeitpunkt entspricht dem Ende der vorherigen Anfrage, und die Anfragezeit entspricht der Wartezeit auf eine neue Anfrage. Die Keepalive-Anfragezeit wird weiterhin durch “timeout http-keep-alive” begrenzt oder, falls nicht gesetzt, durch “timeout http-request”.
Diese Option deaktiviert und ersetzt alle vorherigen Optionen “option httpclose” oder “option http-server-close”.
Siehe auch: “option httpclose”,, “option http-server-close”, “option prefer-last-server” und “option http-pretend-keepalive”.
option http-no-delay
Das System anweisen, bei HTTP geringe interaktive Verzögerungen gegenüber hohem Durchsatz zu bevorzugen
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Bei HTTP fließen die Nutzdaten jeweils nur in eine Richtung; Interaktivität ist nicht vorgesehen. Von jedem Agenten wird erwartet, Daten bei vertretbar geringer Verzögerung in gewissem Umfang zu puffern. Es gibt einige äußerst seltene Anwendungen zwischen Servern, die das HTTP-Protokoll missbrauchen und erwarten, dass die Nutzdatenphase hochgradig interaktiv ist, wobei innerhalb einer einzigen Anfrage viele Datenblöcke abwechselnd in beide Richtungen übertragen werden. Dies wird von der HTTP-Spezifikation überhaupt nicht unterstützt und wird bei den meisten Proxies oder Servern nicht funktionieren. Wenn solche Anwendungen dies über HAProxy versuchen, funktioniert es zwar, doch treten hohe Verzögerungen auf, da die Netzwerkoptimierungen einen hohen Durchsatz bevorzugen, indem sie das System anweisen, auf ausreichend Daten zu warten, um nur vollständige Pakete zu senden. Typische Verzögerungen betragen etwa 200 ms pro Hin- und Rückweg. Beachten Sie, dass dies nur bei abnormalen Anwendungen auftritt. Normale Anwendungen wie CONNECT-Anfragen oder WebSockets sind nicht betroffen.
Wenn “option http-no-delay” im Frontend oder Backend einer Verbindung gesetzt ist, werden alle solchen Optimierungen deaktiviert, um den Datenaustausch möglichst schnell zu machen. Natürlich gibt dies keine Garantie für die Funktionalität, da die Funktion an jeder anderen Stelle scheitern kann. Aber wenn es über HAProxy funktioniert, wird es so schnell wie möglich funktionieren. Diese Option sollte niemals standardmäßig aktiviert werden und sollte niemals verwendet werden, außer wenn eine solche fehlerhafte Anwendung entdeckt wurde. Der Einfluss dieser Option ist eine Erhöhung des Bandbreitenverbrauchs und des CPU-Verbrauchs, was die Leistung in Umgebungen mit hoher Latenz erheblich beeinträchtigen kann.
Siehe auch: “option http-buffer-request”
option http-pretend-keepalive
Festlegen, ob HAProxy gegenüber dem Server Keepalive für eine HTTP/1.x-Verbindung ankündigt
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Wenn “option http-server-close” oder “option httpclose” aktiviert ist, fügt HAProxy einen “Connection: close”-Header zur HTTP/1.x-Anfrage hinzu, die an den Server weitergeleitet wird. Leider verzichten einige Server beim Erkennen dieses Headers automatisch auf die Chunked-Kodierung für Antworten unbekannter Länge, obwohl dies völlig unabhängig davon ist. Die Folge ist, dass ein Client oder ein Cache eine unvollständige Antwort erhalten kann, ohne dies zu bemerken, und die Antwort für vollständig halten könnte.
Durch die Einstellung von “option http-pretend-keepalive” lässt HAProxy den Server glauben, dass die Verbindung weiterhin aktiv bleibt. Der Server fällt dann nicht auf das unerwünschte Verhalten zurück. Sobald HAProxy die gesamte Antwort erhalten hat, schließt es die Verbindung zum Server genau so, wie es bei “option httpclose” der Fall wäre. Auf diese Weise erhält der Client eine normale Antwort, und die Verbindung wird korrekt auf der Serverseite geschlossen.
Es wird empfohlen, diese Option nicht standardmäßig zu aktivieren, da die meisten Server die Verbindung effizienter selbst nach dem letzten Paket schließen und ihre Puffer etwas früher freigeben werden. Außerdem könnte das zusätzliche Paket im Netzwerk die erreichbare Spitzenleistung insgesamt leicht reduzieren. Bei aktivierter Option hat HAProxy allerdings etwas weniger Arbeit zu erledigen. Wenn HAProxy somit der Engpass in der gesamten Architektur ist, könnte die Aktivierung dieser Option einige CPU-Zyklen sparen.
Diese Option kann in Backend- und listen-Abschnitten gesetzt werden. Die Verwendung in einem Frontend-Abschnitt wird ignoriert, und es wird während des Starts eine Warnung ausgegeben. Es handelt sich um eine Backend-bezogene Option, daher besteht kein echter Grund, sie in einem Frontend zu setzen.
Wenn diese Option in einem “defaults”-Abschnitt aktiviert wurde, kann sie in einer bestimmten Instanz durch Voranstellen des “no”-Schlüsselworts deaktiviert werden.
Siehe auch: “option httpclose”, “option http-server-close” und “option http-keep-alive”
option http-restrict-req-hdr-names { preserve | delete | reject }
Das Verhalten von HAProxy für Namen von HTTP-Anfrageheadern mit Zeichen außerhalb des Zeichensatzes “[a-zA-Z0-9-]” festlegen
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Diese Option kann verwendet werden, um die Namen von Anfrageheadern auf alphanumerische Zeichen und Bindestriche ([A-Za-z0-9-]) zu beschränken. Dies kann erforderlich sein, um mit nicht-HTTP-konformen Servern zu interagieren, die bestimmte Zeichen in Headernamen nicht korrekt behandeln. Es kann auch erforderlich sein für FastCGI-Anwendungen, da alle nicht alphanumerischen Zeichen in Headernamen durch einen Unterstrich (’_’) ersetzt werden. Dadurch ist es leicht möglich, Headernamen zu verwechseln und einige Regeln zu umgehen. Zum Beispiel werden die Header “X-Forwarded-For” und “X_Forwarded-For” beide in FastCGI zu “HTTP_X_FORWARDED_FOR” konvertiert.
Diese Option wird für jeden Proxy nach der Auswertung der http-request-Regeln ausgewertet.
option http-server-close
Das Schließen von HTTP/1.x-Verbindungen auf der Serverseite aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Standardmäßig arbeitet HAProxy im Keep-Alive-Modus bezüglich persistenter HTTP/1.x-Verbindungen: Es verarbeitet jede Anfrage und Antwort einer Verbindung und lässt die Verbindung anschließend auf beiden Seiten inaktiv offen. Dieser Modus kann durch mehrere Optionen geändert werden, wie beispielsweise “option http-server-close” oder “option httpclose”. Die Einstellung von “option http-server-close” aktiviert das Schließen von HTTP-Verbindungen auf der Serverseite, während die Fähigkeit zur Unterstützung von HTTP Keep-Alive und Pipelining auf Clientseite erhalten bleibt. Dies bietet die niedrigste Latenz auf Clientseite (bei langsamen Netzwerken) und die schnellste Sitzungs-Wiederverwendung auf Serverseite, um Serverressourcen zu sparen, vergleichbar mit “option httpclose”. Dadurch können auch Server ohne Keepalive-Unterstützung gegenüber Clients im Keepalive-Modus bereitgestellt werden, sofern sie die Anforderungen von RFC7230 erfüllen. Bitte beachten Sie, dass einige Server diese Anforderungen nicht immer erfüllen, wenn sie “Connection: close” in der Anfrage sehen. Die Folge ist, dass Keep-Alive niemals verwendet wird. Eine Lösung besteht darin, “option http-pretend-keepalive” zu aktivieren.
Derzeit geben die Protokolle nicht an, ob Anfragen aus derselben Sitzung stammen oder nicht. Das in den Protokollen angegebene Annahmezeitpunkt entspricht dem Ende der vorherigen Anfrage, und die Anfragezeit entspricht der Zeit, die zum Warten auf eine neue Anfrage benötigt wird. Die Keepalive-Anfragezeit wird weiterhin durch “timeout http-keep-alive” begrenzt oder, falls nicht gesetzt, durch “timeout http-request”.
Diese Option kann sowohl in einem Frontend als auch in einem Backend gesetzt werden. Sie ist aktiviert, wenn sie mindestens im Frontend oder im Backend der Verbindung aktiviert ist. Sie deaktiviert und ersetzt jede vorherige “option httpclose” oder “option http-keep-alive”. Abschnitt 4 (“Proxys”) beschreibt, wie sich diese Option mit anderen kombiniert, wenn Frontend- und Backend-Einstellungen voneinander abweichen.
Wenn diese Option in einem “defaults”-Abschnitt aktiviert wurde, kann sie in einer bestimmten Instanz durch Voranstellen des “no”-Schlüsselworts deaktiviert werden.
Siehe auch: “option httpclose”, “option http-pretend-keepalive” und “option http-keep-alive”.
option http-use-proxy-header
Den nicht standardisierten Header Proxy-Connection anstelle von Connection verwenden
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
RFC7230 schreibt ausdrücklich vor, dass HTTP/1.1-Agenten über den Connection-Header angeben müssen, ob sie dauerhafte oder nicht dauerhafte Verbindungen wünschen. Browser und Proxys ignorieren diesen Header jedoch bei Verbindungen über einen Proxy und verwenden stattdessen den undokumentierten, nicht standardisierten Header Proxy-Connection. Problematisch wird dies, wenn ein Load-Balancer zwischen Browsern und solchen Proxys eingesetzt wird: HAProxy versteht dann etwas anderes als das, was Client und Proxy miteinander vereinbaren.
Wird diese Option in einem Frontend gesetzt, kann HAProxy bei Erkennung von Proxy-Anfragen automatisch auf diesen nicht standardisierten Header wechseln. Als Proxy-Anfrage gilt hier eine Anfrage, deren URI weder mit ‘/’ noch mit ‘*’ beginnt. Dies ist mit dem HTTP-Tunnelmodus inkompatibel. Die Option kann nur in einem Frontend angegeben werden und wirkt sich während der gesamten Verarbeitung auf die Anfrage aus.
Bei gesetzter Option verwendet außerdem eine Anfrage, die eine Authentifizierung erfordert, automatisch die Header zur Proxy-Authentifizierung, sofern sie selbst eine Proxy-Anfrage ist. Damit lässt sich die Authentifizierung vor einem bestehenden Proxy prüfen oder erzwingen.
Diese Option sollte normalerweise niemals verwendet werden, außer vor einem Proxy.
Siehe auch: “option httpclose” und “option http-server-close”.
option httpchk
Das HTTP-Protokoll für Health Checks der Server aktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Standardmäßig bestehen Serverzustandsprüfungen nur aus dem Versuch, eine TCP-Verbindung aufzubauen. Wird “option httpchk” angegeben, wird nach dem Aufbau der TCP-Verbindung eine vollständige HTTP-Anfrage gesendet. Antworten mit 2xx und 3xx gelten als gültig; alle anderen Antworten sowie das vollständige Ausbleiben einer Antwort zeigen einen Serverausfall an.
In Kombination mit “http-check”-Direktiven lassen sich die bei HTTP-Health-Checks gesendete Anfrage oder die Abgleichregeln für die Antwort anpassen. Außerdem kann wie mit der Direktive “tcp-check” für TCP-Health-Checks eine send/expect-Sequenz konfiguriert werden.
Zum Öffnen der Verbindungen für HTTP-Health-Checks wird standardmäßig die Serverkonfiguration verwendet. Serverparameter können jedoch mit “http-check connect”-Regeln überschrieben werden.
Die Option “httpchk” erfordert nicht zwingend ein HTTP-Backend; sie funktioniert auch mit reinen TCP-Backends. Dies ist besonders nützlich, um einfache Skripte zu prüfen, die über den inetd-Daemon an eigene Ports gebunden sind. Intern wird jedoch stets ein HTX-Multiplexer verwendet. Das bedeutet, dass die Anfrageformatierung und das Parsen der Antwort streng erfolgen.
Beispiele:
Siehe auch: “option ssl-hello-chk”, “option smtpchk”, “option mysql-check”, “option pgsql-check”, “http-check” sowie die Serveroptionen “check”, “port” und “inter”.
option httpclose
Das Schließen von HTTP/1.x-Verbindungen aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Standardmäßig arbeitet HAProxy bei dauerhaften HTTP/1.x-Verbindungen im Keepalive-Modus: Es verarbeitet jede Anfrage und Antwort einer Verbindung und lässt die Verbindung anschließend auf beiden Seiten inaktiv offen. Dieser Modus lässt sich durch verschiedene Optionen wie “option http-server-close” oder “option httpclose” ändern.
Ist “option httpclose” gesetzt, schließt HAProxy je nach Ort der Einstellung die Client- oder die Serververbindung. Für Clientverbindungen zählt das Frontend, für Serververbindungen das Backend. Wird die Option in einem Listener gesetzt, gilt sie für beide Seiten. In jeder Richtung wird geprüft, ob bereits ein Header “Connection: close” gesetzt ist; fehlt er, wird er hinzugefügt.
Diese Option kann auch mit “option http-pretend-keepalive” kombiniert werden. Dann wird der Anfrageheader “Connection: close” nicht gesendet, die Verbindung aber weiterhin geschlossen, sobald die vollständige Antwort empfangen wurde.
Sie deaktiviert und ersetzt alle vorherigen Optionen “option http-server-close” oder “option http-keep-alive”.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option http-server-close”.
option httplog [ clf ]
Die Protokollierung von HTTP-Anfrage, Streamstatus und Zeitmessungen aktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Standardmäßig ist das Protokollausgabeformat sehr knapp: Es enthält lediglich Quell- und Zieladressen sowie den Instanznamen. Mit “option httplog” erhält jede Protokollzeile ein wesentlich ausführlicheres Format. Es enthält unter anderem die HTTP-Anfrage, Verbindungszeitmessungen, den Streamstatus, Verbindungszahlen, erfasste Header und Cookies, die Namen von Frontend, Backend und Server sowie natürlich Quelladresse und Ports.
Die alleinige Angabe von “option httplog” hebt automatisch den Modus ‘clf’ auf, wenn dieser standardmäßig gesetzt war.
“option httplog” überschreibt jede vorherige “log-format”-Direktive.
Siehe auch: Abschnitt 8 zur Protokollierung.
option httpslog
Die Protokollierung von HTTPS-Anfrage, Streamstatus und Zeitmessungen aktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Standardmäßig ist das Protokollausgabeformat sehr knapp: Es enthält lediglich Quell- und Zieladressen sowie den Instanznamen. Mit “option httpslog” erhält jede Protokollzeile ein wesentlich ausführlicheres Format. Es enthält unter anderem die HTTP-Anfrage, Verbindungszeitmessungen, den Streamstatus, Verbindungszahlen, erfasste Header und Cookies, die Namen von Frontend, Backend und Server, den Status der SSL-Zertifikatsprüfung und des SSL-Handshakes sowie natürlich Quelladresse und Ports.
“option httpslog” überschreibt jede vorherige “log-format”-Direktive.
Siehe auch: Abschnitt 8 zur Protokollierung.
option idle-close-on-response
Das Schließen inaktiver Frontendverbindungen während eines sanften Stopps vermeiden
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
Standardmäßig werden inaktive Verbindungen bei einem sanften Stopp geschlossen. In manchen Umgebungen hat ein Client bereits inaktive Verbindungen zum Proxy aufgebaut, um später Anfragen zu senden. Wenn Schreibfehler nicht korrekt durch Wiederholungsversuche behandelt werden, kann dies beim Neuladen von haproxy zu Fehlern führen. Obwohl eine korrekte Implementierung bei Verbindungs- oder Schreibfehlern erneut versuchen sollte, wurde diese Option eingeführt, um die Kompatibilität mit haproxy vor Version 2.4 zu erhalten. Vor v2.4 wartete haproxy tatsächlich auf eine letzte Anfrage und Antwort, um vor dem Schließen den Header “connection: close” hinzuzufügen. So wurde dem Client mitgeteilt, dass die Verbindung nicht wiederverwendbar sein würde.
Dieses Verhalten wurde beispielsweise bei AWS mit einem vor haproxy geschalteten ALB beobachtet. Im Ergebnis sendete ALB beim Neuladen von haproxy den Status 502.
Benutzer werden darauf hingewiesen, dass diese Option die Anzahl alter Prozesse erhöhen kann, wenn Verbindungen zu lange inaktiv bleiben. Bei häufigem Neuladen kann es erforderlich sein, die Clientzeitüberschreitungen und/oder den Parameter “hard-stop-after” entsprechend anzupassen.
Siehe auch: “timeout client”, “timeout client-fin”, “timeout http-request”, “hard-stop-after”
option independent-streams
Die unabhängige Behandlung von Zeitüberschreitungen für beide Richtungen aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Standardmäßig werden beim Senden von Daten über ein Socket sowohl dessen Schreib- als auch dessen Lesezeitüberschreitung neu gestartet. Der Grund ist, dass auf dem Socket Aktivität stattfindet und es keine andere Möglichkeit gibt festzustellen, ob Daten empfangen werden sollten.
Dieses Standardverhalten ist für fast alle Anwendungen erwünscht. In einem bestimmten Fall ist es jedoch sinnvoll, es zu deaktivieren und die Lesezeitüberschreitung nur bei eingehenden Daten neu zu starten: bei Streams mit langen Zeitüberschreitungen und wenig Datenaustausch, etwa Telnet-Sitzungen. Verschwindet der Server plötzlich, sammeln sich die ausgehenden Daten in den Socket-Puffern des Systems. Beide Zeitüberschreitungen werden weiterhin korrekt neu gestartet, und es lässt sich nicht erkennen, dass der Server die Daten nicht empfängt. Daher tritt keine Zeitüberschreitung ein. Wenn das zugrunde liegende Protokoll gesendete Daten jedoch stets zurückspiegelt, würde dies allein ausreichen, um das Problem anhand der Lesezeitüberschreitung zu erkennen. Bei Protokollen mit mehr Datenaustausch tritt dieses Problem nicht auf, da sich die Daten nicht lange in den Socket-Puffern ansammeln.
Wird diese Option im Frontend gesetzt, wird die Lesezeitüberschreitung beim Senden von Daten an den Client nicht mehr neu gestartet. Dafür gibt es vermutlich wenig Anwendungsmöglichkeiten. Im Backend verhindert die Option entsprechend das Neustarten der Lesezeitüberschreitung beim Senden von Daten an den Server. Dadurch schlagen gewöhnlich große HTTP-POST-Übertragungen über langsame Leitungen fehl; verwenden Sie die Option daher mit Vorsicht.
Siehe auch: “timeout client”, “timeout server” und “timeout tunnel”
option ldap-check
LDAPv3-Health-Checks zum Testen von Servern verwenden
Kann in folgenden Kontexten verwendet werden: tcp
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Es kann geprüft werden, ob der Server LDAPv3 korrekt verarbeitet, statt lediglich zu testen, ob er die TCP-Verbindung annimmt. Bei gesetzter Option wird eine anonyme Simple-Bind-Nachricht für LDAPv3 an den Server gesendet und die Antwort auf eine LDAPv3-Bind-Antwortnachricht untersucht.
Der Server gilt nur dann als funktionsfähig, wenn die LDAP-Antwort für resultCode den Wert success enthält (http://tools.ietf.org/html/rfc4511#section-4.1.9 ).
Die Protokollierung von Bind-Anfragen hängt vom Server ab. Hinweise zur Konfiguration finden Sie in dessen Dokumentation.
Beispiel:
Siehe auch: “option httpchk”
option log-health-checks
Die Protokollierung von Statusänderungen bei Health Checks aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Standardmäßig werden fehlgeschlagene Health Checks protokolliert, wenn der Server UP ist, und erfolgreiche Prüfungen, wenn er DOWN ist. Dadurch ist die Menge zusätzlicher Informationen begrenzt.
Bei aktivierter Option wird jede Änderung des Prüfungsstatus oder des Serverzustands protokolliert. So lässt sich erkennen, dass ein Server vor seinem Absturz gelegentlich Prüfungen nicht bestand, oder genau nachvollziehen, wann er keinen gültigen HTTP-Status mehr zurückgab, wann anschließend der Port Verbindungen abwies und wann der Server schließlich überhaupt nicht mehr antwortete.
Statusänderungen, die nicht durch Health Checks verursacht werden, etwa das Aktivieren oder Deaktivieren über die CLI, werden von dieser Option absichtlich nicht protokolliert.
Siehe auch: “option httpchk”, “option ldap-check”, “option mysql-check”, “option pgsql-check”, “option redis-check”, “option smtpchk”, “option tcp-check”, “log” und Abschnitt 8 zur Protokollierung.
option log-separate-errors
Die Protokollstufe für nicht vollständig erfolgreiche Verbindungen ändern
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
Fehler in Protokollen zu finden, ist manchmal schwierig. Mit dieser Option erhöht HAProxy die Stufe von Einträgen mit möglicherweise aufschlussreichen Informationen wie Fehlern, Zeitüberschreitungen, Wiederholungsversuchen, erneuten Zuweisungen oder HTTP-Statuscodes 5xx von “info” auf “err”. Die meisten Syslog-Daemons können solche Einträge dadurch getrennt in einer anderen Datei protokollieren. Entfernen Sie sie jedoch nicht aus der ursprünglichen Datei, da sonst die Reihenfolge verloren geht, die sehr wichtige Informationen liefert.
Große Websites mit mehreren Tausend Verbindungen pro Sekunde können damit normalen Datenverkehr in einem Ringpuffer protokollieren und nur die kleineren Fehlerprotokolle archivieren.
Siehe auch: “log”, “dontlognull”, “dontlog-normal” und Abschnitt 8 zur Protokollierung.
option logasap
Frühzeitige Protokollierung aktivieren oder deaktivieren.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
Standardmäßig werden Protokolleinträge ausgegeben, sobald alle in der log-format-Zeichenkette verwendeten Protokollformat-Aliasse und Sample-Abrufe einen Wert liefern oder wenn der Stream beendet wird. So können die eingebauten Protokollformate die Übertragungszeit oder die Anzahl der Bytes in den Protokollmeldungen berücksichtigen.
Bei langlebigen Verbindungen, etwa großen Dateiübertragungen oder RDP, kann es dauern, bis eine Anfrage oder Verbindung im Protokoll erscheint. Mit “option logasap” wird die Protokollmeldung im Modus tcp unmittelbar nach dem Aufbau der Serververbindung erzeugt, im Modus http unmittelbar nach dem Senden der vollständigen Header durch den Server. Es fehlen dann die endgültige Gesamtzahl der Bytes und die vollständige Gesamtzeit: Die Bytezahl gibt nur die bis zur Erzeugung der Meldung übertragenen Daten an, und die Zeit berücksichtigt weder die restliche Verbindungsdauer noch die verbleibende Übertragungszeit. Bei HTTP ist es sinnvoll, den Antwortheader Content-Length zu erfassen, damit das Protokoll zumindest die erwartete Anzahl zu übertragender Bytes angibt.
Beispiele:
Siehe auch: “option httplog”, “capture response header” und Abschnitt 8 zur Protokollierung.
option mysql-check [ user <username> [ { post-41 | pre-41 | post-80 } ] ]
MySQL-Health-Checks zum Testen von Servern verwenden
Kann in folgenden Kontexten verwendet werden: tcp
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Wird ein Benutzername angegeben, besteht die Prüfung aus dem Senden von zwei MySQL-Paketen: einem Paket vom Typ Client Authentication und einem QUIT-Paket, um die MySQL-Sitzung korrekt zu schließen. Anschließend werden das MySQL-Paket Handshake Initialization und/oder das Error-Paket geparst. Dies ist ein einfacher, aber nützlicher Test, der auf dem Server weder Fehler noch abgebrochene Verbindungsaufbauten erzeugt. Er erfordert jedoch einen nicht gesperrten, berechtigten Benutzer ohne Passwort. So lässt sich ein einfacher eingeschränkter MySQL-Benutzer mit optionalen Ressourcenlimits anlegen:
Wird kein Benutzername angegeben, was veraltet ist und nicht empfohlen wird, besteht die Prüfung lediglich aus dem Parsen des MySQL-Pakets Handshake Initialization oder des Error-Pakets. In diesem Modus wird nichts gesendet. Es wurde berichtet, dass dies zu einer Sperrung führen kann, wenn die Prüfung zu häufig erfolgt und/oder nicht genügend Datenverkehr vorhanden ist. In diesem Fall muss der MySQL-Wert “max_connect_errors” geprüft werden: Wird nach einer unterbrochenen Verbindung innerhalb von weniger als MySQL “max_connect_errors” Versuchen erfolgreich eine Verbindung aufgebaut, wird der Fehlerzähler für den Host auf null zurückgesetzt. Wird der Host mit HAProxy gesperrt, lässt sich die Sperre ausschließlich mit der Anweisung “FLUSH HOSTS” aufheben.
Dies prüft weder das Vorhandensein noch die Konsistenz der Datenbank. Dazu kann beispielsweise eine externe Prüfung mit xinetd verwendet werden.
Die Prüfung erfordert MySQL >=3.22. Für ältere Versionen verwenden Sie bitte eine TCP-Prüfung.
Ein MySQL-Server benötigt häufig die IP-Adresse des Clients für verschiedene Zwecke, etwa den Abgleich von IP-basierten Berechtigungen und die Verbindungsprotokollierung. Wenn möglich, ist es daher oft sinnvoll, beim Verbindungsaufbau zum Server mit dem Argument “usesrc” des Schlüsselworts “source” die IP-Adresse des Clients als eigene auszugeben. Dazu muss die Funktion für transparente Proxys einkompiliert sein, und der MySQL-Server muss den Verkehr zum Client über den Rechner mit HAProxy routen.
Siehe auch: “option httpchk”
option nolinger
Das sofortige Freigeben von Sitzungsressourcen nach dem Schließen aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Wenn Clients oder Server Verbindungen unsauber abbrechen, etwa durch eine physische Trennung, greift die Sitzungszeitüberschreitung, und die Sitzung wird geschlossen. Im System bleibt sie jedoch noch einige Zeit im Zustand FIN_WAIT1, belegt Ressourcen und kann den Aufbau neuer Verbindungen einschränken.
In diesem Fall kann “option nolinger” aktiviert werden. Sie zwingt das System, beim Schließen alle noch ausstehenden Daten eines Sockets sofort zu entfernen. Dadurch wird ein TCP RST gesendet, ausstehende Daten werden abgeschnitten, und die Sitzung wird sofort aus den Systemtabellen entfernt. Für den Client zeigt sich dies gewöhnlich in abgeschnittenen Antworten, wenn das Schließen zusammen mit dem letzten Datenblock erfolgt, etwa bei einer Weiterleitung oder Fehlerantwort. Auf der Serverseite kann die Option helfen, beim Weiterleiten eines Clientabbruchs in Tunneln die Quellports sofort freizugeben. In beiden Fällen werden TCP-Resets gesendet. Da die Sitzung sofort zerstört wird, gibt es keine erneute Übertragung. In einem Netz mit Paketverlusten kann dies Probleme verstärken, besonders wenn sich auf der verlustbehafteten Seite eine Firewall befindet: Diese könnte den Reset empfangen und verarbeiten, ihre Sitzung entfernen und anschließend jeden weiteren Datenverkehr dieser Sitzung blockieren, einschließlich erneuter Übertragungen von der anderen Seite. Empfängt die andere Seite den Reset nicht, wird sie daher nie wieder einen RST erhalten, und die Firewall protokolliert möglicherweise viele blockierte Pakete.
Aus all diesen Gründen wird dringend empfohlen, diese Option NICHT zu verwenden, außer wenn sie als letzter Ausweg unbedingt erforderlich ist. In den meisten Situationen erzielen die Zeitüberschreitungen “client-fin” oder “server-fin” ähnliche Ergebnisse bei zuverlässigerem Verhalten. Unter Linux kann auch die bind- oder Servereinstellung “tcp-ut” verwendet werden.
Diese Option kann je nach benötigter Seite in Frontends und Backends verwendet werden: im Frontend für Clients, im Backend für Server. Obwohl sie technisch in “defaults”-Abschnitten unterstützt wird, darf sie dort wirklich nicht verwendet werden. Sie könnte versehentlich in Abschnitte vererbt werden, in denen sie nicht verwendet werden darf, und dort Probleme verursachen.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “timeout client-fin”, “timeout server-fin” sowie das bind- oder Server-Schlüsselwort “tcp-ut”.
option originalto [ except <network> ] [ header <name> ]
Das Einfügen des Headers X-Original-To in an Server gesendete Anfragen aktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Da HAProxy im transparenten Modus arbeiten kann, lässt sich jede Clientanfrage zum Proxy umleiten. HAProxy selbst kann jede Anfrage an eine komplexe SQUID-Umgebung weiterleiten, wobei der Zielhost aus SO_ORIGINAL_DST verloren geht. Dies ist störend, wenn Zugriffsregeln auf Ziel-IP-Adressen beruhen sollen. Als Lösung kann HAProxy allen an den Server gesendeten Anfragen einen neuen HTTP-Header “X-Original-To” hinzufügen. Dessen Wert gibt die ursprüngliche Ziel-IP-Adresse an. Es muss so konfiguriert werden, dass ausschließlich das letzte Vorkommen dieses Headers verwendet wird. Nur dieses darf verwendet werden, da der Client durchaus bereits einen solchen Header mitgesendet haben kann.
Mit dem Schlüsselwort “header” kann anstelle von “X-Original-To” ein anderer Headername angegeben werden. Dies kann nützlich sein, wenn bereits ein “X-Original-To”-Header einer anderen Anwendung vorhanden ist und erhalten bleiben soll. Dasselbe gilt, wenn der Backend-Server “X-Original-To” nicht verwendet und einen anderen Header verlangt.
Manchmal wird dieselbe HAProxy-Instanz sowohl für direkten Clientzugriff als auch für Zugriff über einen Reverse-Proxy verwendet, etwa wenn ein SSL-Reverse-Proxy den HTTPS-Verkehr entschlüsselt. Für eine bekannte Zieladresse oder ein bekanntes Netz lässt sich das Hinzufügen des Headers mit dem Schlüsselwort “except” und der nachfolgenden Netzadresse deaktivieren. Bei Ziel-IP-Adressen, die zu diesem Netz passen, wird der Header dann nicht hinzugefügt. Dies wird am häufigsten mit privaten Netzen oder 127.0.0.1 verwendet. Sowohl IPv4 als auch IPv6 werden unterstützt.
Diese Option kann im Frontend oder im Backend angegeben werden. Verwendet sie mindestens eines von beiden, wird der Header hinzugefügt. Wenn beide das Unterargument header definieren, hat dessen Einstellung im Backend Vorrang vor der im Frontend.
Beispiele:
Siehe auch: “option httpclose”, “option http-server-close”.
option persist
Die erzwungene Sitzungsbindung an ausgefallene Server aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Erreicht eine HTTP-Anfrage ein Backend mit einem Cookie, das auf einen ausgefallenen Server verweist, wird sie standardmäßig einem anderen Server zugewiesen. Falls unbedingt erforderlich, kann mit “option persist” erzwungen werden, dass die Anfrage zunächst an den ausgefallenen Server gesendet wird. Ein häufiger Anwendungsfall sind extrem ausgelastete Server, deren Zustand ständig zwischen verfügbar und ausgefallen wechselt. Benutzer werden dann weiterhin an den Server geleitet, auf dem sie ihre Sitzung eröffnet haben, in der Hoffnung, dass ihre Anfrage korrekt bearbeitet wird. Es wird empfohlen, diese Option zusammen mit “option redispatch” zu verwenden: Kann überhaupt keine Verbindung zum Server hergestellt werden, weil er endgültig ausgefallen ist, wird der Client schließlich an einen anderen funktionsfähigen Server weitergeleitet.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option redispatch”, “retries”, “force-persist”
option pgsql-check user <username>
PostgreSQL-Health-Checks zum Testen von Servern verwenden
Kann in folgenden Kontexten verwendet werden: tcp
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Die Prüfung sendet eine PostgreSQL-StartupMessage und wartet entweder auf eine Authentifizierungsanfrage oder eine ErrorResponse-Nachricht. Dies ist ein einfacher, aber nützlicher Test, der auf dem Server weder Fehler noch abgebrochene Verbindungsaufbauten erzeugt. Diese Prüfung entspricht “mysql-check”.
Siehe auch: “option httpchk”
option prefer-last-server
Mehrere über die Lastverteilung zugewiesene Anfragen auf demselben Server belassen können
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Ist der verwendete Lastverteilungsalgorithmus nicht deterministisch und wurde eine vorherige Anfrage an einen Server gesendet, zu dem HAProxy noch eine Verbindung hält, ist es manchmal erwünscht, nachfolgende Anfragen derselben Sitzung möglichst an denselben Server zu senden. Dies unterscheidet sich von Sitzungsbindung: Es wird lediglich eine Präferenz angegeben, die HAProxy ohne jede Garantie umzusetzen versucht. Der eigentliche Anwendungsfall sind Keepalive-Verbindungen zu Servern. Bei dieser Option versucht HAProxy, dieselbe Verbindung zum Server wiederzuverwenden, statt die Anfrage einem anderen Server zuzuweisen und dadurch die bestehende Verbindung zu schließen. Für Server mit statischen Dateien kann dies sinnvoll sein. In Kombination mit Hashing-Algorithmen ist es wenig sinnvoll. Bei nicht deterministischer Lastverteilung versucht HAProxy bereits automatisch, bei einem Server zu bleiben, der 401 sendet, oder bei einem Proxy, der 407 sendet (Authentifizierung erforderlich). Dies ist für das fehlerhafte NTLM-Authentifizierungsverfahren zwingend erforderlich und erleichtert die Fehlersuche bei manchen mangelhaften Anwendungen erheblich. Auch in solchen Umgebungen kann option prefer-last-server sinnvoll sein, damit der Datenverkehr nicht nach jeder anderen Antwort neu verteilt wird.
Hier ist es hilfreich zu erläutern, welche Lastverteilungsalgorithmen als deterministisch gelten. Deterministische Algorithmen wählen für bestimmte Clientdaten immer denselben Server, sofern sich die Menge verfügbarer Server nicht geändert hat. Im Allgemeinen wählen sie den Zielserver durch Hashing oder Nachschlagen anhand der eingehenden Anfragen. Dies gilt jedoch nicht immer: Auch “static-rr” kann beispielsweise als deterministisch angesehen werden, weil die Serverauswahl auf dem statischen Servergewicht beruht und damit vorhersehbar ist. Der Algorithmus “sticky” bietet deterministisches Routing für wiederkehrende Clients.
Nicht deterministische Algorithmen wählen dagegen anhand des dynamischen Serverzustands oder einer einfachen Rotation aus. Daher ist nicht garantiert, dass zwei aufeinanderfolgende Anfragen denselben Server erreichen. option prefer-last-server ist speziell für solche Algorithmen vorgesehen; roundrobin und leastconn sind Beispiele dafür.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option http-keep-alive”
option redispatch
Die erneute Verteilung von Sitzungen bei Verbindungsfehlern aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Ist im HTTP-Modus ein durch ein Cookie bestimmter Server ausgefallen, können Clients dauerhaft an ihn gebunden bleiben, etwa bei “option persist” oder “force-persist”. Da sie das Cookie nicht löschen können, ist ihnen dann der Zugriff auf den Dienst nicht mehr möglich.
Mit “option redispatch” darf der Proxy die cookie- oder auf konsistentem Hashing beruhende Sitzungsbindung aufheben und die Clients einem funktionierenden Server zuweisen.
Aktive Server werden aus einer Teilmenge der Liste verfügbarer Server ausgewählt. Aktive Server, die weder ausgefallen noch in Wartung sind, also entweder nicht auf ihren Zustand geprüft werden oder als “up” geprüft wurden, werden in folgender Reihenfolge ausgewählt:
Bei einem Wiederholungsversuch versucht HAProxy, einen anderen als den zuletzt verwendeten Server auszuwählen. Der neue Server wird aus der aktuellen Serverliste gewählt.
Wird die Liste zwischen Wiederholungsversuchen aktualisiert, können Verbindungen gelegentlich auch zu einem Ersatzserver umgeleitet werden. Dies kann beispielsweise geschehen, wenn zahlreiche Wiederholungsversuche länger dauern als nötig, um den Ausfall eines Servers zu erkennen, ihn aus der Liste zu entfernen und auf die Ersatzserverliste zurückzufallen.
Die Option erlaubt außerdem, bei mehreren Verbindungsfehlern Verbindungen zu einem anderen Server erneut zu versuchen. Dafür muss “retries” auf einen Wert ungleich null gesetzt sein.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option persist”, “force-persist”, “retries”
option redis-check
Redis-Health-Checks zum Testen von Servern verwenden
Kann in folgenden Kontexten verwendet werden: tcp
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Es kann geprüft werden, ob der Server das REDIS-Protokoll korrekt verarbeitet, statt lediglich zu testen, ob er die TCP-Verbindung annimmt. Bei gesetzter Option wird der Redis-Befehl PING an den Server gesendet und die Antwort auf die Nachricht “+PONG” untersucht.
Beispiel:
Siehe auch: “option httpchk”, “option tcp-check”, “tcp-check expect”
option smtpchk
SMTP-Health-Checks zum Testen von Servern verwenden
Kann in folgenden Kontexten verwendet werden: tcp
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Bei gesetzter “option smtpchk” bestehen die Health Checks aus TCP-Verbindungen, auf die ein SMTP-Befehl folgt. Standardmäßig lautet dieser “HELO localhost”. Der Rückgabecode des Servers wird ausgewertet; nur Codes, die mit “2” beginnen, gelten als gültig. Alle anderen Antworten, einschließlich einer ausbleibenden Antwort, gelten als Fehler und zeigen einen ausgefallenen Server an.
Dieser Test ist für SMTP-Server oder -Relays vorgesehen. Je nach Anfrage protokollieren manche Server möglicherweise nicht jeden Verbindungsversuch. Daher kann es sinnvoll sein, durch Versuche ein besseres Verhalten zu erreichen. Die Verwendung von Telnet auf Port 25 ist häufig einfacher als das Anpassen der Konfiguration.
Ein SMTP-Server benötigt häufig die IP-Adresse des Clients für verschiedene Zwecke, etwa Spamfilter, Schutz vor gefälschten Absendern und Protokollierung. Wenn möglich, ist es daher oft sinnvoll, beim Verbindungsaufbau zum Server mit dem Argument “usesrc” des Schlüsselworts “source” die IP-Adresse des Clients als eigene auszugeben. Dazu muss die Funktion für transparente Proxys einkompiliert sein.
Beispiel:
Siehe auch: “option httpchk”, “source”
Das Erfassen und Bereitstellen getrennter Statistiken für jedes Socket aktivieren oder deaktivieren.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
option splice-auto
Die automatische Kernel-Beschleunigung für Sockets in beiden Richtungen aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Ist diese Option im Frontend oder im Backend aktiviert, prüft HAProxy automatisch, ob TCP-Splicing im Kernel zur Weiterleitung von Daten zwischen Client und Server in einer der beiden Richtungen sinnvoll ist. HAProxy schätzt anhand von Heuristiken, ob Kernel-Splicing die Leistung verbessern könnte. Beide Richtungen werden unabhängig behandelt. Die Heuristiken sind bewusst zurückhaltend, um übermäßigen Einsatz von Splicing zu vermeiden. Diese Option erfordert, dass Splicing beim Kompilieren aktiviert wurde. Mit der globalen Option “nosplice” kann es global deaktiviert werden. Da splice Pipes verwendet, müssen dafür genügend freie Pipes vorhanden sein.
Wichtiger Hinweis: TCP-Splicing im Kernel ist eine Linux-spezifische Funktion, die erstmals in Kernel 2.6.25 erschien. Sie beschleunigt die Übertragung zwischen Sockets im Kernel, ohne Daten in den Benutzeradressraum zu kopieren. Dies kann die Leistung spürbar steigern und CPU-Zyklen sparen. Da viele frühe Implementierungen fehlerhaft sind, Daten beschädigen und/oder ineffizient arbeiten, ist die Funktion nicht standardmäßig aktiviert und sollte mit äußerster Vorsicht verwendet werden. Die Korrektheit einer Implementierung lässt sich zwar nicht erkennen, doch 2.6.29 ist die erste Version mit einer ordnungsgemäß funktionierenden Implementierung. Im Zweifelsfall kann Splicing mit dem globalen Schlüsselwort “nosplice” global deaktiviert werden.
Beispiel:
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option splice-request”, “option splice-response” sowie die globalen Optionen “nosplice” und “maxpipes”
option splice-request
Die automatische Kernel-Beschleunigung für Sockets bei Anfragen aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Ist diese Option im Frontend oder im Backend aktiviert, verwendet HAProxy nach Möglichkeit TCP-Splicing im Kernel, um Daten vom Client zum Server weiterzuleiten. Wenn keine freien Pipes mehr vorhanden sind, kann weiterhin das recv/send-Verfahren verwendet werden. Diese Option erfordert, dass Splicing beim Kompilieren aktiviert wurde. Mit der globalen Option “nosplice” kann es global deaktiviert werden. Da splice Pipes verwendet, müssen dafür genügend freie Pipes vorhanden sein.
Wichtiger Hinweis: Einschränkungen bei der Verwendung finden Sie unter “option splice-auto”.
Beispiel:
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option splice-auto”, “option splice-response” sowie die globalen Optionen “nosplice” und “maxpipes”
option splice-response
Die automatische Kernel-Beschleunigung für Sockets bei Antworten aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Ist diese Option im Frontend oder im Backend aktiviert, verwendet HAProxy nach Möglichkeit TCP-Splicing im Kernel, um Daten vom Server zum Client weiterzuleiten. Wenn keine freien Pipes mehr vorhanden sind, kann weiterhin das recv/send-Verfahren verwendet werden. Diese Option erfordert, dass Splicing beim Kompilieren aktiviert wurde. Mit der globalen Option “nosplice” kann es global deaktiviert werden. Da splice Pipes verwendet, müssen dafür genügend freie Pipes vorhanden sein.
Wichtiger Hinweis: Einschränkungen bei der Verwendung finden Sie unter “option splice-auto”.
Beispiel:
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option splice-auto”, “option splice-request” sowie die globalen Optionen “nosplice” und “maxpipes”
option spop-check
SPOP-Health-Checks zum Testen von Servern verwenden
Kann in folgenden Kontexten verwendet werden: tcp
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Es kann geprüft werden, ob der Server das SPOP-Protokoll korrekt verarbeitet, statt lediglich zu testen, ob er die TCP-Verbindung annimmt. Bei gesetzter Option findet ein HELLO-Handshake zwischen HAProxy und dem Server statt. Die Antwort wird darauf geprüft, dass kein Fehler gemeldet wird.
Beispiel:
Siehe auch: “option httpchk”
option srvtcpka
Das Senden von TCP-Keepalive-Paketen auf der Serverseite aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Befindet sich zwischen einem Client und einem Server eine Firewall oder eine andere Komponente, die Sitzungszustände verfolgt, und verwendet das Protokoll sehr lange Sitzungen mit langen inaktiven Phasen, etwa bei Remotedesktops, besteht ein Risiko: Eine zwischengeschaltete Komponente könnte eine zu lange inaktive Sitzung ablaufen lassen.
Werden TCP-Keepalives auf Socket-Ebene aktiviert, sendet das System regelmäßig Pakete an das andere Ende der Verbindung und hält diese damit aktiv. Der Abstand zwischen Keepalive-Prüfungen wird ausschließlich vom System gesteuert und hängt sowohl vom Betriebssystem als auch von dessen Abstimmungsparametern ab.
Keepalive-Pakete werden auf Anwendungsebene weder gesendet noch empfangen. Nur die Netzwerkstapel sehen sie. Selbst wenn also eine Seite des Proxys bereits Keepalives verwendet, um ihre Verbindung aktiv zu halten, werden diese Pakete nicht zur anderen Seite des Proxys weitergeleitet.
Dies hat nichts mit HTTP-Keepalive zu tun.
Die Option “srvtcpka” aktiviert das Senden von TCP-Keepalive-Prüfungen auf der Serverseite einer Verbindung. Dies sollte helfen, wenn zwischen HAProxy und einem Server Sitzungen ablaufen.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option clitcpka”, “option tcpka”
option ssl-hello-chk
Health Checks mit SSLv3-Client-Hello zum Testen von Servern verwenden
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Wenn SSL-basierte Protokolle im TCP-Modus durch HAProxy weitergeleitet werden, kann geprüft werden, ob der Server SSL korrekt verarbeitet, statt lediglich zu testen, ob er die TCP-Verbindung annimmt. Bei gesetzter “option ssl-hello-chk” werden nach dem Verbindungsaufbau zum Server reine SSLv3-Client-Hello-Nachrichten gesendet. Die Antwort wird auf eine SSL-Server-Hello-Nachricht untersucht. Der Server gilt nur dann als funktionsfähig, wenn die Antwort diese Server-Hello-Nachricht enthält.
Alle bislang getesteten Server antworten korrekt auf SSLv3-Client-Hello-Nachrichten. Die meisten protokollieren Anfragen, die nur Hello-Nachrichten enthalten, nicht einmal, was von Vorteil ist.
Diese Prüfung funktioniert auch ohne einkompilierte SSL-Unterstützung in HAProxy, da sie die SSL-Nachricht selbst erzeugt. Ist SSL-Unterstützung verfügbar, sollten bevorzugt native SSL-Health-Checks verwendet werden.
Siehe auch: “option httpchk”, “check-ssl”
option tcp-check
Health Checks mit tcp-check-send/expect-Sequenzen durchführen
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Diese Prüfmethode ist für die Kombination mit “tcp-check”-Befehlslisten vorgesehen, um Health Checks mit send/expect-Sequenzen zu ermöglichen.
TCP-Prüfungen unterstützen derzeit 4 Betriebsarten: - keine “tcp-check”-Direktive: Der Health Check besteht nur aus einem Verbindungsversuch. Dies bleibt der Standardmodus.
- Nur "tcp-check send" oder "tcp-check send-binary" ist angegeben: Beim
Öffnen der Verbindung wird eine Zeichenkette gesendet. Bei manchen
Protokollen lässt sich so beispielsweise eine "QUIT"-Nachricht senden,
damit der Server nicht bei jedem Health Check einen Verbindungsfehler
protokolliert. Das Prüfergebnis hängt weiterhin ausschließlich davon ab,
ob sich die Verbindung öffnen lässt.
- Nur "tcp-check expect" ist angegeben: Damit wird eine Begrüßungsmeldung
geprüft. Die Verbindung wird geöffnet, und HAProxy wartet auf Inhalte
vom Server, die bestimmte Regeln erfüllen müssen. Das Prüfergebnis
richtet sich nach der Übereinstimmung zwischen Inhalt und Regeln.
Dies eignet sich für POP, IMAP, SMTP, FTP, SSH und TELNET.
- Sowohl "tcp-check send" als auch "tcp-check expect" sind angegeben:
Damit wird ein Protokoll mit einem Begrüßungsaustausch geprüft. HAProxy
sendet eine Nachricht, der Server antwortet, und die Antwort wird
analysiert. Das Prüfergebnis richtet sich nach der Übereinstimmung
zwischen Antwortinhalt und Regeln. Dies eignet sich häufig für Protokolle
mit Bindung oder einem Anfrage-Antwort-Modell. Beispiele sind LDAP,
MySQL, Redis und SSL, obwohl für sie bereits eigene Prüfungen mit einem
tieferen Verständnis des jeweiligen Protokolls vorhanden sind.
In diesem Modus können zahlreiche Anfragen gesendet und zahlreiche
Antworten analysiert werden.
Ein fünfter Modus erlaubt das Einfügen von Kommentaren in verschiedene Schritte des Skripts.
Jeder erstellten tcp-check-Regel kann eine Direktive “comment” mit einer nachfolgenden Zeichenkette hinzugefügt werden. Diese Zeichenkette erscheint im Protokoll und im Debug-Modus auf stderr. Damit lassen sich verständliche Fehlermeldungen erstellen. “comment” ist selbstverständlich optional.
Während eines Health Checks steht ein Variablengültigkeitsbereich bereit, in dem mit “tcp-check set-var” Daten-Samples gespeichert werden können. Diese Variablen lassen sich mit “tcp-check unset-var” freigeben.
Beispiele:
Siehe auch: “tcp-check connect”, “tcp-check expect” und “tcp-check send”.
option tcp-smart-accept
Das Einsparen eines ACK-Pakets bei der Verbindungsannahme aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente: keine
Geht eine HTTP-Verbindungsanfrage ein, bestätigt das System sie im Namen von HAProxy. Anschließend sendet der Client sofort seine Anfrage, die das System ebenfalls bestätigt, während es HAProxy über die neue Verbindung informiert. HAProxy liest daraufhin die Anfrage und antwortet. Das System sendet damit ein unnötiges TCP ACK, denn die Anfrage könnte ebenso gut beim Senden der Antwort durch HAProxy bestätigt werden.
Deshalb bittet HAProxy im HTTP-Modus das System automatisch, dieses unnötige ACK nicht zu senden, sofern die Plattform dies unterstützt, derzeit zumindest Linux. Dies darf keine Probleme verursachen, da das System das ACK ohnehin nach 40 ms sendet, falls die Antwort länger als erwartet ausbleibt.
Bei komplexer Netzwerkfehlersuche kann es sinnvoll sein, diese Optimierung zu deaktivieren: Verzögerte ACKs können es erschweren festzustellen, an welcher Stelle Pakete verzögert werden. Mit “no option tcp-smart-accept” lässt sich dann zum normalen Verhalten zurückkehren.
Auch für Proxys ohne HTTP kann die Optimierung mit “option tcp-smart-accept” erzwungen werden. Dies kann beispielsweise bei Diensten wie SMTP sinnvoll sein, bei denen der Server zuerst spricht.
Es wird empfohlen, diese Option nicht in einem defaults-Abschnitt zu erzwingen. Im Zweifelsfall kann sie durch Voranstellen des Schlüsselworts “default” auf automatische Werte zurückgesetzt oder mit “no” deaktiviert werden.
Siehe auch: “option tcp-smart-connect”
option tcp-smart-connect
Das Einsparen eines ACK-Pakets beim Verbindungsaufbau aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Auf bestimmten Systemen, zumindest Linux, kann HAProxy den Kernel anweisen, bei einer Verbindungsanfrage nicht sofort ein leeres ACK zu senden, sondern direkt die gepufferte Anfrage. Das spart ein Netzwerkpaket und steigert die Leistung. Auch für manche Server kann dies nützlich sein, weil sie die Anfrage unmittelbar mit der eingehenden Verbindung erhalten.
Diese Funktion wird durch “option tcp-smart-connect” in einem Backend aktiviert. Sie ist nicht standardmäßig aktiviert, da sie die Netzwerkfehlersuche erschwert.
Ihre Aktivierung ist nur bei Protokollen sinnvoll, bei denen der Client zuerst spricht, etwa HTTP. In anderen Fällen wird ein normales ACK gesendet, wenn keine Daten anstelle des ACK gesendet werden können.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: “option tcp-smart-accept”
option tcpka
Das Senden von TCP-Keepalive-Paketen auf beiden Seiten aktivieren oder deaktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Befindet sich zwischen einem Client und einem Server eine Firewall oder eine andere Komponente, die Sitzungszustände verfolgt, und verwendet das Protokoll sehr lange Sitzungen mit langen inaktiven Phasen, etwa bei Remotedesktops, besteht ein Risiko: Eine zwischengeschaltete Komponente könnte eine zu lange inaktive Sitzung ablaufen lassen.
Werden TCP-Keepalives auf Socket-Ebene aktiviert, sendet das System regelmäßig Pakete an das andere Ende der Verbindung und hält diese damit aktiv. Der Abstand zwischen Keepalive-Prüfungen wird ausschließlich vom System gesteuert und hängt sowohl vom Betriebssystem als auch von dessen Abstimmungsparametern ab.
Keepalive-Pakete werden auf Anwendungsebene weder gesendet noch empfangen. Nur die Netzwerkstapel sehen sie. Selbst wenn also eine Seite des Proxys bereits Keepalives verwendet, um ihre Verbindung aktiv zu halten, werden diese Pakete nicht zur anderen Seite des Proxys weitergeleitet.
Dies hat nichts mit HTTP-Keepalive zu tun.
Die Option “tcpka” aktiviert das Senden von TCP-Keepalive-Prüfungen sowohl auf der Client- als auch auf der Serverseite einer Verbindung. Dies ist nur in “defaults”- oder “listen”-Abschnitten sinnvoll. Wird die Option in einem Frontend verwendet, erhält nur die Clientseite Keepalives; in einem Backend erhält nur die Serverseite Keepalives. Daher wird bei einer zwischen Frontends und Backends aufgeteilten Konfiguration dringend empfohlen, ausdrücklich “option clitcpka” und “option srvtcpka” zu verwenden.
Siehe auch: “option clitcpka”, “option srvtcpka”
option tcplog [clf]
Die erweiterte Protokollierung von TCP-Verbindungen mit Streamstatus und Zeitmessungen aktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Standardmäßig ist das Protokollausgabeformat sehr knapp: Es enthält lediglich Quell- und Zieladressen sowie den Instanznamen. Mit “option tcplog” erhält jede Protokollzeile ein wesentlich ausführlicheres Format. Es enthält unter anderem Verbindungszeitmessungen, den Streamstatus, Verbindungszahlen, die Namen von Frontend, Backend und Server sowie natürlich Quelladresse und Ports. Bei reinen TCP-Proxys hilft diese Option festzustellen, ob der Client oder der Server die Verbindung trennt oder eine Zeitüberschreitung aufweist. Bei normalen HTTP-Proxys ist “option httplog” vorzuziehen, da es noch vollständiger ist.
“option tcplog” überschreibt jede vorherige “log-format”-Direktive.
Siehe auch: “option httplog” und Abschnitt 8 zur Protokollierung.
option transparent (deprecated)
Transparente Proxyverarbeitung auf der Clientseite aktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Diese Option wurde eingeführt, um Load-Balancern auf Schicht 3 eine Sitzungsbindung auf Schicht 7 bereitzustellen. Dazu wird die Fähigkeit des Betriebssystems genutzt, eine eingehende Verbindung zu einer entfernten Adresse an einen lokalen Prozess, hier HAProxy, umzuleiten und diesem die ursprünglich angeforderte Adresse mitzuteilen. Bei dieser Option werden Sitzungen ohne Cookies an die ursprüngliche Ziel-IP-Adresse der eingehenden Anfrage weitergeleitet, die mit der eines anderen Geräts übereinstimmen sollte. Anfragen mit Cookies werden weiterhin an den passenden Server weitergeleitet.
Entgegen einer verbreiteten Annahme bewirkt diese Option NICHT, dass HAProxy beim Verbindungsaufbau dem Server die IP-Adresse des Clients präsentiert.
Seit 3.3 ist diese Option veraltet, da sie unter mehreren internen technischen Einschränkungen litt. Ihre Verwendung erzeugt eine Warnung, die bei tatsächlichem Bedarf mit dem globalen Schlüsselwort “expose-deprecated-directives” vermieden werden kann.
Der richtige Ansatz besteht darin, einen Server mit der Adresse 0.0.0.0 zu deklarieren, der die Verbindung zur erwarteten Zieladresse herstellt. Ein Server behandelt auch inaktive Verbindungen zu den Zielservern korrekt.
Beispiel:
Siehe auch: das Argument “usesrc” des Schlüsselworts “source” und die Option “transparent” des Schlüsselworts “bind”.
option use-small-buffers [ queue | l7-retries | check ]*
Die Unterstützung kleiner Puffer für die angegebenen Kategorien aktivieren.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Mit dieser Option kann die Unterstützung kleiner Puffer an verschiedenen Stellen aktiviert werden, um Speicher zu sparen. Ohne Parameter werden kleine Puffer standardmäßig überall verwendet, wo dies möglich ist. Andernfalls lässt sich ihre Verwendung auf folgende Bereiche begrenzen:
- queue: Ist dies gesetzt, werden ausreichend kleine Anfragen in kleinen Puffern gespeichert, wenn die Verbindung in der Warteschlange steht.
- l7-retries: Ist dies gesetzt, werden Anfragen bei aktivierten L7-Wiederholungen in kleinen Puffern gesichert.
- check: Ist dies gesetzt, werden kleine Puffer für Anfragen für Health Checks verwendet.
Bei aktivierter Option werden kleine Puffer nur verwendet, wenn dies möglich ist. Sind die Daten zu groß, wird automatisch ein regulärer Puffer verwendet. Die Größe kleiner Puffer lässt sich über die globale Einstellung “tune.bufsize.small” konfigurieren.
Wurde diese Option in einem “defaults”-Abschnitt aktiviert, kann sie in einer bestimmten Instanz durch Voranstellen des Schlüsselworts “no” deaktiviert werden.
Siehe auch: tune.bufsize.small
persist rdp-cookie
Sitzungsbindung anhand von RDP-Cookies aktivieren
Kann in folgenden Kontexten verwendet werden: tcp
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Diese Anweisung aktiviert die Sitzungsbindung anhand eines RDP-Cookies. Das RDP-Cookie enthält alle Informationen, die zur Suche des Servers in der Liste bekannter Server nötig sind. Ist diese Option im Backend gesetzt, wird die Anfrage analysiert. Wird ein RDP-Cookie gefunden, wird es dekodiert. Verweist es auf einen bekannten Server, wird die Verbindung an ihn weitergeleitet, sofern er noch UP ist oder “option persist” gesetzt ist.
Dies ist nur in einem TCP-Backend sinnvoll. Damit es funktioniert, muss das Frontend jedoch lange genug gewartet haben, um sicherzustellen, dass ein RDP-Cookie im Anfragepuffer vorliegt. Dies entspricht der Anforderung der Lastverteilungsmethode “rdp-cookie”. Daher wird dringend empfohlen, alle Anweisungen in einem einzigen “listen”-Abschnitt unterzubringen.
Der Terminalserver gibt dieses RDP-Cookie nur aus, wenn er für “token redirection mode” konfiguriert ist. Das bedeutet, dass die Option “IP address redirection” deaktiviert ist.
Beispiel:
Siehe auch: “balance rdp-cookie”, “tcp-request” und die ACL “req.rdp_cookie”.
quic-initial <action> [ { if | unless } <condition> ]
Eine Aktion auf einem eingehenden QUIC-Initial-Paket ausführen. Anders als bei “tcp-request connection” geschieht dies bereits vor dem Erzeugen jeglicher Verbindungselemente sowie vor Beginn und Abschluss des SSL-Handshakes. Beim Ablehnen von Verbindungsversuchen ist dies effizienter.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja(!) | ja | ja | nein
Argumente:
Diese Aktion wird früh beim Parsen von QUIC-Paketen ausgeführt. Daher wird nur eine kleine Auswahl von Aktionen unterstützt: - accept - dgram-drop - reject - send-retry
rate-limit sessions <rate>
Die Anzahl neuer Sitzungen begrenzen, die ein Frontend pro Sekunde annimmt
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Erreicht das Frontend die angegebene Anzahl neuer Sitzungen pro Sekunde, nimmt es keine neuen Verbindungen mehr an, bis die Rate wieder unter die Grenze fällt. Währenddessen bleiben die wartenden Sitzungen im Backlog des Sockets, also in Systempuffern. HAProxy weiß dann nicht einmal, dass Sitzungen warten. Bei einer sehr niedrigen Grenze für einen stark ausgelasteten Dienst kann es sinnvoll sein, den Socket-Backlog mit dem Schlüsselwort “backlog” zu vergrößern.
Diese Funktion blockiert besonders wirksam verbindungsbasierte Angriffe oder missbräuchliche Nutzung von Diensten auf empfindlichen Servern. Da die Sitzungsrate jede Millisekunde gemessen wird, ist sie äußerst genau. Außerdem greift die Grenze sofort; zum Erkennen des Schwellenwerts ist keinerlei Verzögerung nötig.
Beispiel: Die SMTP-Verbindungsrate auf höchstens 10 pro Sekunde begrenzen.
Hinweis: Bei Erreichen der maximalen Rate ändert sich der Frontendstatus nicht. Wenn die Option “socket-stats” aktiviert ist, erscheinen seine Sockets in den Statistiken jedoch als “WAITING”.
Siehe auch: das Schlüsselwort “backlog” und das ACL-Kriterium “fe_sess_rate”.
redirect location <loc> [code <code>] <option> [{if | unless} <condition>]
Eine HTTP-Weiterleitung zurückgeben, wenn eine Bedingung erfüllt beziehungsweise nicht erfüllt ist
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | ja
Ist die Bedingung bei if erfüllt beziehungsweise bei unless nicht erfüllt, führt die HTTP-Anfrage zu einer Weiterleitungsantwort. Ohne Bedingung gilt die Weiterleitung uneingeschränkt.
Argumente:
Beispiel: Nur die Anmelde-URL auf HTTPS umstellen.
Beispiel: Anfragen nach Artikeln ohne ‘/’ weiterleiten.
Beispiel: Sämtlichen HTTP-Verkehr auf HTTPS weiterleiten, wenn SSL durch HAProxy verarbeitet wird.
Beispiel: Allen Hosts ohne ‘www.’ dieses Präfix voranstellen.
Beispiel: Nur alte URLs dauerhaft auf neue weiterleiten.
Siehe Abschnitt 7 zur ACL-Verwendung.
retries <value>
Die Anzahl der Wiederholungsversuche auf einem Server nach einem Fehler festlegen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Standardmäßig gelten Wiederholungen nur für neue Verbindungsversuche. Mit der Direktive “retry-on” können jedoch andere Bedingungen eine Wiederholung auslösen, etwa eine leere Antwort oder ein unerwünschter Statuscode. Jede davon zählt als ein Versuch. Sobald die Gesamtzahl der Versuche den hier angegebenen Wert erreicht, wird ein Fehler zurückgegeben.
Um sofortige neue Verbindungsversuche zu einem gerade neu startenden Server zu vermeiden, wird vor einer Wiederholung auf demselben Server eine Wartezeit von min(“timeout connect”, eine Sekunde) eingehalten.
Bei gesetzter “option redispatch” können manche Wiederholungen auf einem anderen Server erfolgen, selbst wenn ein Cookie auf einen anderen Server verweist. Standardmäßig gilt dies nur für den letzten Wiederholungsversuch, sofern “option redispatch” kein Argument übergeben wurde.
Siehe auch: “option redispatch”
retry-on [space-delimited list of keywords]
Festlegen, wann automatisch versucht werden soll, eine fehlgeschlagene Anfrage zu wiederholen. Diese Einstellung ist nur gültig, wenn “mode” auf http gesetzt ist; andernfalls wird sie stillschweigend ignoriert.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Diese Direktive ersetzt alle vorherigen Einstellungen durch die neuen; sie wirkt nicht kumulativ.
Jeder andere Wert als “none” und “conn-failure” erfordert das Reservieren eines Puffers und das Kopieren der gesamten Anfrage in diesen Puffer. Dies wirkt sich auf Speicherverbrauch und Leistung aus. Anfragen, die nicht in einen einzelnen Puffer passen, werden niemals wiederholt; siehe die globale Einstellung tune.bufsize.
Sie müssen sicherstellen, dass die Anwendung einen Schutz gegen wiederholte Ausführung besitzt, etwa eindeutige Transaktions-IDs in Anfragen, oder dass die Wiederholung derselben Anfrage folgenlos bleibt. Andernfalls ist jeder retry-on-Wert außer “conn-failure” und “none” sehr gefährlich. Server für statische Dateien und Caches gelten im Allgemeinen bei jeder Art von Wiederholung als sicher. Die Verwendung eines Statuscodes kann nützlich sein, um einen auffällig arbeitenden Server rasch zu verlassen, etwa bei Speichermangel oder Dateisystemproblemen. In diesem Fall kann es jedoch sinnvoll sein, die Verbindung sofort einem anderen Server zuzuweisen; siehe dazu “option redispatch”. Schließlich ist zu bedenken, dass die meisten Fehler durch die Anfragen selbst verursacht werden. Das Wiederholen einer Anfrage, die einen Server zu fehlerhaftem Verhalten bringt, verschlechtert daher häufig die Lage dieses Servers oder bei erneuter Zuweisung sogar die des gesamten Dienstes.
Wenn Sie nicht genau wissen, wie die Anwendung mit wiederholten Anfragen umgeht, sollten Sie diese Direktive nicht verwenden.
Der Standardwert ist “conn-failure”.
Beispiel:
Siehe auch: “retries”, “option redispatch”, “tune.bufsize”
server <name> <address>[:[port]] [param*]
Einen Server in einem Backend deklarieren
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Argumente:
Beispiele:
Hinweis: Bei Sockets im abstrakten Namensraum von Linux verwenden HAProxy-Sockets der Familie “abns” die gesamte Länge von sun_path als Adresslänge. Andere Programme wie socat verwenden standardmäßig nur die Länge der Zeichenkette. Übergeben Sie der Definition eines abstrakten Sockets in socat die Option “,unix-tightsocklen=0”, um Kompatibilität mit HAProxy zu erreichen, oder verwenden Sie stattdessen die HAProxy-Socket-Familie “abnsz”.
Siehe auch: “default-server”, “http-send-name-header” und Abschnitt 5 zu Serveroptionen
server-state-file-name [ { use-backend-name | <file> } ]
Die Serverzustandsdatei festlegen, die gelesen und geladen wird und deren Zustände auf die Server dieses Backends angewendet werden.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Dies gilt nur, wenn die Direktive “load-server-state-from-file” auf “local” gesetzt ist. Wenn <file> nicht angegeben ist, wenn “use-backend-name” verwendet wird oder wenn diese Direktive nicht gesetzt ist, wird der Backendname verwendet. Beginnt <file> mit einem Schrägstrich ‘/’, gilt es als absoluter Pfad. Andernfalls wird <file> an den Wert der globalen Direktive “server-state-base” angehängt.
Beispiel: Mit der folgenden minimalen Konfiguration würde HAProxy die Serverzustandsdatei ‘/etc/haproxy/states/bk’ suchen:
global
server-state-file-base /etc/haproxy/states
backend bk
load-server-state-from-file
Siehe auch: “server-state-base”, “load-server-state-from-file” und “show servers state”
server-template <prefix> <num | range> <fqdn>[:<port>] [params*]
Eine Vorlage zur Initialisierung von Servern mit gemeinsamen Parametern festlegen. Die Namen dieser Server werden aus den Parametern <prefix> und <num | range> gebildet.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Argumente:
Beispiele:
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
Die Quelladresse für ausgehende Verbindungen festlegen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Das Schlüsselwort “source” ist in komplexen Umgebungen nützlich, in denen nur eine bestimmte Adresse Verbindungen zu den Servern herstellen darf. Dies kann beispielsweise nötig sein, wenn eine private Adresse über ein öffentliches Gateway verwendet werden muss und bekannt ist, dass das System die passende Quelladresse nicht selbst bestimmen kann.
Mit dem optionalen Schlüsselwort “usesrc” lässt sich eine Erweiterung verwenden, die auf bestimmten gepatchten Linux-Kerneln verfügbar ist. Sie ermöglicht Verbindungen zu den Servern mit einer IP-Adresse, die nicht zum System selbst gehört. Dies wird als vollständig transparenter Proxymodus bezeichnet. Damit dies funktioniert, müssen die Zielserver ihren Rückverkehr zu dieser Adresse über den Rechner mit HAProxy routen. Auf diesem Rechner muss in der Regel IP-Weiterleitung aktiviert sein.
In diesem vollständig transparenten Proxymodus kann erzwungen werden, dass den Servern eine bestimmte IP-Adresse präsentiert wird. Dies wird tatsächlich selten verwendet. Häufiger soll HAProxy die IP-Adresse des Clients präsentieren. Dafür gibt es zwei Verfahren:
- Die IP-Adresse und den Port des Clients präsentieren. Dies ist der
transparenteste Modus, kann jedoch bei aktivierter IP-Verbindungsverfolgung
auf dem Rechner Probleme verursachen: Dieselbe Verbindung kann zweimal
mit unterschiedlichen Zuständen erscheinen. Der große Vorteil ist jedoch,
dass das System nicht auf 64k ausgehende Adress-Port-Kombinationen begrenzt
ist, da sämtliche Clientbereiche verwendet werden können.
- Nur die IP-Adresse des Clients präsentieren und einen freien Port wählen.
Diese Lösung ist weiterhin recht elegant, aber etwas weniger transparent:
Die Protokolle nachgeschalteter Firewalls stimmen nicht mit denen der
vorgeschalteten überein. Außerdem ist die Anzahl gleichzeitiger
Verbindungen auf die üblichen 64k Ports begrenzt. Da sich die Ports auf
beiden Seiten unterscheiden, wird die lokale IP-Verbindungsverfolgung
des Rechners jedoch nicht durch die Wiederverwendung derselben Sitzung
gestört.
Diese Option legt die Standardquelle für alle Server des Backends fest. Sie kann auch in einem “defaults”-Abschnitt angegeben werden. Eine genauere Festlegung der Quelladresse auf Serverebene ist mit der Serveroption “source” möglich. Weitere Informationen enthält Abschnitt 5 .
“usesrc” benötigt root-Rechte oder auf unterstützten Systemen die Capability “cap_net_raw”. Siehe auch die globale Direktive “setcap”.
Beispiele:
Siehe auch: die Serveroption “source” in Abschnitt 5 , die Tproxy-Patches für den Linux-Kernel auf www.balabit.com und das Schlüsselwort “bind”.
srvtcpka-cnt <count>
Die maximale Anzahl von Keepalive-Prüfungen festlegen, die TCP auf der Serverseite senden soll, bevor es die Verbindung trennt.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Dieses Schlüsselwort entspricht der Socket-Option TCP_KEEPCNT. Wird es nicht angegeben, wird der systemweite TCP-Parameter (tcp_keepalive_probes) verwendet. Die Verfügbarkeit dieser Einstellung hängt vom Betriebssystem ab. Unter Linux funktioniert sie bekanntermaßen.
Siehe auch: “option srvtcpka”, “srvtcpka-idle”, “srvtcpka-intvl”.
srvtcpka-idle <timeout>
Die Zeit festlegen, die eine Verbindung inaktiv bleiben muss, bevor TCP Keepalive-Prüfungen sendet, sofern das Senden von TCP-Keepalive-Paketen auf der Serverseite aktiviert ist.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Dieses Schlüsselwort entspricht der Socket-Option TCP_KEEPIDLE. Wird es nicht angegeben, wird der systemweite TCP-Parameter (tcp_keepalive_time) verwendet. Die Verfügbarkeit dieser Einstellung hängt vom Betriebssystem ab. Unter Linux funktioniert sie bekanntermaßen.
Siehe auch: “option srvtcpka”, “srvtcpka-cnt”, “srvtcpka-intvl”.
srvtcpka-intvl <timeout>
Den zeitlichen Abstand zwischen einzelnen Keepalive-Prüfungen auf der Serverseite festlegen.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Dieses Schlüsselwort entspricht der Socket-Option TCP_KEEPINTVL. Wird es nicht angegeben, wird der systemweite TCP-Parameter (tcp_keepalive_intvl) verwendet. Die Verfügbarkeit dieser Einstellung hängt vom Betriebssystem ab. Unter Linux funktioniert sie bekanntermaßen.
Siehe auch: “option srvtcpka”, “srvtcpka-cnt”, “srvtcpka-idle”.
stats admin { if | unless } <cond>
Die Administration über die Statistikseite aktivieren, wenn eine Bedingung erfüllt beziehungsweise nicht erfüllt ist
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | ja
Diese Anweisung aktiviert die Administrationsstufe der Statistikseite, wenn eine Bedingung bei if erfüllt beziehungsweise bei unless nicht erfüllt ist.
Die Administrationsstufe erlaubt das Aktivieren und Deaktivieren von Servern über die Weboberfläche. Aus Sicherheitsgründen ist die Statistikseite standardmäßig schreibgeschützt. Sind im Abschnitt “stats scope”-Direktiven gesetzt, akzeptieren nur die dadurch bezeichneten Proxys Zustandsänderungen; der Zugriff auf die anderen wird verweigert.
Derzeit ist die POST-Anfrage auf die Puffergröße abzüglich des reservierten Pufferbereichs begrenzt. Ist die Serverliste zu lang, wird die Anfrage daher nicht verarbeitet. Es wird empfohlen, jeweils nur wenige Server zu ändern.
Diese administrativen POST-Anfragen sind für CSRF-Angriffe anfällig. Als teilweise Gegenmaßnahme wird geprüft, ob Origin beziehungsweise bei fehlendem Origin der Referer mit dem Host-Header übereinstimmt. Dies reicht jedoch nicht aus, um solche Angriffe vollständig zu verhindern. Ein vollständiger Schutz ist nicht möglich. Es wird empfohlen, diese Funktion nicht über eine öffentliche Schnittstelle zugänglich zu machen und den zugriffsberechtigten Personenkreis einzuschränken.
Beispiel:
Beispiel:
Beispiel:
Siehe auch: “stats enable”, “stats auth”, “stats http-request”, “stats scope”, Abschnitt 12.2 zu Benutzerlisten und Abschnitt 7 zur ACL-Verwendung.
ssl-f-use [<sslbindconf> ...]*
Dem aktuellen Frontend ein Zertifikat zuweisen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | nein
Argumente:
Ein Zertifikat <crtname> einer crt-list zuweisen, die automatisch aus dem Frontendnamen mit vorangestelltem @ erstellt wird, etwa ‘@frontend1’.
Diese implizite crt-list wird jeder “ssl”-bind-Zeile im aktuellen Frontend zugewiesen.
Die crt-list-Befehle über das Statistik-Socket wirken auf diese Liste. Zertifikate und SSL-Optionen können darin also ersetzt, entfernt oder hinzugefügt werden.
Beispiel:
Siehe auch: “crt-list” und “crt”.
stats auth <user>:<passwd>
Statistiken mit Authentifizierung aktivieren und einem Konto Zugriff gewähren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Diese Anweisung aktiviert Statistiken mit den Standardeinstellungen und beschränkt den Zugriff auf deklarierte Benutzer. Sie kann beliebig oft wiederholt werden, um beliebig vielen Benutzern Zugriff zu gewähren. Versucht ein Benutzer ohne gültiges Konto auf die Statistiken zuzugreifen, wird die Antwort “401 Forbidden” zurückgegeben, damit der Browser nach einem gültigen Benutzernamen und Passwort fragt. Der an den Browser zurückgegebene Realm kann mit “stats realm” konfiguriert werden.
Da HTTP-Basisauthentifizierung verwendet wird, werden die Passwörter im Klartext über das Netz übertragen. Daher wurde entschieden, auch in der Konfigurationsdatei Klartextpasswörter zu verwenden. Dies soll Benutzer daran erinnern, dass diese Passwörter nicht sensibel sein und nicht für andere Konten wiederverwendet werden sollten.
Mit “stats scope” lässt sich außerdem die Auswahl der im Bericht angezeigten Proxys einschränken.
Obwohl diese Anweisung allein ausreicht, um die Statistikdarstellung zu aktivieren, wird empfohlen, alle weiteren Einstellungen ausdrücklich festzulegen, statt sich auf wenig offensichtliche Standardparameter zu verlassen.
Beispiel:
Siehe auch: “stats enable”, “stats realm”, “stats scope”, “stats uri”
stats enable
Die Statistikdarstellung mit Standardeinstellungen aktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Diese Anweisung aktiviert die Statistikdarstellung mit den beim Kompilieren festgelegten Standardeinstellungen. Sofern nicht anders angegeben, gelten folgende Einstellungen: - stats uri : /haproxy?stats - stats realm: “HAProxy Statistics” - stats auth : keine Authentifizierung - stats scope: keine Einschränkung
Obwohl diese Anweisung allein ausreicht, um die Statistikdarstellung zu aktivieren, wird empfohlen, alle weiteren Einstellungen ausdrücklich festzulegen, statt sich auf wenig offensichtliche Standardparameter zu verlassen.
Beispiel:
Siehe auch: “stats auth”, “stats realm”, “stats uri”
stats hide-version
Statistiken aktivieren und die Anzeige der HAProxy-Version ausblenden
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Die Statistikseite kann neben den Statistiken nützliche Statusinformationen anzeigen, darunter die HAProxy-Version. Die genaue Version jedem zugänglich zu machen, gilt jedoch im Allgemeinen als gefährlich, da dies gezielte Angriffe auf bekannte Schwachstellen erleichtern kann. Die Anweisung “stats hide-version” entfernt die Versionsangabe aus dem Statistikbericht. Dies wird für öffentliche Websites und für Websites mit schwachen Zugangsdaten empfohlen und ist das Standardverhalten.
Obwohl diese Anweisung allein ausreicht, um die Statistikdarstellung zu aktivieren, wird empfohlen, alle weiteren Einstellungen ausdrücklich festzulegen, statt sich auf wenig offensichtliche Standardparameter zu verlassen.
Beispiel:
Siehe auch: “stats auth”, “stats enable”, “stats realm”, “stats uri”, “stats show-version”
stats http-request { allow | deny | auth [realm <realm>] }
Zugriffskontrolle für Statistiken
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Wie “http-request” erlaubt diese Gruppe von Optionen eine genaue Steuerung des Zugriffs auf die Statistiken. Auf jede Option können if/unless und eine ACL folgen. Die erste Option mit erfüllter Bedingung oder ohne Bedingung entscheidet abschließend. Bei “deny” wird ein Fehler 403 zurückgegeben, bei “allow” erfolgt die normale Verarbeitung, und bei “auth” wird der Fehlercode 401/407 zurückgegeben, sodass der Client zur Eingabe von Benutzername und Passwort aufgefordert werden sollte.
Die Anzahl der http-request-Anweisungen pro Instanz ist nicht fest begrenzt.
Siehe auch: “http-request”, Abschnitt 12.2 zu Benutzerlisten und Abschnitt 7 zur ACL-Verwendung.
stats realm <realm>
Statistiken aktivieren und den Authentifizierungs-Realm festlegen
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Der Realm wird als einzelnes Wort eingelesen. Enthaltene Leerzeichen sollten daher mit einem Backslash (’\’) maskiert werden.
Diese Anweisung ist nur zusammen mit “stats auth” nützlich, da sie ausschließlich die Authentifizierung betrifft.
Obwohl diese Anweisung allein ausreicht, um die Statistikdarstellung zu aktivieren, wird empfohlen, alle weiteren Einstellungen ausdrücklich festzulegen, statt sich auf wenig offensichtliche Standardparameter zu verlassen.
Beispiel:
Siehe auch: “stats auth”, “stats enable”, “stats uri”
stats refresh <delay>
Statistiken mit automatischer Aktualisierung aktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Diese Anweisung ist für Überwachungsanzeigen nützlich, die dauerhaft eine Seite mit der Aktivität des Load-Balancers anzeigen. Ist sie gesetzt, enthält der HTML-Bericht einen Link “refresh”/“stop refresh”, über den der Benutzer die automatische Aktualisierung der Seite ein- oder ausschalten kann.
Obwohl diese Anweisung allein ausreicht, um die Statistikdarstellung zu aktivieren, wird empfohlen, alle weiteren Einstellungen ausdrücklich festzulegen, statt sich auf wenig offensichtliche Standardparameter zu verlassen.
Beispiel:
Siehe auch: “stats auth”, “stats enable”, “stats realm”, “stats uri”
stats scope { <name> | "." }
Statistiken aktivieren und den Zugriffsbereich begrenzen
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Ist diese Anweisung angegeben, erscheinen nur die mit ihr aufgeführten Abschnitte im Bericht. Alle anderen werden ausgeblendet, und Versuche, ihren Zustand im Administrationsmodus zu ändern, werden abgewiesen. Die Anweisung kann beliebig oft angegeben werden, wenn mehrere Abschnitte angezeigt werden sollen. Die Namen werden lediglich durch einfache Zeichenkettenvergleiche geprüft. Ob ein angegebener Abschnitt tatsächlich existiert, wird niemals geprüft.
Obwohl diese Anweisung allein ausreicht, um die Statistikdarstellung zu aktivieren, wird empfohlen, alle weiteren Einstellungen ausdrücklich festzulegen, statt sich auf wenig offensichtliche Standardparameter zu verlassen.
Beispiel:
Siehe auch: “stats auth”, “stats enable”, “stats realm”, “stats uri” und “stats admin”
stats show-desc [ <desc> ]
Die Anzeige einer Beschreibung auf der Statistikseite aktivieren.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
`<desc>` ist eine optionale anzuzeigende Beschreibung. Fehlt sie, wird
automatisch die Beschreibung aus dem global-Abschnitt verwendet.
Diese Anweisung ist für Benutzer nützlich, die ihren Kunden gemeinsam genutzte Dienste anbieten, bei denen Knotenname oder Beschreibung für jeden Kunden unterschiedlich sein sollten.
Obwohl diese Anweisung allein ausreicht, um die Statistikdarstellung zu aktivieren, wird empfohlen, alle weiteren Einstellungen ausdrücklich festzulegen, statt sich auf wenig offensichtliche Standardparameter zu verlassen. Standardmäßig wird keine Beschreibung angezeigt.
Beispiel:
Siehe auch: “show-node”, “stats enable”, “stats uri” und “description” im global-Abschnitt.
stats show-legends
Die Anzeige zusätzlicher Informationen auf der Statistikseite aktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Die Anzeige zusätzlicher Informationen auf der Statistikseite aktivieren: - cap: Fähigkeiten (Proxy) - mode: einer der Werte tcp, http oder health (Proxy) - id: SNMP ID (Proxy, Socket, Server) - IP (Socket, Server) - cookie (Backend, Server)
Obwohl diese Anweisung allein ausreicht, um die Statistikdarstellung zu aktivieren, wird empfohlen, alle weiteren Einstellungen ausdrücklich festzulegen, statt sich auf wenig offensichtliche Standardparameter zu verlassen. Standardmäßig werden diese Informationen nicht angezeigt.
Siehe auch: “stats enable”, “stats uri”.
stats show-modules
Die Anzeige zusätzlicher Statistikmodule auf der Statistikseite aktivieren
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Am Ende der Zeile werden neue Spalten hinzugefügt, deren Tooltips die zusätzlichen Statistikwerte enthalten.
Obwohl diese Anweisung allein ausreicht, um die Statistikdarstellung zu aktivieren, wird empfohlen, alle weiteren Einstellungen ausdrücklich festzulegen, statt sich auf wenig offensichtliche Standardparameter zu verlassen. Standardverhalten ist, diese Informationen nicht anzuzeigen.
Siehe auch: “stats enable”, “stats uri”.
stats show-node [ <name> ]
Die Anzeige eines Hostnamens auf der Statistikseite aktivieren.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Diese Anweisung ist für Benutzer nützlich, die ihren Kunden gemeinsam genutzte Dienste anbieten, bei denen der Knoten oder die Beschreibung auf einer Statistikseite für jeden Kunden unterschiedlich sein kann. Standardverhalten ist, den Hostnamen nicht anzuzeigen.
Obwohl diese Anweisung allein ausreicht, um die Statistikdarstellung zu aktivieren, wird empfohlen, alle weiteren Einstellungen ausdrücklich festzulegen, statt sich auf wenig offensichtliche Standardparameter zu verlassen.
Beispiel:
Siehe auch: “show-desc”, “stats enable”, “stats uri” und “node” im globalen Abschnitt.
stats show-version
Statistiken aktivieren und die HAProxy-Version anzeigen
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente: keine
Die Statistikseite kann zusätzliche nützliche Statusinformationen zusammen mit den Statistiken anzeigen. Dazu gehört die HAProxy-Version. Es wird jedoch allgemein als gefährlich angesehen, die genaue Version an Dritte zu melden, da dies Angreifern helfen kann, gezielte Angriffe auf bekannte Schwachstellen durchzuführen. Daher ist dies standardmäßig deaktiviert. Die Angabe “stats show-version” ermöglicht die Anzeige dieser Informationen. Dies wird für öffentliche Websites oder Websites mit schwachen Anmeldeinformationen nicht empfohlen.
Siehe auch: “stats auth”, “stats enable”, “stats realm”, “stats uri”, “stats hide-version”
stats uri <prefix>
Statistiken aktivieren und das URI-Präfix für den Zugriff darauf festlegen
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Die Statistik-URI wird im weitergeleiteten Datenverkehr abgefangen, sodass die Statistikseite als Seite innerhalb der normalen Anwendung erscheint. Es wird dringend empfohlen sicherzustellen, dass die gewählte URI niemals in der Anwendung vorkommt. Andernfalls wäre die Anwendungsressource unter dieser URI nicht mehr erreichbar.
Die standardmäßig in HAProxy eingebaute URI ist “/haproxy?stats”, diese kann jedoch beim Kompilieren geändert werden. Daher ist es besser, sie hier stets explizit anzugeben. Es ist allgemein eine gute Idee, ein Fragezeichen in der URI zu verwenden, damit zwischengeschaltete Proxys das Ergebnis nicht zwischenspeichern. Außerdem wird jede Zeichenkette, die mit dem Präfix beginnt, als Statistikanfrage akzeptiert, sodass das Fragezeichen dabei hilft sicherzustellen, dass keine gültige URI mit denselben Wörtern beginnt.
Es ist manchmal sehr praktisch, “/” als URI-Präfix zu verwenden und diese Anweisung in einer eigenen “listen”-Instanz zu platzieren. Dadurch wird es einfach, eine Adresse oder einen Port ausschließlich für Statistiken zu reservieren.
Obwohl diese Anweisung allein ausreicht, um die Statistikdarstellung zu aktivieren, wird empfohlen, alle weiteren Einstellungen ausdrücklich festzulegen, statt sich auf wenig offensichtliche Standardparameter zu verlassen.
Beispiel:
Siehe auch: “stats auth”, “stats enable”, “stats realm”
stick match <pattern> [table <table>] [{if | unless} <cond>]
Eine Bedingung zum Abgleich eines Anfragemusters definieren, um einen Benutzer an einen Server zu binden
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Argumente:
Manche Protokolle oder Anwendungen erfordern komplexe Regeln zur Sitzungsbindung und können sich nicht immer allein auf Cookies oder Hashing verlassen. Die Anweisung “stick match” beschreibt eine Regel, um das Kriterium für die Sitzungsbindung aus einer eingehenden Anfrage oder Verbindung zu extrahieren. Eine vollständige Liste der möglichen Muster und Umwandlungsregeln enthält Abschnitt 7 .
Die Tabelle muss mit der Anweisung “stick-table” deklariert werden. Ihr Typ muss mit dem Muster kompatibel sein. Standardmäßig wird die Tabelle im selben Backend verwendet. Eine Tabelle kann mit anderen Backends gemeinsam genutzt werden, indem sie über das Schlüsselwort “table” referenziert wird. Bei Verweis auf eine andere Tabelle werden die Server-IDs innerhalb der Backends verwendet. Standardmäßig beginnen die Server-IDs in jedem Backend bei 1, sodass die Reihenfolge der Server ausreicht. Im Zweifelsfall wird jedoch dringend empfohlen, die Server-IDs über deren Einstellung “id” ausdrücklich festzulegen.
Mit “if” oder “unless” und einer nachfolgenden Bedingung lässt sich einschränken, wann eine Anweisung “stick match” angewendet wird. ACL-basierte Bedingungen werden in Abschnitt 7 beschrieben.
Die Anzahl der “stick match”-Anweisungen ist nicht begrenzt. Die erste anwendbare Regel mit einem Treffer leitet die Anfrage an denselben Server, der die Anfrage bearbeitet hat, durch die der Eintrag angelegt wurde. So lassen sich mehrere Abgleiche als Rückfallmöglichkeiten verwenden.
Die stick-Regeln werden nach den Cookies zur Sitzungsbindung geprüft. Hat bereits ein Cookie den Server ausgewählt, beeinflussen sie die Sitzungsbindung daher nicht. Damit lassen sich sehr einfach Cookies einfügen und IP-Adressen abgleichen, um die Sitzungsbindung zwischen HTTP und HTTPS aufrechtzuerhalten.
Beispiel:
Siehe auch: “stick-table”, “stick on”, Abschnitt 11 über Stick Tables und Abschnitt 7 über ACLs und Sample-Abruf.
stick on <pattern> [table <table>] [{if | unless} <condition>]
Ein Anfragemuster definieren, um einen Benutzer einem Server zuzuordnen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Hinweis: Diese Form ist genau äquivalent zu “stick match” gefolgt von “stick store-request”, alle mit denselben Argumenten. Einzelheiten finden Sie bei beiden Schlüsselwörtern. Sie dient lediglich dazu, leichter wartbare Konfigurationen zu schreiben.
Beispiele:
Siehe auch: “stick match”, “stick store-request” und Abschnitt 11 über Stick Tables.
stick store-request <pattern> [table <table>] [{if | unless} <condition>]
Ein Anfragemuster definieren, mit dem ein Eintrag in einer Tabelle zur Sitzungsbindung angelegt wird
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Argumente:
Manche Protokolle oder Anwendungen erfordern komplexe Regeln zur Sitzungsbindung und können sich nicht immer allein auf Cookies oder Hashing verlassen. Die Anweisung “stick store-request” beschreibt eine Regel, die festlegt, was wann aus der Anfrage extrahiert werden soll. Das Ergebnis wird in einer Tabelle zur Sitzungsbindung gespeichert, damit spätere Anfragen es mit “stick match” abgleichen können. Der extrahierte Teil muss natürlich sinnvoll sein und bei einer späteren Anfrage wiedergefunden werden können. Häufig ist es beispielsweise sinnvoll, die IP-Adresse eines Clients zu speichern. Auch eine ID aus einem URL-Parameter ist sinnvoll. Einen Quellport zu speichern, ist dagegen fast nie sinnvoll, weil er nur zufällig wiedergefunden würde. Eine vollständige Liste der möglichen Muster und Umwandlungsregeln enthält Abschnitt 7 .
Die Tabelle muss mit der Anweisung “stick-table” deklariert werden. Ihr Typ muss mit dem Muster kompatibel sein. Standardmäßig wird die Tabelle im selben Backend verwendet. Eine Tabelle kann mit anderen Backends gemeinsam genutzt werden, indem sie über das Schlüsselwort “table” referenziert wird. Bei Verweis auf eine andere Tabelle werden die Server-IDs innerhalb der Backends verwendet. Standardmäßig beginnen die Server-IDs in jedem Backend bei 1, sodass die Reihenfolge der Server ausreicht. Im Zweifelsfall wird jedoch dringend empfohlen, die Server-IDs über deren Einstellung “id” ausdrücklich festzulegen.
Mit “if” oder “unless” und einer nachfolgenden Bedingung lässt sich einschränken, wann eine Anweisung “stick store-request” angewendet wird. Die Bedingung wird beim Parsen der Anfrage ausgewertet, sodass beliebige Kriterien verwendet werden können. ACL-basierte Bedingungen werden in Abschnitt 7 beschrieben.
Die Anzahl der “stick store-request”-Anweisungen ist nicht begrenzt. Pro Anfrage oder Antwort sind jedoch höchstens 8 gleichzeitige Speichervorgänge möglich. Unabhängig von der Anzahl der Regeln können dadurch bis zu 8 Kriterien gespeichert werden, die aus der Anfrage oder der Antwort extrahiert wurden. Nur die ersten 8 passenden Kriterien werden behalten. So können mehrere Tabellen gleichzeitig befüllt werden, um die Chance zu erhöhen, einen Benutzer bei einem anderen Protokoll oder Zugriffsverfahren wiederzuerkennen. Mehrere store-request-Regeln dürfen dieselbe Tabelle verwenden. Werden die Regeln in absteigender Präferenzreihenfolge angeordnet, lässt sich so das geeignetste Kriterium auswählen. Für eine bestimmte Tabelle wird nur das erste extrahierte Kriterium gespeichert. Alle nachfolgenden store-request-Regeln für dieselbe Tabelle werden übersprungen, ohne ihre ACLs auszuwerten.
Die “store-request”-Regeln werden ausgewertet, sobald die Verbindung zum Server aufgebaut ist. Dadurch enthält die Tabelle den tatsächlichen Server, der die Anfrage verarbeitet hat.
Beispiel:
Siehe auch: “stick-table”, “stick on”, Abschnitt 11 zu Stick Tables und Abschnitt 7 zu ACLs und Sample-Abrufen.
stick store-response <pattern> [table <table>] [{if | unless} <condition>]
Ein Antwortmuster definieren, mit dem ein Eintrag in einer Tabelle zur Sitzungsbindung angelegt wird
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Argumente:
Manche Protokolle oder Anwendungen erfordern komplexe Regeln zur Sitzungsbindung und können sich nicht immer allein auf Cookies oder Hashing verlassen. Die Anweisung “stick store-response” beschreibt eine Regel, die festlegt, was wann aus der Antwort extrahiert werden soll. Das Ergebnis wird in einer Tabelle zur Sitzungsbindung gespeichert, damit spätere Anfragen es mit “stick match” abgleichen können. Der extrahierte Teil muss natürlich sinnvoll sein und bei einer späteren Anfrage wiedergefunden werden können. Eine ID aus einem Antwortheader zu speichern, ist beispielsweise sinnvoll. Eine vollständige Liste der möglichen Muster und Umwandlungsregeln enthält Abschnitt 7 .
Die Tabelle muss mit der Anweisung “stick-table” deklariert werden. Ihr Typ muss mit dem Muster kompatibel sein. Standardmäßig wird die Tabelle im selben Backend verwendet. Eine Tabelle kann mit anderen Backends gemeinsam genutzt werden, indem sie über das Schlüsselwort “table” referenziert wird. Bei Verweis auf eine andere Tabelle werden die Server-IDs innerhalb der Backends verwendet. Standardmäßig beginnen die Server-IDs in jedem Backend bei 1, sodass die Reihenfolge der Server ausreicht. Im Zweifelsfall wird jedoch dringend empfohlen, die Server-IDs über deren Einstellung “id” ausdrücklich festzulegen.
Mit “if” oder “unless” und einer nachfolgenden Bedingung lässt sich einschränken, wann eine Anweisung “stick store-response” angewendet wird. Die Bedingung wird beim Parsen der Antwort ausgewertet, sodass beliebige Kriterien verwendet werden können. ACL-basierte Bedingungen werden in Abschnitt 7 beschrieben.
Die Anzahl der “stick store-response”-Anweisungen ist nicht begrenzt. Pro Anfrage oder Antwort sind jedoch höchstens 8 gleichzeitige Speichervorgänge möglich. Unabhängig von der Anzahl der Regeln können dadurch bis zu 8 Kriterien gespeichert werden, die aus der Anfrage oder der Antwort extrahiert wurden. Nur die ersten 8 passenden Kriterien werden behalten. So können mehrere Tabellen gleichzeitig befüllt werden, um die Chance zu erhöhen, einen Benutzer bei einem anderen Protokoll oder Zugriffsverfahren wiederzuerkennen. Mehrere store-response-Regeln dürfen dieselbe Tabelle verwenden. Werden die Regeln in absteigender Präferenzreihenfolge angeordnet, lässt sich so das geeignetste Kriterium auswählen. Für eine bestimmte Tabelle wird nur das erste extrahierte Kriterium gespeichert. Alle nachfolgenden store-response-Regeln für dieselbe Tabelle werden übersprungen, ohne ihre ACLs auszuwerten. Eine store-response-Regel darf jedoch dieselbe Tabelle verwenden, auf die bereits eine store-request-Regel verweist. Jede Tabelle kann somit gleichzeitig genau ein Element aus der Anfrage und ein Element aus der Antwort lernen.
Die Tabelle enthält den tatsächlichen Server, der die Anfrage verarbeitet hat.
Beispiel:
Siehe auch: “stick-table”, “stick on”, Abschnitt 11 zu Stick Tables und Abschnitt 7 zu ACLs und Musterextraktion.
stick-table type <type> size <size> [expire <expire>] [args...]
Die Tabelle zur Sitzungsbindung für den aktuellen Abschnitt konfigurieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | ja
Damit wird eine stick-table deklariert und konfiguriert. Vollständige Einzelheiten und die Liste unterstützter Argumente finden Sie in Abschnitt 11.1 . Nur Typ und Größe sind zwingend erforderlich.
tcp-check comment <string>
Einen Kommentar für die nachfolgende tcp-check-Regel definieren, der bei ihrem Fehlschlagen im Protokoll ausgegeben wird.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Dies funktioniert nur für die Regeln connect, send und expect. Es dient einer verständlichen Fehlermeldung.
Siehe auch: “option tcp-check”, “tcp-check connect”, “tcp-check send” und “tcp-check expect”.
tcp-check connect [default] [port <expr>] [addr <ip>] [send-proxy] [via-socks4]
Eine neue Verbindung öffnen
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Verwendet eine Anwendung mehr als einen TCP-Port oder verteilt HAProxy in einem Backend die Last mehrerer Dienste, ist es sinnvoll, jeden Dienst einzeln zu prüfen, bevor ein Server als betriebsbereit gilt.
Wenn weder in der Serverzeile ein TCP-Port noch eine port-Direktive für den Server konfiguriert ist, muss ’tcp-check connect port <port>’ der erste Schritt der Sequenz sein.
In einem tcp-check-Regelsatz ist ein ‘connect’ erforderlich; außerdem muss der Regelsatz mit einer ‘connect’-Regel beginnen. Damit soll sichergestellt werden, dass Administratoren wissen, was sie tun.
Auch wenn der Regelsatz mit connect beginnen muss, dürfen diesem noch Regeln vom Typ set-var, unset-var oder comment vorausgehen.
Beispiele:
Siehe auch: “option tcp-check”, “tcp-check send”, “tcp-check expect”
tcp-check expect [min-recv <int>] [comment <msg>]
Die bei einem allgemeinen Health Check zu erfassenden und zu analysierenden Daten festlegen
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Die verfügbaren Abgleicharten sind bewusst ihren Entsprechungen bei http-check ähnlich:
Die Antworten werden auf eine bestimmte Größe begrenzt, die durch die globale Option “tune.bufsize” festgelegt ist und standardmäßig 16384 Bytes beträgt. Daher enthalten zu große Antworten bei Verwendung von “string”, “rstring” oder binary möglicherweise nicht das erforderliche Muster. Ist eine große Antwort zwingend erforderlich, kann die standardmäßige Maximalgröße über die globale Variable geändert werden. Das Parsen sehr großer Antworten kann jedoch CPU-Zyklen verschwenden, insbesondere bei regulären Ausdrücken. Es ist daher stets besser, kleinere Ressourcen zu prüfen. Außerdem findet die Prüfung in ihrer derzeitigen Form nach einem Nullzeichen in der Antwort weder Zeichenketten noch Treffer für reguläre Ausdrücke. Ebenso kann kein Abgleich auf das Nullzeichen angefordert werden.
Beispiele:
Siehe auch: “option tcp-check”, “tcp-check connect”, “tcp-check send”, “tcp-check send-binary”, “http-check expect”, tune.bufsize
tcp-check send <data> [comment <msg>]
Eine Zeichenkette oder ein benutzerdefiniertes Protokollformat festlegen, das bei einem allgemeinen Health Check als Anfrage gesendet wird
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Beispiele:
Siehe auch: “option tcp-check”, “tcp-check connect”, “tcp-check expect”, “tcp-check send-binary”, tune.bufsize
tcp-check send-binary <hexstring> [comment <msg>]
Eine Zeichenkette aus Hexadezimalziffern oder ein benutzerdefiniertes Protokollformat mit Hexadezimalziffern festlegen, das bei einem rohen TCP-Health-Check als binäre Anfrage gesendet wird
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Beispiele:
Siehe auch: “option tcp-check”, “tcp-check connect”, “tcp-check expect”, “tcp-check send”, tune.bufsize
tcp-check set-var(<var-name>[,<cond>...]) <expr>
Diese Operation legt den Inhalt einer Variablen fest. Die Variable wird inline deklariert.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Beispiele:
tcp-check unset-var(<var-name>)
Eine Referenz auf eine Variable innerhalb ihres Gültigkeitsbereichs freigeben.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Beispiele:
tcp-request connection <action> <options...> [ { if | unless } <condition> ]
Abhängig von einer Bedingung auf Schicht 4 eine Aktion auf einer eingehenden Verbindung ausführen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja(!) | ja | ja | nein
Argumente:
Unmittelbar nach der Annahme einer neuen eingehenden Verbindung können Bedingungen ausgewertet werden, um zu entscheiden, ob die Verbindung akzeptiert oder verworfen werden muss oder ihre Zähler verfolgt werden sollen. Diese Bedingungen können keine Dateninhalte verwenden, da aus der Verbindung noch nichts gelesen wurde und noch keine Puffer reserviert sind. So lassen sich Verbindungen aus verschiedenen Quellen mit sehr geringem Aufwand gezielt und schnell akzeptieren oder verwerfen. Müssen für die Entscheidung Inhalte untersucht werden, sind stattdessen “tcp-request content”-Anweisungen zu verwenden.
Die Regeln “tcp-request connection” werden genau in der Reihenfolge ihrer Deklaration ausgewertet. Passt keine Regel oder gibt es keine Regel, wird die eingehende Verbindung standardmäßig akzeptiert. Die Anzahl der Regeln ist nicht gesondert begrenzt. Auf jede Regel kann optional eine ACL-basierte Bedingung folgen; dann wird die Regel nur ausgewertet, wenn diese Bedingung wahr ist.
Die Bedingung wird unmittelbar vor der Ausführung der Aktion ausgewertet, und die Aktion wird genau einmal ausgeführt. Daher ist es unproblematisch, wenn eine Aktion ein Element ändert, das in der Bedingung geprüft wird. Das bedeutet auch, dass mehrere Aktionen dieselbe Bedingung verwenden können: Die erste Aktion, die das Ergebnis der Bedingung ändert, reicht dann aus, um die übrigen Aktionen implizit zu deaktivieren. Dies wird beispielsweise verwendet, wenn einer leeren Variablen ein Wert aus verschiedenen Quellen zugewiesen werden soll.
Das erste Schlüsselwort nach “tcp-request connection” in der Syntax ist die Aktion der Regel, auf die optional unterschiedlich viele Argumente für die Aktion folgen. Die unterstützten Aktionen und ihre jeweilige Syntax sind in Abschnitt 4.3 „Aktionen“ aufgeführt (suchen Sie nach Aktionen mit einem Häkchen in der Spalte “TCP RqCon”).
Diese Direktive ist nur in benannten defaults-Abschnitten verfügbar, nicht in anonymen. Im defaults-Abschnitt definierte Regeln werden vor denen im zugehörigen Proxy-Abschnitt ausgewertet. Um Mehrdeutigkeiten zu vermeiden, darf derselbe defaults-Abschnitt in diesem Fall nicht zugleich von Proxys mit Frontend-Funktion und von Proxys mit Backend-Funktion verwendet werden. Ein listen-Abschnitt kann daher keinen defaults-Abschnitt verwenden, der solche Regeln definiert.
Die Bedingung “if/unless” ist optional. Ohne Bedingung wird die Aktion uneingeschränkt ausgeführt. Dies kann für “track-sc*"-Aktionen nützlich sein oder um die Standardaktion auf Ablehnen zu ändern.
Beispiel: Alle Verbindungen von Hosts auf einer Positivliste akzeptieren, zu schnell eintreffende Verbindungen ohne Zählung ablehnen und akzeptierte Verbindungen verfolgen. Dadurch wird die Verbindungsrate missbräuchlicher Quellen begrenzt.
tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request connection reject if { src_conn_rate gt 10 }
tcp-request connection track-sc0 src
Beispiel: Alle Verbindungen von Hosts auf der Positivliste annehmen, alle anderen Verbindungen zählen und zu schnell eintreffende ablehnen. Dadurch bleiben missbräuchliche Quellen blockiert, solange sie ihre Rate nicht verringern.
tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request connection track-sc0 src
tcp-request connection reject if { sc0_conn_rate gt 10 }
Beispiel: Das PROXY-Protokoll für Datenverkehr von allen bekannten Proxys aktivieren.
tcp-request connection expect-proxy layer4 if { src -f proxies.lst }
Siehe Abschnitt 7 zur ACL-Verwendung.
Siehe auch: “tcp-request session”, “tcp-request content”, “stick-table”
tcp-request content <action> [{if | unless} <condition>]
Abhängig von einer Bedingung auf den Schichten 4-7 eine Aktion auf einer neuen Sitzung ausführen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja(!) | ja | ja | ja
Argumente:
Der Inhalt einer Anfrage kann in einer frühen Phase der Anfrageverarbeitung untersucht werden, der TCP-Inhaltsprüfung. Dabei werden ACL-basierte Regeln bei jeder Aktualisierung des Anfrageinhalts ausgewertet, bis eine Regel “accept”, “reject” oder “switch-mode” passt oder die Wartezeit für die TCP-Anfrageprüfung ohne passende Regel abläuft.
Der erste Unterschied zu “tcp-request connection”-Regeln besteht darin, dass “tcp-request content”-Regeln Inhalte für ihre Entscheidung verwenden können. Meist geht es dabei um die Erkennung oder Gültigkeit eines Protokolls. Der zweite Unterschied ist, dass inhaltsbasierte Regeln sowohl in Frontends als auch in Backends verwendet werden können. Bei HTTP-Keepalive mit dem Client werden alle tcp-request content-Regeln erneut ausgewertet. HAProxy merkt sich daher, welche Zuordnungen zu Stick-Zählern durch “tcp-request connection” und welche durch “tcp-request content” entstanden sind. Nach der Verarbeitung einer HTTP-Anfrage werden alle inhaltsbezogenen Zuordnungen verworfen, damit die bei der nächsten Anfrage erneut ausgewerteten Regeln sie neu bestimmen können. Dies ist besonders wichtig, wenn eine Regel L7-Informationen verfolgt oder von einer L7-basierten ACL abhängt, da sich die Zuordnung zwischen Anfragen ändern kann.
Inhaltsbasierte Regeln werden genau in der Reihenfolge ihrer Deklaration ausgewertet. Passt keine Regel oder gibt es keine Regel, wird der Inhalt standardmäßig akzeptiert. Die Anzahl der Regeln ist nicht gesondert begrenzt.
Es ist nicht vorgeschrieben, wird aber empfohlen, track-sc0 in “tcp-request connection”-Regeln, track-sc1 in “tcp-request content”-Regeln des Frontends und track-sc2 in “tcp-request content”-Regeln des Backends zu verwenden. Dies macht die Konfiguration lesbarer und erleichtert die Fehlersuche. Es ist jedoch nur eine Empfehlung; alle Zähler dürfen überall verwendet werden.
Das erste Schlüsselwort nach “tcp-request content” in der Syntax ist die Aktion der Regel, auf die optional unterschiedlich viele Argumente für die Aktion folgen. Die unterstützten Aktionen und ihre jeweilige Syntax sind in Abschnitt 4.3 „Aktionen“ aufgeführt (suchen Sie nach Aktionen mit einem Häkchen in der Spalte “TCP RqCnt”).
Diese Direktive ist nur in benannten defaults-Abschnitten verfügbar, nicht in anonymen. Im defaults-Abschnitt definierte Regeln werden vor denen im zugehörigen Proxy-Abschnitt ausgewertet. Um Mehrdeutigkeiten zu vermeiden, darf derselbe defaults-Abschnitt in diesem Fall nicht zugleich von Proxys mit Frontend-Funktion und von Proxys mit Backend-Funktion verwendet werden. Ein listen-Abschnitt kann daher keinen defaults-Abschnitt verwenden, der solche Regeln definiert.
Die Bedingung “if/unless” ist optional. Ohne Bedingung wird die Aktion uneingeschränkt ausgeführt. Dies kann für “track-sc*"-Aktionen nützlich sein oder um die Standardaktion auf Ablehnen zu ändern.
Es wird außerdem empfohlen, Informationen, die nicht vom Inhalt auf Schicht 7 abhängen, mit einer “tcp-request session”-Regel zu verfolgen, besonders bei HTTP-Frontends. Teile der HTTP-Verarbeitung finden auf Sitzungsebene statt und können zu einer frühen Ablehnung der Anfragen führen. Dadurch kann die Verfolgung auf Inhaltsebene beeinträchtigt werden. Beim Start wird eine Warnung ausgegeben, um solche unzuverlässigen Anwendungen möglichst zu verhindern.
In einem TCP-Proxy lassen sich mit “tcp-request content”-Regeln problemlos Inhalte auf Schicht 7 abgleichen. HTTP-spezifische ACL-Abgleiche können den Pufferinhalt vorläufig parsen, bevor sie die benötigten Daten extrahieren. Lässt sich der gepufferte Inhalt nicht als gültige HTTP-Nachricht parsen, passt die ACL nicht. Dabei wird genau derselbe Parser wie bei der übrigen HTTP-Verarbeitung verwendet, sodass keine Gefahr abweichender Interpretation besteht. In einem HTTP-Frontend oder HTTP-Backend ist garantiert, dass die HTTP-Inhalte bereits bei der ersten Auswertung der Regel verfügbar sind: Das HTTP-Parsen erfolgt früh in der Verbindungsverarbeitung auf Sitzungsebene. Für solche Proxys sind “http-request”-Regeln jedoch wesentlich naheliegender und werden empfohlen.
Auch das Verfolgen von layer7-Informationen ist möglich, sofern sie bei der Verarbeitung der Regel vorliegen. Sind die zu verfolgenden Daten noch nicht verfügbar, kann die Regelverarbeitung bis zum Ablauf der Prüfwartezeit warten.
Beispiel:
Beispiel:
Beispiel:
Beispiel:
Beispiel:
Beispiel:
Beispiel: Zähler je Frontend und Backend verfolgen und missbräuchliche Clients im Frontend blockieren, wenn das Backend Missbrauch erkennt und gpc0 markiert.
frontend http
# Use General Purpose Counter 0 in SC0 as a global abuse counter
# protecting all our sites
stick-table type ip size 1m expire 5m store gpc0
tcp-request connection track-sc0 src
tcp-request connection reject if { sc0_get_gpc0 gt 0 }
...
use_backend http_dynamic if { path_end .php }
backend http_dynamic
# if a source makes too fast requests to this dynamic site (tracked
# by SC1), block it globally in the frontend.
stick-table type ip size 1m expire 5m store http_req_rate(10s)
acl click_too_fast sc1_http_req_rate gt 10
acl mark_as_abuser sc0_inc_gpc0(http) gt 0
tcp-request content track-sc1 src
tcp-request content reject if click_too_fast mark_as_abuser
Siehe Abschnitt 7 zur ACL-Verwendung.
Siehe auch: “tcp-request connection”, “tcp-request session”, “tcp-request inspect-delay” und “http-request”.
tcp-request inspect-delay <timeout>
Die maximal zulässige Wartezeit auf Daten während der Inhaltsprüfung festlegen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja(!) | ja | ja | ja
Argumente:
Wer HAProxy hauptsächlich als TCP-Relay verwendet, ist oft besorgt darüber, beliebige Protokolle ohne Analyse an einen Server weiterzugeben. Um Anfrageinhalte analysieren zu können, müssen die Daten zunächst zurückgehalten und anschließend untersucht werden. Diese Anweisung ermöglicht lediglich, Daten höchstens für die angegebene Zeit zurückzuhalten.
Die TCP-Inhaltsprüfung erfolgt sehr früh beim Eintreffen einer Verbindung im Frontend und erneut sehr früh bei ihrer Weiterleitung an ein Backend. Eine Verbindung kann daher zuerst im Frontend und dann ein zweites Mal im Backend verzögert werden, wenn beide tcp-request-Regeln besitzen.
Bei der Inhaltsprüfung wertet HAProxy mit jedem neu eintreffenden Datenblock sämtliche Regeln aus und berücksichtigt dabei, dass die Daten noch unvollständig sind. Passt vor Ablauf der genannten Wartezeit keine Regel, erfolgt beim Ablauf eine letzte Prüfung, bei der die Inhalte als endgültig betrachtet werden. Ohne eingestellte Wartezeit wartet HAProxy überhaupt nicht und entscheidet sofort anhand der verfügbaren Informationen. Dies dürfte wenig nützlich sein und kann sogar von Wettlaufsituationen abhängen; solche Konfigurationen werden daher nicht empfohlen.
Die Prüfwartezeit wird verkürzt, wenn ein Verbindungsfehler oder eine Verbindungsschließung auftritt oder der Anfragepuffer voll ist.
Sobald eine Regel passt, wird die Anfrage freigegeben und wie üblich weiterverarbeitet. Läuft die Zeit ab, ohne dass eine Regel passt, wird die Anfrage standardmäßig unverändert durchgelassen.
Für die meisten Protokolle reichen wenige Sekunden, da die meisten Clients ihre vollständige Anfrage unmittelbar nach dem Verbindungsaufbau senden. Fügen Sie 3 oder mehr Sekunden für TCP-Wiederholungsübertragungen hinzu; mehr ist nicht nötig. Bei manchen Protokollen können große Werte sinnvoll sein, etwa um sicherzustellen, dass der Client niemals vor dem Server spricht, wie bei SMTP, oder um auf Daten des Clients zu warten, bevor Daten an den Server weitergegeben werden, wie bei SSL. Die Clientzeitüberschreitung muss mindestens die Prüfwartezeit abdecken, sonst läuft sie früher ab. Schließt der Client die Verbindung oder ist der Puffer voll, endet die Wartezeit sofort, da sich der Inhalt nicht mehr ändern kann.
Diese Direktive ist nur in benannten defaults-Abschnitten verfügbar, nicht in anonymen. Proxys erben diesen Wert aus ihrem defaults-Abschnitt.
Siehe auch: “tcp-request content accept”, “tcp-request content reject”, “timeout client”.
tcp-request session <action> [{if | unless} <condition>]
Abhängig von einer Bedingung auf Schicht 5 eine Aktion auf einer validierten Sitzung ausführen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja(!) | ja | ja | nein
Argumente:
Sobald eine Sitzung validiert ist, also alle Handshakes abgeschlossen sind, können Bedingungen ausgewertet werden, um zu entscheiden, ob die Sitzung akzeptiert oder verworfen werden muss oder ihre Zähler verfolgt werden sollen. Diese Bedingungen können keine Dateninhalte verwenden, da noch keine Puffer reserviert sind und die Verarbeitung in dieser Phase nicht warten kann. Hauptanwendungsfälle sind das Kopieren früh verfügbarer Informationen in Variablen, die in der Sitzung zugänglich sind, oder das Verfolgen nach dem Handshake erfasster Informationen. Dazu gehören SSL-Elemente wie SNI, Verschlüsselungsverfahren und der CN des Clientzertifikats sowie Informationen aus dem PROXY-Protokollheader, etwa um eine damit übermittelte Quelladresse zu verfolgen. Die extrahierten Informationen können also in eine Variable kopiert oder mit “track-sc”-Regeln verfolgt werden. Natürlich kann wie bei anderen Regelsätzen auch über Akzeptieren oder Ablehnen entschieden werden. Die meisten dieser Vorgänge wären ebenso in “tcp-request content”-Regeln möglich. Bei HTTP werden solche Regeln jedoch bei jeder neuen Anfrage ausgewertet, was nicht immer erwünscht ist. Beispielsweise könnte eine Regel bei jeder Auswertung einen Zähler erhöhen. Ebenso könnte aus der Quell-IP-Adresse per Geolokalisierung ein Land ermittelt und einer sitzungsweit gültigen Variablen zugewiesen werden, während anschließend die Quelladresse für alle Anfragen aus einem HTTP-Header umgeschrieben wird. Müssen für eine Entscheidung Inhalte untersucht werden, sind stattdessen “tcp-request content”-Anweisungen zu verwenden.
Die Regeln “tcp-request session” werden genau in der Reihenfolge ihrer Deklaration ausgewertet. Passt keine Regel oder gibt es keine Regel, wird die eingehende Sitzung standardmäßig akzeptiert. Die Anzahl der Regeln ist nicht gesondert begrenzt.
Das erste Schlüsselwort nach “tcp-request session” in der Syntax ist die Aktion der Regel, auf die optional unterschiedlich viele Argumente für die Aktion folgen. Die unterstützten Aktionen und ihre jeweilige Syntax sind in Abschnitt 4.3 „Aktionen“ aufgeführt (suchen Sie nach Aktionen mit einem Häkchen in der Spalte “TCP RqSes”).
Diese Direktive ist nur in benannten defaults-Abschnitten verfügbar, nicht in anonymen. Im defaults-Abschnitt definierte Regeln werden vor denen im zugehörigen Proxy-Abschnitt ausgewertet. Um Mehrdeutigkeiten zu vermeiden, darf derselbe defaults-Abschnitt in diesem Fall nicht zugleich von Proxys mit Frontend-Funktion und von Proxys mit Backend-Funktion verwendet werden. Ein listen-Abschnitt kann daher keinen defaults-Abschnitt verwenden, der solche Regeln definiert.
Die Bedingung “if/unless” ist optional. Ohne Bedingung wird die Aktion uneingeschränkt ausgeführt. Dies kann für “track-sc*"-Aktionen nützlich sein oder um die Standardaktion auf Ablehnen zu ändern.
Beispiel: Standardmäßig die ursprüngliche Quelladresse verfolgen oder bei Verbindungen von lokalen Proxys die im PROXY-Protokollheader angegebene Adresse. Die erste Regel auf Verbindungsebene aktiviert für diese Verbindungen den Empfang des PROXY-Protokolls. Die zweite Regel verfolgt die Adresse, die nach optionaler Dekodierung beibehalten werden soll.
tcp-request connection expect-proxy layer4 if { src -f proxies.lst }
tcp-request session track-sc0 src
Beispiel: Alle Sitzungen von Hosts auf der Positivliste annehmen, zu schnell eintreffende Sitzungen ablehnen, ohne sie zu zählen, und angenommene Sitzungen verfolgen. Dadurch wird die Sitzungsrate missbräuchlicher Quellen begrenzt.
tcp-request session accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request session reject if { src_sess_rate gt 10 }
tcp-request session track-sc0 src
Beispiel: Alle Sitzungen von Hosts auf der Positivliste annehmen, alle anderen Sitzungen zählen und zu schnell eintreffende ablehnen. Dadurch bleiben missbräuchliche Quellen blockiert, solange sie ihre Rate nicht verringern.
tcp-request session accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request session track-sc0 src
tcp-request session reject if { sc0_sess_rate gt 10 }
Siehe Abschnitt 7 zur ACL-Verwendung.
Siehe auch: “tcp-request connection”, “tcp-request content”, “stick-table”
tcp-response content <action> [{if | unless} <condition>]
Abhängig von einer Bedingung auf den Schichten 4-7 eine Aktion auf einer Sitzungsantwort ausführen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja(!) | nein | ja | ja
Argumente:
Antwortinhalte können in einer frühen Phase der Antwortverarbeitung untersucht werden, der TCP-Inhaltsprüfung. Dabei werden ACL-basierte Regeln bei jeder Aktualisierung des Antwortinhalts ausgewertet, bis entweder eine abschließende Regel passt oder eine festgelegte Wartezeit für die TCP-Antwortprüfung ohne passende Regel abläuft.
Meist geht es bei diesen Entscheidungen um die Erkennung oder Gültigkeit eines Protokolls.
Inhaltsbasierte Regeln werden genau in der Reihenfolge ihrer Deklaration ausgewertet. Passt keine Regel oder gibt es keine Regel, wird der Inhalt standardmäßig akzeptiert. Die Anzahl der Regeln ist nicht gesondert begrenzt.
Das erste Schlüsselwort nach “tcp-response content” in der Syntax ist die Aktion der Regel, auf die optional unterschiedlich viele Argumente für die Aktion folgen. Die unterstützten Aktionen und ihre jeweilige Syntax sind in Abschnitt 4.3 „Aktionen“ aufgeführt (suchen Sie nach Aktionen mit einem Häkchen in der Spalte “TCP RsCnt”).
Diese Direktive ist nur in benannten defaults-Abschnitten verfügbar, nicht in anonymen. Im defaults-Abschnitt definierte Regeln werden vor denen im zugehörigen Proxy-Abschnitt ausgewertet. Um Mehrdeutigkeiten zu vermeiden, darf derselbe defaults-Abschnitt in diesem Fall nicht zugleich von Proxys mit Frontend-Funktion und von Proxys mit Backend-Funktion verwendet werden. Ein listen-Abschnitt kann daher keinen defaults-Abschnitt verwenden, der solche Regeln definiert.
Die Bedingung “if/unless” ist optional. Ohne Bedingung wird die Aktion uneingeschränkt ausgeführt. Dies kann nützlich sein, um die Standardaktion auf Ablehnen zu ändern.
Es werden mehrere Arten von Aktionen unterstützt:
Mit “tcp-response content”-Regeln lassen sich problemlos Inhalte auf Schicht 7 abgleichen. Dabei muss jedoch sichergestellt sein, dass eine vollständige Antwort gepuffert wurde, da andernfalls keine Inhalte passen. Die beste Lösung dafür besteht darin, während der Prüfphase das HTTP-Protokoll zu erkennen.
Siehe Abschnitt 7 zur ACL-Verwendung.
Siehe auch: “tcp-request content”, “tcp-response inspect-delay”
tcp-response inspect-delay <timeout>
Die maximal zulässige Wartezeit auf eine Antwort während der Inhaltsprüfung festlegen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja(!) | nein | ja | ja
Argumente:
Diese Direktive ist nur in benannten defaults-Abschnitten verfügbar, nicht in anonymen. Proxys erben diesen Wert aus ihrem defaults-Abschnitt.
Siehe auch: “tcp-response content”, “tcp-request inspect-delay”.
timeout check <timeout>
Eine zusätzliche Prüfungszeitüberschreitung festlegen, die erst nach dem Aufbau einer Verbindung gilt.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Ist sie gesetzt, verwendet HAProxy min(“timeout connect”, “inter”) als Verbindungszeitüberschreitung der Prüfung und “timeout check” als zusätzliche Lesezeitüberschreitung. “min” verhindert, dass sehr lange Werte für “timeout connect”, etwa wegen Warteschlangen oder Tarpits, die Prüfungen verlangsamen. Für derart lange Verbindungszeitüberschreitungen gibt es allerdings keinen gültigen Grund, da sich dies stets mit “timeout queue” und “timeout tarpit” vermeiden lässt.
Ist “timeout check” nicht gesetzt, verwendet HAProxy “inter” als Zeitüberschreitung für die gesamte Prüfung, also Verbindungsaufbau und Lesen, genau wie alle Versionen <1.3.15.
Prüfanfragen sind meist viel einfacher und schneller zu bearbeiten als normale Anfragen. Da langsame Server gegebenenfalls ausgeschlossen werden sollen, sollte diese Zeitüberschreitung kleiner als “timeout server” sein.
Dieser Parameter gilt speziell für Backends, kann jedoch in “defaults”-Abschnitten einmal für alle festgelegt werden. Dies ist eine der einfachsten Möglichkeiten, ihn nicht zu vergessen.
Siehe auch: “timeout connect”, “timeout queue”, “timeout server”, “timeout tarpit”.
timeout client <timeout>
Die maximale Inaktivitätszeit auf der Clientseite festlegen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Die Inaktivitätszeitüberschreitung gilt, wenn vom Client eine Bestätigung oder das Senden von Daten erwartet wird. Im HTTP-Modus ist sie besonders während der ersten Phase wichtig, in der der Client die Anfrage sendet, sowie während der Antwort, wenn er die vom Server gesendeten Daten liest. Für die erste Phase ist jedoch “timeout http-request” vorzuziehen, um HAProxy besser vor Angriffen wie Slowloris zu schützen. Der Wert wird standardmäßig in Millisekunden angegeben. Durch Anhängen einer Einheit kann entsprechend der Beschreibung am Anfang dieses Dokuments auch eine andere Einheit verwendet werden. Im TCP-Modus und in geringerem Maß auch im HTTP-Modus wird dringend empfohlen, Client- und Serverzeitüberschreitung gleich zu halten, um schwer zu untersuchende Situationen zu vermeiden. Sinnvoll sind Werte knapp oberhalb von Vielfachen von 3 Sekunden, etwa 4 oder 5 Sekunden, um einen oder mehrere TCP-Paketverluste abzudecken. Werden langlebige und kurzlebige Streams wie WebSocket und HTTP gemischt, sollten “timeout tunnel”, das bei Tunneln “timeout client” und “timeout server” überschreibt, sowie “timeout client-fin” für halbgeschlossene Verbindungen erwogen werden.
Dieser Parameter gilt speziell für Frontends, kann jedoch in “defaults”-Abschnitten einmal für alle festgelegt werden. Dies ist eine der einfachsten Möglichkeiten, ihn nicht zu vergessen. Ein nicht angegebener Wert führt zu einer unbegrenzten Wartezeit, was nicht empfohlen wird. Diese Verwendung wird akzeptiert und funktioniert, erzeugt beim Start jedoch eine Warnung: Sind auch die Zeitüberschreitungen des Systems nicht konfiguriert, können sich abgelaufene Sitzungen im System ansammeln.
Siehe auch: “timeout server”, “timeout tunnel”, “timeout http-request”.
timeout client-fin <timeout>
Die Inaktivitätszeitüberschreitung auf der Clientseite für halbgeschlossene Verbindungen festlegen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Die Inaktivitätszeitüberschreitung gilt, wenn vom Client eine Bestätigung oder das Senden von Daten erwartet wird, während eine Richtung bereits geschlossen ist. Anders als “timeout client” gilt sie nur für in einer Richtung geschlossene Verbindungen. Dies ist besonders nützlich, damit Verbindungen nicht zu lange im Zustand FIN_WAIT bleiben, wenn Clients nicht sauber trennen. Dieses Problem tritt besonders häufig bei langen Verbindungen wie RDP oder WebSocket auf. Diese Zeitüberschreitung kann “timeout tunnel” überschreiben, wenn eine Verbindung in einer Richtung geschlossen wird. Sie wird auf inaktive HTTP/2-Verbindungen angewendet, sobald ein GOAWAY-Frame gesendet wurde, was häufig die Erwartung eines raschen Verbindungsendes ausdrückt.
Dieser Parameter gilt speziell für Frontends, kann jedoch in “defaults”-Abschnitten einmal für alle festgelegt werden. Standardmäßig ist er nicht gesetzt; halbgeschlossene Verbindungen verwenden daher die anderen Zeitüberschreitungen (timeout.client oder timeout.tunnel).
Siehe auch: “timeout client”, “timeout server-fin” und “timeout tunnel”.
timeout client-hs <timeout>
Die maximale Wartezeit auf den Abschluss eines Client-TLS-Handshakes festlegen. Dies kann sowohl für TCP- als auch für QUIC-Verbindungen verwendet werden.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Ist diese Handshake-Zeitüberschreitung nicht gesetzt, wird stattdessen die Clientzeitüberschreitung verwendet.
timeout connect <timeout>
Die maximale Wartezeit auf einen erfolgreichen Verbindungsaufbau zu einem Server festlegen.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Befindet sich der Server im selben LAN wie HAProxy, sollte die Verbindung sofort zustande kommen, also innerhalb weniger Millisekunden. Dennoch ist es sinnvoll, einen oder mehrere TCP-Paketverluste abzudecken, indem Zeitüberschreitungen knapp oberhalb von Vielfachen von 3 Sekunden gewählt werden, etwa 4 oder 5 Sekunden. Standardmäßig setzt die Verbindungszeitüberschreitung auch die Zeitüberschreitungen für Warteschlangen und Tarpits auf denselben Wert, sofern diese nicht angegeben wurden.
Dieser Parameter gilt speziell für Backends, kann jedoch in “defaults”-Abschnitten einmal für alle festgelegt werden. Dies ist eine der einfachsten Möglichkeiten, ihn nicht zu vergessen. Ein nicht angegebener Wert führt zu einer unbegrenzten Wartezeit, was nicht empfohlen wird. Diese Verwendung wird akzeptiert und funktioniert, erzeugt beim Start jedoch eine Warnung: Sind auch die Zeitüberschreitungen des Systems nicht konfiguriert, können sich fehlgeschlagene Sitzungen im System ansammeln.
Siehe auch: “timeout check”, “timeout queue”, “timeout server”, “timeout tarpit”.
timeout http-keep-alive <timeout>
Die maximal zulässige Wartezeit auf den Beginn einer neuen HTTP-Anfrage festlegen
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Standardmäßig bestimmt “timeout http-request” bei Keepalive die Wartezeit auf eine neue Anfrage. Dies ist nicht immer praktisch: Manche möchten sehr kurze Keepalive-Zeitüberschreitungen, um Verbindungen schneller freizugeben. Andere bevorzugen längere Wartezeiten, möchten aber weiterhin kurze Zeitüberschreitungen, sobald die Übertragung einer Anfrage begonnen hat.
Die Zeitüberschreitung “http-keep-alive” deckt diese Anforderungen ab. Sie legt fest, wie lange nach dem Senden einer Antwort auf den Beginn einer neuen HTTP-Anfrage gewartet wird. Sobald das erste Byte der Anfrage eingetroffen ist, gilt “http-request” für die Wartezeit auf die vollständige Anfrage. Leerzeilen vor einer neuen Anfrage starten die Zeitüberschreitung nicht neu und zählen nicht als neue Anfrage.
Es gibt noch einen Unterschied: Läuft eine Verbindung während timeout http-keep-alive ab, wird kein Fehler zurückgegeben; sie wird einfach geschlossen. Läuft sie während “http-request” beim Warten auf die vollständige Anfrage ab, erhält der Client vor dem Schließen einen HTTP-Fehler 408, sofern im Frontend nicht “option http-ignore-probes” gesetzt ist.
Im Allgemeinen eignet sich “timeout http-keep-alive” besonders für Websites mit vielen kurzen Verbindungen, um zu verhindern, dass Clients ansonsten inaktive Verbindungen zu lange offenhalten. Bei HTTP/1.1 lässt sich dies mit Werten von einigen zehn bis einigen hundert Millisekunden erreichen. Die Verbindung wird dann nach dem Abruf einer Seite geschlossen, ohne sie für weitere mögliche Clientaktivität offenhalten zu müssen. Neue Browseraktivität erfordert in diesem Fall einen neuen Handshake auf TCP- und/oder SSL-Ebene. Ein häufiger Anwendungsfall sind HTTP-Websites, die lediglich auf die HTTPS-Seite weiterleiten. Solche Verbindungen sollten nicht lange inaktiv offengehalten werden, da sie nicht wiederverwendet werden, allenfalls zum Abruf eines Favicons.
Ein weiterer Anwendungsfall ist das genaue Gegenteil: Manche Websites möchten Clients erlauben, inaktive Verbindungen lange wiederzuverwenden, etwa 30 Sekunden bis eine Minute, aber nicht so lange auf die erste Anfrage warten. Damit soll ein sehr kostengünstiger Angriffsweg vermieden werden. In diesem Fall wird http-keep-alive hoch gesetzt, während http-request niedrig bleibt, bei wenigen Sekunden.
Bei einem sehr kleinen Wert werden zusätzliche Anfragen ohne Pipelining wahrscheinlich über eine andere Verbindung verarbeitet. Nur echtes Pipelining, bei dem Anfragen direkt hintereinander ohne Warten auf eine Antwort gesendet werden, vermeidet dies; bei HTTP/1.1 ist es sehr selten. Die meisten HTTP/1.1-Implementierungen senden eine Anfrage, warten auf die Antwort und senden dann die nächste. Ein kleiner Wert für HTTP/1.1 kann bei Websites mit Hunderttausenden Clients Speicher und Sockets sparen, erhöht jedoch den Rechenaufwand für Handshakes.
Bei HTTP/2 sollte mit kleinen Werten besonders vorsichtig umgegangen werden. HTTP/2 bündelt Anfragen auf einer Verbindung, um den erneuten Aufbau der TCP- und/oder SSL-Schicht zu vermeiden. Das Protokoll verwendet außerdem Steuerframes, die mit frühzeitig geschlossenen TCP-Verbindungen schlecht zurechtkommen. In sehr seltenen Fällen können dadurch Antworten abgeschnitten werden, wenn Daten nach dem Verlassen von HAProxy unterwegs verloren gehen. HAProxy kann dann nicht einmal einen Fehler protokollieren. Ein empfohlener niedriger Ausgangswert für HTTP/2-Verbindungen liegt bei etwa 4 Sekunden. Dies verhindert bei den meisten modernen Keepalive-Implementierungen, dass ungenutzte Verbindungen unnötig offenbleiben, und erlaubt zugleich nachfolgenden Anfragen die Wiederverwendung. Der Wert ist jedoch nur ein Ausgangspunkt und sollte nach Bedarf angepasst werden.
Ist dieser Parameter nicht gesetzt, gilt “http-request”. Sind beide nicht gesetzt, gilt auf der darunterliegenden Ebene weiterhin “timeout client”. Damit der Parameter wirkt, sollte er im Frontend gesetzt werden. Befindet sich das Frontend im TCP-Modus, wird stattdessen die Zeitüberschreitung des HTTP-Backends verwendet.
Siehe auch: “timeout http-request”, “timeout client”.
timeout http-request <timeout>
Die maximal zulässige Wartezeit auf eine vollständige HTTP-Anfrage festlegen
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Für den Schutz vor DoS-Angriffen kann es erforderlich sein, die maximal zulässige Zeit zum Empfang einer vollständigen HTTP-Anfrage zu verkürzen, ohne die Clientzeitüberschreitung zu verändern. Dies schützt vor aufgebauten Verbindungen, über die nichts gesendet wird. Die Clientzeitüberschreitung schützt dagegen nicht ausreichend, weil sie nur Inaktivität erfasst: Sendet ein Angreifer gelegentlich ein Zeichen, wird sie nicht ausgelöst. Mit der HTTP-Anfragezeitüberschreitung wird die Anfrage unabhängig von der Sendegeschwindigkeit des Clients abgebrochen, wenn sie nicht rechtzeitig vollständig vorliegt. Beim Ablauf erhält der Client eine HTTP-Antwort 408 als Hinweis auf das Problem, und die Verbindung wird geschlossen. Im Protokoll erscheint der Beendigungscode “cR”. Manche neueren Browser haben Probleme mit diesem standardkonformen, gut dokumentierten Verhalten. Daher kann es nötig sein, den Code 408 mit “option http-ignore-probes” oder “errorfile 408 /dev/null” zu verbergen. Weitere Einzelheiten stehen bei der Erläuterung des Beendigungscodes “cR” in Abschnitt 8.5 .
Standardmäßig gilt diese Zeitüberschreitung nur für den Headerteil der Anfrage, nicht für Daten. Sobald die Leerzeile empfangen wurde, gilt sie nicht mehr. Zusammen mit “option http-buffer-request” gilt sie auch für den Anfragekörper. Bei Keepalive-Verbindungen wird sie erneut zum Warten auf eine zweite Anfrage verwendet, wenn “timeout http-keep-alive” nicht gesetzt ist.
Meist reichen wenige Sekunden, da die meisten Clients die vollständige Anfrage unmittelbar nach dem Verbindungsaufbau senden. Fügen Sie 3 oder mehr Sekunden für TCP-Wiederholungsübertragungen hinzu; mehr ist nicht nötig. Sehr niedrige Werte, etwa 50 ms, funktionieren in lokalen Netzen gewöhnlich, solange keine Pakete verloren gehen. Sie verhindern allerdings, dass Benutzer rohe HTTP-Anfragen mit Telnet eingeben.
Ist dieser Parameter nicht gesetzt, gilt weiterhin die Clientzeitüberschreitung zwischen den einzelnen eintreffenden Datenblöcken der Anfrage. Damit der Parameter wirkt, sollte er im Frontend gesetzt werden. Befindet sich das Frontend im TCP-Modus, wird stattdessen die Zeitüberschreitung des HTTP-Backends verwendet.
Siehe auch: “errorfile”, “http-ignore-probes”, “timeout http-keep-alive”, “timeout client” und “option http-buffer-request”.
timeout queue <timeout>
Die maximale Wartezeit in der Warteschlange auf einen freien Verbindungsplatz festlegen
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Wird der maxconn-Wert eines Servers erreicht, bleiben Verbindungen in einer Warteschlange. Diese kann serverspezifisch sein oder für das gesamte Backend gelten. Damit die Wartezeit nicht unbegrenzt ist, gilt für die wartenden Anfragen eine Zeitüberschreitung. Wird sie erreicht, wird angenommen, dass die Anfrage praktisch nicht mehr bedient werden kann. Sie wird deshalb verworfen, und der Client erhält einen Fehler 503.
Die Anweisung “timeout queue” legt fest, wie lange eine Anfrage höchstens in einer Warteschlange verbleiben darf. Fehlt die Angabe, gilt aus Gründen der Abwärtskompatibilität mit älteren Versionen ohne “timeout queue” derselbe Wert wie für die Verbindungszeitüberschreitung des Backends (“timeout connect”).
Siehe auch: “timeout connect”.
timeout server <timeout>
Die maximale Inaktivitätszeit auf der Serverseite festlegen.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Die Inaktivitätszeitüberschreitung gilt, wenn vom Server eine Bestätigung oder das Senden von Daten erwartet wird. Im HTTP-Modus ist sie besonders in der ersten Phase der Serverantwort wichtig, in der die Header gesendet werden müssen: Sie bildet unmittelbar die Verarbeitungszeit der Anfrage auf dem Server ab. Zur Wahl eines geeigneten Werts ist es oft sinnvoll, mit einer als nicht mehr akzeptabel angesehenen Antwortzeit zu beginnen, anschließend anhand der Protokolle die Verteilung der Antwortzeiten zu beobachten und den Wert entsprechend anzupassen.
Der Wert wird standardmäßig in Millisekunden angegeben. Durch Anhängen einer Einheit kann entsprechend der Beschreibung am Anfang dieses Dokuments auch eine andere Einheit verwendet werden. Im TCP-Modus und in geringerem Maß auch im HTTP-Modus wird dringend empfohlen, Client- und Serverzeitüberschreitung gleich zu halten, um schwer zu untersuchende Situationen zu vermeiden. Unabhängig von den erwarteten Serverantwortzeiten ist es sinnvoll, mindestens einen oder mehrere TCP-Paketverluste abzudecken. Dafür eignen sich Werte knapp oberhalb von Vielfachen von 3 Sekunden, etwa mindestens 4 oder 5 Sekunden. Werden langlebige und kurzlebige Streams wie WebSocket und HTTP gemischt, sollte “timeout tunnel” erwogen werden, das bei Tunneln “timeout client” und “timeout server” überschreibt.
Dieser Parameter gilt speziell für Backends, kann jedoch in “defaults”-Abschnitten einmal für alle festgelegt werden. Dies ist eine der einfachsten Möglichkeiten, ihn nicht zu vergessen. Ein nicht angegebener Wert führt zu einer unbegrenzten Wartezeit, was nicht empfohlen wird. Diese Verwendung wird akzeptiert und funktioniert, erzeugt beim Start jedoch eine Warnung: Sind auch die Zeitüberschreitungen des Systems nicht konfiguriert, können sich abgelaufene Sitzungen im System ansammeln.
Siehe auch: “timeout client” und “timeout tunnel”.
timeout server-fin <timeout>
Die Inaktivitätszeitüberschreitung auf der Serverseite für halbgeschlossene Verbindungen festlegen.
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Die Inaktivitätszeitüberschreitung gilt, wenn vom Server eine Bestätigung oder das Senden von Daten erwartet wird, während eine Richtung bereits geschlossen ist. Anders als “timeout server” gilt sie nur für in einer Richtung geschlossene Verbindungen. Dies ist besonders nützlich, damit Verbindungen nicht zu lange im Zustand FIN_WAIT bleiben, wenn ein entfernter Server nicht sauber trennt. Dieses Problem tritt besonders häufig bei langen Verbindungen wie RDP oder WebSocket auf. Diese Zeitüberschreitung kann “timeout tunnel” überschreiben, wenn eine Verbindung in einer Richtung geschlossen wird. Die Einstellung wurde der Vollständigkeit halber bereitgestellt, sollte in den meisten Situationen aber nicht benötigt werden.
Dieser Parameter gilt speziell für Backends, kann jedoch in “defaults”-Abschnitten einmal für alle festgelegt werden. Standardmäßig ist er nicht gesetzt; halbgeschlossene Verbindungen verwenden daher die anderen Zeitüberschreitungen (timeout.server oder timeout.tunnel).
Siehe auch: “timeout client-fin”, “timeout server” und “timeout tunnel”.
timeout tarpit <timeout>
Die Dauer festlegen, für die im Tarpit gehaltene Verbindungen bestehen bleiben
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Wird eine Verbindung mit “http-request tarpit” in einen Tarpit versetzt, bleibt sie für eine bestimmte Zeit ohne Aktivität offen und wird anschließend geschlossen. “timeout tarpit” legt fest, wie lange sie offengehalten wird.
Der Wert wird standardmäßig in Millisekunden angegeben. Durch Anhängen einer Einheit kann entsprechend der Beschreibung am Anfang dieses Dokuments auch eine andere Einheit verwendet werden. Fehlt die Angabe, gilt aus Gründen der Abwärtskompatibilität mit älteren Versionen ohne “timeout tarpit” derselbe Wert wie für die Verbindungszeitüberschreitung des Backends (“timeout connect”).
Siehe auch: “timeout connect”.
timeout tunnel <timeout>
Die maximale Inaktivitätszeit auf Client- und Serverseite für Tunnel festlegen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente:
Die Tunnelzeitüberschreitung gilt, wenn zwischen Client und Server eine bidirektionale Verbindung besteht und diese in beiden Richtungen inaktiv bleibt. Sobald die Verbindung zum Tunnel wird, ersetzt sie sowohl die Client- als auch die Serverzeitüberschreitung. Bei TCP gilt sie, sobald an keiner der beiden Verbindungen mehr eine Analysefunktion aktiv ist, etwa nachdem die TCP-Inhaltsregeln den Inhalt akzeptiert haben. Bei HTTP gilt sie nach einem Protokollwechsel, etwa zu WebSocket oder beim Weiterleiten einer CONNECT-Anfrage an einen Proxy, oder nach der ersten Antwort, wenn keine Keepalive- oder Schließoption angegeben ist.
Da diese Zeitüberschreitung gewöhnlich für langlebige Verbindungen verwendet wird, ist es meist sinnvoll, auch “timeout client-fin” zu setzen. Damit lässt sich behandeln, dass ein Client plötzlich aus dem Netz verschwindet und eine Schließung nicht bestätigt oder selbst eine Schließung sendet und ausstehende Daten nicht mehr bestätigt. Dies kann in verlustbehafteten Netzen mit Firewalls auftreten und ist an vielen Sitzungen im Zustand FIN_WAIT erkennbar.
Der Wert wird standardmäßig in Millisekunden angegeben. Durch Anhängen einer Einheit kann entsprechend der Beschreibung am Anfang dieses Dokuments auch eine andere Einheit verwendet werden. Unabhängig von der erwarteten normalen Inaktivitätsdauer ist es sinnvoll, mindestens einen oder mehrere TCP-Paketverluste abzudecken. Dafür eignen sich Werte knapp oberhalb von Vielfachen von 3 Sekunden, etwa mindestens 4 oder 5 Sekunden.
Dieser Parameter gilt speziell für Backends, kann jedoch in “defaults”-Abschnitten einmal für alle festgelegt werden. Dies ist eine der einfachsten Möglichkeiten, ihn nicht zu vergessen.
Beispiel:
Siehe auch: “timeout client”, “timeout client-fin”, “timeout server”.
transparent (deprecated)
Transparente Proxyverarbeitung auf der Clientseite aktivieren
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | nein | ja | ja
Argumente: keine
Dieses Schlüsselwort wurde eingeführt, um Load-Balancern auf Schicht 3 eine Sitzungsbindung auf Schicht 7 bereitzustellen. Dazu wird die Fähigkeit des Betriebssystems genutzt, eine eingehende Verbindung zu einer entfernten Adresse an einen lokalen Prozess, hier HAProxy, umzuleiten und diesem die ursprünglich angeforderte Adresse mitzuteilen. Bei dieser Option werden Sitzungen ohne Cookies an die ursprüngliche Ziel-IP-Adresse der eingehenden Anfrage weitergeleitet, die mit der eines anderen Geräts übereinstimmen sollte. Anfragen mit Cookies werden weiterhin an den passenden Server weitergeleitet.
Das Schlüsselwort “transparent” ist veraltet. Verwenden Sie stattdessen “option transparent”.
Entgegen einer verbreiteten Annahme bewirkt diese Option NICHT, dass HAProxy beim Verbindungsaufbau dem Server die IP-Adresse des Clients präsentiert.
Siehe auch: “option transparent”
unique-id-format <fmt>
Für jede Anfrage eine eindeutige ID erzeugen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | ja
Argumente:
Dieses Schlüsselwort erzeugt mit dem benutzerdefinierten Protokollformat für jede Anfrage eine ID. Eine eindeutige ID hilft, eine Anfrage durch viele Komponenten einer komplexen Infrastruktur zu verfolgen. Die neu erzeugte ID kann auch mit dem Alias %ID in der benutzerdefinierten Formatzeichenkette protokolliert werden.
Das Format sollte aus Elementen bestehen, deren Kombination garantiert eindeutig ist. Sind beispielsweise mehrere HAProxy-Instanzen beteiligt, kann es wichtig sein, den Knotennamen einzubeziehen. Häufig müssen auch Quell- und Zieladressen sowie Ports der eingehenden Verbindung protokolliert werden. Da über dieselbe Verbindung mehrere Anfragen erfolgen können, kann ein Anfragezähler bei ihrer Unterscheidung helfen. Ebenso kann ein Zeitstempel vor dem Überlauf des Zählers schützen. Das Protokollieren der Prozess-ID vermeidet Kollisionen nach einem Neustart des Dienstes.
Für viele Felder wird die hexadezimale Darstellung empfohlen, da sie kompakter ist und Platz im Protokoll spart.
Bei normalen Verbindungen wird die eindeutige ID mit dem im Frontend konfigurierten Format erzeugt. Bei Health Checks wird das Backendformat verwendet, wenn der Abruf “unique-id” innerhalb eines tcp-check- oder http-check-Regelsatzes verwendet wird.
Beispiel:
Siehe auch: “unique-id-header”
unique-id-header <name>
Der HTTP-Anfrage einen Header mit einer eindeutigen ID hinzufügen.
Kann in folgenden Kontexten verwendet werden: http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend ja | ja | ja | nein
Argumente:
Mit unique-id-format einen unique-id-Header in die an den Server gesendete HTTP-Anfrage einfügen. Ohne vorhandenes unique-id-format funktioniert dies nicht.
Beispiel:
use_backend <backend> [{if | unless} <condition>]
Zu einem bestimmten Backend wechseln, wenn eine ACL-basierte Bedingung erfüllt beziehungsweise nicht erfüllt ist.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | ja | ja | nein
Argumente:
Bei der inhaltsabhängigen Umschaltung treffen Verbindungen in einem Frontend ein und werden anschließend anhand verschiedener Bedingungen auf Backends verteilt. Das Schlüsselwort “use_backend” beschreibt die Zuordnung zwischen Bedingungen und Backends. Es wird üblicherweise bei HTTP-Verarbeitung eingesetzt, kann aber auch bei reinem TCP verwendet werden: entweder ohne Inhalte mit zustandslosen ACLs, etwa zur Prüfung der Quelladresse, oder zusammen mit einer “tcp-request”-Regel, um auf Nutzdaten zu warten.
Es können beliebig viele “use_backend”-Regeln angegeben werden. Sie werden in der Reihenfolge ihrer Deklaration ausgewertet; die erste passende Regel bestimmt das Backend. Dies gilt selbst dann, wenn das Backend als ausgefallen gilt. Verweist eine passende Regel jedoch auf ein deaktiviertes oder unveröffentlichtes Backend, wird sie ignoriert und die Regelauswertung fortgesetzt.
Bei der ersten Form wird das Backend verwendet, wenn die Bedingung erfüllt ist, bei der zweiten, wenn sie nicht erfüllt ist. Trifft keine Bedingung zu, wird das mit “default_backend” festgelegte Backend verwendet, sofern es nicht deaktiviert oder unveröffentlicht ist. Ist kein Standardbackend verfügbar, werden bei einem “listen”-Abschnitt die Server desselben Abschnitts verwendet. Bei einem Frontend wird dagegen kein Server verwendet und eine Antwort 503 service unavailable zurückgegeben.
Ein Wechsel von einem TCP-Frontend zu einem HTTP-Backend ist möglich. Hat das Frontend bereits geprüft, dass das Protokoll HTTP ist, beginnt die Backendverarbeitung sofort. Andernfalls wartet das Backend auf eine vollständige HTTP-Anfrage. Dies ist nützlich, wenn ein Frontend mehrere Protokolle auf einem einzigen Port dekodieren muss und eines davon HTTP ist.
Ist <backend> ein einfacher Name, wird er beim Einlesen der Konfiguration aufgelöst. Existiert das angegebene Backend nicht, wird ein Fehler gemeldet. Ist <backend> stattdessen ein benutzerdefiniertes Protokollformat, kann zu diesem Zeitpunkt keine Prüfung erfolgen. Der Backendname wird dann dynamisch zur Laufzeit aufgelöst. Entspricht der ermittelte Name keinem gültigen Backend, werden keine weiteren Regeln ausgewertet; stattdessen wird die Direktive default_backend angewendet. Bei dynamischen Backendnamen wird dringend empfohlen, ein Präfix zu verwenden, das kein anderes Backend verwendet. So wird sichergestellt, dass über die Anfrage kein unzulässiges Backend erzwungen werden kann.
“use_backend”-Regeln mit ausdrücklich angegebenem Namen dienen dazu, die Zuordnung zwischen Frontends und Backends zu ermitteln und damit die Backend-Einstellung “fullconn” zu berechnen. Bei dynamischen Namen ist dies nicht möglich.
Siehe auch: “default_backend”, “tcp-request”, “fullconn”, “log-format” und Abschnitt 7 zu ACLs.
use-fcgi-app <name>
Die für das Backend zu verwendende FastCGI-Anwendung festlegen.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Argumente:
Einzelheiten zur Einrichtung von FastCGI-Anwendungen enthält Abschnitt 10.1 .
use-server <server> if <condition>
Einen bestimmten Server nur verwenden, wenn eine ACL-basierte Bedingung erfüllt beziehungsweise nicht erfüllt ist.
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Argumente:
Standardmäßig werden Verbindungen, die ein Backend erreichen, gemäß dem konfigurierten Algorithmus auf die verfügbaren Server verteilt. Eine Ausnahme besteht, wenn ein Mechanismus zur Sitzungsbindung, etwa ein Cookie, verwendet und in der Anfrage gefunden wird.
Manchmal soll eine bestimmte Anfrage an einen bestimmten Server geleitet werden, ohne dafür ein eigenes Backend zu deklarieren. Dies ermöglichen “use-server”-Regeln. Sie werden nach den “redirect”-Regeln und vor den Cookies ausgewertet und haben Vorrang vor den Cookies. Es können beliebig viele “use-server”-Regeln angegeben werden. Sie werden in der Reihenfolge ihrer Deklaration ausgewertet; die erste passende Regel bestimmt den Server.
Wenn eine Regel einen ausgefallenen Server bezeichnet, “option persist” nicht verwendet wird und keine force-persist-Regel gegriffen hat, wird diese Regel ignoriert. Die Auswertung wird mit den folgenden Regeln fortgesetzt, bis eine passt.
Bei der ersten Form wird der Server verwendet, wenn die Bedingung erfüllt ist, bei der zweiten, wenn sie nicht erfüllt ist. Trifft keine Bedingung zu, wird die Verarbeitung fortgesetzt und der Server anhand anderer Mechanismen zur Sitzungsbindung zugewiesen.
Auch bei einer passenden Regel werden Cookies weiterhin verarbeitet, bestimmen dann aber nicht den Server. So können Präfixe aus Cookies mit vorangestelltem Präfix entfernt werden.
Die Anweisung “use-server” funktioniert sowohl im HTTP- als auch im TCP-Modus und eignet sich daher für die inhaltsbasierte Prüfung. Bei Protokollen mit implizitem TLS könnte beispielsweise ein Server aus einer Farm anhand des TLS-SNI-Felds ausgewählt werden; siehe auch “req.ssl_sni”. Ist das Gewicht dieser Server auf null gesetzt, werden sie nicht für anderen Datenverkehr verwendet.
Beispiel:
Wenn <server> ein einfacher Name ist, wird er mit den vorhandenen Servern in der Konfiguration abgeglichen. Existiert der angegebene Server nicht, wird ein Fehler gemeldet. Handelt es sich um ein benutzerdefiniertes Protokollformat, erfolgt beim Parsen der Konfiguration keine Prüfung. Wenn zur Laufzeit kein gültiger Servername ermittelt werden kann, die use-server-Regel aber von einer ACL abhängig war, die wahr zurückgab, wird keine weitere use-server-Regel angewendet und auf die Lastverteilung zurückgegriffen.
Siehe auch: “use_backend”, Abschnitt 5 zu Servern und Abschnitt 7 zu ACLs.
4.3. Matrix der Aktionsschlüsselwörter
In verschiedenen Phasen der Anfrage- oder Antwortverarbeitung werden mehrere Regelsätze ausgewertet. Für jede darin enthaltene Regel kann eine Aktion ausgeführt werden, wenn die optionale Bedingung erfüllt ist.
Standardmäßig stehen zahlreiche Aktionen zur Verfügung. Sie können Inhalte ändern, die Verarbeitung zulassen oder blockieren, interne Zustände ändern usw. Außerdem können neue Aktionen in Lua definiert werden; deren Namen beginnen dann immer mit “lua.”.
Während einige Aktionen früher nur in bestimmten Regelsätzen verfügbar waren, lassen sich heute viele Aktionen in vielen Regelsätzen verwenden. Die Aufstellung in diesem Abschnitt zeigt für jede unterstützte Aktion durch Markierung der entsprechenden abgekürzten Einträge, in welchen der folgenden Regelsätze sie verwendet werden kann:
- QUIC Ini: Die Aktion ist für “quic-initial”-Regeln gültig.
- TCP RqCon: Die Aktion ist für “tcp-request connection”-Regeln gültig.
- TCP RqSes: Die Aktion ist für “tcp-request session”-Regeln gültig.
- TCP RqCnt: Die Aktion ist für “tcp-request content”-Regeln gültig.
- TCP RsCnt: Die Aktion ist für “tcp-response content”-Regeln gültig.
- HTTP Req: Die Aktion ist für “http-request”-Regeln gültig.
- HTTP Res: Die Aktion ist für “http-response”-Regeln gültig.
- HTTP Aft: Die Aktion ist für “http-after-response”-Regeln gültig.
Dieselben Abkürzungen werden in der nachfolgenden Referenz in Abschnitt 4.4 verwendet.
4.4. Alphabetisch sortierte Aktionsreferenz
Dieser Abschnitt beschreibt jede Aktion und ihre Verwendung ausführlich. Für die Kennzeichnung der Regelsätze wird dieselbe Terminologie wie oben in Abschnitt 4.3 verwendet.
accept
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | X | X | X | X | - | - | -
Dies beendet die Regelauswertung und lässt die Anfrage oder Antwort die Prüfung passieren. Diese Aktion ist abschließend, d. h. für den aktuellen Abschnitt werden keine weiteren Regeln desselben Regelsatzes ausgewertet. Sie unterscheidet sich von der Aktion “allow” nur dadurch, dass aus Gründen historischer Kompatibilität “accept” für TCP- und QUIC-Regeln und “allow” für HTTP-Regeln verwendet wird. Siehe auch die Aktion “allow” weiter unten.
add-acl(<file-name>) <key fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Damit wird einer ACL ein neuer Eintrag hinzugefügt. Die ACL muss aus einer Datei geladen werden, auch wenn diese nur eine leere Platzhalterdatei ist. Der Dateiname der zu aktualisierenden ACL wird in Klammern angegeben. Die Aktion nimmt ein Argument entgegen: <key fmt>, das den in Abschnitt 8.2.6
beschriebenen Regeln für benutzerdefinierte Protokollformate folgt, um den Inhalt des neuen Eintrags zu ermitteln. Vor dem Einfügen wird die ACL durchsucht, um doppelte oder mehrfach vorhandene Werte zu vermeiden. Dies entspricht dem Befehl “add acl” am Statistik-Socket, kann jedoch durch eine HTTP-Anfrage ausgelöst werden.
add-header <name> <fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Dies hängt ein HTTP-Header-Feld an, dessen Name in <name> und dessen Wert durch <fmt> festgelegt wird. Letzteres folgt den Regeln für benutzerdefinierte Protokollformate (siehe „Benutzerdefiniertes Protokollformat“ in Abschnitt 8.2.6
). Dies ist besonders nützlich, um verbindungsspezifische Informationen an den Server weiterzugeben, etwa das SSL-Zertifikat des Clients, oder um mehrere Header zu einem zusammenzufassen. Diese Regel ist nicht abschließend, sodass weitere ähnliche Regeln hinzugefügt werden können. Beachten Sie, dass der Header sofort hinzugefügt wird. Eine Regel kann daher den aus einer vorherigen Regel entstandenen Header wiederverwenden.
add-headers-bin <expr> [ prefix <str> ]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Dies ist eine Variante der Aktion “add-header”, bei der die Header-Namen und -Werte als binäre Zeichenfolge mit varint-Kodierung übergeben werden. Informationen zum varint-Format finden Sie beim Sample-Abruf “req.hdrs_bin”. Dies ist nützlich, wenn mehrere Header gleichzeitig gesetzt werden sollen, ohne ihre Namen im Voraus kennen zu müssen. Beachten Sie, dass diese Header nicht vom HTTP-Parser validiert wurden. Dadurch können ungültige Nachrichten ausgegeben werden; im schlimmsten Fall kann dies Request-Smuggling-Angriffe ermöglichen. Auch die Anzahl der eingefügten Header ist relevant, da sie durch tune.http.maxhdr begrenzt wird. Wird das optionale Präfix angegeben, werden aus der kodierten Zeichenfolge nur die Header gesetzt, die mit <str> beginnen.
Beispiel:
allow
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Dies beendet die Regelauswertung und lässt die Anfrage die Prüfung passieren. Diese Aktion ist abschließend, d. h. für den aktuellen Abschnitt werden keine weiteren Regeln desselben Regelsatzes ausgewertet. Sie unterscheidet sich von der Aktion “accept” nur dadurch, dass aus Gründen historischer Kompatibilität “accept” für TCP-Regeln und “allow” für HTTP-Regeln verwendet wird. Siehe auch die Aktion “accept” weiter oben.
attach-srv <srv> [name <expr>] [ EXPERIMENTAL ]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | X | - | - | - | - | -
Damit wird die Verbindung nach dem ordnungsgemäßen Aufbau von HTTP/2 abgefangen. Die Verbindung wird auf die Backend-Seite umgekehrt und in den Pool ungenutzter Verbindungen des Servers <srv> aufgenommen. Dies kann nur mit Servern verwendet werden, deren Adresse mit ‘rhttp@’ angegeben ist.
Die Verbindung wird unter einem Namen in den Pool ungenutzter Serververbindungen aufgenommen, der sich aus der Auswertung von <expr> ergibt. Mit diesem Namen werden Anfragen abgeglichen, für die der Parameter “pool-conn-name” oder “sni” gilt. Weitere Einzelheiten finden Sie unter “http-reuse”.
Reverse HTTP wird derzeit noch aktiv entwickelt. Der Konfigurationsmechanismus kann sich künftig ändern. Deshalb ist er intern als experimentell gekennzeichnet, was bedeutet, dass “expose-experimental-directives” in einer Zeile vor dieser Direktive stehen muss.
Beachten Sie, dass ein sehr ähnliches, aber unabhängiges Protokoll entwickelt wird. Siehe https://www.ietf.org/archive/id/draft-bt-httpbis-reverse-http-00.html .
auth [realm <realm>]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Dies beendet die Regelauswertung und antwortet sofort mit dem HTTP-Fehlercode 401 oder 407, um den Benutzer zur Angabe eines gültigen Benutzernamens und Passworts aufzufordern. Es werden keine weiteren “http-request”-Regeln ausgewertet. Der optionale Parameter “realm” wird unterstützt. Er legt den mit der Antwort zurückgegebenen Authentifizierungsbereich fest, üblicherweise den Namen der Anwendung.
Es wird die Fehlermeldung des jeweiligen Proxys verwendet. Sie kann mit einer Direktive “errorfile” oder “http-error” angepasst werden. Bei Antworten mit dem Status 401 werden alle Vorkommen des Headers WWW-Authenticate entfernt und durch einen neuen Header mit einer Aufforderung zur Basisauthentifizierung für den Bereich “<realm>” ersetzt. Bei Antworten mit dem Status 407 geschieht dasselbe mit dem Header Proxy-Authenticate. Wenn die Fehlermeldung nicht verändert werden darf, ziehen Sie stattdessen eine Regel “http-request return” in Betracht.
Beispiel:
cache-store <name>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | - | X | -
Speichert eine http-response im Cache. Die Antwort-Header werden in diesem Schritt gespeichert. Sie können also andere http-response-Aktionen verwenden, um Header vor oder nach dem Speichern der Antwort zu ändern. Diese Aktion richtet den Filter zum Speichern im Cache ein.
Siehe Abschnitt 6.2 zur Einrichtung des Caches.
cache-use <name>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Versucht, ein zwischengespeichertes Objekt aus dem Cache <name> auszuliefern. Diese Direktive ist auch für das Speichern im Cache zwingend erforderlich, da sie den Cache-Hash berechnet. Wenn Sie eine Bedingung sowohl für das Speichern als auch für das Ausliefern verwenden möchten, empfiehlt es sich, sie nach dieser Direktive anzugeben.
Siehe Abschnitt 6.2 zur Einrichtung des Caches.
capture <sample> [ len <length> | id <id> ]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | X | X
Dies erfasst den Sample-Ausdruck <sample> aus dem Anfrage- oder Antwortpuffer und wandelt ihn in eine Zeichenfolge mit höchstens <len> Zeichen um. Die resultierende Zeichenfolge wird im nächsten “capture”-Slot für Anfragen bzw. Antworten gespeichert und kann somit neben erfassten HTTP-Headern erscheinen. Sie erscheint anschließend automatisch in den Protokollen und kann mit Sample-Abrufmethoden ausgelesen werden, um sie in Header oder andere Elemente einzufügen. Die Länge sollte begrenzt werden, da diese Größe für jede Erfassung während der gesamten Lebensdauer des Streams reserviert wird. Beachten Sie, dass die Länge nur mit “http-request”-Regeln verwendet werden kann. Ein solcher Slot existiert nur in dem Abschnitt, der ihn deklariert. Wird diese Regel daher in einem “listen”-Abschnitt platziert, der zugleich als Backend eines anderen Frontends dient, wird sie für Streams von diesem Frontend ignoriert. Weitere Informationen finden Sie in Abschnitt 7.3
(Abrufen von Samples), unter “capture request header” und unter “capture response header”.
Wird statt “len” das Schlüsselwort “id” verwendet, versucht die Aktion, die erfasste Zeichenfolge in einem zuvor deklarierten Erfassungsslot zu speichern. Dies ist nützlich, um Erfassungen in Backends durchzuführen. Die Slot-ID kann mit einer vorherigen Direktive “http-request capture” oder mit dem Schlüsselwort “declare capture” deklariert werden.
Wenn Sie diese Aktion in einem Backend verwenden, vergewissern Sie sich, dass die zugehörigen Frontends über die erforderlichen Erfassungsslots verfügen. Andernfalls wird diese Regel zur Laufzeit ignoriert. Da HAProxy Backend-Namen dynamisch zur Laufzeit auflösen kann, lässt sich dies beim Parsen der Konfiguration nicht erkennen.
close
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | X | - | - | -
Damit wird die Verbindung zum Server sofort geschlossen. Es werden keine weiteren “tcp-response content”-Regeln ausgewertet. Diese Aktion dient hauptsächlich dazu, nach einem Austausch das Ende einer Verbindung zwischen Client und Server zu erzwingen, wenn das Anwendungsprotokoll zunächst den Ablauf langer Wartefristen vorsieht. Ziel ist es, ungenutzte Verbindungen zu beseitigen, die bei bestimmten Protokollen erhebliche Serverressourcen belegen.
del-acl(<file-name>) <key fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Damit wird ein Eintrag aus einer ACL gelöscht. Die ACL muss aus einer Datei geladen werden, auch wenn diese nur eine leere Platzhalterdatei ist. Der Dateiname der zu aktualisierenden ACL wird in Klammern angegeben. Die Aktion nimmt ein Argument entgegen: <key fmt>, das den Regeln für benutzerdefinierte Protokollformate in Abschnitt 8.2.6
folgt, um den Inhalt des zu löschenden Eintrags zu ermitteln. Dies entspricht dem Befehl “del acl” am Statistik-Socket, kann jedoch durch eine HTTP-Anfrage oder -Antwort ausgelöst werden.
del-header <name> [ -m <meth> ]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Dies entfernt alle HTTP-Header-Felder mit dem in <name> angegebenen Namen. <meth> bezeichnet die auf den Header-Namen angewendete Abgleichmethode. Unterstützt werden “str” (exakte Übereinstimmung), “beg” (Präfixübereinstimmung), “end” (Suffixübereinstimmung), “sub” (Übereinstimmung mit einer Teilzeichenfolge) und “reg” (Übereinstimmung mit einem regulären Ausdruck). Wird keine Methode angegeben, wird auf exakte Übereinstimmung geprüft.
del-headers-bin <expr> [ -m <meth> ]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Dies entfernt alle HTTP-Header-Felder, deren Namen in <expr> angegeben werden. <expr> muss eine binäre Zeichenfolge mit varint-Kodierung zurückgeben, die alle zu löschenden Header-Namen enthält. Eine Beschreibung der Kodierung und Beispiele finden Sie unter “add-headers-bin” und “set-headers-bin”. <meth> bezeichnet die auf alle Header-Namen angewendete Abgleichmethode. Unterstützt werden “str” (exakte Übereinstimmung), “beg” (Präfixübereinstimmung), “end” (Suffixübereinstimmung) und “sub” (Übereinstimmung mit einer Teilzeichenfolge). “reg” (Übereinstimmung mit einem regulären Ausdruck) wird wegen der nicht vorhersehbaren Leistung zur Laufzeit nicht unterstützt. Wird keine Methode angegeben, wird auf exakte Übereinstimmung geprüft.
del-map(<map-name>) <key fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Damit wird ein Eintrag aus einer MAP gelöscht. <map-name> muss dem in 2.7. beschriebenen Namensformat für Maps und ACLs entsprechen. Der Name der zu aktualisierenden MAP wird in Klammern angegeben. Die Aktion nimmt ein Argument entgegen: <key fmt>, das den Regeln für benutzerdefinierte Protokollformate in Abschnitt
8.2.6
folgt, um den Inhalt des zu löschenden Eintrags zu ermitteln. Sie nimmt ein Argument entgegen: „Dateiname“. Dies entspricht dem Befehl “del map” am Statistik-Socket, kann jedoch durch eine HTTP-Anfrage oder -Antwort ausgelöst werden.
deny [ { status | deny_status } <code> ] [ content-type <type> ]
file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
[ hdr `<name>` `<fmt>` ]*
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Dies beendet die Regelauswertung und weist die Anfrage oder Antwort sofort zurück. Standardmäßig wird für Anfragen ein HTTP-Fehler 403 und für Antworten ein Fehler 502 zurückgegeben. Die zurückgegebene Antwort kann jedoch mit derselben Syntax wie bei der Aktion “return” angepasst werden. Einzelheiten finden Sie daher unter “return” weiter unten. Aus Kompatibilitätsgründen wird das Argument “default-errorfiles” impliziert, wenn kein Argument oder nur “deny_status” angegeben wird. Somit ist “deny [deny_status <status>]” ein Alias für “deny
[status <status>] default-errorfiles”. Diese Aktion ist abschließend, d. h. für den aktuellen Abschnitt werden keine weiteren Regeln desselben Regelsatzes ausgewertet. Zur erweiterten Syntax siehe auch die Aktion “return”.
dgram-drop
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | - | - | - | - | - | - | -
Dies ignoriert ohne Rückmeldung den Empfang eines QUIC-Initial-Pakets, der andernfalls zur Instanziierung einer neuen QUIC-Verbindung und zur Ausführung ihres SSL-Handshakes geführt hätte.
disable-l7-retry
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Dies deaktiviert jeden Versuch, die Anfrage zu wiederholen, wenn sie aus einem anderen Grund als einem Verbindungsfehler fehlschlägt. So lässt sich beispielsweise sicherstellen, dass POST-Anfragen bei einem Fehler nicht wiederholt werden.
do-log [profile <log_profile>]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | X | X | X | X | X | X | X
Diese Aktion löst manuell die Ausgabe eines Protokolleintrags auf dem Proxy aus. Dabei werden die Protokollierungsoptionen des Proxys berücksichtigt, einschließlich Formatierungsoptionen wie “log-format”. Die während der Transaktionsverarbeitung automatisch vom Proxy erzeugten Protokolleinträge werden dadurch jedoch nicht beeinflusst.
Mit “log-profile” lässt sich für jeden verfügbaren Kontext, in dem die Aktion verwendet werden kann, genau beschreiben, wie der Protokolleintrag ausgegeben werden soll. Dazu dient das Schlüsselwort ‘on’, gefolgt von einem der Werte ‘quic-init’, ’tcp-req-conn’, ’tcp-req-sess’, ’tcp-req-cont’, ’tcp-res-cont’, ‘http-req’, ‘http-res’, ‘http-after-res’.
Diese Kontexte werden auch bei Verwendung des Protokollformat-Alias “%OG” korrekt ausgegeben.
Mit dem optionalen Argument “profile” kann der Name eines log-profile-Abschnitts angegeben werden, der speziell für diese do-log-Aktion verwendet werden soll. Er ersetzt das standardmäßig geltende Profil, das dem aktuellen Logger zugeordnet ist.
Beispiel:
do-resolve(<var>,<resolvers>[,ipv4|ipv6]) <expr>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Diese Aktion führt für das Ergebnis von <expr> eine DNS-Auflösung durch und speichert das Ergebnis in der Variablen <var>. Sie verwendet den durch <resolvers> bezeichneten DNS-resolvers-Abschnitt. Mit den optionalen Argumenten ‘ipv4’ oder ‘ipv6’ kann eine bevorzugte Adressfamilie für die Auflösung gewählt werden. Siehe auch das globale Schlüsselwort “dns-accept-family”, mit dem die ausschließliche Verwendung einer bestimmten Familie erzwungen werden kann.
Während der DNS-Auflösung pausiert die clientseitige Verbindung und wartet auf deren Abschluss. Wird eine IP-Adresse gefunden, wird sie in <var> gespeichert. Tritt ein Fehler beliebiger Art auf, wird <var> nicht gesetzt. Mit dieser Aktion lässt sich zur Laufzeit anhand von Informationen aus der Anfrage eine Server-IP-Adresse ermitteln, beispielsweise anhand eines Host-Headers. Wird diese Aktion zum Ermitteln der Server-IP-Adresse verwendet, die mit der Aktion “set-dst” gesetzt wird, muss die Server-IP-Adresse im Backend auf 0.0.0.0 gesetzt sein. Die Aktion do-resolve nimmt einen Parameter entgegen, der nur den Host enthält; jeder Port muss aus der Zeichenfolge entfernt werden.
Beispiel:
HINWEIS: Vergessen Sie nicht, die Schutzregeln einzurichten, damit HAProxy weder zum Scannen des Netzwerks verwendet wird noch, schlimmer noch, sich selbst in einer Schleife aufruft …
early-hint <name> <fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Damit wird vor jeder anderen Antwort eine HTTP-Antwort 103 Early Hints erstellt. Der Antwort wird ein HTTP-Header-Feld angehängt, dessen Name in <name> und dessen Wert durch <fmt> festgelegt wird. Letzteres folgt den Regeln für benutzerdefinierte Protokollformate (siehe „Benutzerdefiniertes Protokollformat“ in Abschnitt 8.2.6
). Dies ist besonders nützlich, um dem Client Link-Header zu übermitteln, mit denen für die Darstellung der HTML-Dokumente benötigte Ressourcen vorab geladen werden können.
Weitere Informationen finden Sie in RFC 8297.
expect-netscaler-cip layer4
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | - | - | - | - | - | -
Dies konfiguriert die dem Client zugewandte Verbindung so, dass sie einen Header des NetScaler Client IP insertion protocol empfängt, bevor auch nur ein Byte vom Socket gelesen wird. Dies entspricht dem Schlüsselwort “accept-netscaler-cip” in der “bind”-Zeile. Mit der TCP-Regel kann das PROXY-Protokoll jedoch anhand einer ACL nur für bestimmte IP-Adressbereiche akzeptiert werden. Dies ist praktisch, wenn Datenverkehr von öffentlichen Hosts mehrere Ebenen von Load-Balancern durchläuft.
expect-proxy layer4
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | - | - | - | - | - | -
Dies konfiguriert die dem Client zugewandte Verbindung so, dass sie einen Header des PROXY-Protokolls empfängt, bevor auch nur ein Byte vom Socket gelesen wird. Dies entspricht dem Schlüsselwort “accept-proxy” in der “bind”-Zeile. Mit der TCP-Regel kann das PROXY-Protokoll jedoch anhand einer ACL nur für bestimmte IP-Adressbereiche akzeptiert werden. Dies ist praktisch, wenn Datenverkehr von öffentlichen Hosts mehrere Ebenen von Load-Balancern durchläuft.
normalize-uri <normalizer>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Normalisiert die URI der Anfrage.
Die URI-Normalisierung ist in HAProxy 2.4 derzeit als experimentelle technische Vorschau verfügbar. Daher muss zuerst die globale Direktive ’expose-experimental-directives’ angegeben werden, damit sie aufgerufen werden kann. Sie sollten darauf vorbereitet sein, dass sich das Verhalten der Normalisierer zur Behebung möglicher Probleme ändern und dadurch möglicherweise die korrekte Anfrageverarbeitung in Ihrer Infrastruktur beeinträchtigen kann.
Jeder Normalisierer behandelt genau eine Art der Normalisierung. So lässt sich der für das unterstützte Backend geeignete Normalisierungsumfang gezielt auswählen.
Beispielsweise kann der Normalisierer “path-strip-dotdot” für einen statischen Dateiserver nützlich sein, der die angeforderte URI direkt auf den Pfad im lokalen Dateisystem abbildet. Er kann jedoch das Routing einer API beeinträchtigen, die eine bestimmte Anzahl von Pfadsegmenten erwartet.
Beachten Sie, dass einige Normalisierer bei fehlerhaften URIs zu unsicheren Umwandlungen führen können. Auch eine ungeeignete Kombination von Normalisierern, die für sich genommen sicher sind, kann zu unsicheren Umwandlungen führen.
Beispielsweise kann der Normalisierer “percent-decode-unreserved” unerwartete Ergebnisse liefern, wenn eine fehlerhafte URI einzelne Prozentzeichen enthält. Eine solche fehlerhafte URI ist “/%%36%36”: Sie würde zu “/%66” dekodiert, was wiederum “/f” entspricht. Mit der Option “strict” werden Anfragen für eine solche fehlerhafte URI sicher zurückgewiesen.
Folgende Normalisierer sind verfügbar:
-
fragment-encode: Kodiert “#” als “%23”.
Der Normalisierer “fragment-strip” sollte bevorzugt werden, sofern nicht bekannt ist, dass fehlerhafte Clients ‘#’ innerhalb der Pfadkomponente nicht korrekt kodieren.
Beispiel:
- /#foo -> /%23foo
-
fragment-strip: Entfernt die “fragment”-Komponente der URI.
Gemäß RFC 3986#3.5 sollte die “fragment”-Komponente einer URI nicht gesendet, sondern nach dem Abrufen einer Ressource vom Benutzeragenten verarbeitet werden.
Dieser Normalisierer sollte zuerst angewendet werden, damit das Fragment nicht als Teil der Pfadkomponente der Anfrage interpretiert wird.
Beispiel:
- /#foo -> /
-
path-strip-dot: Entfernt “/./"-Segmente innerhalb der “path”-Komponente (RFC 3986#6.2.2.3).
Segmente mit prozentkodierten Punkten ("%2E”) werden nicht erkannt. Falls dies unerwünscht ist, verwenden Sie zuerst den Normalisierer “percent-decode-unreserved”.
Beispiel:
- /. -> /
- /./bar/ -> /bar/
- /a/./a -> /a/a
- /.well-known/ -> /.well-known/ (unverändert)
-
path-strip-dotdot: Normalisiert “/../"-Segmente innerhalb der “path”-Komponente (RFC 3986#6.2.2.3).
Dabei werden Segmente, die auf das übergeordnete Verzeichnis zugreifen wollen, mit ihrem jeweils vorhergehenden Segment zusammengeführt.
Leere Segmente werden nicht gesondert behandelt. Falls dies unerwünscht ist, verwenden Sie zuerst den Normalisierer “merge-slashes”.
Segmente mit prozentkodierten Punkten ("%2E”) werden nicht erkannt. Falls dies unerwünscht ist, verwenden Sie zuerst den Normalisierer “percent-decode-unreserved”.
Beispiel:
- /foo/../ -> /
- /foo/../bar/ -> /bar/
- /foo/bar/../ -> /foo/
- /../bar/ -> /../bar/
- /bar/../../ -> /../
- /foo//../ -> /foo/
- /foo/%2E%2E/ -> /foo/%2E%2E/
Wenn die Option “full” angegeben ist, wird auch ein führendes “../” entfernt:
Beispiel:
- /../bar/ -> /bar/
- /bar/../../ -> /
-
path-merge-slashes: Führt benachbarte Schrägstriche innerhalb der “path”-Komponente zu einem einzigen Schrägstrich zusammen.
Beispiel:
- // -> /
- /foo//bar -> /foo/bar
-
percent-decode-unreserved: Dekodiert nicht reservierte, prozentkodierte Zeichen zu ihrer Darstellung als gewöhnliche Zeichen (RFC 3986#6.2.2.2).
Zu den nicht reservierten Zeichen gehören alle Buchstaben, alle Ziffern, “-”, “.”, “_” und “~”.
Beispiel:
- /%61dmin -> /admin
- /foo%3Fbar=baz -> /foo%3Fbar=baz (unverändert)
- /%%36%36 -> /%66 (unsicher)
- /%ZZ -> /%ZZ
Wenn die Option “strict” angegeben ist, führen ungültige Sequenzen zur Rückgabe von HTTP 400 Bad Request.
Beispiel:
- /%%36%36 -> HTTP 400
- /%ZZ -> HTTP 400
-
percent-to-uppercase: Wandelt Buchstaben innerhalb prozentkodierter Sequenzen in Großbuchstaben um (RFC 3986#6.2.2.1).
Beispiel:
- /%6f -> /%6F
- /%zz -> /%zz
Wenn die Option “strict” angegeben ist, führen ungültige Sequenzen zur Rückgabe von HTTP 400 Bad Request.
Beispiel:
- /%zz -> HTTP 400
-
query-sort-by-name: Sortiert die Parameter der Abfragezeichenfolge nach Parameternamen. Dabei wird angenommen, dass die Parameter durch ‘&’ getrennt sind. Kürzere Namen werden vor längeren einsortiert; Parameter mit identischem Namen behalten ihre relative Reihenfolge bei.
Beispiel:
- /?c=3&a=1&b=2 -> /?a=1&b=2&c=3
- /?aaa=3&a=1&aa=2 -> /?a=1&aa=2&aaa=3
- /?a=3&b=4&a=1&b=5&a=2 -> /?a=3&a=1&a=2&b=4&b=5
pause { <timeout> | <expr> }
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Dies setzt die Nachrichtenanalyse für die angegebene Anzahl von Millisekunden aus. Die Wartezeit kann in Millisekunden oder in einer anderen Einheit angegeben werden, wenn der Zahl wie zu Beginn dieses Dokuments beschrieben die Einheit angehängt wird. Auch ein Ausdruck kann angegeben werden; er muss eine Zahl zurückgeben, die als Wartezeit in Millisekunden interpretiert wird. Schlägt die Auswertung des Ausdrucks fehl oder liefert sie einen ungültigen Wert, wird die Aktion ignoriert und die Auswertung fortgesetzt.
Diese Aktion kann zur Fehlersuche verwendet werden. Sie kann aber auch dazu dienen, bestimmte Clients anhand bestimmter Kriterien zu verlangsamen. Beispielsweise können Clients bei zu hoher Anfragerate verlangsamt werden, indem sie mit einer “track-sc”-Regel verfolgt werden.
redirect <rule>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Dies führt anhand einer Weiterleitungsregel eine HTTP-Weiterleitung durch. Die Aktion entspricht genau der Anweisung “redirect”, fügt jedoch eine Weiterleitungsregel ein, die inmitten anderer “http-request”- oder “http-response”-Regeln verarbeitet wird. Außerdem verwenden diese Regeln das benutzerdefinierte Protokollformat. Bei Antworten sind nur Weiterleitungen vom Typ “location” zulässig. Wird während einer Antwort eine Weiterleitung ausgeführt, wird zudem die Übertragung vom Server an HAProxy unterbrochen, sodass keine Nutzdaten an den Client weitergeleitet werden können. Bei HTTP/1 kann dies dazu führen, dass einige Verbindungen geschlossen werden. Diese Aktion ist abschließend, d. h. für den aktuellen Abschnitt werden keine weiteren Regeln desselben Regelsatzes ausgewertet. Die Regelsyntax finden Sie beim Schlüsselwort “redirect”.
reject
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | X | X | X | X | X | - | -
Dies beendet die Regelauswertung und schließt die Verbindung sofort, ohne eine Antwort zu senden. Bei HTTP-Regeln verhält sich die Aktion ähnlich wie “tcp-request content reject”-Regeln. Sie kann nützlich sein, um das sofortige Schließen von HTTP/2-Verbindungen zu erzwingen.
Bei “tcp-request connection”-Regeln werden zurückgewiesene Verbindungen nicht einmal zu einer Sitzung. Deshalb werden sie in den Statistiken separat als “denied connections” gezählt. Sie werden weder bei der Ratenbegrenzung für Sitzungen berücksichtigt noch protokolliert. Der Grund dafür ist, dass diese Regeln nur zum Filtern extrem hoher Verbindungsraten verwendet werden sollten, wie sie bei einem massiven DDoS-Angriff auftreten. Unter solch extremen Bedingungen würde bereits das Protokollieren jedes Ereignisses das System zusammenbrechen lassen und die Filterkapazität erheblich verringern. Wenn die Protokollierung unbedingt gewünscht ist, sollten stattdessen “tcp-request content”-Regeln verwendet werden, da auch “tcp-request session”-Regeln nichts protokollieren.
Bei Verwendung in “tcp-response content”-Regeln wird die Serververbindung geschlossen und die Antwort abgebrochen. Dies wird im Allgemeinen eingesetzt, um die Offenlegung vertraulicher Informationen zu verhindern, typischerweise nach einer Inhaltsprüfung zusammen mit der Aktion “wait-for-body”.
Diese Aktion kann auch in “quic-initial”-Regeln verwendet werden. Die neu geöffnete QUIC-Verbindung wird sofort geschlossen, ohne den SSL-Handshake zu verarbeiten. Der Client wird mit dem Fehlercode CONNECTION_REFUSED benachrichtigt.
replace-header <name> <match-regex> <replace-fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Dies gleicht den Wert aller Vorkommen des Header-Felds <name> mit <match-regex> ab. Der Abgleich unterscheidet Groß- und Kleinschreibung. Übereinstimmende Werte werden vollständig durch <replace-fmt> ersetzt. In <replace-fmt> sind Formatzeichen zulässig; sie funktionieren wie die <fmt>-Argumente in “http-request
add-header”. Übliche Rückverweise mit einem Backslash (’\’), gefolgt von einer Zahl, werden unterstützt.
Diese Aktion arbeitet auf vollständigen Header-Zeilen, unabhängig von der Anzahl der darin enthaltenen Werte. Sie eignet sich daher gut für Header, deren Wert von Natur aus Kommas enthält, etwa If-Modified-Since oder Set-Cookie. Header mit einer kommagetrennten Werteliste, etwa Accept oder Cache-Control, sollten stattdessen mit der Aktion “replace-value” verarbeitet werden. Siehe auch die Aktion “replace-value”.
Beispiel:
Beispiel:
replace-path <match-regex> <replace-fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Dies funktioniert wie “replace-header”, arbeitet jedoch auf der Pfadkomponente der Anfrage statt auf einem Header. Die Pfadkomponente beginnt am ersten ‘/’ nach einer optionalen Kombination aus Schema und Authority und endet vor dem Fragezeichen. Die Ersetzung ändert daher weder das Schema noch die Authority oder die Abfragezeichenfolge.
Beachten Sie, dass die Auswertung regulärer Ausdrücke aufwendiger sein kann als die bestimmter ACLs. Bei seltenen Ersetzungen kann daher eine Bedingung sinnvoll sein, um die Auswertung vollständig zu vermeiden, wenn die Bedingung nicht zutrifft.
Beispiel:
replace-pathq <match-regex> <replace-fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Dies bewirkt dasselbe wie “http-request replace-path”, wobei der Pfad jedoch eine gegebenenfalls vorhandene Abfragezeichenfolge einschließt. Somit werden sowohl der Pfad als auch die Abfragezeichenfolge ersetzt.
Beispiel:
replace-uri <match-regex> <replace-fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Dies funktioniert wie “replace-header”, arbeitet jedoch auf dem URI-Teil der Anfrage statt auf einem Header. Der URI-Teil kann optional ein Schema, eine Authority oder eine Abfragezeichenfolge enthalten. Diese gelten als Teil des Werts, mit dem der Abgleich erfolgt.
Beachten Sie, dass die Auswertung regulärer Ausdrücke aufwendiger sein kann als die bestimmter ACLs. Bei seltenen Ersetzungen kann daher eine Bedingung sinnvoll sein, um die Auswertung vollständig zu vermeiden, wenn die Bedingung nicht zutrifft.
WICHTIGER HINWEIS: Historisch verwendet bei HTTP/1.x die überwiegende Mehrheit der von Browsern gesendeten Anfragen die “origin form”. Diese unterscheidet sich von der “absolute form” dadurch, dass ihr URI-Teil weder ein Schema noch eine Authority enthält. Meist verwenden nur an Proxys gesendete Anfragen, von Hand erstellte Anfragen und einige von bestimmten Anwendungen erzeugte Anfragen die absolute Form. Deshalb funktioniert “replace-uri” bei HTTP/1.x mit Regeln, die mit “/” beginnen, normalerweise problemlos. Bei HTTP/2 wird Clients jedoch nahegelegt, ausschließlich absolute URIs zu senden, die denen ähneln, mit denen HTTP/1-Clients Proxys ansprechen. Solche partiellen replace-uri-Regeln können dann unter HTTP/2 fehlschlagen, obwohl sie unter HTTP/1 funktionieren. Entweder müssen die Regeln so angepasst werden, dass sie optional auch ein Schema und eine Authority erfassen, oder es sollte replace-path verwendet werden.
Beispiel:
replace-value <name> <match-regex> <replace-fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Dies funktioniert wie “replace-header”, gleicht den regulären Ausdruck jedoch mit jedem kommagetrennten Wert des Header-Felds <name> ab, statt mit dem gesamten Header. Dies eignet sich für alle Header, die mehrere Werte enthalten dürfen. Beispiele sind der Anfrage-Header Accept oder Cache-Control in Anfragen und Antworten.
Beispiel:
Beispiel:
return [ status <code> ] [ content-type <type> ]
file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
[ hdr `<name>` `<fmt>` ]*
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Dies beendet die Regelauswertung und gibt sofort eine Antwort zurück. Der standardmäßige Statuscode der Antwort ist 200. Er kann optional als Argument von “status” angegeben werden. Der Inhaltstyp der Antwort kann ebenfalls als Argument von “content-type” angegeben werden. Schließlich kann auch die Antwort selbst definiert werden: als vollständige HTTP-Antwort durch Angabe der zu verwendenden Fehlerdatei oder als Antwortnutzdaten durch Angabe der zu verwendenden Datei oder Zeichenfolge. Die Antwort wird nach folgenden Regeln erstellt:
-
Wenn weder eine Fehlerdatei noch zu verwendende Nutzdaten definiert sind, wird eine leere Platzhalterantwort zurückgegeben. Nur das Argument “status” wird berücksichtigt. Es kann ein beliebiger Code im Bereich [200, 599] sein. Ein gegebenenfalls vorhandenes Argument “content-type” wird ignoriert.
-
Wenn das Argument “default-errorfiles” gesetzt ist, werden die Fehlerdateien des Proxys berücksichtigt. Wird das Argument “status” definiert, muss es einer der von HAProxy unterstützten Statuscodes sein (200, 400, 403, 404, 405, 408, 410, 413, 414, 425, 429, 431, 500, 501, 502, 503 und 504). Ein gegebenenfalls vorhandenes Argument “content-type” wird ignoriert.
-
Wenn mit dem Argument “errorfile” eine bestimmte Fehlerdatei definiert ist, wird die entsprechende Datei zurückgegeben, die eine vollständige HTTP-Antwort enthält. Nur das Argument “status” wird berücksichtigt. Es muss einer der von HAProxy unterstützten Statuscodes sein (200, 400, 403, 404, 405, 408, 410, 413, 414, 425, 429, 431, 500, 501, 502, 503 und 504). Ein gegebenenfalls vorhandenes Argument “content-type” wird ignoriert.
-
Wenn mit dem Argument “errorfiles” ein http-errors-Abschnitt definiert ist, wird die entsprechende Datei aus dem angegebenen http-errors-Abschnitt zurückgegeben, die eine vollständige HTTP-Antwort enthält. Nur das Argument “status” wird berücksichtigt. Es muss einer der von HAProxy unterstützten Statuscodes sein (200, 400, 403, 404, 405, 408, 410, 413, 414, 425, 429, 431, 500, 501, 502, 503 und 504). Ein gegebenenfalls vorhandenes Argument “content-type” wird ignoriert.
-
Wenn das Argument “file” oder “lf-file” angegeben wird, wird der Dateiinhalt als Antwortnutzdaten verwendet. Ist die Datei nicht leer, muss ihr Inhaltstyp als Argument von “content-type” gesetzt werden. Andernfalls wird jedes Argument “content-type” ignoriert. Bei “lf-file” wird der Dateiinhalt als benutzerdefiniertes Protokollformat ausgewertet (siehe Abschnitt 8.2.6 ). Bei “file” wird er als unverarbeiteter Inhalt behandelt.
-
Wenn das Argument “string” oder “lf-string” angegeben wird, wird die definierte Zeichenfolge als Antwortnutzdaten verwendet. Der Inhaltstyp muss stets als Argument von “content-type” gesetzt werden. Bei “lf-string” wird die Zeichenfolge als benutzerdefiniertes Protokollformat ausgewertet (siehe Abschnitt 8.2.6 ). Bei “string” wird sie als unverarbeitete Zeichenfolge behandelt.
Wenn die Antwort nicht auf einer Fehlerdatei beruht, können mit “hdr”-Argumenten HTTP-Header-Felder an die Antwort angehängt werden. Andernfalls werden alle “hdr”-Argumente ignoriert. Für jeden Header wird der Name in <name> und der Wert durch <fmt> festgelegt. Letzteres folgt den in Abschnitt 8.2.6
beschriebenen Regeln für benutzerdefinierte Protokollformate.
Beachten Sie, dass die erzeugte Antwort kleiner als ein Puffer sein muss. Um Warnungen zu vermeiden, sollte beim Laden einer Fehlerdatei oder einer unverarbeiteten Datei außerdem der für das Umschreiben von Headern reservierte Pufferbereich frei bleiben.
Diese Aktion ist abschließend, d. h. für den aktuellen Abschnitt werden keine weiteren Regeln desselben Regelsatzes ausgewertet.
Beispiel:
sc-add-gpc(<idx>,<sc-id>) { <int> | <expr> }
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Diese Aktion erhöht den allgemeinen Zähler am Index <idx> des Arrays, das dem mit <sc-id> bezeichneten Sitzungsbindungszähler zugeordnet ist. Der Erhöhungswert stammt entweder aus der Ganzzahl <int> oder aus dem als Ganzzahl ausgewerteten Ausdruck <expr>. Ganzzahlen und Ausdrücke sind auf vorzeichenlose 32-Bit-Werte begrenzt. Tritt ein Fehler auf, schlägt die Aktion ohne Meldung fehl und die Auswertung der Aktionen wird fortgesetzt. <idx> ist eine Ganzzahl zwischen 0 und 99, <sc-id> eine Ganzzahl zwischen 0 und 2. Auch wenn an diesem Index kein GPC gespeichert ist, schlägt die Aktion ohne Meldung fehl. Der Tabelleneintrag wird selbst dann aufgefrischt, wenn der Wert null ist. ‘gpc_rate’ wird automatisch angepasst, um die durchschnittliche Wachstumsrate des gpc-Werts widerzuspiegeln.
Diese Aktion gilt nur für die Array-Datentypen ‘gpc’ und ‘gpc_rate’, nicht für die älteren Datentypen ‘gpc0’, ‘gpc1’, ‘gpc0_rate’ oder ‘gpc1_rate’. Für die älteren Datentypen gibt es keine entsprechende Funktion. Wenn der Wert jedoch immer 1 ist, siehe ‘sc-inc-gpc()’, ‘sc-inc-gpc0()’ und ‘sc-inc-gpc1()’. Auch ein Verringern des Werts ist nicht möglich. Stattdessen können jedoch mit ‘sc-set-gpt()’ genaue Werte in einem allgemeinen Tag gespeichert werden.
Diese Aktion dient hauptsächlich dazu, Bewertungen oder Gesamtmengen zu zählen, etwa die vom Server oder von einer WAF gemeldete geschätzte Gefährlichkeit pro Quell-IP oder die insgesamt hochgeladenen Bytes.
sc-inc-gpc(<idx>,<sc-id>)
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Diese Aktion erhöht den allgemeinen Zähler am Index <idx> des Arrays, das dem mit <sc-id> bezeichneten Sitzungsbindungszähler zugeordnet ist. Tritt ein Fehler auf, schlägt die Aktion ohne Meldung fehl und die Auswertung der Aktionen wird fortgesetzt. <idx> ist eine Ganzzahl zwischen 0 und 99, <sc-id> eine Ganzzahl zwischen 0 und 2. Auch wenn an diesem Index kein GPC gespeichert ist, schlägt die Aktion ohne Meldung fehl. Diese Aktion gilt nur für die Array-Datentypen ‘gpc’ und ‘gpc_rate’, nicht für die älteren Datentypen ‘gpc0’, ‘gpc1’, ‘gpc0_rate’ oder ‘gpc1_rate’.
sc-inc-gpc0(<sc-id>)
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Diese Aktion erhöht den Zähler GPC0 oder GPC1 entsprechend dem mit <sc-id> bezeichneten Sitzungsbindungszähler. Tritt ein Fehler auf, schlägt die Aktion ohne Meldung fehl und die Auswertung der Aktionen wird fortgesetzt.
sc-set-gpt(<idx>,<sc-id>) { <int> | <expr> }
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Diese Aktion setzt das vorzeichenlose 32-Bit-GPT am Index <idx> des Arrays, das dem mit <sc-id> bezeichneten Sitzungsbindungszähler zugeordnet ist, auf den Wert von <int>/<expr>. Das erwartete Ergebnis ist ein boolescher Wert.
Tritt ein Fehler auf, schlägt die Aktion ohne Meldung fehl und die Auswertung der Aktionen wird fortgesetzt. <idx> ist eine Ganzzahl zwischen 0 und 99, <sc-id> eine Ganzzahl zwischen 0 und 2. Auch wenn an diesem Index kein GPT gespeichert ist, schlägt die Aktion ohne Meldung fehl.
Diese Aktion gilt nur für den Array-Datentyp ‘gpt’, nicht für den älteren Datentyp ‘gpt0’.
sc-set-gpt0(<sc-id>) { <int> | <expr> }
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Diese Aktion setzt das vorzeichenlose 32-Bit-Tag GPT0 entsprechend dem mit <sc-id> bezeichneten Sitzungsbindungszähler und dem Wert von <int>/<expr>. Das erwartete Ergebnis ist ein boolescher Wert. Tritt ein Fehler auf, schlägt die Aktion ohne Meldung fehl und die Auswertung der Aktionen wird fortgesetzt. Diese Aktion ist ein Alias für “sc-set-gpt(0,<sc-id>)”. Siehe auch die Aktion “sc-set-gpt”.
send-retry
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | - | - | - | - | - | - | -
Diese Aktion erzwingt das Senden eines Retry-Pakets als Antwort auf ein Initial-Paket eines Clients ohne Token. Dies ist nützlich, um sicherzustellen, dass die Clientadresse validiert wird, bevor Verbindungselemente instanziiert werden und der Handshake beginnt.
send-spoe-group <engine-name> <group-name>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | -
Mit dieser Aktion wird das Senden einer Gruppe von SPOE-Nachrichten ausgelöst. Dazu müssen sowohl die zum Senden verwendete SPOE-Engine als auch die zu sendende SPOE-Gruppe definiert sein. Die SPOE-Engine muss selbstverständlich auf einen vorhandenen SPOE-Filter verweisen. Ist in der SPOE-Filterzeile kein Engine-Name angegeben, muss der Name des SPOE-Agenten verwendet werden.
Argumente:
set-bandwidth-limit <name> [limit {<expr> | <size>}] [period {<expr> | <time>}]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | -
Mit dieser Aktion wird der Filter <name> zur Bandbreitenbegrenzung aktiviert, je nach Filtertyp für Uploads oder Downloads. Eine individuelle Grenze und ein individueller Zeitraum können genau dann definiert werden, wenn <name> auf einen Filter zur Bandbreitenbegrenzung pro Stream verweist. Bei der Ausführung einer set-bandwidth-limit-Regel werden zunächst alle Einstellungen des Filters auf ihre Standardwerte zurückgesetzt, bevor er aktiviert wird. Werden mehrere “set-bandwidth-limit”-Aktionen für denselben Filter ausgeführt, wird deshalb nur die letzte berücksichtigt. Für denselben Stream können mehrere Filter zur Bandbreitenbegrenzung aktiviert werden.
Beachten Sie, dass diese Aktion nicht in einem defaults-Abschnitt verwendet werden kann, weil Filter zur Bandbreitenbegrenzung nicht in defaults-Abschnitten definiert werden können. Außerdem wird nur die Übertragung der HTTP-Nutzdaten begrenzt. Die HTTP-Header werden nicht berücksichtigt.
Argumente:
Beispiel:
Siehe Abschnitt 9.7 zur Einrichtung von Filtern zur Bandbreitenbegrenzung.
set-bc-mark { <mark> | <expr> }
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Damit wird auf unterstützten Plattformen der Netfilter/IPFW MARK für die Backend-Verbindung, also für alle an den Server gesendeten Pakete, auf den in <mark> oder <expr> übergebenen Wert gesetzt. Dies ist ein vorzeichenloser 32-Bit-Wert, der von netfilter/ipfw und der Routingtabelle oder bei der Paketüberwachung mit DTrace abgeglichen werden kann. <mark> kann dezimal oder hexadezimal mit dem Präfix “0x” angegeben werden. Alternativ kann <expr> verwendet werden: ein gewöhnlicher HAProxy-Ausdruck aus einem Sample-Abruf und nachfolgenden Konvertern, der einen Ganzzahltyp ergeben muss. Diese Aktion kann nützlich sein, um bestimmte Pakete auf eine andere Route zu zwingen, etwa einen günstigeren Netzwerkpfad für große Downloads. Dies funktioniert ab Linux-Kernel 2.6.32 und erfordert Administratorrechte; es funktioniert außerdem unter FreeBSD und OpenBSD. Die Markierung bleibt während der gesamten Backend-/Serververbindung gesetzt, vom Verbindungsaufbau bis zum Schließen.
set-bc-tos { <tos> | <expr> }
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Damit wird auf unterstützten Plattformen der Wert des TOS- oder DSCP-Felds für die Backend-Verbindung, also für alle an den Server gesendeten Pakete, auf den in <tos> oder <expr> übergebenen Wert gesetzt. Dieser Wert umfasst sämtliche 8 Bits des IP-TOS-Felds. Beachten Sie, dass bei DSCP oder TOS nur die oberen 6 Bits verwendet werden und die beiden unteren Bits immer 0 sind. Alternativ kann <expr> verwendet werden: ein gewöhnlicher HAProxy-Ausdruck aus einem Sample-Abruf und nachfolgenden Konvertern, der einen Ganzzahltyp ergeben muss. Mit dieser Aktion lässt sich das Routingverhalten interner Router anhand von Informationen aus der Anfrage anpassen. Der tos-Wert bleibt während der gesamten Backend-/Serververbindung gesetzt, vom Verbindungsaufbau bis zum Schließen.
Weitere Informationen finden Sie in RFC 2474, 2597, 3260 und 4594.
set-dst <expr>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -
Damit wird die Ziel-IP-Adresse auf den Wert des angegebenen Ausdrucks gesetzt. Dies ist nützlich, wenn ein HAProxy vorgeschalteter Proxy die Ziel-IP umschreibt, die korrekte IP jedoch in einem HTTP-Header bereitstellt, oder wenn Sie die IP aus Datenschutzgründen verbergen möchten. Wenn Sie eine Verbindung mit der neuen Adresse bzw. dem neuen Port herstellen möchten, verwenden Sie im Backend ‘0.0.0.0:0’ als Serveradresse.
Argumente:
Beispiel:
Wenn möglich, behält set-dst den ursprünglichen Zielport bei, sofern die Adressfamilie dies zulässt. Andernfalls wird der Zielport auf 0 gesetzt.
set-dst-port <expr>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -
Damit wird der Zielport auf den Wert des angegebenen Ausdrucks gesetzt. Wenn Sie eine Verbindung mit der neuen Adresse bzw. dem neuen Port herstellen möchten, verwenden Sie im Backend ‘0.0.0.0:0’ als Serveradresse.
Argumente:
Beispiel:
Wenn möglich, behält set-dst-port die ursprüngliche Zieladresse bei, sofern die Adressfamilie einen Port unterstützt. Andernfalls setzt es die Zieladresse vor dem Umschreiben des Ports auf die IPv4-Adresse “0.0.0.0”.
set-fc-mark { <mark> | <expr> }
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | -
Damit wird auf unterstützten Plattformen der Netfilter/IPFW MARK für alle an den Client gesendeten Pakete auf den in <mark> oder <expr> übergebenen Wert gesetzt. Dies ist ein vorzeichenloser 32-Bit-Wert, der von netfilter/ipfw und der Routingtabelle oder bei der Paketüberwachung mit DTrace abgeglichen werden kann. <mark> kann dezimal oder hexadezimal mit dem Präfix “0x” angegeben werden. Alternativ kann <expr> verwendet werden: ein gewöhnlicher HAProxy-Ausdruck aus einem Sample-Abruf und nachfolgenden Konvertern, der einen Ganzzahltyp ergeben muss. Diese Aktion kann nützlich sein, um bestimmte Pakete auf eine andere Route zu zwingen, etwa einen günstigeren Netzwerkpfad für große Downloads. Dies funktioniert ab Linux-Kernel 2.6.32 und erfordert Administratorrechte; es funktioniert außerdem unter FreeBSD und OpenBSD.
set-fc-tos { <tos | <expr> }
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | -
Damit wird auf unterstützten Plattformen der Wert des TOS- oder DSCP-Felds für an den Client gesendete Pakete auf den in <tos> oder <expr> übergebenen Wert gesetzt. Dieser Wert umfasst sämtliche 8 Bits des IP-TOS-Felds. Beachten Sie, dass bei DSCP oder TOS nur die oberen 6 Bits verwendet werden und die beiden unteren Bits immer 0 sind. Alternativ kann <expr> verwendet werden: ein gewöhnlicher HAProxy-Ausdruck aus einem Sample-Abruf und nachfolgenden Konvertern, der einen Ganzzahltyp ergeben muss. Mit dieser Aktion lässt sich das Routingverhalten von Grenzroutern anhand von Informationen aus der Anfrage anpassen.
Weitere Informationen finden Sie in RFC 2474, 2597, 3260 und 4594.
set-header <name> <fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Dies bewirkt dasselbe wie die Aktion “add-header”, entfernt jedoch zuerst den Header, falls er bereits vorhanden ist. Dies ist nützlich, wenn Sicherheitsinformationen an den Server übergeben werden und der Header nicht von externen Benutzern manipuliert werden darf, oder um bestimmte Antwort-Header wie “Server” zu erzwingen und damit externe Informationen zu verbergen. Beachten Sie, dass der neue Wert vor dem Entfernen berechnet wird. So kann ein Wert an einen vorhandenen Header angehängt werden.
Beispiel:
set-headers-bin <expr> [ prefix <str> ]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Dies ist eine Variante der Aktion “set-header”, bei der die Header-Namen und -Werte als binäre Zeichenfolge mit varint-Kodierung übergeben werden. Informationen zum varint-Format finden Sie beim Sample-Abruf “req.hdrs_bin”. Dies ist nützlich, wenn mehrere Header gleichzeitig gesetzt werden sollen, ohne ihre Namen im Voraus kennen zu müssen. Beachten Sie, dass diese Header nicht vom HTTP-Parser validiert wurden. Dadurch können ungültige Nachrichten ausgegeben werden; im schlimmsten Fall kann dies Request-Smuggling-Angriffe ermöglichen. Auch die Anzahl der eingefügten Header ist relevant, da sie durch tune.http.maxhdr begrenzt wird. Wird das optionale Präfix angegeben, werden aus der kodierten Zeichenfolge nur die Header gesetzt, die mit <str> beginnen.
Beispiel:
set-log-level <level>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | X
Damit wird die Protokollierungsstufe der aktuellen Anfrage geändert, wenn eine bestimmte Bedingung erfüllt ist. Gültige Stufen sind die 8 syslog-Stufen (siehe Schlüsselwort “log”) sowie die besondere Stufe “silent”, die die Protokollierung für diese Anfrage deaktiviert. Diese Regel ist nicht abschließend; die letzte passende Regel hat daher Vorrang. Sie kann nützlich sein, um Health Checks von anderen Geräten auszublenden.
set-map(<map-name>) <key fmt> <value fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Damit wird einer Map ein neuer Eintrag hinzugefügt. <map-name> muss dem in 2.7. beschriebenen Namensformat für Maps und ACLs entsprechen. Der Name der zu aktualisierenden MAP wird in Klammern angegeben. Die Aktion nimmt 2 Argumente entgegen: <key fmt> folgt den in Abschnitt 8.2.6
beschriebenen Regeln für benutzerdefinierte Protokollformate und dient zum Ermitteln des Map-Schlüssels. <value fmt> folgt ebenfalls den Regeln für benutzerdefinierte Protokollformate und dient zum Ermitteln des Inhalts für den neuen Eintrag. Vor dem Einfügen wird die Map durchsucht, um doppelte oder mehrfach vorhandene Werte zu vermeiden. Dies entspricht dem Befehl “set map” am Statistik-Socket, kann jedoch durch eine HTTP-Anfrage ausgelöst werden.
set-mark <mark> (deprecated)
Dies ist ein Alias für “set-fc-mark”, das stattdessen verwendet werden sollte.
set-method <fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Dies überschreibt die Anfragemethode mit dem Ergebnis der Auswertung der Formatzeichenfolge <fmt>. Dafür sollte es nur sehr wenige triftige Gründe geben, da dies eher etwas beschädigt als etwas behebt.
set-nice <nice>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | -
Dies setzt den “nice”-Faktor der gerade verarbeiteten Anfrage oder Antwort. Er wirkt sich nur im Verhältnis zu anderen gleichzeitig verarbeiteten Anfragen aus. Der Standardwert ist 0, sofern er nicht durch die Einstellung “nice” in der “bind”-Zeile geändert wird. Der zulässige Bereich ist -1024..1024. Je höher der Wert, desto mehr Vorrang lässt die Anfrage anderen. Niedrigere Werte machen die Anfrage wichtiger als andere. Dies kann nützlich sein, um bestimmte Anfragen zu beschleunigen oder die Priorität unwichtiger Anfragen zu senken. Eine Verwendung dieser Einstellung ohne vorherige Erprobung kann erhebliche Verlangsamungen verursachen.
set-path <fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Dies überschreibt den Anfragepfad mit dem Ergebnis der Auswertung der
Formatzeichenfolge `<fmt>`. Eine vorhandene Abfragezeichenfolge bleibt
unverändert. Stehen vor dem Pfad ein Schema und eine Authority, bleiben
auch diese unverändert. Hat die Anfrage keinen Pfad ("*"), wird dieser
durch das Format ersetzt. Damit kann beispielsweise einem Pfad eine
Verzeichniskomponente vorangestellt werden. Siehe auch
"http-request set-query" und "http-request set-uri".
Beispiel:
set-pathq <fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Dies bewirkt dasselbe wie “http-request set-path”, schreibt jedoch auch die Abfragezeichenfolge um. Damit kann die Abfragezeichenfolge einschließlich des Fragezeichens entfernt werden; mit “http-request set-query” ist dies nicht möglich.
set-priority-class <expr>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Damit wird die Prioritätsklasse der aktuellen Anfrage in der Warteschlange gesetzt. Der Wert muss ein Sample-Ausdruck sein, der sich in eine Ganzzahl im Bereich -2047..2047 umwandeln lässt. Ergebnisse außerhalb dieses Bereichs werden auf dessen Grenzen beschränkt. Die Prioritätsklasse bestimmt die Reihenfolge, in der wartende Anfragen verarbeitet werden. Niedrigere Werte haben eine höhere Priorität.
set-priority-offset <expr>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Damit wird der Zeitstempelversatz für die Warteschlangenpriorität der aktuellen Anfrage gesetzt. Der Wert muss ein Sample-Ausdruck sein, der sich in eine Ganzzahl im Bereich -524287..524287 umwandeln lässt. Ergebnisse außerhalb dieses Bereichs werden auf dessen Grenzen beschränkt. Wird eine Anfrage in die Warteschlange aufgenommen, erfolgt ihre Einordnung zuerst nach der Prioritätsklasse und dann nach dem aktuellen Zeitstempel, korrigiert um den angegebenen Versatz in Millisekunden. Niedrigere Werte haben eine höhere Priorität. Beachten Sie, dass der resultierende Zeitstempel nur mit ausreichender Genauigkeit für 524,287ms (8m44s287ms) erfasst wird. Bleibt die Anfrage so lange in der Warteschlange, dass der korrigierte Zeitstempel diesen Wert überschreitet, wird sie fälschlich als Anfrage mit höchster Priorität erkannt. Daher ist es wichtig, “timeout queue” so zu wählen, dass der Wert zusammen mit dem Versatz diese Grenze nicht überschreitet.
set-query <fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Dies überschreibt die Abfragezeichenfolge der Anfrage nach dem ersten Fragezeichen (”?”) mit dem Ergebnis der Auswertung der Formatzeichenfolge <fmt>. Der Teil vor dem Fragezeichen bleibt unverändert. Enthält die Anfrage kein Fragezeichen und ist der neue Wert nicht leer, wird am Ende der URI ein Fragezeichen angefügt, gefolgt vom neuen Wert. War bereits ein Fragezeichen vorhanden, wird es niemals entfernt, auch nicht bei einem leeren Wert. Damit können Parameter zur Abfragezeichenfolge hinzugefügt oder daraus entfernt werden.
Siehe auch “http-request set-query” und “http-request set-uri”.
Beispiel:
set-retries <int> | <epxr>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Diese Aktion überschreibt den angegebenen Wert “retries” nur für den aktuellen Stream. Er kann eine Ganzzahl im Bereich [0, 100] oder ein Ausdruck sein, der eine Ganzzahl im Bereich [0, 100] zurückgeben muss.
Beachten Sie, dass diese Aktion nur auf der Backend-Seite relevant ist und die Regel daher nur für Proxys mit Backend-Funktion verfügbar ist. In “defaults”-Abschnitten ist sie ebenfalls nicht zulässig. Wird die Aktion für einen Listener verwendet, wird sie im Frontend-Kontext ausgewertet. Der retries-Wert bleibt daher nur erhalten, wenn der Stream nicht zu einem anderen Backend geleitet wird, etwa durch eine use-backend-Regel. Andernfalls wird der standardmäßige retries-Wert des ausgewählten Backends voreingestellt.
Beispiel:
set-src <expr>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -
Damit wird die Quell-IP-Adresse auf den Wert des angegebenen Ausdrucks gesetzt. Dies ist nützlich, wenn ein HAProxy vorgeschalteter Proxy die Quell-IP umschreibt, die korrekte IP jedoch in einem HTTP-Header bereitstellt, oder wenn Sie die Quell-IP aus Datenschutzgründen verbergen möchten. Alle nachfolgenden Aufrufe des Abrufs “src” geben diesen Wert zurück (siehe Beispiel).
Argumente:
Siehe auch “option forwardfor”.
Beispiel:
Wenn möglich, behält set-src den ursprünglichen Quellport bei, sofern die Adressfamilie dies zulässt. Andernfalls wird der Quellport auf 0 gesetzt.
set-src-port <expr>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -
Damit wird der Quellport auf den Wert des angegebenen Ausdrucks gesetzt.
Argumente:
Beispiel:
Wenn möglich, behält set-src-port die ursprüngliche Quelladresse bei, sofern die Adressfamilie einen Port unterstützt. Andernfalls setzt es die Quelladresse vor dem Umschreiben des Ports auf die IPv4-Adresse “0.0.0.0”.
set-status <status> [reason <str>]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | - | X | X
Dies ersetzt den Statuscode der Antwort durch <status>, der eine Ganzzahl zwischen 100 und 999 sein muss. Optional kann mit <str> ein individueller Begründungstext angegeben werden. Andernfalls wird ersatzweise die Standardbegründung für den angegebenen Code verwendet. Beachten Sie, dass die Begründungszeichenfolge nur in HTTP/1.x existiert und von anderen Protokollversionen ignoriert wird.
Beispiel:
set-timeout { client | connect | queue | server | tarpit | tunnel } { <timeout> | <expr> }
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Diese Aktion überschreibt die angegebene Wartezeit “client”, “connect”, “queue”, “server”, “tarpit” oder “tunnel” nur für den aktuellen Stream. Das Ändern einer Wartezeit beeinflusst keine anderen Wartezeiten, auch wenn sie beim Parsen der Konfiguration voneinander geerbt werden (siehe letztes Beispiel). Die Wartezeit kann in Millisekunden oder in einer anderen Einheit angegeben werden, wenn der Zahl wie zu Beginn dieses Dokuments beschrieben die Einheit angehängt wird. Auch ein Ausdruck kann angegeben werden; er muss eine Zahl zurückgeben, die als Wartezeit in Millisekunden interpretiert wird.
Beachten Sie, dass die Wartezeiten connect, queue, server und tunnel nur auf der Backend-Seite relevant sind und diese Regel daher nur für Proxys mit Backend-Funktion verfügbar ist. Entsprechend ist die client-Wartezeit nur auf der Frontend-Seite relevant. Die tarpit-Wartezeit ist auf beiden Seiten verfügbar. Der Wartezeitwert muss ungleich null sein, um die erwarteten Ergebnisse zu erzielen. Wird die Aktion für einen Listener verwendet, wird sie im Frontend-Kontext ausgewertet. Individuelle Werte für backendseitige Wartezeiten bleiben daher nur erhalten, wenn der Stream nicht zu einem anderen Backend geleitet wird, etwa durch eine use-backend-Regel. Andernfalls werden die Standardwerte des ausgewählten Backends voreingestellt.
Beispiel:
Beispiel:
Beispiel:
set-tos <tos> (deprecated)
Dies ist ein Alias für “set-fc-tos”, das stattdessen verwendet werden sollte.
set-uri <fmt>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Dies überschreibt die Anfrage-URI mit dem Ergebnis der Auswertung der Formatzeichenfolge <fmt>. Schema, Authority, Pfad und Abfragezeichenfolge werden gleichzeitig ersetzt. Damit können Hostangaben vor Proxys umgeschrieben oder komplexe Änderungen an der URI vorgenommen werden, etwa das Verschieben von Teilen zwischen Pfad und Abfragezeichenfolge. Wird eine absolute URI gesetzt, wird sie unverändert an HTTP/1.1-Server gesendet. Ist dieses Verhalten nicht erwünscht, sollten Host, Pfad und/oder Abfragezeichenfolge separat gesetzt werden. Siehe auch “http-request set-path” und “http-request set-query”.
set-var(<var-name>[,<cond>...]) <expr>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Damit wird der Inhalt einer Variablen gesetzt. Die Variable wird direkt an dieser Stelle deklariert.
Argumente:
Für HTTP-Regeln können alle Geltungsbereiche verwendet werden. In Regelsätzen ohne Zugriff auf Inhalte, etwa “tcp-request connection” und “tcp-request session”, sind jedoch nur die Geltungsbereiche “proc” und “sess” verwendbar.
Beispiel:
silent-drop [ rst-ttl <ttl> ]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | -
Dies beendet die Regelauswertung und lässt die dem Client zugewandte Verbindung plötzlich auf systemabhängige Weise verschwinden, wobei eine Benachrichtigung des Clients möglichst verhindert wird. Beim Aufruf ohne das Argument rst-ttl wird mit TCP_REPAIR versucht, das Zurücksenden von FIN- oder RST-Paketen an den Client zu verhindern. Schlägt dies fehl, hauptsächlich wegen fehlender Berechtigungen, wird ersatzweise ein RST-Paket mit einer TTL von 1 gesendet.
Der Client sieht dadurch weiterhin eine bestehende Verbindung, während auf HAProxy keine mehr vorhanden ist, was Ressourcen spart. Zustandsbehaftete Geräte zwischen HAProxy und dem Client, etwa Firewalls, Proxys oder Load-Balancer, behalten die bestehende Verbindung jedoch ebenfalls in ihren Sitzungstabellen.
Das optionale rst-ttl ändert dieses Verhalten: TCP_REPAIR wird nicht verwendet, und es wird ein RST-Paket mit einer konfigurierbaren TTL gesendet. Bei einem sinnvollen Wert durchläuft das RST-Paket die lokale Infrastruktur und löscht die Verbindung in Firewalls und anderen Systemen, verschwindet jedoch, bevor es den Client erreicht. Zukünftige Pakete des Clients werden dann bereits von vorgeschalteten Geräten verworfen. Diese lokalen RSTs schützen lokale Ressourcen, aber nicht die des Clients. Dies darf nur verwendet werden, wenn die Folgen vollständig verstanden wurden.
strict-mode { on | off }
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Dies aktiviert oder deaktiviert den strikten Umschreibmodus für nachfolgende Regeln. Zuvor deklarierte Regeln sind davon nicht betroffen. Der Modus gilt nur für Regeln, die Anfragen umschreiben. Ist der strikte Modus aktiviert, löst jeder Fehler beim Umschreiben einen internen Fehler aus. Andernfalls werden solche Fehler ohne Meldung ignoriert. Der strikte Umschreibmodus dient dazu, manche Umschreibungen optional zu machen, während andere durchgeführt werden müssen, damit die Anfrageverarbeitung fortgesetzt werden kann.
Standardmäßig ist der strikte Umschreibmodus aktiviert. Sein Wert wird außerdem zurückgesetzt, wenn die Auswertung eines Regelsatzes endet. Wenn Sie den Modus beispielsweise im Frontend ändern, wird der Standardmodus wiederhergestellt, sobald HAProxy mit der Auswertung der Backend-Regeln beginnt.
switch-mode http [ proto <name> ]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | - | - | -
Mit dieser Aktion wird ein Verbindungs-Upgrade durchgeführt. Derzeit werden nur HTTP-Upgrades unterstützt. Das Protokoll kann optional angegeben werden. Diese Aktion ist nur für Proxys mit Frontend-Funktion verfügbar. Das Verbindungs-Upgrade wird sofort durchgeführt; nachfolgende “tcp-request content”-Regeln werden nicht ausgewertet. Diese Upgrade-Methode sollte der impliziten Methode vorgezogen werden, die sich auf den Backend-Modus stützt. Bei ihrer Verwendung können HTTP-Direktiven ohne Warnung in einem Frontend gesetzt werden. Diese Direktiven werden bedingt ausgewertet, wenn das HTTP-Upgrade durchgeführt wird. Es muss jedoch weiterhin ein HTTP-Backend ausgewählt werden. Das Weiterleiten einer HTTP-Verbindung, mit oder ohne Upgrade, an einen TCP-Server wird weiterhin nicht unterstützt.
Weitere Einzelheiten zu HTTP-Upgrades finden Sie in Abschnitt 4 über Proxys.
tarpit [ { status | deny_status } <code>] [content-type <type>]
file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
[ hdr `<name>` `<fmt>` ]*
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Dies beendet die Regelauswertung und blockiert die Anfrage sofort, ohne zu antworten. Die Dauer wird durch “timeout tarpit” festgelegt oder, wenn dieser Wert nicht gesetzt ist, durch “timeout connect”. Ist der Client nach Ablauf dieser Zeit noch verbunden, wird eine Antwort zurückgegeben, damit er keinen Verdacht schöpft, dass er absichtlich aufgehalten wurde. In den Protokollen erscheinen die Flags “PT”. Die tarpit-Regel soll Bots während eines Angriffs verlangsamen, wenn deren Anzahl gleichzeitiger Anfragen begrenzt ist. Gegen sehr einfache Bots kann sie äußerst wirksam sein und die Last auf Firewalls gegenüber einer “deny”-Regel deutlich verringern. Gegen „korrekt“ entwickelte Bots kann sie die Lage jedoch verschlimmern, indem sie HAProxy und die vorgeschaltete Firewall zwingt, eine enorme Anzahl gleichzeitiger Verbindungen zu verwalten. Standardmäßig wird ein HTTP-Fehler 500 zurückgegeben. Die Antwort kann jedoch mit derselben Syntax wie bei “http-request return”-Regeln angepasst werden. Einzelheiten finden Sie daher unter “http-request return”.
Aus Kompatibilitätsgründen wird das Argument “default-errorfiles” impliziert, wenn kein Argument oder nur “deny_status” angegeben wird. Somit ist “http-request tarpit [deny_status <status>]” ein Alias für “http-request tarpit [status <status>] default-errorfiles”. Es werden keine weiteren “http-request”-Regeln ausgewertet. Siehe auch “http-request return” und “http-request silent-drop”.
track-sc0 <key> [table <table>]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | X | -
Dies aktiviert die Verfolgung von Sitzungsbindungszählern anhand der aktuellen Anfrage. Diese Regeln beenden weder die Auswertung noch ändern sie die Standardaktion. Die Anzahl der Zähler, die von derselben Verbindung gleichzeitig verfolgt werden können, wird durch die globale Einstellung “tune.stick-counters” festgelegt. Ihr Standardwert ist MAX_SESS_STKCTR, sofern dieser beim Erstellen gesetzt wurde; er wird in haproxy -vv ausgegeben. Dessen Standardwert ist 3, sodass die track-sc-Nummer zwischen 0 und (tune.stick-counters-1) liegt. Die erste ausgeführte Regel “track-sc0” aktiviert die Verfolgung der Zähler der angegebenen Tabelle als ersten Satz. Die erste ausgeführte Regel “track-sc1” aktiviert die Verfolgung der Zähler der angegebenen Tabelle als zweiten Satz. Die erste ausgeführte Regel “track-sc2” aktiviert die Verfolgung der Zähler der angegebenen Tabelle als dritten Satz. Es wird empfohlen, den ersten Zählersatz für Zähler pro Frontend und den zweiten für Zähler pro Backend zu verwenden. Dies ist jedoch lediglich eine Richtlinie; alle Sätze können überall verwendet werden.
Argumente:
Sobald eine “track-sc*"-Regel ausgeführt wird, wird der Schlüssel in der Tabelle gesucht. Wird er nicht gefunden, wird ein Eintrag dafür angelegt. Anschließend wird während der gesamten Lebensdauer der Sitzung ein Zeiger auf diesen Eintrag behalten. Seine Zähler werden so oft wie möglich aktualisiert, nämlich jedes Mal, wenn die Sitzungszähler aktualisiert werden, sowie grundsätzlich beim Ende der Sitzung. Zähler werden nur für Ereignisse aktualisiert, die nach Beginn der Verfolgung eintreten. Eine Ausnahme bilden Verbindungs- und Anfragezähler: Sie werden grundsätzlich aktualisiert, damit sie nützliche Informationen widerspiegeln.
Wenn der Eintrag Zähler für gleichzeitige Verbindungen verfolgt, wird eine Verbindung so lange gezählt, wie der Eintrag verfolgt wird. Während dieser Zeit läuft der Eintrag nicht ab. Das Verfolgen von Zählern bietet gegenüber dem bloßen Prüfen von Schlüsseln auch einen Leistungsvorteil, da für alle ACL-Prüfungen, die davon Gebrauch machen, nur ein Tabellenzugriff erfolgt.
unset-var(<var-name>)
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Damit wird eine Variable zurückgesetzt. Einzelheiten zu <var-name> finden Sie bei der Aktion “set-var”.
Beispiel:
use-service <service-name>
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Diese Aktion führt je nach Regelsatz, in dem sie verwendet wird, den konfigurierten TCP- oder HTTP-Dienst aus, um auf die Anfrage zu antworten. Die Regel ist abschließend, d. h. im selben Regelsatz werden keine weiteren Regeln ausgewertet.
Ein Dienst kann eine beliebige gültige Antwort senden oder die Verbindung sofort schließen, ohne eine Antwort zu senden. Bei HTTP-Diensten muss eine gültige Antwort eine gültige HTTP-Antwort sein. Neben nativen Diensten, etwa dem Prometheus-Exporter für HTTP-Dienste, können auch eigene TCP- und HTTP-Dienste in Lua geschrieben werden.
Argumente:
Beispiel:
wait-for-body time <time> [ at-least <bytes> ] [use-large-buffer]
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Dies verzögert die Verarbeitung der Anfrage oder Antwort, bis eine der folgenden Bedingungen eintritt:
- Der vollständige Anfragekörper wurde empfangen; die Verarbeitung wird normal fortgesetzt.
<bytes>Bytes wurden empfangen, wenn das Argument “at-least” angegeben und<bytes>ungleich null ist; die Verarbeitung wird normal fortgesetzt.- Der Anfragepuffer ist voll; die Verarbeitung wird normal fortgesetzt. Die Größe dieses Puffers wird durch die Option “tune.bufsize” bestimmt.
- Die Anfrage wartet seit mehr als
<time>Millisekunden. In diesem Fall antwortet HAProxy dem Client mit dem Fehler 408 “Request Timeout” und beendet die Verarbeitung der Anfrage. Beachten Sie, dass diese Zeitüberschreitung nicht eintritt, wenn zuvor eine der anderen Bedingungen erfüllt wurde, selbst wenn der vollständige Körper noch nicht empfangen wurde.
Die Option “use-large-buffer” kann gesetzt werden, um einen großen Puffer zuzuweisen, wenn der gewöhnliche Puffer zum Speichern des Nachrichtenkörpers zu klein ist. Dazu muss die globale Option “tune.bufsize.large” definiert sein.
Diese Aktion kann als Ersatz für “option http-buffer-request” verwendet werden.
Argumente:
Beispiel:
Siehe auch: “option http-buffer-request” und “tune.bufsize.large”
wait-for-handshake
Verwendbar in: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Dies verzögert die Verarbeitung der Anfrage, bis der SSL-Handshake stattgefunden hat. Dies ist hauptsächlich nützlich, um die Verarbeitung früher Daten so lange aufzuschieben, bis ihre Gültigkeit sichergestellt ist.
14 - 5. Bind- und Server-Optionen
Die Schlüsselwörter “bind”, “server” und “default-server” unterstützen je nach Build-Optionen und der Systemumgebung, auf der HAProxy gebaut wurde, eine Reihe von Einstellungen. Diese Einstellungen bestehen in der Regel aus einem Wort, gegebenenfalls gefolgt von einem Wert, und werden in derselben Zeile wie die “bind”- oder “server”-Zeile angegeben. Alle diese Optionen werden in diesem Abschnitt beschrieben.
5.1. Bind-Optionen
Das Schlüsselwort “bind” unterstützt eine bestimmte Anzahl von Einstellungen, die alle als Argumente in derselben Zeile übergeben werden. Die Reihenfolge, in der diese Argumente erscheinen, ist ohne Bedeutung, solange sie nach der Bind-Adresse stehen. Alle diese Parameter sind optional. Einige bestehen aus einem einzelnen Wort (Boolescher Wert), während andere danach einen Wert erwarten. In diesem Fall muss der Wert unmittelbar nach dem Einstellungsnamen angegeben werden.
Die derzeit unterstützten Einstellungen sind die folgenden.
accept-netscaler-cip <magic number>
Erzwingt die Verwendung des NetScaler Client IP Insertion-Protokolls für jede Verbindung, die von einem der auf derselben Zeile deklarierten TCP-Sockets akzeptiert wird. Das NetScaler Client IP Insertion-Protokoll legt die Layer-3/4-Adressen der eingehenden Verbindung fest, die überall dort verwendet werden, wo eine Adresse benötigt wird, mit der Ausnahme von „tcp-request connection“-Regeln, die nur die echte Verbindungsadresse sehen. Die Protokollausgaben spiegeln die in diesem Protokoll angegebenen Adressen wider, sofern das Protokoll nicht verletzt wird; in diesem Fall wird weiterhin die echte Adresse verwendet. Dieses Schlüsselwort, kombiniert mit Unterstützung durch externe Komponenten, kann als effizienter und zuverlässiger Ersatz für das X-Forwarded-For-Verfahren dienen, das nicht immer zuverlässig ist und nicht einmal immer verwendbar ist. Siehe auch „tcp-request connection expect-netscaler-cip“ für eine feinere Einstellung, welche Clients das Protokoll nutzen dürfen.
accept-proxy
Erzwingt die Verwendung des PROXY-Protokolls für jede Verbindung, die von einem der auf derselben Zeile deklarierten Sockets akzeptiert wird. Versionen 1 und 2 des PROXY-Protokolls werden unterstützt und korrekt erkannt. Das PROXY-Protokoll legt die Layer-3/4-Adressen der eingehenden Verbindung fest, die überall dort verwendet werden, wo eine Adresse benötigt wird, mit der Ausnahme von „tcp-request connection“-Regeln, die nur die echte Verbindungsadresse sehen. Die Protokollausgaben spiegeln die in diesem Protokoll angegebenen Adressen wider, sofern das Protokoll nicht verletzt wird; in diesem Fall wird weiterhin die echte Adresse verwendet. Dieses Schlüsselwort, kombiniert mit Unterstützung durch externe Komponenten, kann als effizienter und zuverlässiger Ersatz für das X-Forwarded-For-Verfahren dienen, das nicht immer zuverlässig ist und nicht einmal immer verwendbar ist. Siehe auch „tcp-request connection expect-proxy“ für eine feinere Einstellung, welche Clients das Protokoll nutzen dürfen.
allow-0rtt
Erlaubt den Empfang früher Daten bei Verwendung von TLSv1.3. Dies ist aus Sicherheitsgründen standardmäßig deaktiviert. Da es anfällig für Replay-Angriffe ist, sollten Sie dies nur für Anfragen zulassen, die sicher wiederholt werden können, also für idempotente Anfragen. Sie können die Aktion “wait-for-handshake” für jede Anfrage verwenden, die mit frühen Daten nicht sicher ist. Bei QUIC wird 0rtt mit QuicTLS, OpenSSL >= 3.5.2 und AWS-LC unterstützt. Bei TCP/TLS wird 0rtt nur mit OpenSSL unterstützt und erfordert, dass der Client ein ALPN sendet, andernfalls werden frühe Daten vor dem Handshake nicht berücksichtigt.
alpn <protocols>
Aktiviert die TLS-ALPN-Erweiterung und meldet die angegebene Protokollliste als unterstützte Protokolle über ALPN. Die Protokollliste besteht aus einer durch Kommas getrennten Liste von Protokollnamen, beispielsweise: “http/1.1,http/1.0” (ohne Anführungszeichen). Dies erfordert, dass die SSL-Bibliothek mit Unterstützung für TLS-Erweiterungen gebaut wurde (überprüfen Sie mit haproxy -vv). Die ALPN-Erweiterung ersetzt die ursprüngliche NPN-Erweiterung. Auf Protokollebene ist ALPN erforderlich, um HTTP/2 auf einem HTTPS-Frontend und HTTP/3 auf einem QUIC-Frontend zu aktivieren. Wenn bei solchen Frontends keine der Einstellungen “npn”, “alpn” und “no-alpn” gesetzt ist, wird für ein reguläres HTTPS-Frontend standardmäßig “h2,http/1.1” und für ein QUIC-Frontend “h3” verwendet. Versionen von OpenSSL vor 1.0.2 unterstützten ALPN nicht und unterstützten lediglich die mittlerweile veraltete NPN-Erweiterung. Zum Zeitpunkt der Erstellung dieses Dokuments unterstützen die meisten Browser weiterhin sowohl ALPN als auch NPN für HTTP/2, sodass ein Fallback auf NPN noch eine Weile funktionieren könnte. ALPN muss jedoch, wann immer möglich, verwendet werden. Protokolle, die nicht angeboten werden, werden nicht verhandelt. Es ist beispielsweise möglich, nur HTTP/2-Verbindungen zu akzeptieren:
QUIC unterstützt nur h3 und hq-interop als ALPN. h3 steht für HTTP/3 und hq-interop wird für http/0.9 und den QUIC-Interop-Runner verwendet (siehe https://interop.seemann.io ). Jede “alpn”-Anweisung ersetzt die vorherige. Um sie zu entfernen, verwenden Sie “no-alpn”.
Beachten Sie, dass einige ältere Browser wie Firefox 88 Probleme mit WebSocket über H2 hatten. Falls ein solcher Einsatz vorliegt, kann es erforderlich sein, entweder HTTP/2 in der “alpn”-Zeichenkette explizit zu deaktivieren, indem Sie es auf “http/1.1” oder “no-alpn” setzen, oder “h2-workaround-bogus-websocket-clients” global zu aktivieren.
backlog <backlog>
Legt die Backlog-Einstellung des Sockets auf diesen Wert fest. Wenn nicht angegeben oder 0, wird stattdessen der Backlog des Frontends verwendet, der in der Regel auf den Wert von maxconn festgelegt ist.
ca-file <cafile>
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie legt eine PEM-Datei fest, aus der CA-Zertifikate geladen werden, die zur Überprüfung des Clientzertifikats verwendet werden. Es ist möglich, ein Verzeichnis mit mehreren CAs zu laden; in diesem Fall versucht HAProxy, jede Datei mit den Endungen “.pem”, “.crt”, “.cer” und .crl" im Verzeichnis zu laden. Dateien, die mit einem Punkt beginnen, werden ignoriert.
Warnung: Der Parameter “@system-ca” kann anstelle von cafile verwendet werden, um die vertrauenswürdigen CAs Ihres Systems zu nutzen, wie dies bei der server-Anweisung geschieht. Sie dürfen ihn jedoch nur verwenden, wenn Sie wissen, was Sie tun. Die Konfiguration auf diese Weise bedeutet im Wesentlichen, dass der mit bind konfigurierte Listener jedes Clientzertifikat akzeptiert, das von einer der CAs auf Ihrem System generiert wurde, was äußerst unsicher ist.
ca-ignore-err [all|<errorID>,...]
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Legt eine durch Kommas getrennte Liste von Fehler-IDs fest, die bei der Überprüfung auf Tiefe > 0 ignoriert werden sollen. Es kann sich um eine numerische ID oder um den Konstantennamen (X509_V_ERR) handeln, der in der OpenSSL-Dokumentation verfügbar ist: https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html#ERROR-CODES Es wird empfohlen, den Konstantennamen zu verwenden, da der numerische Wert in neuen OpenSSL-Versionen geändert werden kann. Wenn auf ‘all’ gesetzt, werden alle Fehler ignoriert. Der SSL-Handshake wird nicht abgebrochen, wenn ein Fehler ignoriert wird.
ca-sign-file <cafile>
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie legt eine PEM-Datei fest, die sowohl das CA-Zertifikat als auch den CA-Privatschlüssel enthält, der zur Erstellung und Signierung von Serverzertifikaten verwendet wird. Dies ist eine obligatorische Einstellung, wenn die dynamische Generierung von Zertifikaten aktiviert ist. Weitere Details finden Sie unter ‘generate-certificates’.
ca-sign-pass <passphrase>
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie gibt die Passphrase für den CA-Privatschlüssel an. Diese Einstellung ist optional und wird nur verwendet, wenn die dynamische Generierung von Zertifikaten aktiviert ist. Weitere Details finden Sie unter ‘generate-certificates’.
ca-verify-file <cafile>
Diese Einstellung legt eine PEM-Datei fest, aus der CA-Zertifikate geladen werden, die zur Überprüfung des Clientzertifikats verwendet werden. Sie legt CA-Zertifikate fest, die nicht in den in der Server-Hello-Nachricht gesendeten CA-Namen enthalten sein dürfen. Typischerweise muss “ca-file” mit Zwischenzertifikaten und “ca-verify-file” mit Zertifikaten definiert werden, die die Kette abschließen, wie beispielsweise die Root-CA.
cc <algo>
Diese Einstellung ist nur auf Systemen verfügbar, die TCP_CONGESTION definieren, und wurde unter Linux und FreeBSD überprüft. Sie übernimmt den Namen eines TCP-Überlastungssteuerungsalgorithmus und richtet den Listener so ein, dass er diesen Algorithmus für alle von ihm angenommenen Verbindungen verwendet. Typische Namen sind “reno” und “cubic”; sie hängen vom Betriebssystem ab. Auf manchen Systemen können besondere Berechtigungen erforderlich sein, um bestimmte Algorithmen zu konfigurieren. Unter Linux steht die Liste verfügbarer Algorithmen im sysctl “net.ipv4.tcp_available_congestion_control”; die ohne besondere Rechte zulässigen Algorithmen stehen in “net.ipv4.tcp_allowed_congestion_control”. Für Algorithmen, die zusätzliche Berechtigungen benötigen, kann die Capability “cap_net_admin” erforderlich sein (siehe “setcap” im global-Abschnitt). Kann ein bestimmter Überlastungssteuerungsalgorithmus nicht konfiguriert werden, bleibt der Standardalgorithmus unverändert und eine Warnung meldet das Problem. Siehe auch das server-Schlüsselwort “cc” (Abschnitt 5.2 ). Beispiel:
ciphers <ciphers>
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie legt die Zeichenfolge mit der Liste der Verschlüsselungsalgorithmen (“Cipher-Suite”) fest, die beim SSL/TLS-Handshake bis einschließlich TLSv1.2 ausgehandelt werden. Das Format der Zeichenfolge ist in “man 1 ciphers” in den OpenSSL-Handbuchseiten definiert. Hintergrundinformationen und Empfehlungen finden Sie beispielsweise unter (https://wiki.mozilla.org/Security/Server_Side_TLS ) und (https://mozilla.github.io/server-side-tls/ssl-config-generator/ ). Zur Konfiguration der Verschlüsselungsalgorithmen für TLSv1.3 siehe das Schlüsselwort “ciphersuites”.
ciphersuites <ciphersuites>
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde und HAProxy mit OpenSSL 1.1.1 oder neuer gebaut wurde. Sie legt die Zeichenfolge mit der Liste der Verschlüsselungsalgorithmen (“Cipher-Suite”) fest, die beim TLSv1.3-Handshake ausgehandelt werden. Das Format der Zeichenfolge ist im Abschnitt “ciphersuites” von “man 1 ciphers” in den OpenSSL-Handbuchseiten definiert. Zur Konfiguration der Verschlüsselungsalgorithmen für TLSv1.2 und ältere Versionen siehe das Schlüsselwort “ciphers”. Diese Einstellung akzeptiert möglicherweise TLSv1.2-Cipher-Suites; dieses Verhalten ist jedoch nicht dokumentiert und wird nicht empfohlen, da es inkonsistent oder fehlerhaft sein könnte. Die standardmäßigen TLSv1.3-Cipher-Suites von OpenSSL sind: “TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256”
TLSv1.3 unterstützt nur 5 Cipher-Suites:
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_AES_128_CCM_SHA256
- TLS_AES_128_CCM_8_SHA256
Beispiel:
client-sigalgs <sigalgs>
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie legt die Zeichenfolge mit der Liste der ausgehandelten Signaturalgorithmen für die Clientauthentifizierung fest. Das Format der Zeichenfolge ist in “man 3 SSL_CTX_set1_client_sigalgs” in den OpenSSL-Handbuchseiten definiert. Ohne konkreten Anwendungsfall wird von dieser Einstellung abgeraten.
crl-file <crlfile>
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie gibt eine PEM-Datei an, aus der die zur Überprüfung des Clientzertifikats verwendete Zertifikatssperrliste geladen wird. Für jedes Zertifikat in Ihrer Zertifizierungsstellenkette muss eine Zertifikatssperrliste bereitgestellt werden.
crt <cert>
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde.
HAProxy verwendet einen Cache: Dateien werden nur einmal in den Zertifikatsspeicher geladen; jedes weitere Schlüsselwort “crt” verwendet diese zwischengespeicherte Version. Wurde das Zertifikat in einem “crt-store” deklariert, wird der Zertifikatsspeicher von dort befüllt. Es wird dann nicht versucht, anhand von Dateierweiterungen zusätzliche Dateien zu laden.
Die Einstellung gibt eine PEM-Datei an, die sowohl die erforderlichen Zertifikate als auch die zugehörigen privaten Schlüssel enthält. Diese Datei kann durch Zusammenfügen mehrerer PEM-Dateien erstellt werden (z. B. cat cert.pem key.pem > combined.pem). Benötigt Ihre CA ein Zwischenzertifikat, kann dieses ebenfalls an die Datei angehängt werden. Zwischenzertifikate können auch über die Direktive “issuers-chain-path” gemeinsam in einem Verzeichnis bereitgestellt werden.
Enthält die Datei keinen privaten Schlüssel, versucht HAProxy, den Schlüssel unter demselben Pfad mit der angehängten Endung “.key” zu laden.
Unterstützt die verwendete OpenSSL-Version Diffie-Hellman, werden die in dieser Datei enthaltenen Parameter geladen.
Wird statt einer PEM-Datei ein Verzeichnisname verwendet, werden alle Dateien dieses Verzeichnisses in alphabetischer Reihenfolge geladen, außer ihre Namen enden auf ‘.key’, ‘.issuer’, ‘.ocsp’ oder ‘.sctl’ (reservierte Erweiterungen). Dateien, deren Namen mit einem Punkt beginnen, werden ebenfalls ignoriert. Die Direktive kann mehrfach angegeben werden, um Zertifikate aus mehreren Dateien oder Verzeichnissen zu laden. Die Zertifikate werden Clients präsentiert, die ein gültiges TLS-Feld Server Name Indication übermitteln, das zu einem ihrer CN oder alternativen Subjektnamen passt. Platzhalter werden unterstützt; dabei ersetzt das Platzhalterzeichen ‘*’ den ersten Bestandteil des Hostnamens (z. B. passt *.example.org zu www.example.org , aber nicht zu www.sub.example.org ). Bei einem leeren Verzeichnis startet HAProxy nur, wenn das Schlüsselwort “strict-sni” verwendet wird.
Übermittelt der Client keine SNI, unterstützt die SSL-Bibliothek keine TLS-Erweiterungen oder übermittelt der Client einen SNI-Hostnamen, der zu keinem Zertifikat passt, wird das zuerst geladene Zertifikat präsentiert. Beim Laden von Zertifikaten aus einem Verzeichnis wird daher dringend empfohlen, das Standardzertifikat zuerst als Datei zu laden oder sicherzustellen, dass es stets die erste Datei im Verzeichnis ist. Zur Auswahl mehrerer Standardzertifikate (1 rsa und 1 ecdsa) gibt es 3 Möglichkeiten:
- Ein Zertifikatsbündel kann als erstes Zertifikat konfiguriert werden (
crt foobar.pemin der Konfiguration, wobei die vorhandenen Dateienfoobar.pem.ecdsaundfoobar.pem.rsasind). - Oder für jedes Zertifikat ein Filter ‘*’ in einer crt-list-Zeile.
- Das Schlüsselwort ‘default-crt’ kann verwendet werden.
Dasselbe Zertifikat kann ohne Nebenwirkungen mehrfach geladen werden.
Einige CAs (wie GoDaddy) bieten beim Bezug eines Zertifikats eine Auswahlliste von Servertypen an, in der HAProxy fehlt. Wählen Sie in diesem Fall unbedingt einen Webserver, für den die CA ein Zwischenzertifikat voraussetzt (bei GoDaddy liefert die Auswahl Apache Tomcat das richtige Bündel; viele andere, z. B. NGINX, ergeben dagegen ein falsches Bündel, das bei manchen Clients nicht funktioniert).
HAProxy prüft für jede PEM-Datei, ob eine Datei unter demselben Pfad mit der angehängten Endung “.ocsp” vorhanden ist. Wird eine solche Datei gefunden, wird die Unterstützung für die TLS-Erweiterung Certificate Status Request (auch als “OCSP stapling” bekannt) automatisch aktiviert. Der Inhalt dieser Datei ist optional. Ist sie nicht leer, muss sie eine gültige OCSP-Antwort im DER-Format enthalten. Eine gültige OCSP-Antwort muss folgende Regeln erfüllen: Sie muss den Status good anzeigen, eine einzelne Antwort für das Zertifikat der PEM-Datei enthalten und zum Zeitpunkt des Hinzufügens gültig sein. Werden diese Regeln nicht eingehalten, wird die OCSP-Antwort ignoriert und eine Warnung ausgegeben. Um festzustellen, für welches Zertifikat eine OCSP-Antwort gilt, wird das Zertifikat des Ausstellers benötigt. Wird dieses in der PEM-Datei nicht gefunden, wird es aus einer Datei mit dem Pfad der PEM-Datei und der angehängten Endung “.issuer” geladen, sofern diese vorhanden ist. Andernfalls schlägt der Vorgang mit einem Fehler fehl.
HAProxy prüft für jede PEM-Datei außerdem, ob eine Datei unter demselben Pfad mit der angehängten Endung “.sctl” vorhanden ist. Wird eine solche Datei gefunden, wird die Unterstützung für die TLS-Erweiterung Certificate Transparency (RFC6962) aktiviert. Die Datei muss eine gültige Signed Certificate Timestamp List enthalten, wie im RFC beschrieben. Beim Einlesen wird die grundlegende Syntax geprüft, jedoch werden keine Signaturen verifiziert.
In manchen Fällen ist es sinnvoll, in den für Clients angebotenen Cipher-Suites mehrere Schlüsseltypen zu unterstützen, etwa RSA und ECDSA. So können Clients, die EC-Zertifikate unterstützen, EC-Verschlüsselungsalgorithmen nutzen, während zugleich ältere Clients unterstützt werden, die nur RSA beherrschen.
Dafür ist OpenSSL 1.1.1 erforderlich. Sie können dieses Verhalten konfigurieren, indem Sie für jeden Zertifikatstyp einen crt-Eintrag angeben oder ein Zertifikatsbündel konfigurieren, wie es vor HAProxy 1.8 erforderlich war. Siehe “ssl-load-extra-files”.
crt-ignore-err <errors>
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie legt eine durch Kommas getrennte Liste von Fehler-IDs fest, die bei der Überprüfung in der Tiefe == 0 ignoriert werden. Dies kann eine numerische ID oder der Konstantenname (X509_V_ERR) aus der OpenSSL-Dokumentation sein: https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html#ERROR-CODES Es wird empfohlen, den Konstantennamen zu verwenden, da sich der numerische Wert in neuen OpenSSL-Versionen ändern kann. Beim Wert ‘all’ werden alle Fehler ignoriert. Wird ein Fehler ignoriert, wird der SSL-Handshake nicht abgebrochen.
crt-list <file>
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie gibt eine Liste von PEM-Dateien mit einer optionalen ssl-Konfiguration und einem SNI-Filter pro Zertifikat an. Jede Zeile hat das folgende Format:
Leerzeilen und Zeilen, die mit einem Rautezeichen (’#’) beginnen, werden ignoriert.
Die crt-list kann dynamisch über den Statistik-Socket bearbeitet werden. (Siehe “add ssl crt-list”, “del ssl crt-list” und “show ssl crt-list” im Verwaltungshandbuch.)
crt-list sind normalerweise eigene Dateien. Ein über die Direktive “crt” geladenes Verzeichnis wird intern jedoch ebenfalls als crt-list dargestellt. Die Direktive “ssl-f-use” in einem Frontend deklariert außerdem eine mit diesem Frontend verknüpfte crt-list.
crtfile:
sslbindconf:
snifilter:
Beispiel:
default-crt <cert>
Diese Option wirkt wie die Option “crt”; zusätzlich wird dieses Zertifikat jedoch als Standardzertifikat verwendet. Es können mehrere Standardzertifikate hinzugefügt werden, um sowohl ein ECDSA- als auch ein RSA-Zertifikat bereitzustellen. Weitere Zertifikate sind kaum sinnvoll.
Diese Option deaktiviert implizite Standardzertifikate nicht. Wird zuerst ein ‘crt’-Zertifikat vor allen ‘default-crt’- oder weiteren ‘crt’-Angaben deklariert, wird es weiterhin als Standardzertifikat verwendet.
Ein Standardzertifikat wird verwendet, wenn in der bind-Zeile keine Option “strict-sni” angegeben ist. Es wird bereitgestellt, wenn der Client die servername-Erweiterung nicht verwendet hat oder wenn servername zu keinem konfigurierten Zertifikat passt.
Beispiel:
Siehe auch das Schlüsselwort “crt”.
curves <curves>
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie legt die Zeichenfolge mit der Liste elliptischer Kurvenalgorithmen (“Kurvensuite”) fest, die beim SSL/TLS-Handshake mit ECDHE ausgehandelt werden. Die Zeichenfolge ist eine durch Doppelpunkte getrennte Liste von Kurvennamen, beispielsweise “X25519:P-256” (ohne Anführungszeichen). Ist “curves” gesetzt, wird der Parameter “ecdhe” ignoriert.
defer-accept
Ist ein optionales Schlüsselwort, das nur auf bestimmten Linux-Kerneln unterstützt wird. Es legt fest, dass eine Verbindung erst akzeptiert wird, sobald Daten eintreffen, oder spätestens nach der ersten Neuübertragung. Dies sollte nur bei Protokollen verwendet werden, bei denen der Client zuerst Daten sendet (z. B. HTTP). Es kann die Leistung leicht verbessern, indem sichergestellt wird, dass der Großteil der Anfrage bereits verfügbar ist, wenn die Verbindung akzeptiert wird. Andererseits kann es keine Verbindungen erkennen, über die keine Daten gesendet werden. Es ist wichtig zu beachten, dass diese Option in allen Kerneln bis einschließlich 2.6.31 fehlerhaft ist, da die Verbindung erst akzeptiert wird, wenn der Client Daten sendet. Dies kann Probleme mit vorgeschalteten Firewalls verursachen, die eine aufgebaute Verbindung sehen, während der Proxy sie nur im Zustand SYN_RECV sieht. Diese Option wird nur auf TCPv4/TCPv6-Sockets unterstützt und von anderen ignoriert.
ecdhe <named curve>
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie legt die benannte Kurve (RFC 4492) fest, die zum Generieren von ephemeren ECDH-Schlüsseln verwendet wird. Standardmäßig wird die benannte Kurve prime256v1 verwendet.
ech <dir> [ EXPERIMENTAL ]
Wendet alle ECH-Schlüssel aus <dir> auf die bind-Zeile an. Die Dateien müssen die Erweiterung .ech haben und das PEM-Dateiformat für ECH verwenden. ( https://datatracker.ietf.org/doc/draft-farrell-tls-pemesni/
)
Dieses Schlüsselwort aktiviert ECH im Shared-Modus, wobei HAProxy sowohl TLS-Endpunkt als auch ECH-Endpunkt ist. Siehe https://datatracker.ietf.org/doc/draft-ietf-tls-esni/
Dies ist eine experimentelle Funktion, die die Option “expose-experimental-directives” im globalen Abschnitt erfordert. Außerdem wird eine OpenSSL-Version benötigt, die ECH unterstützt ( https://github.com/openssl/openssl/tree/feature/ech ), und HAProxy muss mit USE_ECH=1 kompiliert sein. Die ECH-API von AWS-LC wird nicht unterstützt.
Beispiel:
expose-fd listeners
Diese Option ist nur mit dem Statistik-Socket verwendbar. Sie ermöglicht dem Statistik-Socket, Dateideskriptoren (FD) der Listener an einen anderen HAProxy-Prozess weiterzuleiten. Im Master-Worker-Modus ist dies nicht mehr erforderlich, da die Listener über interne Socket-Paare zwischen Master und Workern übertragen werden. Siehe auch “-x” im Verwaltungshandbuch.
force-sslv3
Erzwingt für die von diesem Listener aufgebauten SSL-Verbindungen die ausschließliche Verwendung von SSLv3. SSLv3 ist im Allgemeinen weniger kostspielig als die TLS-Gegenstücke bei hohen Verbindungsraten. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar. Siehe auch “ssl-min-ver” und “ssl-max-ver”.
force-tlsv10
Erzwingt für die von diesem Listener aufgebauten SSL-Verbindungen die ausschließliche Verwendung von TLSv1.0. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar. Siehe auch “ssl-min-ver” und “ssl-max-ver”.
force-tlsv11
Erzwingt für die von diesem Listener aufgebauten SSL-Verbindungen die ausschließliche Verwendung von TLSv1.1. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar. Siehe auch “ssl-min-ver” und “ssl-max-ver”.
force-tlsv12
Erzwingt für die von diesem Listener aufgebauten SSL-Verbindungen die ausschließliche Verwendung von TLSv1.2. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar. Siehe auch “ssl-min-ver” und “ssl-max-ver”.
force-tlsv13
Erzwingt für die von diesem Listener aufgebauten SSL-Verbindungen die ausschließliche Verwendung von TLSv1.3. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar. Siehe auch “ssl-min-ver” und “ssl-max-ver”.
generate-certificates
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie aktiviert die dynamische Generierung von SSL-Zertifikaten. Ein CA-Zertifikat und dessen privater Schlüssel sind erforderlich (siehe ‘ca-sign-file’). Wenn HAProxy als transparenter Forward-Proxy konfiguriert ist, treten bei SSL-Anfragen Fehler auf, weil der Common Name des dem Client präsentierten Zertifikats nicht übereinstimmt. Mit dieser Option versucht HAProxy, ein Zertifikat unter Verwendung des vom Client angegebenen SNI-Hostnamens zu erzeugen. Dies geschieht nur, wenn kein Zertifikat zum SNI-Hostnamen passt (siehe ‘crt-list’).
Im Fall eines Fehlers bei der Zertifikaterzeugung fällt die Verbindung auf das Standardzertifikat zurück. Wenn ‘strict-sni’ verwendet wird, wird das Standardzertifikat nicht verwendet, und die Verbindung führt zu einem Handshake-Fehler.
Sie kann auch verwendet werden, wenn HAProxy als Reverse-Proxy konfiguriert ist, um die Bereitstellung einer Architektur mit vielen Backends zu vereinfachen.
Das Erstellen eines SSL-Zertifikats ist eine aufwändige Operation, daher wird ein LRU-Cache verwendet, um nachgebildete Zertifikate zu speichern (siehe ’tune.ssl.ssl-ctx-cache-size’). Dies erhöht den Speicherverbrauch von HAProxy, um die Latenz zu reduzieren, wenn dasselbe Zertifikat häufig verwendet wird.
gid <gid>
Legt die Gruppe der Unix-Sockets auf die angegebene System-GID fest. Sie kann auch standardmäßig im globalen Abschnitt über die “unix-bind”-Anweisung gesetzt werden. Beachten Sie, dass einige Plattformen dies ignorieren. Diese Einstellung ist äquivalent zur “group”-Einstellung, unterscheidet sich jedoch dadurch, dass die Gruppen-ID anstelle des Namens verwendet wird. Diese Einstellung wird von nicht-Unix-Sockets ignoriert.
group <group>
Legt die Gruppe der Unix-Sockets auf die angegebene Systemgruppe fest. Sie kann auch standardmäßig im globalen Abschnitt über die “unix-bind”-Anweisung gesetzt werden. Beachten Sie, dass einige Plattformen dies ignorieren. Diese Einstellung ist äquivalent zur “gid”-Einstellung, unterscheidet sich jedoch dadurch, dass der Gruppenname anstelle der GID verwendet wird. Diese Einstellung wird von nicht-Unix-Sockets ignoriert.
guid-prefix <string>
Erzeugt für jeden dieser bind-Zeile zugewiesenen lauschenden Socket global eindeutige IDs, bei denen Groß- und Kleinschreibung unterschieden wird. Das Präfix wird mit dem Index der Listenerposition auf der aktuellen bind-Zeile verbunden, getrennt durch das Zeichen ‘-’. Weitere Informationen zum Format finden Sie in der Beschreibung des proxy-Schlüsselworts “guid”. Siehe auch “shm-stats-file”.
id <id>
Fixiert die Socket-ID. Standardmäßig werden Socket-IDs automatisch zugewiesen, aber manchmal ist es zweckmäßiger, sie festzulegen, um die Überwachung zu erleichtern. Der Wert muss strikt positiv und innerhalb des Listeners/Frontends eindeutig sein. Diese Option kann nur verwendet werden, wenn nur ein einzelner Socket definiert wird.
idle-ping <delay>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Definiert ein Intervall für regelmäßige Erreichbarkeitsprüfungen bei inaktiven Frontend-Verbindungen. Wenn die Gegenstelle vor der nächsten geplanten Prüfung nicht antworten kann, wird die Verbindung geschlossen. Andernfalls wird der Timer für die Client-Zeitüberschreitung neu gestartet und die Verbindung bleibt bestehen. Beachten Sie, dass http-request/http-keep-alive-Timer parallel laufen und nicht durch idle-ping zurückgesetzt werden.
Diese Funktion beruht auf spezifischer Unterstützung durch das zugrundeliegende Protokoll. Derzeit implementiert nur der H2-Multiplexer diese Funktion. idle-ping wird von anderen Protokollen einfach ignoriert.
Diese Option ist besonders nützlich bei der Verwendung von Reverse-HTTP. Die Einstellung auf der bind-Zeile ist nützlich für den Peer, der für die aktive Herstellung von Verbindungen verantwortlich ist und dann eingehenden Datenverkehr über sie empfängt.
interface <interface>
Beschränkt den Socket auf eine bestimmte Schnittstelle. Wenn angegeben, werden nur Pakete, die von dieser spezifischen Schnittstelle empfangen wurden, vom Socket verarbeitet. Dies wird derzeit nur unter Linux unterstützt. Die Schnittstelle muss eine primäre Systemschnittstelle sein, keine aliasierte Schnittstelle. Es ist auch möglich, mehrere Frontends an dieselbe Adresse zu binden, wenn sie an unterschiedliche Schnittstellen gebunden sind. Beachten Sie, dass die Bindung an eine Netzwerkschnittstelle root-Rechte erfordert. Dieser Parameter ist nur mit TCPv4/TCPv6-Sockets kompatibel. Wenn angegeben, verwendet der Rückverkehr dieselbe Schnittstelle wie der eingehende Verkehr und deren zugehörige Routing-Tabelle, selbst wenn explizite Routen über verschiedene Schnittstellen konfiguriert sind. Dies kann nützlich sein, um asymmetrische Routing-Probleme zu beheben, wenn dieselben Client-IP-Adressen auf Frontends auf unterschiedlichen Schnittstellen zugreifen müssen.
ktls <on|off> [ EXPERIMENTAL ]
Aktiviert oder deaktiviert kTLS für diese Sockets. Wenn aktiviert, wird kTLS verwendet, falls der Kernel dies unterstützt und der Verschlüsselungsalgorithmus kompatibel ist. Dies ist nur auf Linux-Kerneln ab 4.17 verfügbar. Bitte beachten Sie, dass einige Netztreiber und/oder TLS-Stacks die Verwendung von kTLS auf TLS v1.2 beschränken können. Siehe auch “force-tlsv12”.
label <label>
Legt ein optionales Label für diese Sockets fest. Es kann verwendet werden, um Sockets nach Label zu gruppieren, unabhängig davon, wo die bind-Zeilen deklariert wurden.
level <level>
Diese Einstellung wird ausschließlich mit Statistik-Sockets verwendet, um die Art der Befehle zu beschränken, die auf dem Socket ausgeführt werden dürfen. Sie wird von anderen Sockets ignoriert. <level> kann einer der folgenden Werte sein:
- “user” ist die geringste Berechtigungsstufe; nur nicht sensible Statistiken können gelesen werden, und keine Änderungen sind erlaubt. Dies ist auf Systemen sinnvoll, bei denen der Zugriff auf den Socket nicht einfach eingeschränkt werden kann.
- “operator” ist die Standardstufe und eignet sich für die meisten gängigen Anwendungsfälle. Alle Daten können gelesen werden, und nur nicht sensible Änderungen sind erlaubt (z. B. Zurücksetzen der Max-Zähler).
- “admin” sollte mit Vorsicht verwendet werden, da alles erlaubt ist (z. B. Zurücksetzen aller Zähler).
maxconn <maxconn>
Beschränkt die Sockets auf diese Anzahl gleichzeitiger Verbindungen. Zusätzliche Verbindungen verbleiben im Backlog des Systems, bis eine Verbindung freigegeben wird. Wenn nicht angegeben, entspricht der Grenzwert dem Wert von maxconn des Frontends. Beachten Sie, dass bei Portbereichen oder mehreren Adressen der gleiche Wert für jeden Socket angewendet wird. Diese Einstellung ermöglicht unterschiedliche Beschränkungen für kostspielige Sockets, beispielsweise SSL-Einträge, die leicht den gesamten Speicher verbrauchen können.
mode <mode>
Legt die oktale Berechtigungsstufe für den Unix-Socket fest. Sie kann auch standardmäßig in der globalen Abschnitt mittels der “unix-bind”-Anweisung gesetzt werden. Beachten Sie, dass einige Plattformen diese Einstellung einfach ignorieren. Diese Einstellung wird von nicht-Unix-Sockets ignoriert.
mss <maxseg>
Legt den TCP-Maximum-Segment-Size (MSS)-Wert fest, der bei eingehenden Verbindungen angeboten wird. Dies kann verwendet werden, um eine niedrigere MSS für bestimmte Ports zu erzwingen, beispielsweise für Verbindungen, die durch ein VPN laufen. Beachten Sie, dass dies von einer Kernel-Funktion abhängt, die theoretisch unter Linux unterstützt wird, aber in allen Versionen vor 2.6.28 fehlerhaft war. Es kann auf anderen Betriebssystemen funktionieren oder nicht. Es kann auch vorkommen, dass sich der angebotene Wert nicht ändert, sondern nur die tatsächliche Größe ausgehender Segmente. Der üblicherweise angebotene Wert für TCPv4 über Ethernet-Netzwerke beträgt 1460 = 1500(MTU) - 40(IP+TCP). Wenn dieser Wert positiv ist, wird er als angebotene MSS verwendet. Wenn er negativ ist, gibt er an, um wie viel die angebotene MSS der eingehenden Verbindung für ausgehende Segmente reduziert werden soll. Dieser Parameter ist nur mit TCP v4/v6-Sockets kompatibel.
name <name>
Legt einen optionalen Namen für diese Sockets fest, der auf der Statistikseite angezeigt wird.
namespace <name>
Unter Linux ist es möglich, anzugeben, welchem Netzwerknamensraum ein Socket angehört. Diese Anweisung ermöglicht es, einen Listener explizit an einen anderen Namensraum als den Standardnamensraum zu binden. Weitere Informationen zu Netzwerknamensräumen finden Sie in der Dokumentation Ihres Betriebssystems.
nbconn <nbconn> [ EXPERIMENTAL ]
Diese Einstellung ist nur für Listener-Instanzen gültig, die Reverse HTTP verwenden. Sie definiert die Anzahl der Verbindungen, die parallel aufgebaut werden. Wenn nicht angegeben, wird ein Standardwert von 1 verwendet.
Reverse HTTP ist derzeit noch in aktiver Entwicklung. Die Konfigurationsmechanismus kann sich zukünftig ändern. Aus diesem Grund ist sie intern als experimentell markiert, was bedeutet, dass “expose-experimental-directives” vor dieser Anweisung auf einer Zeile stehen muss.
nice <nice>
Legt die ’niceness’ der von diesem Socket initiierten Verbindungen fest. Der Wert muss im Bereich -1024..1024 inklusive liegen und hat standardmäßig den Wert null. Positive Werte bedeuten, dass solche Verbindungen anderen gegenüber freundlicher sind und leichter ihren Platz im Scheduler abgeben. Im Gegensatz dazu bedeuten negative Werte, dass Verbindungen eine höhere Priorität als andere haben möchten. Der Unterschied tritt nur unter hoher Last auf, wenn das System nahe an der Sättigung ist. Negative Werte sind für Low-Latency- oder Verwaltungsdienste geeignet, und hohe Werte werden allgemein für CPU-intensive Aufgaben wie SSL-Verarbeitung oder Massentransfers empfohlen, die weniger empfindlich gegenüber Latenz sind. Beispielsweise könnte es sinnvoll sein, einen positiven Wert für einen SMTP-Socket und einen negativen Wert für einen RDP-Socket zu verwenden.
no-alpn
Deaktiviert die ALPN-Verarbeitung (technisch gesehen wird die ALPN-Zeichenkette auf eine leere Zeichenkette gesetzt, die nicht angeboten wird). Damit kann eine vorherige Einstellung von “alpn” rückgängig gemacht und die Aushandlung des Anwendungsprotokolls deaktiviert werden. Es kann auch verwendet werden, um zu verhindern, dass ein Listener mit einem Client auf einem HTTPS- oder QUIC-Listener ALPN aushandelt; standardmäßig bieten HTTPS-Listener “h2,http/1.1” an und QUIC-Listener bieten “h3”. Siehe auch “alpn” oben. Beachten Sie, dass bei Verwendung von “crt-list” ein Zertifikat die “alpn”-Einstellung überschreiben und die Verarbeitung wieder aktivieren kann.
no-ca-names
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie verhindert, dass CA-Namen in der Server-Hello-Nachricht gesendet werden, wenn ca-file verwendet wird. Verwenden Sie “ca-verify-file” anstelle von “ca-file” mit “no-ca-names”.
no-sslv3
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie deaktiviert die Unterstützung für SSLv3 auf allen Sockets, die vom Listener erzeugt werden, wenn SSL unterstützt wird. Beachten Sie, dass SSLv2 im Code zwangsweise deaktiviert ist und nicht durch eine Konfigurationseinstellung aktiviert werden kann. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar. Verwenden Sie stattdessen “ssl-min-ver” und “ssl-max-ver”.
no-strict-sni
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie deaktiviert die strikte SNI-Prüfung, die durch eine vorherige “strict-sni”-Anweisung festgelegt wurde. Dies kann erforderlich sein, um die strikte SNI-Nutzung selektiv auf einer “bind”-Zeile zu deaktivieren, wenn sie bereits global über “ssl-default-bind-options” erzwungen wurde. Siehe auch die bind-Option “strict-sni”.
no-tls-tickets
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie deaktiviert die zustandslose Sitzungswiederaufnahme (RFC 5077 TLS Ticket-Erweiterung) und zwingt zur zustandsbasierten Sitzungswiederaufnahme. Die zustandslose Sitzungswiederaufnahme ist rechenintensiver. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar. Der TLS-Ticket-Mechanismus wird nur bis zu TLS 1.2 verwendet. Forward Secrecy ist mit TLS-Tickets beeinträchtigt, es sei denn, die Ticket-Schlüssel werden regelmäßig rotiert (durch Neuladen oder durch Verwendung von “tls-ticket-keys”).
no-tlsv10
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie deaktiviert bei SSL-Unterstützung TLSv1.0 auf allen vom Listener erzeugten Sockets. Beachten Sie, dass SSLv2 im Code zwangsweise deaktiviert ist und durch keine Konfigurationsoption aktiviert werden kann. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar. Verwenden Sie stattdessen “ssl-min-ver” und “ssl-max-ver”.
no-tlsv11
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie deaktiviert bei SSL-Unterstützung TLSv1.1 auf allen vom Listener erzeugten Sockets. Beachten Sie, dass SSLv2 im Code zwangsweise deaktiviert ist und durch keine Konfigurationsoption aktiviert werden kann. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar. Verwenden Sie stattdessen “ssl-min-ver” und “ssl-max-ver”.
no-tlsv12
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie deaktiviert bei SSL-Unterstützung TLSv1.2 auf allen vom Listener erzeugten Sockets. Beachten Sie, dass SSLv2 im Code zwangsweise deaktiviert ist und durch keine Konfigurationsoption aktiviert werden kann. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar. Verwenden Sie stattdessen “ssl-min-ver” und “ssl-max-ver”.
no-tlsv13
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie deaktiviert bei SSL-Unterstützung TLSv1.3 auf allen vom Listener erzeugten Sockets. Beachten Sie, dass SSLv2 im Code zwangsweise deaktiviert ist und durch keine Konfigurationsoption aktiviert werden kann. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar. Verwenden Sie stattdessen “ssl-min-ver” und “ssl-max-ver”.
npn <protocols>
Aktiviert die TLS-Erweiterung NPN und bietet die angegebene Protokollliste über NPN als unterstützt an. Die Protokollliste besteht aus durch Kommas getrennten Protokollnamen, beispielsweise “http/1.1,http/1.0” (ohne Anführungszeichen). Dafür muss die SSL-Bibliothek mit aktivierter Unterstützung für TLS-Erweiterungen gebaut worden sein (mit haproxy -vv prüfen). Beachten Sie, dass die NPN-Erweiterung durch die ALPN-Erweiterung ersetzt wurde (siehe das Schlüsselwort “alpn”), die allerdings erst ab OpenSSL 1.0.2 verfügbar ist. Wird HTTP/2 mit einer älteren OpenSSL-Version gewünscht, kann weiterhin NPN verwendet werden, da die meisten Clients es zum Zeitpunkt der Erstellung dieses Textes noch unterstützen. NPN und ALPN lassen sich auch gemeinsam aktivieren, was außerhalb von Tests jedoch vermutlich nicht sinnvoll ist.
prefer-client-ciphers
Verwendet bei der Auswahl der Cipher-Suite die Präferenz des Clients; standardmäßig wird die Präferenz des Servers durchgesetzt. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar.
Beachten Sie, dass mit OpenSSL >= 1.1.1 ChaCha20-Poly1305 ohnehin höher priorisiert wird (auch ohne diese Option), wenn ein ChaCha20-Poly1305-Cipher an erster Stelle der Cipher-Liste des Clients steht.
Bei einer Konfiguration mit zwei Algorithmen (RSA + ECDSA) wählt der Auswahlalgorithmus zwischen RSA und ECDSA und bevorzugt dabei immer ECDSA. Sobald das passende Zertifikat gewählt wurde, überlässt er der SSL-Bibliothek die Priorisierung von Ciphers, Kurven usw. Diese Option kann somit nicht verwendet werden, um ein RSA-Zertifikat gegenüber einem ECDSA-Zertifikat zu bevorzugen.
proto <name>
Erzwingt das Multiplexer-Protokoll für eingehende Verbindungen. Es muss mit dem Modus des Frontends (TCP oder HTTP) kompatibel sein. Außerdem muss es auf der Frontend-Seite verwendbar sein. Die Liste verfügbarer Protokolle wird von haproxy -vv ausgegeben. Angezeigt werden die Protokolleigenschaften: der Modus (TCP/HTTP), die Seite (FE/BE), der Name des Multiplexers und seine Flags.
Bei manchen Protokollen kann auf der Serverseite Head-of-Line-Blocking auftreten (flag=HOL_RISK). Einige Protokolle unterstützen außerdem keine Upgrades (flag=NO_UPG). Auch die HTX-Kompatibilität wird angegeben (flag=HTX).
Die folgenden Protokolle können als Argument einer “proto”-Direktive in einer bind-Zeile verwendet werden:
Mit dieser Option wird für alle von diesem lauschenden Socket erzeugten Verbindungen die Auswahl des am besten geeigneten Multiplexer-Protokolls umgangen. Beispielsweise lässt sich http/2 über unverschlüsseltem TCP erzwingen, indem in der bind-Zeile “proto h2” angegeben wird.
Wenn ALPN oder NPN konfiguriert ist, sollten die angegebenen Protokolle mit dem Multiplexer-Protokoll kompatibel sein, um Probleme zu vermeiden. Ist beispielsweise “proto h1” gesetzt, sollte ALPN nicht auf “h2” gesetzt werden.
QMux ist eine Teilmenge von QUIC, die über TCP läuft. Sie entspricht dem folgenden Protokollentwurf: https://www.ietf.org/archive/id/draft-ietf-quic-qmux-01.html . In haproxy gilt sie derzeit als experimentell.
quic-cc-algo { cubic | newreno | bbr | nocc }[(<args,...>)]
Diese QUIC-spezifische Einstellung wählt den Algorithmus zur Überlastkontrolle für alle Verbindungsversuche zu den konfigurierten QUIC-Listenern. Die Algorithmen ähneln denen von TCP.
Zusätzlich zum Algorithmus zur Überlastkontrolle ist Pacing aktiviert, um Paketverluste zu verringern und den Durchsatz zu verbessern. Es kann mit dem globalen Schlüsselwort “tune.quic.fe.tx.pacing” deaktiviert werden. In den meisten Fällen sollte Pacing aktiviert bleiben, insbesondere bei BBR, da dessen ordnungsgemäße Funktion davon abhängt. BBR ohne Pacing kann bei Übertragungen zu Verlangsamungen oder hohen Verlustraten führen.
Standardwert: cubic
Zur weiteren Anpassung kann nach dem Algorithmus eine Liste von Parametern angegeben werden. Sie muss in Klammern und durch Kommas getrennt geschrieben werden. Jedes Argument ist optional und kann bei Bedarf leer bleiben. Die Parameter müssen in folgender Reihenfolge stehen:
- maximale Fenstergröße in Bytes. Sie muss größer als 10k und kleiner als 4g sein. Standardmäßig wird der Wert von “tune.quic.fe.cc.max-win-size” verwendet.
Beispiel:
Mit dem besonderen Wert “nocc” kann ein festes Überlastfenster erzwungen werden, das immer auf die maximale Größe gesetzt ist. Dies ist für die Fehlersuche vorgesehen, um alle Nebeneffekte des Algorithmus zur Überlastkontrolle auszuschließen. Es darf nicht in der Produktion verwendet werden, da es schnell zu Netzwerkproblemen wie hohen Verlustraten führen kann.
quic-force-retry
Diese QUIC-spezifische Einstellung erzwingt die Verwendung der QUIC-Retry-Funktion für alle Verbindungsversuche zu den konfigurierten QUIC-Listenern. Dabei wird überprüft, ob die Gegenstellen an der Transportadresse, von der aus sie eine neue Verbindung eingeleitet haben, Pakete empfangen können. Dazu wird ihnen ein Retry-Paket mit einem Token gesendet. Dieses Token muss an den Absender des Retry-Pakets zurückgesendet werden, da nur dieser das Token validieren kann. Beachten Sie, dass QUIC Retry damit immer verwendet wird, selbst wenn ein Retry-Schwellenwert gesetzt wurde (siehe “tune.quic.fe.sec.retry-threshold”).
Diese Einstellung setzt voraus, dass das Cluster-Geheimnis festgelegt ist; andernfalls wird beim Start ein Fehler gemeldet (siehe “cluster-secret”).
Weitere Informationen zu QUIC Retry finden Sie unter https://www.rfc-editor.org/rfc/rfc9000.html#section-8.1.2 .
quic-socket [ connection | listener ]
Mit dieser QUIC-spezifischen Einstellung wird der Modus für die Socket-Zuweisung für die jeweiligen Listener festgelegt. Eine vollständige Beschreibung der Vor- und Nachteile der einzelnen Modi finden Sie unter “tune.quic.fe.sock-per-conn”.
Diese Einstellung wirkt zusammen mit der globalen Option “tune.quic.fe.sock-per-conn”. Ist global der Modus “default-on” aktiv (der Standardwert), verwendet jede QUIC-Verbindung ihren eigenen Socket; ausgenommen sind Listener mit “quic-socket listener”. Ist der globale Modus hingegen auf “force-off” gesetzt, wird die Konfiguration der einzelnen Listener ignoriert.
severity-output <format>
Diese Einstellung wird nur bei Statistik-Sockets verwendet. Sie legt fest, wie der Schweregrad vor
informativen Rückmeldungen ausgegeben wird. Der Schweregrad einer Meldung kann gemäß Syslog rfc5424
zwischen 0 und 7 liegen. Bei gültigen, erfolgreich ausgeführten Socket-Befehlen zur Datenabfrage
(etwa “show map”, “get acl foo” usw.) wird niemals ein Schweregrad vorangestellt. Bei anderen
Sockets wird die Einstellung ignoriert. <format> kann einer der folgenden Werte sein:
- “none” (Standard): Rückmeldungen wird kein Schweregrad vorangestellt.
- “number”: Der Schweregrad wird als Zahl vorangestellt.
- “string”: Der Schweregrad wird als Zeichenfolge gemäß rfc5424 vorangestellt.
shards { <number> | by-thread | by-group }
Im Multithread-Modus erzeugt diese Einstellung auf Betriebssystemen, die mehrere Listener auf derselben Kombination IP:port unterstützen, automatisch die angegebene Anzahl identischer Listener für dieselbe Zeile. Jedem wird ein gleich großer Anteil der diesem Listener zugeordneten Threads zugewiesen. Das kann bei sehr vielen Threads nützlich sein, wenn die Sperren im Kernel für einen einzigen Socket erheblichen Zusatzaufwand verursachen. Eingehender Datenverkehr wird dann auf mehrere Sockets verteilt, wodurch die Konkurrenz um gemeinsame Ressourcen abnimmt. Beachten Sie, dass dies leicht die CPU-Auslastung erhöhen kann, weil mehr Threads jeweils etwas Arbeit leisten.
Ist die Anzahl der Shards größer als die Anzahl verfügbarer Threads, wird sie automatisch auf die Anzahl der Threads begrenzt (also ein Shard pro Thread). Auch der besondere Wert “by-thread” erzeugt so viele Shards, wie der “bind”-Zeile Threads zugeordnet sind. Da das System den eingehenden Datenverkehr gleichmäßig auf diese Shards verteilt, ist es wichtig, dass deren Anzahl ein ganzzahliger Teiler der Thread-Anzahl ist. Alternativ erzeugt der besondere Wert “by-group” einen Shard pro Thread-Gruppe. Das kann bei vielen Threads nützlich sein, wenn nicht zu viele Sockets erzeugt werden sollen. Die Lastverteilung ist dann etwas weniger optimal, aber die Konkurrenz um gemeinsame Ressourcen (insbesondere im System) ist weiterhin geringer als bei einem einzigen Socket.
Auf Betriebssystemen, die nicht mehrere an dieselbe Adresse gebundene Sockets unterstützen, fallen “by-thread” und “by-group” automatisch auf einen einzigen Shard zurück. Bei “by-group” geschieht dies ohne Warnung, da es für eine einzelne Gruppe nichts ändert und die Sockets ohnehin für jede Gruppe dupliziert werden. Bei “by-thread” wird in diesem Fall jedoch eine Diagnosewarnung ausgegeben, da die resultierende Anzahl von Listenern nicht der erwarteten Anzahl entspricht.
sigalgs <sigalgs>
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie legt die Zeichenfolge mit der Liste der Signaturalgorithmen fest, die beim TLSv1.2- und TLSv1.3-Handshake ausgehandelt werden. Das Format der Zeichenfolge ist in “man 3 SSL_CTX_set1_sigalgs” in den OpenSSL-Handbuchseiten beschrieben. Von dieser Einstellung wird abgeraten, sofern keine Kompatibilität mit einer Middlebox erforderlich ist.
ssl
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie aktiviert die SSL-Entschlüsselung für die von diesem Listener erzeugten Verbindungen. Ein Zertifikat ist erforderlich (siehe “crt” oben). Alle Inhalte in den Puffern liegen im Klartext vor, sodass ACLs und HTTP-Verarbeitung nur auf entschlüsselte Inhalte zugreifen. SSLv3 ist standardmäßig deaktiviert; verwenden Sie “ssl-min-ver SSLv3”, um es zu aktivieren.
ssl-max-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
Diese Option erzwingt für die von diesem Listener erzeugten SSL-Verbindungen die Verwendung von
<version> oder einer niedrigeren Version. Diese Einstellung ohne “ssl-min-ver” zu verwenden, kann
mehrdeutig sein, da sich der Standardwert von ssl-min-ver in zukünftigen HAProxy-Versionen ändern
könnte. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar.
Siehe auch “ssl-min-ver”.
ssl-min-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
Diese Option erzwingt für die von diesem Listener erzeugten SSL-Verbindungen die Verwendung von
<version> oder einer höheren Version. Der Standardwert ist “TLSv1.2”. Diese Option ist auch in der
globalen Anweisung “ssl-default-bind-options” verfügbar. Siehe auch “ssl-max-ver”.
strict-sni
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Die SSL/TLS-Aushandlung ist nur zulässig, wenn der Client eine zu einem Zertifikat passende SNI angegeben hat. Das Standardzertifikat wird nicht verwendet. Mit dieser Option kann eine bind-Zeile auch ohne Zertifikat gestartet werden; so lässt sich ein leeres Verzeichnis verwenden und später über den Statistik-Socket füllen. Diese Option ist auch in der globalen Anweisung “ssl-default-bind-options” verfügbar und kann in einer “bind”-Zeile gezielt mit “no-strict-sni” deaktiviert werden. Weitere Informationen finden Sie bei der Option “crt”. Siehe auch den Befehl “add ssl crt-list” im Verwaltungshandbuch.
tcp-md5sig <password>
Aktiviert die TCP-MD5-Signatur (RFC 2385 Schutz von BGP-Sitzungen mithilfe der TCP-MD5-Signaturoption)
für alle eingehenden Verbindungen, die von diesem lauschenden Socket erzeugt werden. Diese Option
ist nur unter Linux verfügbar. Wenn sie aktiviert ist, wird die Zeichenfolge <password> verwendet,
um jedes TCP-Segment mit einem 16-Byte-MD5-Digest zu signieren. Dies schützt die TCP-Verbindung vor
Spoofing. Der wichtigste Anwendungsfall ist der Schutz von BGP gegen das Einschleusen gefälschter
TCP-Segmente in den Verbindungsstrom. Die Option kann aber für alle sehr langlebigen
TCP-Verbindungen nützlich sein.
tcp-ss <mode>
Setzt die Option TCP Save SYN für alle eingehenden Verbindungen, die von diesem lauschenden Socket erzeugt werden. Diese Option ist unter Linux seit Version 4.3 verfügbar. Sie weist den Kernel an, eine Kopie des eingehenden IP-Pakets mit dem TCP-SYN-Flag nach Möglichkeit aufzubewahren, damit es später mit der Sample-Abruffunktion “fc_saved_syn” untersucht werden kann. Die Option kennt 3 Modi: - 0 Das Speichern von SYN-Paketen ist deaktiviert; dies ist der Standard - 1 Das Speichern von SYN-Paketen ist aktiviert und umfasst IP- und TCP-Header - 2 Das Speichern von SYN-Paketen ist aktiviert und umfasst ETH-, IP- und TCP-Header
Dies funktioniert nur bei regulären TCP-Verbindungen und wird bei anderen Protokollen (z. B. UNIX-Sockets) ignoriert. Siehe auch “fc_saved_syn”.
tcp-ut <delay>
Setzt den TCP User Timeout für alle eingehenden Verbindungen, die von diesem lauschenden Socket erzeugt werden. Diese Option ist unter Linux seit Version 2.6.37 verfügbar. Damit kann HAProxy eine Zeitüberschreitung für Sockets konfigurieren, deren Daten innerhalb der angegebenen Zeit keine Bestätigung erhalten. Dies ist besonders für langlebige Verbindungen mit langen Leerlaufzeiten nützlich, etwa Remote-Terminals oder Datenbank-Verbindungspools. Dort müssen die Zeitüberschreitungen für Client und Server hoch bleiben, um lange Leerlaufzeiten zu ermöglichen; zugleich ist es wichtig, das Verschwinden eines Clients zu erkennen, um alle Ressourcen seiner Verbindung (und der Serversitzung) freizugeben. Das Argument ist eine Zeitspanne, standardmäßig in Millisekunden. Dies funktioniert nur bei regulären TCP-Verbindungen und wird bei anderen Protokollen ignoriert.
tfo
Ein optionales Schlüsselwort, das nur auf Linux-Kerneln >= 3.7 unterstützt wird. Es aktiviert TCP Fast Open auf dem lauschenden Socket. Clients, die diese Funktion unterstützen, können damit ab der zweiten Verbindung bereits während des 3-Wege-Handshakes eine Anfrage senden und eine Antwort empfangen. Nach der ersten Verbindung wird dadurch jeweils ein Roundtrip eingespart. Dies ist nur bei Protokollen mit hohen Verbindungsraten sinnvoll, bei denen jeder Roundtrip zählt. Die Option kann Probleme mit vielen Firewalls verursachen, die keine Daten in SYN-Paketen akzeptieren. Sie sollte deshalb erst nach gründlichen Tests aktiviert werden. Sie wird nur für TCPv4/TCPv6-Sockets unterstützt und bei anderen Sockets ignoriert. Möglicherweise müssen Sie HAProxy mit USE_TFO=1 bauen, wenn Ihre libc TCP_FASTOPEN nicht definiert.
thread [<thread-group>/]<thread-set>[,...]
Beschränkt die Liste der Threads, auf denen dieser Listener ausgeführt werden darf. Dabei wird keiner dieser Threads erzwungen; lediglich nicht passende Threads werden ausgeschlossen. Die Einstellung begrenzt die Threads, die eingehende Verbindungen dieses Listeners verarbeiten dürfen.
Es gibt zwei Nummerierungsschemata. Standardmäßig sind Thread-Nummern innerhalb des Prozesses absolut und liegen zwischen 1 und dem in global.nbthread angegebenen Wert. Ein Thread kann auch über seine relative Nummer innerhalb seiner Thread-Gruppe bezeichnet werden. Dazu wird zuerst die Nummer der Thread-Gruppe angegeben, gefolgt von einem Schrägstrich (’/’) und den relativen Thread-Nummern. In diesem Fall beginnen die Thread-Nummern ebenfalls bei 1 und enden je nach Plattform bei 32 oder 64. Absolute Thread-Nummern werden automatisch in relative Nummern umgewandelt, sobald die Thread-Gruppen bekannt sind. Üblicherweise werden absolute Nummern für einfache Konfigurationen bevorzugt und relative Nummern für komplexe Konfigurationen, bei denen die CPU-Anordnung für die Leistung entscheidend ist.
Nach der optionalen Thread-Gruppennummer muss die “thread-set”-Angabe folgendes Format verwenden:
Wie die Namen nahelegen, wählt “all” alle Threads der Menge aus (entweder alle Threads der Gruppe, wenn eine Gruppe angegeben ist, oder alle Threads des Prozesses). “odd” wählt alle ungeradzahligen Threads aus (jeden zweiten Thread, beginnend bei 1), entweder im Prozess oder in der Gruppe; “even” wählt alle geradzahligen Threads aus (jeden zweiten Thread, beginnend bei 2). Werden stattdessen Bereiche von Thread-Nummern verwendet, werden alle Threads von der ersten bis zur letzten Thread-Nummer des Bereichs ausgewählt. Je nachdem, ob eine Thread-Gruppennummer angegeben ist, sind die Nummern relativ zur Gruppe oder absolut. Fehlt die erste Thread-Nummer, wird “1” verwendet, also der erste Thread der Gruppe oder des Prozesses. Fehlt die letzte Thread-Nummer, wird entweder die letzte Thread-Nummer der Gruppe (32 oder 64) oder die letzte Thread-Nummer des Prozesses (global.nbthread) verwendet.
Diese Bereiche können, durch Kommas getrennt, mehrfach angegeben werden, um nicht zusammenhängende Thread-Mengen zu definieren. Eine gegebenenfalls verwendete Gruppe muss für jeden neuen Bereich erneut angegeben werden. Beachten Sie, dass gruppenrelative und absolute Angaben nicht gemischt werden dürfen: Die gesamte “bind”-Zeile muss entweder absolute oder relative Notation verwenden, da nicht gesetzte Werte erst am Ende des Parsens aufgelöst werden.
Dabei ist wichtig, dass jeder durch eine “bind”-Zeile beschriebene Listener mindestens einen Socket erzeugt, der durch mindestens einen Dateideskriptor repräsentiert wird. Da Dateideskriptoren sich nicht über mehrere Thread-Gruppen erstrecken können, werden automatisch mehrere Dateideskriptoren erzeugt, wenn der Thread-Bereich einer “bind”-Zeile mehr als eine Gruppe umfasst. So ist für jede Gruppe mindestens einer vorhanden. Technisch verweisen sie alle auf denselben Socket im Kernel, erhalten in haproxy aber jeweils eine eigene Kennung und bei Verwendung von “option socket-stats” sogar einen eigenen Statistikeintrag.
Der Hauptzweck besteht darin, mehrere bind-Zeilen in einem Listener mit derselben Kombination IP:port, aber verschiedenen Threads zu verwenden. Das System kann eingehende Verbindungen dann auf mehrere Warteschlangen verteilen und damit die interne Lastverteilung der Warteschlangen von haproxy umgehen. Derzeit ist bekannt, dass Linux ab 3.9 dies unterstützt. Siehe auch das oben beschriebene Schlüsselwort “shards”, das die Duplizierung von “bind”-Zeilen und ihre Zuweisung zu mehreren Thread-Gruppen automatisiert.
Dieses Schlüsselwort ist mit Reverse-HTTP-bind-Zeilen kompatibel. Für einen solchen Listener darf jedoch keine Thread-Menge angegeben werden, die mehrere Thread-Gruppen umfasst, da “nbconn” sonst möglicherweise nicht wie vorgesehen funktioniert.
tls-tickets
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie aktiviert die zustandslose Sitzungswiederaufnahme (RFC 5077 TLS-Ticket-Erweiterung). Dies ist der Standard; die Option kann jedoch nötig sein, um die Funktion gezielt in einer “bind”-Zeile erneut zu aktivieren, wenn sie global durch “no-tls-tickets” in “ssl-default-bind-options” deaktiviert wurde. Siehe auch das bind-Schlüsselwort “no-tls-tickets”.
tls-ticket-keys <keyfile>
Legt die Datei fest, aus der die TLS-Ticket-Schlüssel geladen werden. Die Schlüssel müssen je nach Verwendung von aes128 oder aes256 48 oder 80 Bytes lang und base64-codiert sein, mit einer Zeile pro Schlüssel (z. B. openssl rand 80 | openssl base64 -A | xargs echo). Der erste Schlüssel bestimmt die Schlüssellänge der folgenden Schlüssel; aes128- und aes256-Schlüssel können nicht gemischt werden. Die Anzahl der Schlüssel wird mit der Build-Option TLS_TICKETS_NO festgelegt (Standard 3), und die Datei muss mindestens so viele Schlüssel enthalten. Die letzten TLS_TICKETS_NO Schlüssel werden zur Entschlüsselung verwendet, der vorletzte zur Verschlüsselung. Das ermöglicht einen einfachen Schlüsselwechsel: Ein neuer Schlüssel wird an die Datei angehängt und der Prozess neu geladen. Die Schlüssel müssen regelmäßig gewechselt werden (z. B. alle 12h), sonst ist Perfect Forward Secrecy gefährdet. Es empfiehlt sich auch, die Schlüssel nicht auf dauerhaftem Speicher wie Festplatten abzulegen (Tipp: tmpfs verwenden und diese Dateien nicht auslagern). Der Hinweis auf die Lebensdauer kann mit tune.ssl.timeout geändert werden.
transparent
Ein optionales Schlüsselwort, das nur auf bestimmten Linux-Kerneln unterstützt wird. Es bewirkt, dass die Adressen auch dann gebunden werden, wenn sie nicht zum lokalen Rechner gehören. An diese Adressen gerichtete Pakete werden dann so abgefangen, als wären die Adressen lokal konfiguriert. Dafür muss normalerweise IP-Weiterleitung aktiviert sein. Achtung! Verwenden Sie dies nicht mit der Standardadresse ‘*’, da dadurch jeglicher Datenverkehr für den angegebenen Port umgeleitet würde. Dieses Schlüsselwort ist nur verfügbar, wenn HAProxy mit USE_LINUX_TPROXY=1 gebaut wurde. Der Parameter ist je nach Kernel-Version nur mit TCPv4- und TCPv6-Sockets kompatibel. Einige Distributionskernel enthalten Rückportierungen dieser Funktion; erkundigen Sie sich daher bei Ihrem Anbieter nach der Unterstützung.
uid <uid>
Setzt den Eigentümer der UNIX-Sockets auf die angegebene System-UID. Der Standardwert kann auch mit der Anweisung “unix-bind” im globalen Abschnitt gesetzt werden. Beachten Sie, dass manche Plattformen dies einfach ignorieren. Diese Einstellung entspricht “user”, verwendet aber die numerische ID des Benutzers anstelle seines Namens. Bei anderen als UNIX-Sockets wird sie ignoriert.
user <user>
Setzt den Eigentümer der UNIX-Sockets auf den angegebenen Systembenutzer. Der Standardwert kann auch mit der Anweisung “unix-bind” im globalen Abschnitt gesetzt werden. Beachten Sie, dass manche Plattformen dies einfach ignorieren. Diese Einstellung entspricht “uid”, verwendet aber den Benutzernamen anstelle seiner uid. Bei anderen als UNIX-Sockets wird sie ignoriert.
v4v6
Ein optionales Schlüsselwort, das nur auf neueren Systemen einschließlich Linux-Kerneln >= 2.4.21 unterstützt wird. Es bindet einen Socket sowohl an IPv4 als auch an IPv6, wenn dieser die Standardadresse verwendet. Dies ist manchmal auf Systemen erforderlich, die standardmäßig nur an IPv6 binden. Auf anderen als IPv6-Sockets hat es keine Wirkung und wird von der Option “v6only” überschrieben.
v6only
Ein optionales Schlüsselwort, das nur auf neueren Systemen einschließlich Linux-Kerneln >= 2.4.21 unterstützt wird. Es bindet einen Socket nur an IPv6, wenn dieser die Standardadresse verwendet. Da es pro Listener wirkt, wird dies manchmal einer systemweiten Einstellung vorgezogen. Auf anderen als IPv6-Sockets hat es keine Wirkung und hat Vorrang vor der Option “v4v6”.
verify [none|optional|required]
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Bei ’none’ wird kein Client-Zertifikat angefordert; dies ist der Standard. In allen anderen Fällen wird ein Client-Zertifikat angefordert. Liefert der Client nach der Anforderung kein Zertifikat und ist ‘verify’ auf ‘required’ gesetzt, wird der Handshake abgebrochen; mit ‘optional’ wäre er dagegen erfolgreich. Ein vom Client geliefertes Zertifikat wird immer mit den CAs aus ‘ca-file’ und optionalen CRLs aus ‘crl-file’ überprüft. Schlägt die Überprüfung fehl, wird der Handshake unabhängig von der Option ‘verify’ abgebrochen, es sei denn, der Fehlercode stimmt exakt mit einem der unter ‘ca-ignore-err’ oder ‘crt-ignore-err’ aufgeführten Codes überein.
5.2. Server- und default-server-Optionen
Die Schlüsselwörter “server” und “default-server” unterstützen verschiedene Einstellungen, die alle als Argumente in der server-Zeile übergeben werden. Die Reihenfolge dieser Argumente spielt keine Rolle, und alle sind optional. Einige Einstellungen bestehen aus einzelnen Wörtern (boolesche Werte), andere erwarten dahinter einen oder mehrere Werte. In diesem Fall müssen die Werte unmittelbar auf den Einstellungsnamen folgen. Außer bei default-server müssen alle diese Einstellungen, sofern verwendet, nach der Serveradresse angegeben werden:
Beachten Sie, dass alle diese Einstellungen sowohl von “server” als auch von “default-server” unterstützt werden, außer “id”, das nur von “server” unterstützt wird.
Derzeit werden die folgenden Einstellungen unterstützt.
addr <ipv4|ipv6>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Mit dem Parameter “addr” kann eine andere IP-Adresse zum Senden von Health Checks oder zum Abfragen des Agent-Checks verwendet werden. Auf manchen Servern kann es sinnvoll sein, einer bestimmten Komponente eine eigene IP-Adresse zuzuweisen, wenn diese komplexe Tests ausführen kann, die für Health Checks besser geeignet sind als die Anwendung selbst. Dieser Parameter wird ignoriert, wenn “check” nicht gesetzt ist. Siehe auch den Parameter “port”.
agent-check
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Aktiviert einen zusätzlichen Agent-Check, der unabhängig von einem regulären Health Check ausgeführt wird. Für einen Agent-Health-Check wird eine TCP-Verbindung zum durch “agent-port” festgelegten Port hergestellt und eine ASCII-Zeichenfolge gelesen, die mit dem ersten gefundenen ‘\r’ oder ‘\n’ endet. Die Zeichenfolge besteht aus Wörtern in beliebiger Reihenfolge, die durch Leerzeichen, Tabulatoren oder Kommas getrennt sind. Jedes Wort hat eine der folgenden Formen:
-
Die ASCII-Darstellung einer positiven ganzzahligen Prozentangabe, z. B. “75%”. Werte in diesem Format setzen das Gewicht proportional zum anfänglichen Gewicht des Servers, das beim Start von HAProxy konfiguriert war. Beachten Sie, dass ein Gewicht von null auf der Statistikseite als “DRAIN” angezeigt wird, da es dieselbe Wirkung auf den Server hat (er wird aus der LB-Farm entfernt). Dies ist die ältere Methode, das Servergewicht zu setzen. Die Verwendung des Präfixes “weight:” wird bevorzugt.
-
Die Zeichenfolge “weight:”, unmittelbar gefolgt von einer positiven Ganzzahl oder einer positiven ganzzahligen Prozentangabe, ohne Leerzeichen. Endet der Wert mit ‘%’, ist das neue Gewicht proportional zum anfänglichen Servergewicht. Andernfalls gilt der Wert als absolutes Gewicht und muss zwischen 0 und 256 liegen. Für Server in einer Farm mit einem statischen Lastverteilungsalgorithmus gelten strengere Grenzen, da das einmal gesetzte Gewicht nicht geändert werden kann. Für diese Server sind daher nur 0 und 100% zulässig (oder 0 und das anfängliche Gewicht). Änderungen wirken sofort, obwohl manche LB-Algorithmen eine gewisse Anzahl von Anfragen benötigen, um Änderungen zu berücksichtigen. Beachten Sie, dass ein Gewicht von null auf der Statistikseite als “DRAIN” angezeigt wird, da es dieselbe Wirkung auf den Server hat (er wird aus der LB-Farm entfernt).
-
Die Zeichenfolge “maxconn:”, unmittelbar gefolgt von einer Ganzzahl (ohne Leerzeichen). Werte in diesem Format setzen maxconn für einen Server. Die angegebene maximale Verbindungsanzahl muss mit der Anzahl der Load-Balancer und der unterschiedlichen Backends multipliziert werden, die diesen Health Check verwenden, um die Gesamtzahl der Verbindungen zu erhalten, die der Server empfangen könnte. Beispiel: maxconn:30
-
Das Wort “ready”. Es setzt den administrativen Zustand des Servers auf READY und hebt damit jeden DRAIN- oder MAINT-Zustand auf.
-
Das Wort “drain”. Es setzt den administrativen Zustand des Servers auf DRAIN. Der Server nimmt dann nur noch neue Verbindungen an, die aufgrund von Persistenz zugelassen werden.
-
Das Wort “maint”. Es setzt den administrativen Zustand des Servers auf MAINT. Der Server nimmt dann keinerlei neue Verbindungen an, und Health Checks werden eingestellt.
-
Die Wörter “down”, “fail” oder “stopped”, optional gefolgt von einer Beschreibung nach einem Rautezeichen (’#’). Alle setzen den Betriebszustand des Servers auf DOWN. Da jedoch das Wort selbst auf der Statistikseite angezeigt wird, kann ein Administrator daran erkennen, ob die Situation erwartet war: Der Dienst kann absichtlich gestoppt sein, scheinbar laufen, aber einige Gültigkeitsprüfungen nicht bestehen, oder als ausgefallen gelten (z. B. weil der Prozess fehlt oder der Port nicht antwortet).
-
Das Wort “up” setzt den Betriebszustand des Servers wieder auf UP, sofern auch die Health Checks melden, dass der Dienst erreichbar ist.
Parameter, die der Agent nicht übermittelt, werden nicht geändert. Ein Agent könnte beispielsweise die CPU-Auslastung überwachen und nur ein relatives Gewicht melden, ohne jemals den Betriebszustand zu beeinflussen. Ebenso könnte ein Agent als Benutzeroberfläche mit 3 Optionsfeldern gestaltet sein, mit denen ein Administrator ausschließlich den administrativen Zustand ändert. Dabei ist jedoch zu beachten, dass nur der Agent seine eigenen Aktionen rückgängig machen kann. Wenn ein Server über den Agenten auf DRAIN oder DOWN gesetzt wird, muss der Agent daher auch die entsprechenden Gegenaktionen implementieren, um den Dienst wieder in Betrieb nehmen zu können.
Wenn keine Verbindung zum Agenten hergestellt werden kann, gilt dies nicht als Fehler, da die Erreichbarkeit durch den regulären, mit “check” aktivierten Health Check getestet wird. Achtung: Es ist keine gute Idee, einen Agenten zu stoppen, nachdem er “down” gemeldet hat. Nur ein Agent, der “up” meldet, kann den Server wieder aktivieren. Beachten Sie, dass die CLI am Unix-Statistik-Socket ebenfalls das Ergebnis eines Agenten erzwingen kann, um bei Bedarf einen fehlerhaften Agenten zu umgehen.
Der Parameter “agent-port” muss gesetzt sein. Siehe auch “agent-inter” und “no-agent-check”.
agent-send <string>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Wenn diese Option angegeben ist, sendet HAProxy beim Verbindungsaufbau die angegebene Zeichenfolge unverändert an den Agent-Server. Sie könnten darin beispielsweise den Backend-Namen codieren, damit der Agent je nach Backend unterschiedliche Antworten senden kann. Fügen Sie ein ‘\n’ ein, wenn die Anfrage mit einem Zeilenumbruch enden soll.
agent-inter <delay>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Der Parameter “agent-inter” setzt das Intervall zwischen zwei Agent-Checks auf <delay>
Millisekunden. Ist er nicht angegeben, beträgt das Intervall standardmäßig 2000 ms.
Wie bei allen zeitbasierten Parametern kann explizit eine andere Einheit aus { us, ms, s, m, h, d } angegeben werden. Der Parameter “agent-inter” dient auch als Zeitüberschreitung für Agent-Checks, wenn “timeout check” nicht gesetzt ist. Um “Resonanz”-Effekte bei mehreren Servern auf derselben Hardware zu verringern, werden die Agent- und Health Checks aller Server mit einem kleinen zeitlichen Versatz zueinander gestartet. Mit dem globalen Schlüsselwort “spread-checks” kann den Intervallen der Agent- und Health Checks außerdem eine zufällige Abweichung hinzugefügt werden. Das ist beispielsweise sinnvoll, wenn viele Backends dieselben Server verwenden.
Siehe auch die Parameter “agent-check” und “agent-port”.
agent-addr <addr>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Der Parameter “agent-addr” legt die Adresse für den Agent-Check fest.
Sie können den Agent-Check auf ein anderes Ziel auslagern und so Status und Gewichte der in HAProxy definierten Server zentral verwalten, falls sich die Dienste nicht selbst überwachen und verwalten können. Es kann sowohl eine IP-Adresse als auch ein Hostname angegeben werden; dieser wird aufgelöst.
agent-port <port>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Der Parameter “agent-port” legt den TCP-Port für Agent-Checks fest.
Siehe auch die Parameter “agent-check” und “agent-inter”.
allow-0rtt
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Erlaubt beim Einsatz von TLS 1.3 das Senden früher Daten an den Server. Beachten Sie, dass frühe Daten nur gesendet werden, wenn der Client frühe Daten verwendet hat oder das Backend “retry-on” mit dem Schlüsselwort “0rtt-rejected” verwendet. Bei QUIC wird 0rtt von QuicTLS, OpenSSL >= 3.5.2 und AWS-LC unterstützt. Bei TCP/TLS wird 0rtt nur von OpenSSL unterstützt.
alpn <protocols>
Kann in folgenden Kontexten verwendet werden: tcp, http
Aktiviert die TLS-Erweiterung ALPN und bietet die angegebene Protokollliste über ALPN als unterstützt an. Die Protokollliste besteht aus durch Kommas getrennten Protokollnamen, beispielsweise “http/1.1,http/1.0” (ohne Anführungszeichen). Dafür muss die SSL-Bibliothek mit aktivierter Unterstützung für TLS-Erweiterungen gebaut worden sein (mit haproxy -vv prüfen). Die ALPN-Erweiterung ersetzt die ursprüngliche NPN-Erweiterung. ALPN ist für Verbindungen zu HTTP/2-Servern erforderlich. Sie ist auch erforderlich, um HTTP/3 über einen QUIC-Server verwenden zu können; für QUIC-Server ohne “alpn”-Einstellung ist “h3” der Standardwert. OpenSSL-Versionen vor 1.0.2 unterstützten ALPN nicht, sondern nur die inzwischen veraltete NPN-Erweiterung. Wenn sowohl HTTP/2 als auch HTTP/1.1 unterstützt werden sollen, können beide Versionen in der gewünschten Präferenzreihenfolge angeboten werden, wie unten gezeigt:
Siehe auch “ws”, um eine alternative ALPN-Angabe für Websocket-Streams zu verwenden.
backup
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Steht “backup” in einer server-Zeile, wird der Server nur dann für die Lastverteilung verwendet, wenn alle anderen Server ohne backup-Option nicht verfügbar sind. Anfragen mit einem Persistenz-Cookie, das auf diesen Server verweist, werden jedoch immer bedient. Standardmäßig wird nur der erste betriebsbereite Backup-Server verwendet, sofern nicht die Option “allbackups” im Backend gesetzt ist. Siehe auch die Optionen “no-backup” und “allbackups”.
ca-file <cafile>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie gibt eine PEM-Datei an, aus der CA-Zertifikate zur Überprüfung des Serverzertifikats geladen werden. Es kann auch ein Verzeichnis mit mehreren CAs geladen werden. In diesem Fall versucht HAProxy, alle Dateien mit den Endungen “.pem”, “.crt”, “.cer” und “.crl” aus dem Verzeichnis zu laden. Dateien, deren Name mit einem Punkt beginnt, werden ignoriert.
Um die vertrauenswürdigen CAs des Systems zu verwenden, kann anstelle der cafile der Parameter “@system-ca” angegeben werden. Der Pfad dieses Verzeichnisses kann durch Setzen der Umgebungsvariablen SSL_CERT_DIR überschrieben werden.
cc <algo>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Einstellung ist nur auf Systemen verfügbar, die TCP_CONGESTION definieren, und wurde unter Linux und FreeBSD geprüft. Sie nimmt den Namen eines TCP-Algorithmus zur Überlastkontrolle entgegen und konfiguriert ausgehende Verbindungen für dessen Verwendung. Typische Namen sind “reno” und “cubic”; die Auswahl hängt vom Betriebssystem ab. Auf manchen Systemen können für bestimmte Algorithmen besondere Berechtigungen erforderlich sein. Unter Linux listet die Sysctl-Einstellung “net.ipv4.tcp_available_congestion_control” die verfügbaren Algorithmen auf und “net.ipv4.tcp_allowed_congestion_control” die ohne Privilegien zulässigen Algorithmen. Für Algorithmen mit zusätzlichen Berechtigungsanforderungen kann die Capability “cap_net_admin” erforderlich sein (siehe “setcap” im globalen Abschnitt). Kann ein bestimmter Algorithmus nicht konfiguriert werden, bleibt der Standardalgorithmus unverändert. Siehe auch das bind-Schlüsselwort “cc” (Abschnitt 5.1 ).
check
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Diese Option aktiviert Health Checks für einen Server: - Ist sie nicht gesetzt, werden keine Health Checks durchgeführt und der Server gilt immer als verfügbar. - Ist sie gesetzt und keine andere Prüfmethode konfiguriert, gilt der Server als verfügbar, wenn auf der höchsten konfigurierten Transportschicht eine Verbindung aufgebaut werden kann. Standardmäßig ist dies TCP, bei gesetztem “ssl” oder “check-ssl” dagegen SSL/TLS. Beides kann mit Verbindungspräfixen wie einem PROXY-Protokoll-Header kombiniert werden, wenn “send-proxy” oder “check-send-proxy” gesetzt ist. Für dynamische Server weicht dieses Verhalten etwas ab; Einzelheiten stehen in den folgenden Absätzen. - Ist die Option gesetzt und ein Health Check auf Anwendungsebene definiert, wird der Datenaustausch auf Anwendungsebene über der konfigurierten Transportschicht durchgeführt. Der Server gilt als verfügbar, wenn der gesamte Datenaustausch erfolgreich ist.
Standardmäßig verwenden Health Checks dieselbe Adresse und denselben Port wie die Serverkonfiguration sowie dieselben Kapselungsparameter (SSL/TLS, Proxy-Protokoll-Header usw.). Die Zieladresse kann mit “addr” und der Port mit “port” geändert werden. In diesem Fall wird angenommen, dass der Server nicht am Dienstport geprüft wird, und die konfigurierten Kapselungsparameter werden nicht übernommen. Zum Senden von Verbindungsheadern muss “check-send-proxy” explizit gesetzt werden, für SSL/TLS entsprechend “check-ssl”.
Beachten Sie, dass für dynamische Server keine implizite Konfiguration von ssl und PROXY-Protokoll erfolgt. Hier müssen “check-ssl” und “check-send-proxy” bei Bedarf explizit verwendet werden, selbst wenn der Prüfport nicht überschrieben wird.
Wenn “sni” oder “alpn” in der server-Zeile gesetzt sind, werden ihre Werte nicht für Health Checks verwendet; dafür müssen “check-sni” bzw. “check-alpn” verwendet werden.
Die standardmäßige Quelladresse für Health-Check-Datenverkehr entspricht der im Backend definierten Adresse. Sie kann mit dem Schlüsselwort “source” geändert werden.
Das Intervall zwischen Prüfungen kann mit “inter” gesetzt werden. Mit “rise” und “fall” kann festgelegt werden, wie viele erfolgreiche bzw. fehlgeschlagene Health Checks erforderlich sind, um einen Server als verfügbar bzw. nicht verfügbar zu markieren.
Optionale Health Checks auf Anwendungsebene können mit “option httpchk”, “option mysql-check”, “option smtpchk”, “option pgsql-check”, “option ldap-check” oder “option redis-check” konfiguriert werden.
Beispiel:
check-reuse-pool
Kann in folgenden Kontexten verwendet werden: tcp, http
Diese Option erlaubt Prüfungen, vorhandene ungenutzte Verbindungen wiederzuverwenden, anstatt eine eigene Verbindung zu öffnen. Nach Abschluss der Prüfung wird die Verbindung wieder in den Pool aufgenommen. Das Hauptziel ist, die Anzahl der Verbindungsaufbauten und -schließungen zu einem bestimmten Server zu begrenzen. Diese Funktion ist nur mit http-check-Regelsätzen kompatibel. Bei anderen Prüftypen wird sie ohne Meldung ignoriert. Außerdem sollte die Wiederverwendungsrichtlinie im Backend auf aggressive gesetzt sein, da jeder Prüfversuch in einer eigenen Sitzung erfolgt.
Zur Vereinfachung der Konfiguration wird diese Option ohne Meldung ignoriert, wenn eine spezielle Verbindungsoption für Prüfungen definiert ist, entweder in der server-Zeile oder über eine benutzerdefinierte Regel tcp-check connect.
Diese Option wird automatisch für Server aktiviert, die als passives Reverse-HTTP-Gateway dienen, da bei diesen Servern ein Verbindungsaufbau nur durch Wiederverwendung unterstützt wird.
Siehe auch: “check-pool-conn-name”
check-send-proxy
Kann in folgenden Kontexten verwendet werden: tcp, http
Diese Option erzwingt das Senden einer PROXY-Protokollzeile bei ausgehenden Health Checks, unabhängig davon, ob der Server send-proxy für den normalen Datenverkehr verwendet. Standardmäßig ist das PROXY-Protokoll für Health Checks aktiviert, wenn es bereits für den normalen Datenverkehr aktiviert ist und weder eine “port”- noch eine “addr”-Direktive vorhanden ist. Ist eine solche Direktive vorhanden, muss jedoch “check-send-proxy” verwendet werden, um die Verwendung des Protokolls zu erzwingen. Weitere Informationen finden Sie bei der Option “send-proxy”.
check-alpn <protocols>
Kann in folgenden Kontexten verwendet werden: tcp, http
Legt fest, welche Protokolle über ALPN angeboten werden. Die Protokollliste besteht aus durch Kommas getrennten Protokollnamen, beispielsweise “http/1.1,http/1.0” (ohne Anführungszeichen). Ist dies nicht gesetzt, wird die ALPN-Einstellung des Servers verwendet.
check-pool-conn-name <name>
Kann in folgenden Kontexten verwendet werden: tcp, http
Wenn für Prüfungen Verbindungen wiederverwendet werden, wird <name>, sofern gesetzt, als
Verbindungskennung verwendet, um eine passende Verbindung im Pool zu finden. Dies entspricht dem
Server-Schlüsselwort “pool-conn-name”. Wird diese Option nicht verwendet, dient auch “check-sni”
als Rückfallwert.
Siehe auch: “check-reuse-pool”
check-proto <name>
Kann in folgenden Kontexten verwendet werden: tcp, http
Erzwingt das Multiplexer-Protokoll für die Health-Check-Verbindungen des Servers. Es muss mit dem Health-Check-Typ (TCP oder HTTP) kompatibel und auf der Backend-Seite verwendbar sein. Die Liste verfügbarer Protokolle wird von haproxy -vv ausgegeben. Angezeigt werden die Protokolleigenschaften: der Modus (TCP/HTTP), die Seite (FE/BE), der Name des Multiplexers und seine Flags.
Bei manchen Protokollen kann auf der Serverseite Head-of-Line-Blocking auftreten (flag=HOL_RISK). Einige Protokolle unterstützen außerdem keine Upgrades (flag=NO_UPG). Auch die HTX-Kompatibilität wird angegeben (flag=HTX).
Die folgenden Protokolle können als Argument einer “check-proto”-Direktive in einer server-Zeile verwendet werden:
Mit dieser Option wird die Auswahl des am besten geeigneten Multiplexer-Protokolls für Health-Check-Verbindungen zu diesem Server umgangen. Ist sie nicht definiert, wird das Protokoll des Servers verwendet, sofern es gesetzt ist.
Wenn ALPN oder NPN konfiguriert ist, sollten die angegebenen Protokolle mit dem Multiplexer-Protokoll kompatibel sein, um Probleme zu vermeiden. Ist beispielsweise “proto h1” gesetzt, sollte ALPN nicht auf “h2” gesetzt werden.
Die Konfiguration von QUIC-Prüfungen ist noch nicht vollständig implementiert. Erstens können QUIC-Prüfungen nur für QUIC-Server durchgeführt werden. Zweitens fällt das Prüfprotokoll auf TCP zurück, wenn für einen QUIC-Server mindestens ein prüfungsspezifischer Verbindungsparameter angegeben ist.
check-sni-auto
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Diese Option aktiviert die automatische SNI-Auswahl bei Health Checks über SSL, sofern noch kein Wert gesetzt wurde. Sie ist standardmäßig aktiviert. Als “server”-Einstellung kann dieser Parameter jedoch eine über die Direktive “default-server” geerbte Standardeinstellung “no-check-sni-auto” zurücksetzen. Er kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “no-check-sni-auto”-Einstellung aus “default-server” zurückzusetzen.
Für HTTPS-Verbindungen wird die SNI automatisch ausgewählt, allerdings nur, wenn keine Regel “http-check connect” vorhanden ist. In diesem Fall richtet sich die SNI nach dem Wert des Host-Headers, der über “option httpchk” oder eine Regel “http-check send” angegeben wurde. Für Regeln “http-check connect” erfolgt keine automatische Auswahl. Bei anderen Protokollen wird die Option ignoriert.
Wenn die automatische SNI-Auswahl für Health Checks verwendet wird und “check-reuse-pool” gesetzt ist, wird der Wert dem Verbindungsnamen zugewiesen, sofern er nicht durch das Server-Schlüsselwort “check-pool-conn-name” überschrieben wird.
Siehe die Option “sni-auto”, um die automatische SNI-Auswahl für weitergeleiteten Datenverkehr zu aktivieren.
check-sni <sni>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Mit dieser Option wird die SNI für Health Checks über SSL angegeben. <sni> kann nur mit einer
Zeichenfolge gesetzt werden. Soll die SNI für weitergeleiteten Datenverkehr gesetzt werden, siehe
“sni”.
check-ssl
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Diese Option erzwingt die SSL-Verschlüsselung aller Health Checks, unabhängig davon, ob der Server SSL für den normalen Datenverkehr verwendet. Sie wird üblicherweise verwendet, wenn explizit eine “port”- oder “addr”-Direktive angegeben ist und SSL-Health-Checks deshalb nicht geerbt werden. Dabei ist wichtig, dass diese Option eine SSL-Transportschicht unter den Prüfungen einfügt: Aus einer einfachen TCP-Verbindungsprüfung wird damit eine SSL-Verbindungsprüfung, die das frühere ssl-hello-chk ersetzt. Am häufigsten wird “httpchk” mit SSL-Prüfungen kombiniert, um HTTPS-Prüfungen zu senden. Alle SSL-Einstellungen gelten gemeinsam für Health Checks und Datenverkehr (z. B. Ciphers). Weitere Informationen finden Sie bei “ssl”; mit “no-check-ssl” wird diese Option deaktiviert.
check-via-socks4
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Diese Option aktiviert ausgehende Health Checks über einen vorgeschalteten socks4-Proxy. Standardmäßig durchlaufen Health Checks den socks-Tunnel nicht, auch wenn er für normalen Datenverkehr aktiviert ist.
ciphers <ciphers>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie legt die Zeichenfolge mit der Liste der Verschlüsselungsalgorithmen fest, die beim SSL/TLS-Handshake mit dem Server ausgehandelt werden. Das Format ist in “man 1 ciphers” in den OpenSSL-Handbuchseiten beschrieben. Hintergrundinformationen und Empfehlungen finden Sie beispielsweise unter (https://wiki.mozilla.org/Security/Server_Side_TLS ) und (https://mozilla.github.io/server-side-tls/ssl-config-generator/ ). Zur Konfiguration der Verschlüsselungsalgorithmen für TLSv1.3 siehe das Schlüsselwort “ciphersuites”.
ciphersuites <ciphersuites>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde und HAProxy mit OpenSSL 1.1.1 oder neuer gebaut wurde. Sie legt die Zeichenfolge mit der Liste der Verschlüsselungsalgorithmen fest, die beim TLS-1.3-Handshake mit dem Server ausgehandelt werden. Das Format ist in “man 1 ciphers” in den OpenSSL-Handbuchseiten im Abschnitt “ciphersuites” beschrieben. Zur Konfiguration der Verschlüsselungsalgorithmen für TLSv1.2 und älter siehe das Schlüsselwort “ciphers”.
client-sigalgs <sigalgs>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie legt die Zeichenfolge mit der Liste der auszuhandelnden Signaturalgorithmen für die Client-Authentifizierung fest. Das Format ist in “man 3 SSL_CTX_set1_client_sigalgs” in den OpenSSL-Handbuchseiten beschrieben. Von dieser Einstellung wird abgeraten, sofern kein konkreter Anwendungsfall dafür besteht.
cookie <value>
Kann in folgenden Kontexten verwendet werden: http
Der Parameter “cookie” setzt den dem Server zugeordneten Cookie-Wert auf <value>. Dieser Wert
wird in eingehenden Anfragen geprüft; ausgewählt wird der erste betriebsbereite Server mit demselben
Wert. Im Gegenzug wird dieser Wert im Modus zum Einfügen oder Umschreiben von Cookies dem Cookie
zugewiesen, das an den Client gesendet wird. Mehrere Server können problemlos denselben Cookie-Wert
verwenden; bei normalen und Backup-Servern ist dies sogar recht üblich. Siehe auch das Schlüsselwort
“cookie” im Backend-Abschnitt.
crl-file <crlfile>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie gibt eine PEM-Datei an, aus der die Zertifikatssperrliste zur Überprüfung des Serverzertifikats geladen wird.
crt <cert>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie gibt eine PEM-Datei an, aus der sowohl ein Zertifikat als auch der zugehörige private Schlüssel geladen werden. Die Datei kann durch Aneinanderhängen beider PEM-Dateien erzeugt werden. Dieses Zertifikat wird gesendet, wenn der Server ein Client-Zertifikat anfordert.
Enthält die Datei keinen privaten Schlüssel, versucht HAProxy, den Schlüssel vom selben Pfad mit der angehängten Endung “.key” zu laden (sofern “ssl-load-extra-files” entsprechend gesetzt ist).
curves <curves>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie legt die Zeichenfolge fest, die die Liste der elliptischen Kurvenalgorithmen (“Kurvensuite”) beschreibt, die während des SSL/TLS-Handshakes mit ECDHE vereinbart werden. Das Format der Zeichenfolge ist eine durch Doppelpunkte getrennte Liste von Kurvennamen. Beispiel: “X25519:P-256” (ohne Anführungszeichen)
disabled
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Das Schlüsselwort “disabled” startet den Server im Zustand “disabled”. Das bedeutet, dass er im Wartungsmodus als down markiert ist, und keine Verbindung außer denjenigen, die durch den Persistenzmodus erlaubt sind, erreicht ihn. Es eignet sich sehr gut zum Einrichten neuer Server, da normaler Datenverkehr sie niemals erreichen wird, während es dennoch möglich ist, den Dienst über den force-persist-Mechanismus zu testen. Siehe auch die “enabled”-Einstellung.
enabled
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Diese Option kann als ‘server’-Einstellung verwendet werden, um jede ‘disabled’-Einstellung zurückzusetzen, die als Standardwert von der ‘default-server’-Anweisung geerbt wurde. Sie kann auch als ‘default-server’-Einstellung verwendet werden, um jede vorherige ‘default-server’ ‘disabled’-Einstellung zurückzusetzen.
error-limit <count>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Wenn die Zustandsüberwachung aktiviert ist, legt der “error-limit”-Parameter die Anzahl aufeinanderfolgender Fehler fest, die ein Ereignis auslösen, das durch die “on-error”-Option ausgewählt wurde. Standardmäßig ist dieser Wert auf 10 aufeinanderfolgende Fehler festgelegt.
Siehe auch “check”, “error-limit” und “on-error”.
fall <count>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Der “fall”-Parameter legt fest, dass ein Server nach <count> aufeinanderfolgenden fehlgeschlagenen Health Checks als ausgefallen gilt. Ohne Angabe beträgt dieser Wert standardmäßig 3. Siehe auch die Parameter “check”, “inter” und “rise”.
force-sslv3
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option erzwingt die ausschließliche Verwendung von SSLv3, wenn die Kommunikation mit dem Server über SSL erfolgt. SSLv3 ist im Allgemeinen weniger kostspielig als die TLS-Gegenstücke bei hohen Verbindungsraten. Diese Option ist auch in der globalen Anweisung “ssl-default-server-options” verfügbar. Siehe auch “ssl-min-ver” und ssl-max-ver".
force-tlsv10
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option erzwingt die ausschließliche Verwendung von TLSv1.0, wenn die Kommunikation mit dem Server über SSL erfolgt. Diese Option ist auch in der globalen Anweisung “ssl-default-server-options” verfügbar. Siehe auch “ssl-min-ver” und ssl-max-ver".
force-tlsv11
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option erzwingt die ausschließliche Verwendung von TLSv1.1, wenn die Kommunikation mit dem Server über SSL erfolgt. Diese Option ist auch in der globalen Anweisung “ssl-default-server-options” verfügbar. Siehe auch “ssl-min-ver” und ssl-max-ver".
force-tlsv12
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option erzwingt die ausschließliche Verwendung von TLSv1.2, wenn die Kommunikation mit dem Server über SSL erfolgt. Diese Option ist auch in der globalen Anweisung “ssl-default-server-options” verfügbar. Siehe auch “ssl-min-ver” und ssl-max-ver".
force-tlsv13
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option erzwingt die ausschließliche Verwendung von TLSv1.3, wenn die Kommunikation mit dem Server über SSL erfolgt. Diese Option ist auch in der globalen Anweisung “ssl-default-server-options” verfügbar. Siehe auch “ssl-min-ver” und ssl-max-ver".
guid <string>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Geben Sie eine global eindeutige ID, bei der Groß- und Kleinschreibung unterschieden wird, für diesen Server an. Diese ID muss innerhalb der gesamten haproxy-Konfiguration über alle Objekttypen hinweg eindeutig sein. Weitere Informationen zum Format finden Sie in der Beschreibung des Proxy-Schlüsselworts “guid”. Siehe auch “shm-stats-file”.
hash-key <key>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Geben Sie an, wie “hash-type consistent”-Knotenschlüssel berechnet werden.
Argumente:
Die Optionen “addr” und “addr-port” können in Szenarien nützlich sein, in denen mehrere HAProxy-Prozesse den Datenverkehr an die gleiche Gruppe von Servern verteilen. Wenn die Serverreihenfolge jedes Prozesses unterschiedlich ist (z. B. weil DNS-Einträge in unterschiedlicher Reihenfolge aufgelöst wurden), ermöglicht dies jedem unabhängigen HAProxy-Prozess, sich auf Routing-Entscheidungen zu einigen. Hinweis: “balance random” verwendet ebenfalls “hash-type consistent”, und die Qualität der Verteilung hängt von der Qualität der Schlüssel ab.
healthcheck <name>
Kann in folgenden Kontexten verwendet werden: tcp, http
Geben Sie den Health-Check-Abschnitt an, der zum Durchführen des Checks auf dem Server verwendet werden soll.
Argument:
Dank dieser Option ist es möglich, eine serverspezifische Health-Check-Konfiguration anstelle der Proxy-Konfiguration zu verwenden. Siehe auch “healthcheck section”.
id <value>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Legen Sie eine persistente ID für den Server fest. Diese ID muss eine positive Zahl mit 32 Bit sein und innerhalb des Proxys eindeutig sein. Wenn nicht gesetzt, wird automatisch eine nicht verwendete ID zugewiesen. Der erste zugewiesene Wert ist 1. Diese ID wird derzeit nur in der Statistik zurückgegeben und wird verwendet, um bei konsistenten Hash-Algorithmen LB-Knoten zu platzieren, wenn “hash-key” auf “id” (Standard) gesetzt ist. In diesem Fall werden nur die 20 niedrigsten Bits des Werts verwendet (d. h. (id % 1048576)), sodass es besser ist, Werte im Bereich zwischen 1 und diesem Wert zu verwenden, um Überlappungen zu vermeiden.
idle-ping <delay>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Definieren Sie ein Intervall für regelmäßige Erreichbarkeitsprüfungen bei ungenutzten Backend-Verbindungen. Wenn die Gegenstelle vor der nächsten geplanten Prüfung nicht antwortet, wird die Verbindung geschlossen. Dieses Schlüsselwort bezieht sich auf die Backend-Seite, sodass es nützlich ist, um sicherzustellen, dass ungenutzte Verbindungen weiterhin verwendbar sind. Beachten Sie, dass dies das Schließen der Verbindung beim Bereinigen des Pools ungenutzter Verbindungen nicht verhindert.
Diese Funktion basiert auf spezifischer Protokollunterstützung. Derzeit wird sie nur vom H2-Multiplexer unterstützt. Idle-ping wird von anderen Protokollen einfach ignoriert.
Diese Option ist besonders bei Reverse HTTP nützlich. In der server-Zeile hilft sie der Gegenstelle, die auf eingehende Verbindungen lauscht und diese einem passenden Server zuordnet, damit sie später zur Weiterleitung von Datenverkehr wiederverwendet werden können.
init-addr {last | libc | none | <ip>},[...]*
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Gibt an, in welcher Reihenfolge die Serveradresse beim Start aufgelöst werden soll, wenn sie einen FQDN verwendet. Die Methoden der durch Kommas getrennten Liste werden nacheinander zur Auflösung angewendet. Verwendet wird die erste erfolgreiche Methode. Wird das Listenende ohne erfolgreiche Methode erreicht, wird ein Fehler ausgelöst. Die Methode “last” verwendet die im Statusdatei angegebene Adresse (siehe “server-state-file”). “libc” verwendet den internen Resolver der libc (gethostbyname() oder getaddrinfo(), abhängig von Betriebssystem und Build-Optionen). Die Methode “none” gibt ausdrücklich an, dass der Server ohne gültige IP-Adresse im Zustand down starten soll. Dies kann nützlich sein, um DNS-Probleme beim Start zu ignorieren und auf ihre spätere Behebung zu warten. Schließlich kann auch eine IP-Adresse (IPv4 oder IPv6) angegeben werden. Das kann die aktuell bekannte Serveradresse sein (z. B. von einem Konfigurationsgenerator eingetragen) oder die Adresse eines Dummy-Servers, der alte Sitzungen abfängt und ihnen beispielsweise eine verständliche Fehlermeldung liefert. Beim Lastverteilungsalgorithmus “first” könnte die IP-Adresse auf einen Dummy-Server verweisen, der bei Bedarf die Erzeugung neuer Instanzen auslöst. Der Standardwert ist “last,libc”: Zunächst wird die frühere Adresse aus dem Statusdatei verwendet, sofern vorhanden, andernfalls der Resolver der libc. Dies erhält die Kompatibilität mit dem bisherigen Verhalten. Bei internen Resolvern wird allgemein empfohlen, die libc-basierte Auflösung entweder zu deaktivieren oder explizit zu machen (Einzelheiten in Abschnitt 5.3 ).
Beispiel 1:
Beispiel 2:
inter <delay>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Der Parameter “inter” setzt das Intervall zwischen zwei aufeinanderfolgenden Health Checks auf
<delay> Millisekunden. Ist er nicht angegeben, beträgt das Intervall standardmäßig 2000 ms.
Mit “fastinter” und “downinter” können die Prüfintervalle außerdem abhängig vom Serverzustand
optimiert werden:
Wie bei allen zeitbasierten Parametern kann explizit eine andere Einheit aus { us, ms, s, m, h, d } angegeben werden. Der Parameter “inter” dient auch als Zeitüberschreitung für Health Checks an Server, wenn “timeout check” nicht gesetzt ist. Um “Resonanz”-Effekte bei mehreren Servern auf derselben Hardware zu verringern, werden die Agent- und Health Checks aller Server mit einem kleinen zeitlichen Versatz zueinander gestartet. Mit dem globalen Schlüsselwort “spread-checks” kann den Intervallen der Agent- und Health Checks außerdem eine zufällige Abweichung hinzugefügt werden. Das ist beispielsweise sinnvoll, wenn viele Backends dieselben Server verwenden. Ist die globale Einstellung “tune.max-checks-per-thread” auf einen Wert ungleich null gesetzt, begrenzt sie die Anzahl gleichzeitig ausgeführter Prüfungen pro Thread. Dazu stellt haproxy Prüfungen, die auf einem Thread mit bereits erreichtem Limit starten sollten, in eine Warteschlange, bis eine andere Prüfung endet. Dadurch verlängert sich das tatsächliche Prüfintervall. In diesem Fall hat eine Verringerung von “inter” nur eine sehr begrenzte Wirkung, da sie die Wartezeit in der Warteschlange nicht verkürzen kann.
init-state { fully-up | up | down | fully-down | none }
Kann in folgenden Kontexten verwendet werden: tcp, http
Kann in folgenden Abschnitten verwendet werden: defaults | frontend | listen | backend nein | nein | ja | ja
Die Option “init-state” setzt den anfänglichen Serverzustand: - Bei ‘fully-up’ gilt der Server sofort als verfügbar. Sind Health Checks für diesen Server aktiviert, wechselt er in den Zustand DOWN, wenn ALLE Health Checks fehlschlagen. - Bei ‘up’ gilt der Server sofort als verfügbar. Sind Health Checks aktiviert, wechselt er sofort nach der nächsten fehlgeschlagenen Prüfung in den Zustand DOWN. - Bei ‘down’ gilt der Server zunächst als nicht verfügbar. Sind Health Checks aktiviert, kann er nach der nächsten erfolgreichen Prüfung in den Zustand UP wechseln. - Bei ‘fully-down’ gilt der Server zunächst als nicht verfügbar. Sind Health Checks aktiviert, wechselt er in den Zustand UP, wenn ALLE Health Checks erfolgreich sind. - Bei ’none’ (dem Standardwert) ist die Verwaltung von init-state deaktiviert. Damit kann das Standardverhalten wiederhergestellt werden, wenn der Parameter von einer ‘default-server’-Direktive geerbt wurde.
Der init-state eines Servers wird berücksichtigt, wenn die HAProxy-Instanz (neu) gestartet wird, ein neuer Server erkannt wird (beispielsweise durch Diensterkennung / DNS-Auflösung), ein dynamischer Server aktiviert wird, ein Server den Wartungsmodus verlässt usw. Diese Direktive kann nicht verwendet werden, wenn der Server einen anderen Server verfolgt.
Beispiele:
Siehe auch: “option tcp-check”, “option httpchk”
ktls <on|off> [ EXPERIMENTAL ]
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Aktiviert oder deaktiviert ktls für diese Sockets. Wenn aktiviert, wird kTLS verwendet, sofern der Kernel dies unterstützt und der Verschlüsselungsalgorithmus kompatibel ist. Dies ist nur unter Linux ab 4.17 verfügbar. Beachten Sie, dass einige Netzwerktreiber und/oder TLS-Stacks die Verwendung von kTLS auf TLS v1.2 beschränken können. Siehe auch “force-tlsv12”.
log-bufsize <bufsize>
Kann in folgenden Kontexten verwendet werden: log
“log-bufsize” legt die Größe des Ringpuffers für den impliziten Ring fest, der dem Log-Server in einem Log-Backend zugeordnet wird. Ohne Angabe gilt der Standardwert BUFSIZE. Ein größerer Wert erhöht den Speicherverbrauch, kann bei langsamen Servern aber den Verlust von Protokollmeldungen verhindern helfen, da mehr ausstehende Meldungen im Puffer Platz finden. Dieses Schlüsselwort darf nur in Log-Backend-Abschnitten (mit “mode log”) verwendet werden.
log-proto <logproto>
Kann in folgenden Kontexten verwendet werden: log, ring
“log-proto” legt das Protokoll zur Weiterleitung von Ereignismeldungen an einen Server fest, der in einem log- oder ring-Abschnitt konfiguriert ist. Mögliche Werte sind “legacy” und “octet-count”; sie entsprechen “Non-transparent-framing” bzw. “Octet counting” in rfc6587. Der Standardwert ist “legacy”.
maxconn <maxconn>
Kann in folgenden Kontexten verwendet werden: tcp, http
Der Parameter “maxconn” gibt die maximale Anzahl gleichzeitiger Verbindungen zu diesem Server an. Übersteigt die Anzahl gleichzeitig eingehender Verbindungen diesen Wert, werden sie in eine Warteschlange gestellt, bis ein Platz frei wird. Dieser Parameter ist sehr wichtig, da er empfindliche Server bei extremer Last vor dem Ausfall bewahren kann. Ist “minconn” angegeben, wird die Grenze dynamisch. Der Standardwert “0” bedeutet unbegrenzt. Siehe auch “minconn”, “maxqueue” und das Backend-Schlüsselwort “fullconn”.
Im HTTP-Modus begrenzt dieser Parameter die Anzahl gleichzeitiger Anfragen statt der Verbindungen. Mehrere Anfragen können über eine einzige TCP-Verbindung zum Server multiplexiert werden. Bei einem maxconn-Wert von 50 können beispielsweise zwischen 1 und 50 tatsächliche Serververbindungen bestehen, aber höchstens 50 gleichzeitige Anfragen.
maxqueue <maxqueue>
Kann in folgenden Kontexten verwendet werden: tcp, http
Der Parameter “maxqueue” gibt die maximale Anzahl von Verbindungen an, die in der Warteschlange für diesen Server warten. Ist diese Grenze erreicht, werden weitere Anfragen auf andere Server umverteilt, anstatt unbegrenzt auf Bedienung zu warten. Das unterbricht die Persistenz, kann Benutzern aber eine schnelle erneute Anmeldung ermöglichen, wenn der gewünschte Server ausfällt. Einige Lastverteilungsalgorithmen wie leastconn berücksichtigen dies und nehmen bis zu dieser Grenze Anfragen in die Serverwarteschlange auf, wenn der Wert explizit auf einen Wert größer als null gesetzt ist. Gerade bei einstelligen maxconn-Werten lässt sich die Last damit häufig besser glätten. Der Standardwert “0” bedeutet eine unbegrenzte Warteschlange. Siehe auch die Parameter “maxconn” und “minconn” sowie “balance leastconn”.
max-reuse <count>
Kann in folgenden Kontexten verwendet werden: http, ring
Bei Verwendung im http-Kontext:
Das Argument “max-reuse” weist die HTTP-Verbindungsverarbeitung an, eine Serververbindung höchstens so oft für neue Anfragen wiederzuverwenden. Zulässig sind -1 (der Standardwert), wodurch die Grenze deaktiviert wird, oder ein positiver Wert. Der Wert null deaktiviert Keep-Alive effektiv. Dies dient ausschließlich dazu, bestimmte Serverfehler zu umgehen, die mit der Zeit Ressourcenlecks verursachen. Die unteren Schichten halten sich nicht zwingend an dieses Argument, da technische Einschränkungen dessen Durchsetzung unmöglich machen können. Zumindest HTTP/2-Verbindungen zu Servern beachten es.
Bei Verwendung im ring-Kontext:
Das Argument “max-reuse” weist die TCP-Verbindungsverarbeitung der Senke an, eine Serververbindung höchstens so oft zum Senden von Meldungen wiederzuverwenden. Die Verbindung zum Server wird also zwangsweise abgebaut, sobald mindestens “max-reuse + 1” Meldungen über dieselbe Verbindung verarbeitet wurden. Anschließend wird sie automatisch neu aufgebaut. Bei vielen Meldungen im Multithread-Betrieb kann dies helfen, die Last des Rings besser auf mehrere Threads zu verteilen. Eine Verbindung bleibt nämlich während ihrer gesamten Lebensdauer an denselben CPU-Thread gebunden: Anders als bei HTTP gibt es keine Syslog-Transaktionen. Daher könnte die Serververbindung unbegrenzt bestehen bleiben, solange der Server sie nicht schließt und kein Netzwerkfehler auftritt. Durch gelegentliches Abbauen der Verbindungen erhalten andere Threads die Möglichkeit, ihrerseits einige Meldungen zu übernehmen. Dies kann auch einen geordneten Wechsel von Log-Servern unterstützen, wenn zwischen haproxy und den Log-Servern eine zusätzliche Lastverteilungsschicht liegt. Bedenken Sie jedoch, dass bei jeder Verbindungserneuerung ein ausgehender Port im Zustand TIME_WAIT verbleibt, der auf modernen Betriebssystemen etwa eine Minute lang nicht wiederverwendet werden kann. Deshalb muss auf ausreichend hohe Werte geachtet werden, damit die Quellports nicht schnell erschöpft sind. Als Faustregel gilt: Schließen Sie Verbindungen niemals häufiger als einige Male pro Sekunde und vorzugsweise deutlich seltener. Zulässig sind -1 (der Standardwert), wodurch die Grenze deaktiviert wird, oder ein positiver Wert. Anders als im HTTP-Kontext wird “max-reuse” bei Senkenservern nur nach Möglichkeit eingehalten: Meldungen des Rings werden in Stapeln verarbeitet, und die Grenze wird zwischen den Stapeln geprüft.
minconn <minconn>
Kann in folgenden Kontexten verwendet werden: tcp, http
Wenn “minconn” gesetzt ist, wird maxconn zu einer dynamischen Grenze, die der Backend-Last folgt.
Der Server akzeptiert immer mindestens <minconn> Verbindungen und nie mehr als <maxconn>.
Hat das Backend weniger als <fullconn> gleichzeitige Verbindungen, verläuft die Grenze linear zwischen
beiden Werten. So lässt sich die Serverlast bei normaler Auslastung begrenzen und bei hoher
Last stärker erhöhen, ohne den Server bei außergewöhnlich hoher Last zu überlasten. Siehe auch
“maxconn”, “maxqueue” und das Backend-Schlüsselwort “fullconn”.
namespace <name>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Unter Linux kann festgelegt werden, welchem Netzwerknamensraum ein Socket angehört. Mit dieser Direktive kann ein Server explizit an einen anderen Namensraum als den Standardnamensraum gebunden werden. Weitere Informationen zu Netzwerknamensräumen finden Sie in der Dokumentation Ihres Betriebssystems.
no-agent-check
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “agent-check” zurückzusetzen. Sie kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “agent-check”-Einstellung aus “default-server” zurückzusetzen.
no-backup
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “backup” zurückzusetzen. Sie kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “backup”-Einstellung aus “default-server” zurückzusetzen.
no-check
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “check” zurückzusetzen. Sie kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “check”-Einstellung aus “default-server” zurückzusetzen.
no-check-reuse-pool
Kann in folgenden Kontexten verwendet werden: tcp, http
Diese Option hebt eine frühere Einstellung “check-reuse-pool” auf, die möglicherweise von “default-server” geerbt wurde. Jede Prüfung wird über ihre eigene Verbindung durchgeführt.
no-check-sni-auto
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Diese Option kann als “server”-Einstellung verwendet werden, um die standardmäßig aktivierte automatische SNI-Auswahl für SSL-Health-Checks zu deaktivieren.
Siehe “no-sni-auto”, um die automatische SNI-Auswahl für weitergeleiteten Datenverkehr zu deaktivieren.
no-check-ssl
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “check-ssl” zurückzusetzen. Sie kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “check-ssl”-Einstellung aus “default-server” zurückzusetzen.
no-renegotiate
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie deaktiviert für das betreffende SSL-Backend die Mechanismen zur Neuverhandlung, sowohl den alten unsicheren als auch die neuere “secure renegotiation” (RFC 5746 TLS Renegotiation Indication Extension). Diese Option ist auch in der globalen Anweisung “ssl-default-server-options” verfügbar. In TLS 1.3 ist keine Neuverhandlung mehr möglich. Sind weder “renegotiate” noch “no-renegotiate” angegeben, bleibt das Standardverhalten der SSL-Bibliothek erhalten. Beispielsweise aktiviert OpenSSL standardmäßig die sichere Neuverhandlung, während AWS-LC sie deaktiviert. Siehe auch “renegotiate”.
no-send-proxy
Kann in folgenden Kontexten verwendet werden: tcp, http
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “send-proxy” zurückzusetzen. Sie kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “send-proxy”-Einstellung aus “default-server” zurückzusetzen.
no-send-proxy-v2
Kann in folgenden Kontexten verwendet werden: tcp, http
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “send-proxy-v2” zurückzusetzen. Sie kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “send-proxy-v2”-Einstellung aus “default-server” zurückzusetzen.
no-send-proxy-v2-ssl
Kann in folgenden Kontexten verwendet werden: tcp, http
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “send-proxy-v2-ssl” zurückzusetzen. Sie kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “send-proxy-v2-ssl”-Einstellung aus “default-server” zurückzusetzen.
no-send-proxy-v2-ssl-cn
Kann in folgenden Kontexten verwendet werden: tcp, http
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “send-proxy-v2-ssl-cn” zurückzusetzen. Sie kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “send-proxy-v2-ssl-cn”-Einstellung aus “default-server” zurückzusetzen.
no-sni-auto
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option kann als “server”-Einstellung verwendet werden, um die standardmäßig aktivierte automatische SNI-Auswahl zu deaktivieren.
Siehe “no-check-sni-auto”, um die automatische SNI-Auswahl für SSL-Health-Checks zu deaktivieren.
no-ssl
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “ssl” zurückzusetzen. Sie kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “ssl”-Einstellung aus “default-server” zurückzusetzen.
Beachten Sie, dass bei Verwendung von default-server ssl und no-ssl für den Server dennoch eine
SSL-Verbindung initialisiert wird, damit sie später über die Runtime-API aktiviert werden kann:
Siehe die Befehle set server in der Verwaltungsdokumentation.
no-ssl-reuse
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option deaktiviert die Wiederverwendung von SSL-Sitzungen, wenn die Kommunikation mit dem Server über SSL erfolgt. Damit muss der Server für jede neue Verbindung einen vollständigen Handshake durchführen. Dies ist vermutlich nur für Benchmarks, die Fehlerbehebung und besonders misstrauische Benutzer nützlich.
no-sslv3
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option deaktiviert die Unterstützung für SSLv3, wenn die Kommunikation mit dem Server über SSL erfolgt. Beachten Sie, dass SSLv2 im Code deaktiviert ist und durch keine Konfigurationsoption aktiviert werden kann. Verwenden Sie stattdessen “ssl-min-ver” und “ssl-max-ver”.
In default-server unterstützt: Nein
no-tls-tickets
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie deaktiviert die zustandslose Sitzungswiederaufnahme (RFC 5077 TLS-Ticket-Erweiterung) und erzwingt zustandsbehaftete Sitzungswiederaufnahme. Die zustandslose Sitzungswiederaufnahme erfordert auf Servern mehr CPU-Leistung. Diese Option ist auch in der globalen Anweisung “ssl-default-server-options” verfügbar. Der TLS-Ticket-Mechanismus wird nur bis TLS 1.2 verwendet. Forward Secrecy ist mit TLS-Tickets beeinträchtigt, sofern die Ticket-Schlüssel nicht regelmäßig gewechselt werden (durch Neuladen oder mit “tls-ticket-keys”). Siehe auch “tls-tickets”.
no-tlsv10
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option deaktiviert die Unterstützung für TLSv1.0, wenn die Kommunikation mit dem Server über SSL erfolgt. Beachten Sie, dass SSLv2 im Code deaktiviert ist und durch keine Konfigurationsoption aktiviert werden kann. TLSv1 ist aufwendiger als SSLv3, daher ist es bei der Kommunikation mit lokalen Servern oft sinnvoll, es zu deaktivieren. Diese Option ist auch in der globalen Anweisung “ssl-default-server-options” verfügbar. Verwenden Sie stattdessen “ssl-min-ver” und “ssl-max-ver”.
In default-server unterstützt: Nein
no-tlsv11
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option deaktiviert die Unterstützung für TLSv1.1, wenn die Kommunikation mit dem Server über SSL erfolgt. Beachten Sie, dass SSLv2 im Code deaktiviert ist und durch keine Konfigurationsoption aktiviert werden kann. TLSv1 ist aufwendiger als SSLv3, daher ist es bei der Kommunikation mit lokalen Servern oft sinnvoll, es zu deaktivieren. Diese Option ist auch in der globalen Anweisung “ssl-default-server-options” verfügbar. Verwenden Sie stattdessen “ssl-min-ver” und “ssl-max-ver”.
In default-server unterstützt: Nein
no-tlsv12
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option deaktiviert die Unterstützung für TLSv1.2, wenn die Kommunikation mit dem Server über SSL erfolgt. Beachten Sie, dass SSLv2 im Code deaktiviert ist und durch keine Konfigurationsoption aktiviert werden kann. TLSv1 ist aufwendiger als SSLv3, daher ist es bei der Kommunikation mit lokalen Servern oft sinnvoll, es zu deaktivieren. Diese Option ist auch in der globalen Anweisung “ssl-default-server-options” verfügbar. Verwenden Sie stattdessen “ssl-min-ver” und “ssl-max-ver”.
In default-server unterstützt: Nein
no-tlsv13
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option deaktiviert die Unterstützung für TLSv1.3, wenn die Kommunikation mit dem Server über SSL erfolgt. Beachten Sie, dass SSLv2 im Code deaktiviert ist und durch keine Konfigurationsoption aktiviert werden kann. TLSv1 ist aufwendiger als SSLv3, daher ist es bei der Kommunikation mit lokalen Servern oft sinnvoll, es zu deaktivieren. Diese Option ist auch in der globalen Anweisung “ssl-default-server-options” verfügbar. Verwenden Sie stattdessen “ssl-min-ver” und “ssl-max-ver”.
In default-server unterstützt: Nein
no-verifyhost
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “verifyhost” zurückzusetzen. Sie kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “verifyhost”-Einstellung aus “default-server” zurückzusetzen.
no-tfo
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “tfo” zurückzusetzen. Sie kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “tfo”-Einstellung aus “default-server” zurückzusetzen.
non-stick
Kann in folgenden Kontexten verwendet werden: tcp, http
Fügt diesem Server zugewiesene Verbindungen niemals einer stick-table hinzu. Dies kann zusammen mit backup verwendet werden, um die Persistenz über stick-table für Backup-Server zu deaktivieren.
npn <protocols>
Kann in folgenden Kontexten verwendet werden: tcp, http
Dies aktiviert die NPN-TLS-Erweiterung und bietet die angegebene Protokollliste über NPN als unterstützt an. Die Protokollliste besteht aus einer durch Kommas getrennten Liste von Protokollnamen, beispielsweise: “http/1.1,http/1.0” (ohne Anführungszeichen). Dies erfordert, dass die SSL-Bibliothek mit aktivierter Unterstützung für TLS-Erweiterungen gebaut wurde (überprüfen Sie mit haproxy -vv). Beachten Sie, dass die NPN-Erweiterung durch die ALPN-Erweiterung ersetzt wurde (siehe das Schlüsselwort “alpn”), diese ist jedoch erst ab OpenSSL 1.0.2 verfügbar.
observe <mode>
Kann in folgenden Kontexten verwendet werden: tcp, http
Diese Option aktiviert die Anpassung des Serverzustands basierend auf der Beobachtung der Kommunikation mit dem Server. Standardmäßig ist diese Funktion deaktiviert und deren Aktivierung erfordert zudem die Aktivierung von Health Checks. Es werden zwei Modi unterstützt: “layer4” und “layer7”. Im layer4-Modus sind nur erfolgreiche oder fehlgeschlagene TCP-Verbindungen von Bedeutung. Im layer7-Modus, der nur für HTTP-Proxys erlaubt ist, werden Antworten vom Server überprüft, beispielsweise gültige oder ungültige HTTP-Codes, nicht parsbare Header, Zeitüberschreitungen usw. Gültige Statuscodes umfassen 100 bis 499, 501 und 505.
Siehe auch: “check”, “on-error” und “error-limit”.
on-error <mode>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Wählt aus, was geschehen soll, wenn genügend aufeinanderfolgende Fehler erkannt werden. Derzeit sind vier Modi verfügbar:
- fastinter: erzwingt fastinter
- fail-check: simuliert eine fehlgeschlagene Prüfung und erzwingt fastinter (Standard)
- sudden-death: simuliert eine fehlgeschlagene Health-Check-Prüfung unmittelbar vor der Ausfallgrenze; eine weitere fehlgeschlagene Prüfung markiert den Server als ausgefallen; erzwingt fastinter
- mark-down: markiert den Server sofort als ausgefallen und erzwingt fastinter
Siehe auch: “check”, “observe” und “error-limit”.
on-marked-down <action>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Ändert, was geschieht, wenn ein Server als ausgefallen markiert wird. Derzeit ist eine Aktion verfügbar:
- shutdown-sessions: Beendet Peer-Streams. Wenn diese Einstellung aktiviert ist, werden alle Verbindungen zum Server sofort beendet, sobald der Server ausfällt. Dies kann verwendet werden, wenn der Health Check komplexere Fälle als ein einfacher Verbindungsstatus erkennt und lange Zeitüberschreitungen dazu führen würden, dass der Dienst zu lange unerreichbar bleibt. Beispielsweise kann ein Health Check erkennen, dass eine Datenbank blockiert ist und dass keine bestehenden Verbindungen mehr wiederverwendet werden können. Verbindungen, die auf diese Weise beendet werden, werden mit einem ‘D’-Beendigungscode protokolliert (für “Down”).
Aktionen sind standardmäßig deaktiviert.
on-marked-up <action>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Ändert, was geschieht, wenn ein Server als aktiv markiert wird. Derzeit ist eine Aktion verfügbar:
- shutdown-backup-sessions: Beendet Streams auf allen Backup-Servern. Dies erfolgt nur, wenn der Server nicht im Backup-Status ist und nicht deaktiviert ist (er muss ein effektives Gewicht von > 0 haben). Dies kann gelegentlich verwendet werden, um einen aktiven Server nach der Wiederherstellung dazu zu zwingen, die gesamte Last wieder aufzunehmen, insbesondere bei langen Sitzungen (z. B. LDAP, SQL, …). Dies kann mehr Probleme verursachen, als es lösen soll (z. B. unvollständige Transaktionen), verwenden Sie diese Funktion daher mit äußerster Vorsicht. Streams, die aufgrund der erneuten Verfügbarkeit eines Servers beendet werden, werden mit einem ‘U’-Beendigungscode protokolliert (für “Up”).
Aktionen sind standardmäßig deaktiviert.
pool-conn-name <expr>
Kann in folgenden Kontexten verwendet werden: http
Beim Aufbau einer Backend-Verbindung wird dieser Ausdruck ausgewertet, um den Verbindungsnamen zu erzeugen. Dieser Name ist eine der Schlüsseleigenschaften der Verbindung im Pool ungenutzter Serververbindungen. Siehe das Schlüsselwort “http-reuse”. Sucht eine Anfrage eine vorhandene ungenutzte Verbindung, wird der Ausdruck ausgewertet, um eine identische Verbindung zu finden.
Im Kontext, in dem SSL SNI für die Backend-Verbindung verwendet wird, wird der Verbindungsname automatisch auf das Ergebnis des “sni”-Ausdrucks gesetzt. Dies entspricht dem häufigsten Einsatzfall. Für erweiterte Konfigurationen kann “pool-conn-name” verwendet werden, um dies zu überschreiben.
Siehe auch: “http-reuse”, “sni”
pool-low-conn <max>
Kann in folgenden Kontexten verwendet werden: http
Legt einen unteren Schwellenwert für die Anzahl ungenutzter Verbindungen zu einem Server fest. Unterhalb dieses Werts versucht ein Thread nicht, eine Verbindung von einem anderen Thread zu übernehmen. Das kann die CPU-Nutzung bei vielen sehr schnellen Servern verbessern: Alle Threads behalten jederzeit einige ungenutzte Verbindungen, statt diese bei einem Thread anzusammeln und anschließend zwischen Threads zu verschieben. Typische Werte in Höhe der doppelten Thread-Anzahl scheinen bereits bei Antwortzeiten unter einer Millisekunde sehr gute Leistung zu liefern. Der Standardwert null erlaubt, jede ungenutzte Verbindung jederzeit zu verwenden; dies ist für den normalen Einsatz empfohlen. Es gilt nur für Verbindungen, die nach denselben Grundsätzen wie bei “http-reuse” gemeinsam genutzt werden können. Wird die gemeinsame Nutzung von Verbindungen durch Threads mit “tune.idle-pool.shared” deaktiviert, kann diese Einstellung sehr wichtig sein, um jedem Thread stets einige Verbindungen zu sichern. Andernfalls sinkt die Wiederverwendungsrate mit steigender Thread-Anzahl.
pool-max-conn <max>
Kann in folgenden Kontexten verwendet werden: http
Legt die maximale Anzahl ungenutzter Verbindungen zu einem Server fest. -1 bedeutet unbegrenzt, 0 bedeutet keine ungenutzten Verbindungen. Der Standardwert ist -1. Sind ungenutzte Verbindungen aktiviert, werden verwaiste Verbindungen, die keiner Clientsitzung mehr angehören, in einen eigenen Pool verschoben. So bleiben sie für spätere Clients verwendbar. Dies gilt nur für Verbindungen, die nach denselben Grundsätzen wie bei “http-reuse” gemeinsam genutzt werden können.
pool-purge-delay <delay>
Kann in folgenden Kontexten verwendet werden: http
Legt die Verzögerung bis zum Beginn der Bereinigung ungenutzter Verbindungen fest. In jedem
Intervall von <delay> wird die Hälfte der ungenutzten Verbindungen geschlossen. 0 bedeutet, dass
keine ungenutzten Verbindungen gehalten werden. Der Standardwert ist 5s.
port <port>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Mit dem “port”-Parameter wird es möglich, einen anderen Port für Health Checks oder zur Prüfung des Agent-Checks zu verwenden. Bei einigen Servern kann es sinnvoll sein, einen Port speziell für eine Komponente zu reservieren, die komplexe Tests durchführen kann, die besser für Health Checks geeignet sind als die Anwendung selbst. Häufig wird beispielsweise ein einfaches Skript in inetd ausgeführt. Dieser Parameter wird ignoriert, wenn der “check”-Parameter nicht gesetzt ist. Siehe auch: “addr”-Parameter.
proto <name>
Kann in folgenden Kontexten verwendet werden: tcp, http
Erzwingt das Multiplexer-Protokoll für ausgehende Verbindungen zu diesem Server. Es muss mit dem Modus des Backends (TCP oder HTTP) kompatibel und auf der Backend-Seite verwendbar sein. Die Liste verfügbarer Protokolle wird von haproxy -vv ausgegeben. Angezeigt werden die Protokolleigenschaften: der Modus (TCP/HTTP), die Seite (FE/BE), der Name des Multiplexers und seine Flags.
Einige Protokolle sind anfällig für Head-of-Line-Blocking auf der Server-Seite (flag=HOL_RISK). Schließlich unterstützen einige Protokolle keine Upgrades (flag=NO_UPG). Die HTX-Kompatibilität wird ebenfalls angegeben (flag=HTX).
Folgende Protokolle können als Argument für eine “proto”-Anweisung in einer Server-Zeile verwendet werden:
Idee hinter dieser Option ist, die Auswahl des besten Multiplexer-Protokolls für alle Verbindungen, die zu diesem Server hergestellt werden, zu umgehen.
Wenn ALPN oder NPN konfiguriert ist, sollten die angegebenen Protokolle mit dem Multiplexer-Protokoll kompatibel sein, um Probleme zu vermeiden. Ist beispielsweise “proto h1” gesetzt, sollte ALPN nicht auf “h2” gesetzt werden.
Siehe auch “ws”, um für Websocket-Streams ein alternatives Protokoll zu verwenden.
QMux ist eine Teilmenge von QUIC, die über TCP läuft. Sie entspricht dem folgenden Protokollentwurf: https://www.ietf.org/archive/id/draft-ietf-quic-qmux-01.html . In haproxy gilt sie derzeit als experimentell.
quic-cc-algo { cubic | newreno | bbr | nocc }[(<args,...>)]
Diese QUIC-spezifische Einstellung wählt den Algorithmus zur Überlastkontrolle für alle Verbindungen zu diesem Server. Die Algorithmen ähneln denen von TCP. Eine vollständige Beschreibung aller Anpassungsmöglichkeiten finden Sie bei der gleichnamigen bind-Option.
Standardwert: cubic
Siehe auch: “tune.quic.be.tx.pacing” und “tune.quic.be.cc.max-win-size”
redir <prefix>
Kann in folgenden Kontexten verwendet werden: http
Der Parameter “redir” aktiviert die Umleitung für alle an diesen Server gerichteten GET- und
HEAD-Anfragen. HAProxy leitet die Anfrage dann nicht an den Server weiter, sondern sendet eine
Antwort “HTTP 302”. Deren “Location”-Header besteht aus diesem Präfix, unmittelbar gefolgt von der
angefragten URI ab dem führenden ‘/’ des Pfadbestandteils. Nach <prefix> sollte deshalb kein
abschließender Schrägstrich stehen. Alle ungültigen Anfragen werden abgewiesen; Anfragen, die weder
GET noch HEAD sind, werden normal vom Server bedient. Da die Antwort vollständig erzeugt wird,
sind darin weder Header-Änderungen noch das Einfügen von Cookies möglich. Cookies in Anfragen
werden jedoch weiterhin ausgewertet. Damit lässt sich diese Lösung auch verwenden, um Benutzer
bei einem lokalen Ausfall an einen entfernten Standort umzuleiten. Der wichtigste Einsatzzweck
besteht darin, die Bandbreite für statische Server zu erhöhen, indem Clients direkt Verbindungen
zu ihnen aufbauen. Hinweis: Verwenden Sie hier niemals ein relatives Ziel, da sonst eine Schleife
zwischen Client und HAProxy entsteht!
Beispiel: server srv1 192.168.1.1:80 redir http://image1.mydomain.com check
renegotiate
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Diese Option aktiviert den Mechanismus zur sicheren Neuverhandlung (RFC 5746 TLS Renegotiation Indication Extension) für ein bestimmtes SSL-Backend. Das bedeutet nicht, dass der SSL-Client Anfragen zur Neuverhandlung sendet; es erlaubt Backends lediglich, auf Anforderung des Servers neu zu verhandeln. Die zugrunde liegende SSL-Bibliothek muss Neuverhandlung weiterhin tatsächlich unterstützen. Diese Option ist auch in der globalen Anweisung “ssl-default-server-options” verfügbar. In TLS 1.3 ist keine Neuverhandlung mehr möglich. Sind weder “renegotiate” noch “no-renegotiate” angegeben, bleibt das Standardverhalten der SSL-Bibliothek erhalten. Beispielsweise aktiviert OpenSSL standardmäßig die sichere Neuverhandlung, während AWS-LC sie deaktiviert.
rise <count>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Der Parameter “rise” legt fest, dass ein Server nach <count> aufeinanderfolgenden erfolgreichen
Health Checks als betriebsbereit gilt. Ohne Angabe beträgt dieser Wert standardmäßig 2. Siehe auch
die Parameter “check”, “inter” und “fall”.
resolve-opts <option>,<option>,… Kann in folgenden Kontexten verwendet werden: tcp, http, log
Durch Kommas getrennte Liste von Optionen für die DNS-Auflösung dieses Servers.
Verfügbare Optionen:
-
allow-dup-ip Standardmäßig verhindert HAProxy doppelte IP-Adressen in einem Backend, wenn die DNS-Auflösung zur Laufzeit aktiv ist. In manchen Fällen ist es jedoch sinnvoll, dass zwei Server (im selben Backend und über denselben FQDN aufgelöst) dieselbe IP-Adresse haben. Aktivieren Sie dafür einfach diese Option. Sie ist das Gegenteil von prevent-dup-ip.
-
ignore-weight Ignoriert das in einem SRV-Eintrag gesetzte Gewicht. Dies ist nützlich, wenn Gewichte anders gesteuert werden sollen, beispielsweise über “agent-check” oder die Runtime-API.
-
prevent-dup-ip Setzt das Standardverhalten von HAProxy für einen Server durch: Eine IP-Adresse, die bereits einem Server im selben Backend mit demselben fqdn zugeordnet ist, darf nicht erneut verwendet werden. Dies ist das Gegenteil von allow-dup-ip.
Beispiel:
Wenn allow-dup-ip gesetzt ist:
- Gibt der Nameserver eine einzige IP-Adresse zurück, verwenden beide Server diese Adresse.
- Gibt der Nameserver 2 IP-Adressen zurück, wählt jeder Server eine andere Adresse.
Standardwert: nicht gesetzt
resolve-prefer <family>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Wenn DNS-Auflösung für einen Server aktiviert ist und mehrere IP-Adressen aus verschiedenen Adressfamilien zurückgegeben werden, bevorzugt HAProxy eine Adresse aus der im Parameter “resolve-prefer” angegebenen Familie. Siehe auch das globale Schlüsselwort “dns-accept-family”, um ausschließlich eine bestimmte Familie zu erzwingen. Verfügbare Familien: “ipv4” und “ipv6”.
Standardwert: ipv6
Beispiel:
resolve-net <network>[,<network[,...]]
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Diese Option bevorzugt die Auswahl einer IP-Adresse, die zu einem Netzwerk passt. In Clouds ist dies nützlich, um eine lokale IP-Adresse zu bevorzugen. Ein Hochverfügbarkeitsdienst in einer Cloud kann mit vielen IP-Adressen in verschiedenen Rechenzentren bekanntgegeben werden. Da die Latenz zwischen Rechenzentren nicht vernachlässigbar ist, ermöglicht diese Änderung, ein lokales Rechenzentrum zu bevorzugen. Passt keine Adresse zum konfigurierten Netzwerk, wird eine andere Adresse ausgewählt.
Beispiel:
resolvers <id>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Verweist auf einen vorhandenen Abschnitt “resolvers”, um den Hostnamen dieses Servers aufzulösen. Bei Verwendung von Resolvern wird häufig empfohlen, die libc-basierte Auflösung zu deaktivieren, auch wenn es Ausnahmen gibt (siehe Abschnitt 5.3.1 ). In jedem Fall empfiehlt es sich, bei Resolvern “init-addr” explizit anzugeben, um diesen Punkt nicht zu übersehen.
Beispiel:
Siehe auch Abschnitt 5.3 für Details zur Implementierung und zu beachtende Fallstricke.
send-proxy
Kann in folgenden Kontexten verwendet werden: tcp, http
Der Parameter “send-proxy” erzwingt das PROXY-Protokoll für jede Verbindung zu diesem Server. Das PROXY-Protokoll informiert die Gegenstelle über die Adressen auf Schicht 3/4 der eingehenden Verbindung. Dadurch kennt sie unabhängig vom Protokoll der oberen Schicht die Client-Adresse oder die angesprochene öffentliche Adresse. Bei Verbindungen, die von einem Listener mit “accept-proxy” oder “accept-netscaler-cip” angenommen wurden, wird die übermittelte Adresse verwendet. Es werden nur die Adressfamilien TCPv4 und TCPv6 unterstützt. Andere Familien, etwa Unix-Sockets, melden die Familie UNKNOWN. Server mit dieser Option können vollständig mit einer weiteren HAProxy-Instanz verkettet werden, die mit “accept-proxy” lauscht. Die Einstellung darf nicht verwendet werden, wenn der Server das Protokoll nicht versteht. Bei Health Checks an den Server wird das PROXY-Protokoll mit dieser Option automatisch verwendet, sofern nicht explizit “port” oder “addr” angegeben ist. In diesem Fall ist zusätzlich eine explizite Direktive “check-send-proxy” erforderlich. Siehe auch “no-send-proxy” in diesem Abschnitt sowie die Optionen “accept-proxy” und “accept-netscaler-cip” des Schlüsselworts “bind”.
send-proxy-v2
Kann in folgenden Kontexten verwendet werden: tcp, http
Der Parameter “send-proxy-v2” erzwingt Version 2 des PROXY-Protokolls für jede Verbindung zu diesem Server. Das PROXY-Protokoll informiert die Gegenstelle über die Adressen auf Schicht 3/4 der eingehenden Verbindung. Dadurch kennt sie unabhängig vom Protokoll der oberen Schicht die Client-Adresse oder die angesprochene öffentliche Adresse. Außerdem werden ALPN-Informationen gesendet, wenn alpn ausgehandelt wurde. Die Einstellung darf nicht verwendet werden, wenn der Server diese Protokollversion nicht versteht. Siehe auch “no-send-proxy-v2” in diesem Abschnitt und die Option send-proxy" des Schlüsselworts “bind”.
set-proxy-v2-tlv-fmt(<id>) <fmt>
Kann in folgenden Kontexten verwendet werden: tcp, http
Mit “set-proxy-v2-tlv-fmt” können beliebige TLVs der PROXY-Protokollversion 2 gesendet werden.
Zum Typbereich (<id>) der definierten TLV-Typen siehe Abschnitt 2.2.8. der PROXY-Protokollspezifikation.
Der Wert kann dagegen frei gewählt werden, sofern er die maximale Länge von 65,535 Bytes nicht
überschreitet. Die Option kann auch TLVs weiterleiten: Mit dem Sample-Abruf “fc_pp_tlv” wird dazu
ein vom Frontend empfangenes TLV-Feld abgerufen. Sie kann als server- oder default-server-Option
verwendet werden. Damit PPv2-TLVs tatsächlich gesendet werden, muss sie zusammen mit send-proxy-v2
verwendet werden.
Beispiel: server srv1 192.168.1.1:80 send-proxy-v2 set-proxy-v2-tlv-fmt(0x20) %[fc_pp_tlv(0x20)]
In diesem Fall wird das TLV-Feld vom Typ 0x20 als Zeichenfolge abgerufen und als Wert eines neu erzeugten TLV-Felds verwendet, das ebenfalls den Typ 0x20 hat.
proxy-v2-options <option>[,<option>]*
Kann in folgenden Kontexten verwendet werden: tcp, http
Der Parameter “proxy-v2-options” fügt Optionen hinzu, die bei Verwendung von “send-proxy-v2” mit Version 2 des PROXY-Protokolls gesendet werden. Verfügbar sind:
- ssl : Siehe auch “send-proxy-v2-ssl”.
- cert-cn : Siehe auch “send-proxy-v2-ssl-cn”.
- ssl-cipher: Name des verwendeten Ciphers.
- cert-sig : Signaturalgorithmus des verwendeten Zertifikats.
- cert-key : Schlüsselalgorithmus des verwendeten Zertifikats.
- authority: Vom Client übermittelter Hostname (nur SNI aus einer TLS-Verbindung wird unterstützt).
- crc32c : Prüfsumme des PROXYv2-Headers.
- unique-id: Sendet eine mit “unique-id-format” des Frontends erzeugte eindeutige ID im PROXYv2-Header. Diese unique-id ist hauptsächlich für “mode tcp” vorgesehen. In “mode http” kann sie zu unerwarteten Ergebnissen führen, da die erzeugte eindeutige ID auch für die erste HTTP-Anfrage einer Keep-Alive-Verbindung verwendet wird.
send-proxy-v2-ssl
Kann in folgenden Kontexten verwendet werden: tcp, http
Der Parameter “send-proxy-v2-ssl” erzwingt Version 2 des PROXY-Protokolls für jede Verbindung zu diesem Server. Das PROXY-Protokoll informiert die Gegenstelle über die Adressen auf Schicht 3/4 der eingehenden Verbindung. Dadurch kennt sie unabhängig vom Protokoll der oberen Schicht die Client-Adresse oder die angesprochene öffentliche Adresse. Zusätzlich wird die SSL-Informationserweiterung des PROXY-Protokolls in den PROXY-Protokoll-Header aufgenommen. Die Einstellung darf nicht verwendet werden, wenn der Server diese Protokollversion nicht versteht. Siehe auch “no-send-proxy-v2-ssl” in diesem Abschnitt und die Option “send-proxy-v2” des Schlüsselworts “bind”.
send-proxy-v2-ssl-cn
Kann in folgenden Kontexten verwendet werden: tcp, http
Der Parameter “send-proxy-v2-ssl” erzwingt Version 2 des PROXY-Protokolls für jede Verbindung zu diesem Server. Das PROXY-Protokoll informiert die Gegenstelle über die Adressen auf Schicht 3/4 der eingehenden Verbindung. Dadurch kennt sie unabhängig vom Protokoll der oberen Schicht die Client-Adresse oder die angesprochene öffentliche Adresse. Zusätzlich werden die SSL-Informationserweiterung des PROXY-Protokolls sowie der Common Name aus dem Subject des Client-Zertifikats (falls vorhanden) in den PROXY-Protokoll-Header aufgenommen. Die Einstellung darf nicht verwendet werden, wenn der Server diese Protokollversion nicht versteht. Siehe auch “no-send-proxy-v2-ssl-cn” in diesem Abschnitt und die Option “send-proxy-v2” des Schlüsselworts “bind”.
shard <shard>
Kann in folgenden Kontexten verwendet werden: peers
Dieser Parameter wird nur bei der Synchronisierung von stick-tables über das peers-Protokoll verwendet. “shard” bezeichnet die Peers, die alle Stick-Table-Aktualisierungen für Schlüssel empfangen, deren Verteilungshash diesem Shard entspricht. Zulässige Werte reichen von 0 bis zum Wert des Parameters “shards” im Abschnitt “peers”. Der Standardwert 0 bedeutet, dass der Peer alle Schlüsselaktualisierungen empfängt. Werte größer als “shards” werden ignoriert. Ebenso wird jeder für den lokalen Peer angegebene Wert ignoriert.
Beispiel:
sigalgs <sigalgs>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Sie legt die Zeichenfolge mit der Liste der Signaturalgorithmen fest, die beim TLSv1.2- und TLSv1.3-Handshake ausgehandelt werden. Das Format der Zeichenfolge ist in “man 3 SSL_CTX_set1_sigalgs” in den OpenSSL-Handbuchseiten beschrieben. Von dieser Einstellung wird abgeraten, sofern keine Kompatibilität mit einer Middlebox erforderlich ist.
slowstart <start_time_in_ms>
Kann in folgenden Kontexten verwendet werden: tcp, http
Der Parameter “slowstart” eines Servers nimmt einen Wert in Millisekunden entgegen. Dieser gibt an, nach welcher Zeit ein gerade wieder verfügbar gewordener Server mit voller Leistung arbeitet. Wie bei allen zeitbasierten Parametern kann explizit eine andere Einheit aus { us, ms, s, m, h, d } angegeben werden. Die Leistung steigt während dieser Zeit linear von 0 auf 100%. Die Begrenzung wirkt auf zwei Parameter:
-
maxconn: Die vom Server akzeptierte Verbindungsanzahl steigt von 1 auf 100% der üblichen dynamischen Grenze, die durch (minconn,maxconn,fullconn) definiert ist.
-
weight: Verwendet das Backend einen dynamisch gewichteten Algorithmus, steigt das Gewicht linear von 1 auf 100%. Dabei wird es bei jedem Health Check aktualisiert. Deshalb ist es wichtig, dass “inter” kleiner als “slowstart” ist, um die Anzahl der Schritte zu maximieren.
slowstart gilt niemals beim Start von HAProxy, da dies laufende Server beeinträchtigen würde. Es gilt nur, wenn ein Server zuvor als ausgefallen erkannt wurde.
sni <expression>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Der Parameter “sni” wertet den Sample-Abrufausdruck aus, wandelt ihn in eine Zeichenfolge um und verwendet das Ergebnis als Hostnamen in der SNI-TLS-Erweiterung an den Server. Ein typischer Anwendungsfall ist, in einem TCP/SSL-Brückenszenario die vom Client empfangene SNI weiterzugeben; als Ausdruck dient dabei der Sample-Abruf “ssl_fc_sni”. DIES DARF NICHT FÜR HTTPS VERWENDET WERDEN. Dort sollte stattdessen req.hdr(host) verwendet werden, da die SNI bei HTTPS immer dem Host-Feld entsprechen muss und Clients über dieselbe Verbindung verschiedene Hostnamen verwenden dürfen). Ist “verify required” gesetzt (die empfohlene Einstellung), wird der resultierende Name außerdem mit den Namen im Serverzertifikat abgeglichen. Weitere Informationen finden Sie bei “verify”. Soll die SNI für Health Checks gesetzt werden, finden Sie Einzelheiten bei “check-sni”.
Standardmäßig wird die SNI dem Verbindungsnamen für “http-reuse” zugewiesen, sofern dieser nicht durch das Server-Schlüsselwort “pool-conn-name” überschrieben wird.
sni-auto
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Der Parameter “sni-auto” aktiviert die automatische SNI-Auswahl, sofern noch kein Wert gesetzt wurde. Er setzt den Ausdruck “sni” auf “req.hdr(host),field(1,:)”. Damit wird die SNI mit dem Hostnamen der an den Server gesendeten Anfrage übermittelt, jedoch ohne Portnummer. Dies ist standardmäßig aktiviert. Als “server”-Einstellung kann dieser Parameter jedoch eine über “default-server” geerbte Standardeinstellung “no-sni-auto” zurücksetzen. Er kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “no-sni-auto”-Einstellung aus “default-server” zurückzusetzen.
Bei HTTPS-Verbindungen richtet sich die gewählte SNI nach dem Wert des host-Headers der Anfrage, sofern dieser vorhanden ist. Andernfalls bleibt sie ungesetzt. Bei anderen Protokollen wird die Option ignoriert.
Wird die automatische SNI-Auswahl verwendet, wird der Wert dem Verbindungsnamen für “http-reuse” zugewiesen, sofern dieser nicht durch das Server-Schlüsselwort “pool-conn-name” überschrieben wird.
Siehe “check-sni-auto”, um die automatische SNI-Auswahl für SSL-Health-Checks zu aktivieren.
source <addr>[:<pl>[-<ph>]] [usesrc { <addr2>[:<port2>] | client | clientip } ]
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Der Parameter “source” setzt die Quelladresse für Verbindungen zum Server. Er verwendet genau dieselben Parameter und dasselbe Prinzip wie das Backend-Schlüsselwort “source”, gilt aber nur für den Server, der darauf verweist. Einzelheiten finden Sie beim Schlüsselwort “source”.
Zusätzlich kann mit “source” in einer server-Zeile ein Quellportbereich angegeben werden. Dazu werden die untere und obere Grenze durch einen Bindestrich (’-’) getrennt. Einige Betriebssysteme verlangen möglicherweise eine gültige IP-Adresse, wenn ein Quellportbereich angegeben ist. Mehrere Server dürfen dieselbe IP-Adresse und denselben Bereich verwenden. Damit lässt sich die Grenze von insgesamt 64k gleichzeitigen Verbindungen umgehen; die Grenze liegt dann bei 64k Verbindungen pro Server.
Seit Linux 4.2/libc 2.23 wird IP_BIND_ADDRESS_NO_PORT für Verbindungen gesetzt, bei denen eine Quelladresse ohne Portangabe angegeben ist.
ssl
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option aktiviert die SSL-Verschlüsselung ausgehender Verbindungen zum Server. Bei SSL-Verbindungen zu Servern ist die Prüfung der Serverzertifikate mit “verify” entscheidend; andernfalls ist die Kommunikation für einfache Man-in-the-Middle-Angriffe anfällig, wodurch SSL nutzlos wird. Mit dieser Option werden auch Health Checks automatisch über SSL gesendet, sofern nicht eine “port”- oder “addr”-Direktive ein anderes Prüfziel angibt. Siehe “no-ssl”, um “ssl” zu deaktivieren, und “check-ssl”, um SSL-Health-Checks zu erzwingen.
ssl-max-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option erzwingt die Verwendung von <version> oder einer niedrigeren Version, wenn die
Kommunikation mit dem Server über SSL erfolgt. Sie ist auch in der globalen Anweisung
“ssl-default-server-options” verfügbar. Siehe auch “ssl-min-ver”.
ssl-min-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option erzwingt die Verwendung von <version> oder einer höheren Version, wenn die
Kommunikation mit dem Server über SSL erfolgt. Sie ist auch in der globalen Anweisung
“ssl-default-server-options” verfügbar. Siehe auch “ssl-max-ver”.
ssl-reuse
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “no-ssl-reuse” zurückzusetzen. Sie kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “no-ssl-reuse”-Einstellung aus “default-server” zurückzusetzen.
stick
Kann in folgenden Kontexten verwendet werden: tcp, http
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “non-stick” zurückzusetzen. Sie kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “non-stick”-Einstellung aus “default-server” zurückzusetzen.
strict-maxconn
Kann in folgenden Kontexten verwendet werden: tcp, http
Die Bezeichnung maxconn für Server ist etwas irreführend: Sie legt tatsächlich die maximale Anzahl an Anfragen fest, die an einen Server gesendet werden. Mit ungenutzten Verbindungen kann die Gesamtzahl der Verbindungen zum Server jedoch höher sein. Wird eine strikte Verbindungsgrenze benötigt, kann strict-maxconn ergänzt werden. Dann werden niemals mehr als maxconn Verbindungen zu einem Server aufgebaut; bei Bedarf werden Verbindungen wiederverwendet oder beendet. Beachten Sie jedoch, dass Anfragen dadurch fehlschlagen können, wenn keine neue Verbindung aufgebaut werden kann und keine ungenutzte Verbindung verfügbar ist. Das kann bei als “private” bezeichneten Verbindungen geschehen, die wegen einer erfolgten Authentifizierung ausschließlich an eine Sitzung gebunden sind.
socks4 <addr>:<port>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option aktiviert einen vorgeschalteten socks4-Tunnel für ausgehende Verbindungen zum Server. Sie erzwingt standardmäßig nicht, dass Health Checks über socks4 laufen. Dafür muss das Schlüsselwort “check-via-socks4” verwendet werden.
tcp-md5sig <password>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Aktiviert die TCP-MD5-Signatur (RFC 2385 Schutz von BGP-Sitzungen mithilfe der TCP-MD5-Signaturoption)
für alle ausgehenden Verbindungen zu diesem Server. Diese Option ist nur unter Linux verfügbar.
Wenn sie aktiviert ist, wird die Zeichenfolge <password> verwendet, um jedes TCP-Segment mit
einem 16-Byte-MD5-Digest zu signieren. Dies schützt die TCP-Verbindung vor Spoofing. Der wichtigste
Anwendungsfall ist der Schutz von BGP gegen das Einschleusen gefälschter TCP-Segmente in den
Verbindungsstrom. Die Option kann aber für alle sehr langlebigen TCP-Verbindungen nützlich sein.
tcp-ut <delay>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Setzt den TCP User Timeout für alle ausgehenden Verbindungen zu diesem Server. Diese Option ist unter Linux seit Version 2.6.37 verfügbar. Damit kann HAProxy eine Zeitüberschreitung für Sockets konfigurieren, deren Daten innerhalb der angegebenen Zeit keine Bestätigung erhalten. Dies ist besonders für langlebige Verbindungen mit langen Leerlaufzeiten nützlich, etwa Remote-Terminals oder Datenbank-Verbindungspools. Dort müssen die Zeitüberschreitungen für Client und Server hoch bleiben, um lange Leerlaufzeiten zu ermöglichen; zugleich ist es wichtig, das Verschwinden des Servers zu erkennen, um alle Ressourcen seiner Verbindung (und der Clientsitzung) freizugeben. Ein weiterer typischer Anwendungsfall ist, Verbindungen zu ausgefallenen Servern zwangsweise zu beenden, wenn Health Checks zu langsam sind oder während eines unterbrechungsfreien Neuladens, bei dem Health Checks deaktiviert sind. Das Argument ist eine Zeitspanne, standardmäßig in Millisekunden. Dies funktioniert nur bei regulären TCP-Verbindungen und wird bei anderen Protokollen ignoriert.
tfo
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option aktiviert TCP Fast Open für Verbindungen zu Servern auf Systemen, die es unterstützen (derzeit nur Linux-Kernel >= 4.11). Weitere Informationen zu TCP Fast Open finden Sie bei der bind-Option “tfo”. Beachten Sie, dass bei tfo auch die Schlüsselwörter “conn-failure”, “empty-response” und “response-timeout” für “retry-on” verwendet werden sollten. Andernfalls kann HAProxy die Verbindung bei einem Fehler nicht erneut versuchen. Siehe auch “no-tfo”.
track [<backend>/]<server>
Kann in folgenden Kontexten verwendet werden: tcp, http, log
Mit dieser Option wird der aktuelle Zustand eines Servers durch Verfolgen eines anderen Servers
bestimmt. Auch ein Server, der seinerseits einen anderen verfolgt, kann verfolgt werden, sofern am
Ende der Kette ein Server mit aktivierten Health Checks steht. Fehlt <backend>, wird das aktuelle
Backend verwendet. Wird disable-on-404 verwendet, muss es auf beiden Proxys aktiviert sein.
Beispiel:
tls-tickets
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Option kann als “server”-Einstellung verwendet werden, um eine über “default-server” als Standardwert geerbte Einstellung “no-tls-tickets” zurückzusetzen. Der TLS-Ticket-Mechanismus wird nur bis TLS 1.2 verwendet. Forward Secrecy ist mit TLS-Tickets beeinträchtigt, sofern die Ticket-Schlüssel nicht regelmäßig gewechselt werden (durch Neuladen oder mit “tls-ticket-keys”). Die Option kann auch als “default-server”-Einstellung verwendet werden, um eine frühere “no-tls-tickets”-Einstellung aus “default-server” zurückzusetzen.
verify [none|required]
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde. Bei ’none’ wird das Serverzertifikat nicht überprüft. Andernfalls wird das vom Server bereitgestellte Zertifikat mit den CAs aus ‘ca-file’ und optionalen CRLs aus ‘crl-file’ überprüft, nachdem geprüft wurde, ob die Namen in den Zertifikatsattributen subject und subjectAlternateNames mit dem über “sni” übergebenen Namen übereinstimmen. Wurde dieser nicht angegeben, wird der mit “verifyhost” übergebene statische Hostname verwendet. Wird kein Name gefunden, werden die Namen im Zertifikat ignoriert. Deshalb ist es ohne SNI wichtig, “verifyhost” zu verwenden. Schlägt die Überprüfung fehl, wird der Handshake abgebrochen. Bei SSL-Verbindungen zu Servern ist die Überprüfung der Serverzertifikate von entscheidender Bedeutung; andernfalls ist die Kommunikation für einfache Man-in-the-Middle-Angriffe anfällig und SSL dadurch völlig nutzlos. Sofern “ssl_server_verify” nicht im globalen Abschnitt steht, ist “verify” standardmäßig auf “required” gesetzt.
verifyhost <hostname>
Kann in folgenden Kontexten verwendet werden: tcp, http, log, peers, ring
Diese Einstellung ist nur verfügbar, wenn Unterstützung für OpenSSL einkompiliert wurde, und wirkt nur, wenn auch ‘verify required’ angegeben ist. Sie legt einen statischen Standardhostnamen fest, gegen den das Serverzertifikat geprüft wird, wenn für die Verbindung zum Server keine SNI verwendet wurde. Ohne SNI ist dies die einzige Möglichkeit, die Hostnamenprüfung zu aktivieren. Der statische Hostname wird, sofern gesetzt, auch für Health Checks verwendet, wenn diese keinen SNI-Wert bereitstellen. Passt keiner der Hostnamen im Zertifikat zum angegebenen Hostnamen, wird der Handshake abgebrochen. Die Hostnamen im vom Server bereitgestellten Zertifikat dürfen Platzhalter enthalten. Siehe auch “verify”, “sni” und “no-verifyhost”.
weight <weight>
Kann in folgenden Kontexten verwendet werden: tcp, http
Der Parameter “weight” passt das Gewicht des Servers im Verhältnis zu anderen Servern an. Alle Server erhalten Last proportional zu ihrem Gewicht im Verhältnis zur Summe aller Gewichte: Je höher das Gewicht, desto höher die Last. Das Standardgewicht ist 1, der Maximalwert 256. Bei 0 nimmt der Server nicht an der Lastverteilung teil, akzeptiert aber weiterhin durch Persistenz zugeordnete Verbindungen. Wird die Last damit entsprechend der Serverkapazität verteilt, empfiehlt es sich, mit Werten zu beginnen, die erhöht und verringert werden können, beispielsweise zwischen 10 und 100. So bleibt für spätere Anpassungen ausreichend Spielraum nach oben und unten.
ws { auto | h1 | h2 }
Kann in folgenden Kontexten verwendet werden: http
Mit dieser Option wird das Protokoll zur Weiterleitung von Websocket-Streams konfiguriert. Dies ist besonders bei einem HTTP/2-Backend nützlich, das H2-Websockets gemäß RFC8441 nicht unterstützt.
Der Standardmodus ist “auto”. Er verwendet dasselbe Protokoll wie das Hauptprotokoll. Nur bei ALPN gibt es einen Unterschied: Hier kann versucht werden, die ALPN ausschließlich für Websocket-Streams auf “http/1.1” herabzusetzen, sofern die konfigurierte Server-ALPN dieses Protokoll enthält.
Der Wert “h1” erzwingt HTTP/1.1 für Websocket-Streams; ist SSL-ALPN für den Server aktiviert, erfolgt dies über ALPN. Entsprechend kann “h2” HTTP/2.0-Websockets erzwingen. Verwenden Sie diesen Wert mit Vorsicht: Der Server muss RFC8441 unterstützen, andernfalls meldet haproxy beim Weiterleiten von Websockets einen Fehler.
Beachten Sie, dass NPN nicht berücksichtigt wird, da es zugunsten der ALPN-Erweiterung als veraltet gilt.
Siehe auch “alpn” und “proto”.
5.3. Auflösung von Server-IP-Adressen über DNS
HAProxy erlaubt einen Hostnamen in der server-Zeile, um die IP-Adresse über Nameserver zu ermitteln. Standardmäßig löst HAProxy den Namen beim Start während des Parsens der Konfigurationsdatei auf und speichert das Ergebnis für die gesamte Prozesslebensdauer zwischen. In manchen Fällen reicht dies nicht aus, etwa bei Amazon, wo sich die IP eines Servers nach einem Neustart ändern kann oder die virtuelle IP eines ELB von der aktuellen Auslastung abhängt.
Dieses Kapitel beschreibt, wie HAProxy zur Namensauflösung von Servern während der Laufzeit konfiguriert werden kann.
Unabhängig davon, ob die Servernamensauflösung zur Laufzeit aktiviert ist, führt HAProxy standardmäßig beim Start während des Parsens der Konfiguration die erste Auflösung über libc durch, sofern dies nicht mit “init-addr” deaktiviert wurde.
5.3.1. Überblick
Wie in der Einleitung beschrieben, erfolgt die Namensauflösung in HAProxy an zwei verschiedenen Punkten der Prozesslebensdauer:
Weitere Ereignisse können zur Laufzeit eine Namensauflösung auslösen:
- Wenn der Health Check eines Servers mit einer Verbindungszeitüberschreitung endet, kann dies daran liegen, dass der Server eine neue IP-Adresse hat. Daher muss eine Namensauflösung ausgelöst werden, um die neue IP zu ermitteln.
Bei Verwendung von Resolvern kann der Servername entweder ein Hostname oder ein SRV-Label sein. HAProxy betrachtet alles, was mit einem Unterstrich beginnt, als SRV-Label. Ist ein SRV-Label angegeben, werden die zugehörigen SRV-Einträge vom DNS-Server abgerufen und die darin enthaltenen Hostnamen verwendet. Das SRV-Label wird regelmäßig geprüft. Werden Server hinzugefügt oder entfernt, übernimmt HAProxy diese Änderungen automatisch.
Dabei ist Folgendes zu beachten:
-
Alle Nameserver werden gleichzeitig abgefragt. HAProxy verarbeitet die erste gültige Antwort.
-
Eine Auflösung gilt als ungültig (NX, Zeitüberschreitung, abgelehnt), wenn alle Server einen Fehler zurückgeben.
-
Der in HAProxy implementierte DNS-Client ist sehr einfach und versteht die Vielzahl von Optionen und erweiterten Konfigurationen nicht, die der Resolver eines Betriebssystems verarbeiten kann. Außer bei sehr einfachen Konfigurationen, in denen ein durch seinen FQDN bekannter Server stets genau eine IP-Adresse hat und diese gelegentlich erneuert (z. B. nach einem Neustart), wird daher dringend empfohlen, libc-basierte Auflösung beim Start nicht mit DNS-basierter Auflösung zur Laufzeit zu mischen. Solche Mischkonfigurationen verursachen bekanntermaßen Fehler bei der Adresserneuerung. Sofern Sie nicht genau wissen, was Sie tun, sollten Sie deshalb “libc” immer aus “init-addr” ausschließen, wenn Sie “resolvers” in einer server-Zeile verwenden.
5.3.2. Der Abschnitt resolvers
Dieser Abschnitt enthält Informationen zur Namensauflösung in HAProxy. Es können beliebig viele resolvers-Abschnitte angelegt werden. Jeder Abschnitt kann mehrere Nameserver enthalten.
Beim Start versucht HAProxy, einen resolvers-Abschnitt namens “default” zu erzeugen, sofern in der Konfiguration noch kein Abschnitt so benannt wurde. Er wird standardmäßig vom httpclient verwendet und nutzt das Schlüsselwort parse-resolv-conf. Kann HAProxy diesen Abschnitt nicht automatisch erzeugen, wird weder ein Fehler noch eine Warnung ausgegeben.
Sind in einem resolvers-Abschnitt mehrere Nameserver konfiguriert, verwendet HAProxy die erste gültige Antwort. Bei ungültigen Antworten wird nur die letzte behandelt. So erhält ein langsamer Server die Möglichkeit, nach einem schnellen fehlerhaften oder veralteten Server noch eine gültige Antwort zu liefern.
Gibt jeder Server einen anderen Fehlertyp zurück, verwendet HAProxy nur den letzten Fehler. Auf diesen wird die folgende Verarbeitung angewendet:
Bei 2 Nameservern in einem resolvers-Abschnitt sind beispielsweise folgende Abläufe möglich:
-
Die erste Antwort ist gültig und wird sofort übernommen; die zweite wird ignoriert.
-
Die erste Antwort ist ungültig, die zweite gültig; dann wird die zweite übernommen.
-
Die erste Antwort ist NX domain, die zweite ist abgeschnitten; HAProxy wiederholt die Abfrage dann mit einem neuen Typ.
-
Die erste Antwort ist NX domain, bei der zweiten tritt eine Zeitüberschreitung auf; HAProxy wiederholt die Abfrage dann mit einem neuen Typ.
-
Bei beiden Nameservern tritt eine Zeitüberschreitung auf; HAProxy wiederholt die Abfrage dann mit demselben Abfragetyp.
Da ein DNS-Server möglicherweise nicht alle IP-Adressen in einer DNS-Antwort zurückgibt, speichert
HAProxy frühere Antworten zwischen. Eine Antwort gilt als veraltet, wenn die IP-Adresse
<hold obsolete> Sekunden lang nicht zurückgegeben wurde.
resolvers <resolvers id>
Erzeugt eine neue Nameserverliste mit der Kennung <resolvers id>. Wie oben beschrieben, existiert
der besondere Name “default” immer und wird automatisch erzeugt, wenn er nicht explizit deklariert
wurde. Interne Dienste wie httpclient verwenden diesen Eintrag. Die Deklaration eines Eintrags
“default” beeinflusst daher die Namensauflösung dieser Dienste.
Ein resolvers-Abschnitt akzeptiert die folgenden Parameter:
accepted_payload_size <nb>
Definiert die maximale Nutzlastgröße, die HAProxy akzeptiert und allen in diesem resolvers-Abschnitt
konfigurierten Nameservern mitteilt. <nb> wird in Bytes angegeben. Ohne Angabe meldet HAProxy 512
(den von RFC 6891 definierten Mindestwert).
Hinweis: Der höchste zulässige Wert ist 65535. Für UDP wird 4096 empfohlen; von Werten über 8192 wird abgeraten, sofern Sie nicht sicher sind, dass System und Netzwerk damit umgehen können. Werte über 65507 sind nicht sinnvoll, da dies die maximale UDP-Nutzlastgröße ist. Wenn Sie nur TCP-Nameserver zur Verarbeitung sehr großer DNS-Antworten verwenden, sollten Sie den Höchstwert 65535 setzen.
nameserver <name> <address>[:port] [param*]
Konfiguriert einen Nameserver. Dessen <name> sollte eindeutig sein. Standardmäßig wird <address>
als Datagramm-Adresse betrachtet. Ist also eine IPv4- oder IPv6-Adresse ohne besondere
Adresspräfixe (Absatz 11.) konfiguriert, wird UDP verwendet. Mit einem Adresspräfix für ein
Stream-Protokoll gilt der Nameserver als Stream-Server (beispielsweise TCP), und die für
DNS-Auflösung relevanten “server”-Parameter aus Abschnitt 5.2 werden berücksichtigt. Hinweis:
Derzeit werden im TCP-Modus 4 Abfragen im Pipelining-Verfahren über dieselben Verbindungen gesendet.
Alle 5 Sekunden wird eine Gruppe ungenutzter Verbindungen entfernt. Mit “maxconn” kann die Anzahl
dieser gleichzeitigen Verbindungen begrenzt werden. TLS sollte ebenfalls nutzbar sein, sofern der
Server es unterstützt.
parse-resolv-conf
Fügt alle Nameserver aus /etc/resolv.conf zur Nameserverliste dieses resolvers-Abschnitts hinzu. Die Reihenfolge entspricht der, die entstünde, wenn jeder Nameserver aus /etc/resolv.conf anstelle dieser Direktive einzeln im resolvers-Abschnitt stünde.
hold <status> <period>
Bestimmt beim Empfang einer DNS-Antwort mit <status>, ob der Serverzustand von UP zu DOWN
wechseln soll. Dazu wird geprüft, ob innerhalb der zurückliegenden Zeitspanne <period> ein
gültiger Status empfangen wurde, der den gerade empfangenen ungültigen Status aufhebt.
`<status>`: letzter Status der Namensauflösung.
nx Nach einem NXDOMAIN-Status wird geprüft, ob im
zurückliegenden Zeitraum ein gültiger Status vorlag.
refused Nach einem REFUSED-Status wird geprüft, ob im
zurückliegenden Zeitraum ein gültiger Status vorlag.
timeout Nach Ablauf von "timeout retry" wird geprüft, ob im
zurückliegenden Zeitraum ein gültiger Status vorlag.
other Nach einem anderen ungültigen Status wird geprüft, ob im
zurückliegenden Zeitraum ein gültiger Status vorlag.
valid Gilt nur für die Aktionen "http-request do-resolve" und
"tcp-request content do-resolve". Definiert, wie lange
der Server eine gültige Antwort behält, bevor er eine
weitere Auflösung auslöst. Beeinflusst nicht die
dynamische Auflösung von Servern.
obsolete Definiert, wie lange nach Empfang eines aktualisierten
Antworteintrags gewartet wird, bevor veraltete DNS-Einträge
entfernt werden. Gilt für SRV-Einträge.
`<period>`: Zurückliegende Zeitspanne, innerhalb derer eine gültige Antwort
empfangen worden sein muss. Verwendet das HAProxy-Zeitformat
und wird standardmäßig in Millisekunden angegeben.
Bei einem Server, dessen IP-Adresse dynamisch über DNS ermittelt wird, führt eine ungültige
DNS-Antwort wie NXDOMAIN zum Wechsel von UP zu DOWN. Die hold-Direktiven legen fest, wie weit in
der Vergangenheit nach einer gültigen Antwort gesucht wird. Wurde innerhalb von <period> eine
gültige Antwort empfangen, wird der gerade empfangene ungültige Status ignoriert.
Wurde im zurückliegenden Zeitraum keine gültige Antwort empfangen, wird der Server als DOWN markiert. Ist beispielsweise “hold nx 30s” gesetzt und die zuletzt empfangene DNS-Antwort war NXDOMAIN, wird der Server als DOWN markiert, sofern in den letzten 30 Sekunden keine gültige Antwort empfangen wurde.
Ein Server im Zustand DOWN wird sofort als UP markiert, sobald ein gültiger Status vom DNS-Server eintrifft.
Für “hold valid” und “hold obsolete” gilt ein gesondertes Verhalten.
Der Standardwert beträgt 10s für “valid”, 0s für “obsolete” und 30s für die anderen Werte.
resolve_retries <nb>
Definiert die Anzahl <nb> der Abfragen zur Auflösung eines Servernamens, bevor aufgegeben wird.
Standardwert: 3
Ein Wiederholungsversuch erfolgt bei einer Nameserver-Zeitüberschreitung oder wenn die gesamte Folge des Wechsels zwischen DNS-Abfragetypen abgeschlossen ist und erneut beim standardmäßigen Abfragetyp ANY begonnen werden muss.
timeout <event> <time>
Definiert Zeitüberschreitungen für die Namensauflösung. <event> bezeichnet das Ereignis, für das
die Zeitspanne <time> gilt. Verfügbar sind: - resolve: Standardzeit bis zum Auslösen von
Namensauflösungen, wenn keine andere Zeit gilt. Standardwert: 1s - retry : Zeit zwischen zwei
DNS-Abfragen, wenn keine gültige Antwort empfangen wurde. Standardwert: 1s <time> : dem Ereignis
zugeordnete Zeit. Verwendet das HAProxy-Zeitformat. <time> wird in Millisekunden angegeben.
Beispiel:
15 - 6. Cache
HAProxy bietet einen Cache für kleine Objekte wie Favicons oder CSS-Dateien. Dieser einfache, wartungsarme Cache arbeitet im RAM.
Der Cache verwendet einen von allen Threads gemeinsam genutzten Speicherbereich, der in Blöcke von 1kB aufgeteilt ist.
Wird ein Objekt nicht mehr verwendet, kann es unabhängig von seinem Ablaufdatum gelöscht werden, um ein neues Objekt zu speichern. Beim Reservieren eines neuen Objekts werden die ältesten Objekte zuerst gelöscht.
Als Schlüssel verwendet der Cache einen Hash aus Host-Header und URI.
Der Cache-Status lässt sich mit dem UNIX-Socket-Befehl “show cache” anzeigen. Einzelheiten stehen in Abschnitt 9.3 „UNIX-Socket-Befehle“ des Verwaltungshandbuchs.
Wird ein Objekt aus dem Cache ausgeliefert, steht im Protokoll statt des Servernamens “<CACHE>”.
6.1. Einschränkungen
In folgenden Fällen speichert der Cache keine Objekte und liefert auch keine aus:
-
Wenn die Antwort keinen Status 200 hat.
-
Wenn die Antwort einen Vary-Header enthält und entweder process-vary deaktiviert ist oder der Vary-Wert einen derzeit nicht unterstützten Header nennt. Unterstützt werden derzeit nur accept-encoding, referer und origin.
-
Wenn Content-Length plus Header-Größe größer als “max-object-size” ist.
-
Wenn die Antwort nicht zwischengespeichert werden darf.
-
Wenn die Antwort weder einen ausdrücklichen Ablaufzeitpunkt (Cache-Control-Direktiven s-maxage oder max-age beziehungsweise Expires-Header) noch einen Validator (ETag- oder Last-Modified-Header) enthält.
-
Wenn process-vary aktiviert ist und bereits max-secondary-entries Einträge mit demselben Primärschlüssel wie die aktuelle Antwort vorhanden sind.
-
Wenn process-vary aktiviert ist, die Antwort vom Client-Header accept-encoding abhängt und eine unbekannte Kodierung verwendet, die nicht unter https://www.iana.org/assignments/http-parameters/http-parameters.xhtml aufgeführt ist.
-
Wenn die Anfrage keine GET-Anfrage ist.
-
Wenn die HTTP-Version der Anfrage kleiner als 1.1 ist.
-
Wenn die Anfrage einen Authorization-Header enthält.
6.2. Einrichtung
Zur Einrichtung muss ein cache-Abschnitt definiert und mit den entsprechenden http-request- und http-response-Aktionen in einem Proxy verwendet werden.
6.2.1. Cache-Abschnitt
cache <name>
Deklariert einen Cache-Abschnitt und reserviert gemeinsam genutzten Cache-Speicher namens <name>. Die Cache-Größe muss angegeben werden; siehe unten “total-max-size”.
max-age <seconds>
Legt die maximale Gültigkeitsdauer fest. Als Ablaufzeit gilt der kleinere Wert aus dieser Einstellung und der Direktive s-maxage beziehungsweise max-age (in dieser Reihenfolge) im Antwort-Header Cache-Control. Der Standardwert beträgt 60 Sekunden; standardmäßig kann ein Objekt daher höchstens 60 Sekunden zwischengespeichert werden.
max-object-size <bytes>
Legt die maximale Größe zwischengespeicherter Objekte fest. Sie darf die Hälfte von “total-max-size” nicht überschreiten. Ohne Angabe entspricht sie dem 256. Teil der Cache-Größe. Objekte, die größer als “max-object-size” sind, werden nicht zwischengespeichert.
max-secondary-entries <number>
Legt die maximale Anzahl gleichzeitig vorhandener Sekundäreinträge mit demselben Primärschlüssel im Cache fest. Dafür muss die Vary-Unterstützung aktiviert sein. Der Standardwert ist 10; angegeben werden sollte eine strikt positive Ganzzahl.
process-vary <on/off>
Aktiviert oder deaktiviert die Verarbeitung des Vary-Headers. Bei deaktivierter Verarbeitung werden Antworten mit diesem Header niemals zwischengespeichert. Bei aktivierter Verarbeitung muss für alle eingehenden Anfragen zunächst ein Hash über einen Teil der Anfrage-Header berechnet werden, was CPU-Zeit kosten kann. Daraus entsteht der Sekundärschlüssel der jeweiligen Anfrage (siehe RFC 7234#4.1). Derzeit werden dazu die Inhalte von ‘accept-encoding’, ‘referer’ und ‘origin’ verwendet. Nach RFC haben ‘origin’ und ‘referer’ jeweils nur einen Wert. Eine Anfrage mit mehreren Vorkommen eines dieser Header sollte daher als fehlerhaft gelten. Für solche Anfragen wird kein Sekundärschlüssel erzeugt und die Antwort niemals aus dem Cache ausgeliefert, damit der Server über die Behandlung entscheiden kann. Standardmäßig gilt off, also deaktiviert.
total-max-size <megabytes>
Legt die RAM-Größe des Caches in Megabyte fest. Sie wird in Blöcke von 1kB für Cache-Einträge aufgeteilt. Der Höchstwert beträgt 4095.
6.2.2. Proxy-Abschnitt
Der Proxy-Abschnitt muss im Regelsatz “http-request” die Aktion “cache-use” verwenden, um das angeforderte Objekt im Cache zu suchen. Zum Speichern oder Aktualisieren des abgerufenen Objekts dient “cache-store” im Regelsatz “http-response”. Beide Aktionen können optional an Bedingungen geknüpft werden. Beispielsweise lässt sich “cache-use” für ein bekanntermaßen nicht cachefähiges Unterverzeichnis oder “cache-store” für ungeeignete Inhaltstypen überspringen. Der Indexschlüssel des Caches wird jedoch während “cache-use” berechnet. Wird diese Aktion übersprungen, wird auch bei der Antwort keine Aktualisierung des Caches versucht.
Beispiel:
16 - 7. ACLs und Sample-Abruf
HAProxy ist in der Lage, Daten aus Anfrage- oder Antwortströmen, aus Client- oder Serverinformationen, aus Tabellen, Umgebungsdaten usw. zu extrahieren. Der Vorgang, solche Daten zu extrahieren, wird als Sample-Abruf bezeichnet. Nach dem Abruf können diese Samples für verschiedene Zwecke verwendet werden, beispielsweise als Schlüssel einer Stick Table. Am häufigsten werden sie jedoch mit vordefinierten konstanten Daten, sogenannten Mustern, verglichen.
7.1. ACL-Grundlagen
Mit Zugriffskontrolllisten (ACL) wird eine benannte Methode deklariert, die beliebige Informationen mit einer Liste vordefinierter Muster vergleicht. Sie sollten als praktisch gleichwertig mit Funktionen in den meisten Programmiersprachen betrachtet werden: Durch die Deklaration stehen sie bereit und können später bei Bedarf aufgerufen werden. Ihre Auswertung ergibt lediglich eine Übereinstimmung oder Nichtübereinstimmung, was vergleichbar mit booleschen Werten in vielen Programmiersprachen ist. Im Gegensatz zu Funktionen in Programmiersprachen können ACLs beliebig oft überladen werden, um zusätzliche Übereinstimmungsmethoden für denselben Namen zu definieren. In diesem Fall werden sie alle in der Deklarationsreihenfolge ausgewertet, bis eine Übereinstimmung vorliegt.
ACLs bieten eine flexible Lösung, um anhand von Inhalten zwischen Zielen umzuschalten und allgemein Entscheidungen auf Grundlage von Daten aus der Anfrage, der Antwort oder dem Umgebungsstatus zu treffen. Das Prinzip ist einfach:
- ein Daten-Sample aus einem Datenstrom, einer Tabelle oder der Umgebung extrahieren
- optional das Format des extrahierten Samples umwandeln
- eine oder mehrere Methoden zum Musterabgleich auf dieses Sample anwenden
- Aktionen nur ausführen, wenn ein Muster auf das Sample zutrifft
Die Aktionen bestehen in der Regel darin, eine Anfrage zu blockieren, ein Backend auszuwählen oder einen Header hinzuzufügen.
Um einen Test zu definieren, wird das Schlüsselwort “acl” verwendet. Die Syntax lautet:
Dies erstellt eine neue ACL <aclname> oder ergänzt eine bestehende mit neuen Tests. Diese Tests gelten für den im <criterion> angegebenen Teil der Anfrage/Antwort und können mit optionalen Flags [flags] angepasst werden. Einige Kriterien unterstützen auch einen Operator, der vor der Wertemenge angegeben werden kann. Optional können einige Konverter auf das Sample angewendet werden, und sie werden als durch Kommas getrennte Liste von Schlüsselwörtern unmittelbar nach dem ersten Schlüsselwort angegeben. Die Werte sind vom Typ, der vom Kriterium unterstützt wird, und werden durch Leerzeichen getrennt.
ACL-Namen müssen aus Groß- und Kleinbuchstaben, Ziffern, ‘-’ (Bindestrich), ‘_’ (Unterstrich), ‘.’ (Punkt) und ‘:’ (Doppelpunkt) bestehen. Bei ACL-Namen wird zwischen Groß- und Kleinschreibung unterschieden, was bedeutet, dass “my_acl” und “My_Acl” zwei verschiedene ACLs sind.
Es gibt keine festgelegte Obergrenze für die Anzahl der ACLs. Unbenutzte ACLs beeinflussen die Leistung nicht, sie belegen lediglich wenig Speicher.
Das Kriterium ist im Allgemeinen der Name einer Sample-Abruf-Methode oder einer ihrer ACL-spezifischen Varianten. Die Standardtestmethode wird implizit durch den Ausgabetyp dieser Sample-Abruf-Methode bestimmt. Die ACL-Varianten können alternative Übereinstimmungsmethoden für dieselbe Sample-Abruf-Methode beschreiben. Nur die Sample-Abruf-Methoden unterstützen eine Umwandlung.
Sample-Abruf-Methoden geben Daten zurück, die von folgenden Typen sein können:
- boolesch
- Ganzzahl (vorzeichenbehaftet oder vorzeichenlos)
- IPv4- oder IPv6-Adresse
- Zeichenkette
- Datenblock
Konverter können Daten eines dieser Typen in jeden dieser Typen umwandeln. Beispielsweise wandeln einige Konverter eine Zeichenkette in Kleinbuchstaben um; andere konvertieren eine Zeichenkette in eine IPv4-Adresse oder wenden eine Netzmaske auf eine IP-Adresse an. Das resultierende Sample hat den Typ des zuletzt in der Liste angewendeten Konverters. Ohne Konverter entspricht er dem Typ der Sample-Abruf-Methode.
Jedes Sample oder jeder Konverter gibt Daten eines bestimmten Typs zurück, der mit seinem Schlüsselwort in dieser Dokumentation angegeben wird. Wird eine ACL mit einer Standard-Sample-Abruf-Methode deklariert, wird für bestimmte Typen automatisch eine Standardabgleichsmethode verwendet, wie in der folgenden Tabelle zusammengefasst:
Beachten Sie, dass zum Abgleich von Binär-Samples eine Übereinstimmungsmethode explizit angegeben werden muss, siehe unten.
Die ACL-Engine kann diese Typen gegen Muster folgender Typen abgleichen:
- boolesch
- Ganzzahl oder Ganzzahlbereich
- IP-Adresse / Netzwerk
- Zeichenkette (genau, Teilzeichenkette, Suffix, Präfix, Unterordner, Domain)
- regulärer Ausdruck
- Hex-Block
Die folgenden ACL-Flags werden derzeit unterstützt:
Auf das Flag “-f” folgt ein Name, der dem in 2.7 beschriebenen Namensformat für Maps und ACLs entsprechen muss. Es ist sogar möglich, mehrere “-f”-Argumente anzugeben, wenn die Muster aus mehreren Listen geladen werden sollen. Wenn eine vorhandene Datei referenziert wird, werden alle Zeilen als einzelne Werte gelesen. Leere Zeilen sowie Zeilen, die mit einem Rautezeichen (’#’) beginnen, werden ignoriert. Alle führenden Leerzeichen und Tabulatoren werden entfernt. Muss unbedingt ein gültiges Muster eingefügt werden, das mit einem Rautezeichen beginnt, einfach ein Leerzeichen voranstellen, damit es nicht als Kommentar interpretiert wird. Je nach Datentyp und Abgleichsmethode kann HAProxy die Zeilen in einen binären Baum laden, was sehr schnelle Abfragen ermöglicht. Dies gilt für IPv4 und exakte Zeichenkettenabgleiche. In diesem Fall werden Duplikate automatisch entfernt.
Das Flag “-M” ermöglicht einer ACL die Verwendung einer Map. Wenn dieses Flag gesetzt ist, wird die Liste als zweispaltige Einträge analysiert. Die erste Spalte enthält die Muster, die von der ACL verwendet werden, und die zweite Spalte enthält die Samples. Das Sample kann später von einer Map verwendet werden. Dies kann in seltenen Fällen nützlich sein, wenn eine ACL lediglich dazu dient, die Existenz eines Musters in einer Map zu überprüfen, bevor eine Zuordnung angewendet wird.
Das Flag “-u” erzwingt die eindeutige ID der ACL. Diese eindeutige ID wird mit der Socket-Schnittstelle verwendet, um ACLs zu identifizieren und deren Werte dynamisch zu ändern. Beachten Sie, dass eine Datei immer anhand ihres Namens identifiziert wird, selbst wenn eine ID festgelegt ist.
Außerdem gilt: Das Flag “-i” wirkt sich auf nachfolgende Einträge aus und nicht auf Einträge, die aus vorhergehenden Dateien geladen wurden. Zum Beispiel:
In diesem Beispiel wird jeder Eintrag aus “exact-ua.lst” exakt gegen den “user-agent”-Header der Anfrage abgeglichen. Danach wird jeder Eintrag aus “generic-ua” ohne Berücksichtigung der Groß-/Kleinschreibung abgeglichen. Anschließend wird auch das Wort “test” ohne Berücksichtigung der Groß-/Kleinschreibung abgeglichen.
Das Flag “-m” dient zur Auswahl einer bestimmten Musterabgleichsmethode für die Eingabedaten. Alle ACL-spezifischen Kriterien implizieren eine Musterabgleichsmethode und benötigen dieses Flag im Allgemeinen nicht. Es ist jedoch nützlich bei generischen Sample-Abrufmethoden, um anzugeben, wie diese gegen Muster abgeglichen werden sollen. Dies ist erforderlich für Sample-Abrufe, die einen Datentyp zurückgeben, für den keine offensichtliche Abgleichsmethode existiert (z. B. Zeichenkette oder Binärdaten). Wenn “-m” angegeben und gefolgt von einem Namen einer Musterabgleichsmethode ist, wird diese statt der Standardmethode für das Kriterium verwendet. Dadurch ist es möglich, Inhalte auf Arten abzugleichen, die ursprünglich nicht geplant waren, oder mit Sample-Abrufmethoden, die eine Zeichenkette zurückgeben. Die Abgleichsmethode beeinflusst auch die Art und Weise, wie die Muster analysiert werden. Daher darf sie nicht mit Sample-Abrufen verwendet werden, die ein Suffix für den Musterabgleich haben (_beg, _end, _sub…). Außerdem ist die Angabe mehrerer “-m” Musterabgleichsmethoden nicht zulässig.
Das Flag “-n” verbietet DNS-Auflösungen. Es wird zusammen mit dem Laden von IP-Dateien verwendet. Standardmäßig nimmt der Parser an, dass eine nicht parsbare IP-Adresse möglicherweise ein Domänenname ist und versucht dann eine DNS-Auflösung. Das Flag “-n” deaktiviert diese Auflösung. Es ist nützlich, um fehlerhafte IP-Listen zu erkennen. Beachten Sie, dass bei nicht erreichbarem DNS-Server die HAProxy-Konfigurationsanalyse viele Minuten dauern kann, während auf das Eintreten der Zeitüberschreitung gewartet wird. Während dieser Zeit werden keine Fehlermeldungen angezeigt. Das Flag “-n” deaktiviert dieses Verhalten. Beachten Sie außerdem, dass diese Funktion während der Laufzeit für dynamische ACL-Änderungen deaktiviert ist.
Es gibt jedoch Einschränkungen. Nicht alle Methoden können mit allen Sample-Abrufmethoden verwendet werden. Außerdem muss “-m” vor “-f” stehen, wenn beide gemeinsam verwendet werden. Die Musterabgleichsmethode muss eine der folgenden sein:
-
“found”: Prüft lediglich, ob das angeforderte Sample im Datenstrom vorhanden ist, vergleicht es jedoch nicht mit einem Muster. Es wird empfohlen, kein Muster anzugeben, um Verwirrung zu vermeiden. Diese Abgleichsmethode ist besonders nützlich, um das Vorhandensein bestimmter Inhalte wie Header, Cookies usw. zu erkennen, auch wenn sie leer sind, ohne sie mit etwas zu vergleichen oder zu zählen.
-
“bool”: Prüft den Wert als booleschen Wert. Kann nur auf Sample-Abrufe angewendet werden, die einen booleschen oder ganzzahligen Wert zurückgeben, und benötigt kein Muster. Der Wert null oder false liefert keinen Treffer; alle anderen Werte liefern einen Treffer.
-
“int”: Vergleicht den Wert als Ganzzahl. Kann mit Ganzzahl- und booleschen Samples verwendet werden. Boolesch false entspricht der Ganzzahl 0, boolesch true der Ganzzahl 1.
-
“ip”: Vergleicht den Wert als IPv4- oder IPv6-Adresse. Ist nur mit IP-Adress-Samples kompatibel, daher implizit und nie erforderlich.
-
“bin”: Vergleicht den Inhalt mit einer Hexadezimalzeichenkette, die eine Binärsequenz darstellt. Kann mit Binär- oder Zeichenketten-Samples verwendet werden.
-
“len”: Vergleicht die Länge des Samples als Ganzzahl. Kann mit Binär- oder Zeichenketten-Samples verwendet werden.
-
“str”: Genauer Abgleich: Vergleicht den Inhalt mit einer Zeichenkette. Kann mit Binär- oder Zeichenketten-Samples verwendet werden.
-
“sub”: Teilstring-Abgleich: Prüft, ob der Inhalt mindestens eines der bereitgestellten Zeichenkettenmuster enthält. Kann mit Binär- oder Zeichenketten-Samples verwendet werden.
-
“reg”: Regex-Abgleich: Vergleicht den Inhalt mit einer Liste von regulären Ausdrücken. Kann mit Binär- oder Zeichenketten-Samples verwendet werden.
-
“beg”: Präfix-Abgleich: Prüft, ob der Inhalt mit einem der bereitgestellten Zeichenkettenmuster beginnt. Kann mit Binär- oder Zeichenketten-Samples verwendet werden.
-
“end”: Suffix-Abgleich: Prüft, ob der Inhalt mit einem der bereitgestellten Zeichenkettenmuster endet. Kann mit Binär- oder Zeichenketten-Samples verwendet werden.
-
“dir”: Unterverzeichnis-Abgleich: Prüft, ob ein durch Schrägstriche getrennter Teil des Inhalts exakt mit einem der bereitgestellten Zeichenkettenmuster übereinstimmt. Kann mit Binär- oder Zeichenketten-Samples verwendet werden.
-
“dom”: Domänen-Abgleich: Prüft, ob ein durch Punkte getrennter Teil des Inhalts exakt mit einem der bereitgestellten Zeichenkettenmuster übereinstimmt. Kann mit Binär- oder Zeichenketten-Samples verwendet werden.
Beispielsweise kann die Anwesenheit des Cookies “JSESSIONID” in einer HTTP-Anfrage schnell erkannt werden durch:
Um einen regulären Ausdruck auf die ersten 500 Bytes der Daten im Puffer anzuwenden, würde man folgende ACL verwenden:
Auf Systemen, auf denen die Regex-Bibliothek bei Verwendung von “-i” viel langsamer ist, kann das Sample vor dem Abgleich in Kleinbuchstaben konvertiert werden, wie folgt:
Alle ACL-spezifischen Kriterien implizieren eine Standardabgleichsmethode. Meistens bestehen diese Kriterien aus der Verkettung des Namens der ursprünglichen Sample-Abrufmethode und der Abgleichsmethode. Zum Beispiel wendet “hdr_beg” die “beg”-Abgleichsmethode auf Samples an, die mit der “hdr”-Abrufmethode abgerufen wurden. Diese Abgleichsmethode ist nur verwendbar, wenn das Schlüsselwort allein verwendet wird, ohne Konverter. Wird nach einem solchen ACL-Schlüsselwort ein Konverter angewendet, wird die Standardabgleichsmethode dieses ACL-Schlüsselworts einfach ignoriert, da für den Abgleich der Ausgabetyp des letzten Konverters maßgeblich ist. Da alle ACL-spezifischen Kriterien auf einer Sample-Abrufmethode basieren, ist es immer möglich, stattdessen die ursprüngliche Sample-Abrufmethode und die explizite Abgleichsmethode unter Verwendung von “-m” zu verwenden.
Wenn mit “-m” eine alternative Abgleichsmethode für ein ACL-spezifisches Kriterium angegeben wird, wird diese Methode einfach auf die zugrunde liegende Sample-Abrufmethode angewendet. Zum Beispiel sind alle folgenden ACLs exakt äquivalent:
Die folgende Tabelle fasst die Kompatibilitätsmatrix zwischen Sample- oder Konvertertypen und den Mustertypen, mit denen sie abgeglichen werden können, zusammen. Sie gibt für jede kompatible Kombination den Namen der zu verwendenden Abgleichsmethode an, umgeben von spitzen Klammern “>” und “<”, wenn die Methode die Standardmethode ist und standardmäßig ohne “-m” funktioniert.
7.1.1. Abgleich boolescher Werte
Für den Abgleich eines booleschen Werts ist kein Vergleichswert erforderlich; alle angegebenen Werte werden ignoriert. Der boolesche Abgleich wird standardmäßig für alle Abrufmethoden vom Typ “boolean” verwendet. Dabei wird der abgerufene Wert unverändert zurückgegeben: Der boolesche Wert “true” liefert immer einen Treffer, “false” niemals.
Der boolesche Abgleich kann auch mit “-m bool” für Abrufmethoden erzwungen werden, die einen ganzzahligen Wert zurückgeben. Dabei wird der Ganzzahlwert 0 in den booleschen Wert “false” umgewandelt, alle anderen Werte in “true”.
7.1.2. Abgleich von Ganzzahlen
Der Ganzzahlabgleich wird standardmäßig für Abrufmethoden verwendet, die Ganzzahlen zurückgeben. Er kann mit “-m int” auch für boolesche Abrufe erzwungen werden. Dabei wird “false” in die Ganzzahl 0 und “true” in die Ganzzahl 1 umgewandelt.
Der Ganzzahlabgleich unterstützt außerdem Ganzzahlbereiche und Operatoren. Er ist nur auf positive Werte anwendbar. Ein Bereich wird durch eine Unter- und eine Obergrenze ausgedrückt, die durch einen Doppelpunkt getrennt sind; beide Grenzen können jeweils weggelassen werden.
Beispielsweise ist “1024:65535” ein gültiger Bereich für nicht privilegierte Ports; auch “1024:” funktioniert. “0:1023” ist eine gültige Darstellung privilegierter Ports; auch “:1023” funktioniert.
Als Sonderfall unterstützen einige ACL-Funktionen Dezimalzahlen, die tatsächlich aus zwei durch einen Punkt getrennten Ganzzahlen bestehen. Dies wird beispielsweise für bestimmte Versionsprüfungen verwendet. Alle Eigenschaften des Ganzzahlabgleichs gelten auch für diese Dezimalzahlen, einschließlich Bereichen und Operatoren.
Zur einfacheren Verwendung werden auch Vergleichsoperatoren unterstützt. Operatoren mit Bereichen zu verwenden, ist kaum sinnvoll; davon wird dringend abgeraten. Ebenso ist es kaum sinnvoll, Größenvergleiche mit einer Menge von Werten durchzuführen.
Für den Ganzzahlabgleich stehen folgende Operatoren zur Verfügung:
Die folgende ACL trifft beispielsweise auf jeden negativen Content-Length-Header zu:
Die folgende ACL trifft auf SSL-Versionen zwischen 3.0 und 3.1 einschließlich der Grenzen zu:
7.1.3. Abgleich von Zeichenketten
Der Zeichenkettenabgleich ist auf Abrufmethoden für Zeichenketten oder Binärdaten anwendbar und steht in 6 verschiedenen Formen zur Verfügung:
-
exakter Abgleich (-m str): Die extrahierte Zeichenkette muss exakt mit den Mustern übereinstimmen;
-
Teilzeichenkettenabgleich (-m sub): Die Muster werden in der extrahierten Zeichenkette gesucht. Die ACL trifft zu, wenn eines davon darin gefunden wird;
-
Präfixabgleich (-m beg): Die Muster werden mit dem Anfang der extrahierten Zeichenkette verglichen. Die ACL trifft zu, wenn eines davon übereinstimmt.
-
Suffixabgleich (-m end): Die Muster werden mit dem Ende der extrahierten Zeichenkette verglichen. Die ACL trifft zu, wenn eines davon übereinstimmt.
-
Unterverzeichnisabgleich (-m dir): Die Muster werden an beliebiger Stelle in der extrahierten Zeichenkette gesucht, begrenzt durch Schrägstriche ("/"), den Anfang oder das Ende der Zeichenkette. Die ACL trifft zu, wenn eines davon übereinstimmt. Die Zeichenkette “/images/png/logo/32x32.png” würde somit auf “/images”, “/images/png”, “images/png”, “/png/logo”, “logo/32x32.png” oder “32x32.png” passen, aber weder auf “png” noch auf “32x32”.
-
Domainabgleich (-m dom): Die Muster werden an beliebiger Stelle in der extrahierten Zeichenkette gesucht, begrenzt durch Punkte ("."), Doppelpunkte (":"), Schrägstriche ("/"), Fragezeichen ("?"), den Anfang oder das Ende der Zeichenkette. Dies ist für URLs vorgesehen. Führende und nachgestellte Trennzeichen im Muster werden ignoriert. Die ACL trifft zu, wenn eines der Muster übereinstimmt. In der Beispielzeichenkette “http://www1.dc-eu.example.com:80/blah ” würden somit die Muster “http”, “www1”, “.www1”, “dc-eu”, “example”, “com”, “80”, “dc-eu.example”, “blah”, “:www1:” und “dc-eu.example:80” passen, aber weder “eu” noch “dc”. Domain-Suffixe zum Filtern oder für das Routing auf diese Weise abzugleichen, ist im Allgemeinen keine gute Idee: Das Routing ließe sich beispielsweise leicht täuschen, indem das passende Präfix einer anderen Domain vorangestellt wird.
Beim Zeichenkettenabgleich werden Zeichenketten so verwendet, wie sie übergeben werden. Eine Ausnahme bildet der Backslash ("\"), mit dem bestimmte Zeichen wie Leerzeichen maskiert werden können. Wenn das Flag “-i” vor der ersten Zeichenkette übergeben wird, erfolgt der Abgleich ohne Berücksichtigung der Groß-/Kleinschreibung. Um die Zeichenkette “-i” abzugleichen, diese entweder an zweiter Stelle angeben oder das Flag “–” vor der ersten Zeichenkette übergeben. Dasselbe gilt selbstverständlich für den Abgleich der Zeichenkette “–”.
Für Binärabrufe, die Nullbytes (0x00) enthalten können, keinen Zeichenkettenabgleich verwenden, da der Vergleich beim ersten Nullbyte endet. Stattdessen den Binärabruf zunächst mit dem Konverter hex in eine Hexadezimalzeichenkette umwandeln.
Beispiel:
7.1.4. Abgleich mit regulären Ausdrücken (Regex)
Wie beim Zeichenkettenabgleich werden auch beim Abgleich mit regulären Ausdrücken die Zeichenketten so verwendet, wie sie übergeben werden. Eine Ausnahme bildet der Backslash ("\"), mit dem bestimmte Zeichen wie Leerzeichen maskiert werden können. Wenn das Flag “-i” vor dem ersten regulären Ausdruck übergeben wird, erfolgt der Abgleich ohne Berücksichtigung der Groß-/Kleinschreibung. Um die Zeichenkette “-i” abzugleichen, diese entweder an zweiter Stelle angeben oder das Flag “–” vor der ersten Zeichenkette übergeben. Dasselbe Prinzip gilt selbstverständlich für den Abgleich der Zeichenkette “–”.
7.1.5. Abgleich beliebiger Datenblöcke
Extrahierte Samples können mit einem Binärblock abgeglichen werden, der sich nicht zuverlässig als Zeichenkette darstellen lässt. Dazu müssen die Muster bei binärer Abgleichsmethode als Folge einer geraden Anzahl hexadezimaler Ziffern übergeben werden. Je zwei Ziffern stellen ein Byte dar. Hexadezimale Ziffern können in Groß- oder Kleinschreibung angegeben werden.
Beispiel:
7.1.6. Abgleich von IPv4- und IPv6-Adressen
IPv4-Adressen können entweder als reine Adressen oder mit angehängter Netzmaske angegeben werden. Im zweiten Fall trifft der Abgleich zu, wenn die IPv4-Adresse innerhalb des Netzwerks liegt. Reine Adressen können auch durch einen auflösbaren Hostnamen ersetzt werden. Davon wird jedoch generell abgeraten, da Konfigurationen dadurch schwerer zu lesen und zu debuggen sind. Werden Hostnamen verwendet, sollte zumindest sichergestellt werden, dass sie in /etc/hosts stehen, damit die Konfiguration nicht von einem zufälligen DNS-Ergebnis zum Zeitpunkt des Einlesens abhängt.
Die durch Punkte getrennte IPv4-Notation wird sowohl in der üblichen Form als auch in einer verkürzten Form unterstützt, bei der nur aus 0 bestehende Oktette weggelassen werden:
Dies unterscheidet sich von der CIDR-Adressnotation nach RFC 4632, in der 192.168.42/24 gleichbedeutend mit 192.168.42.0/24 wäre.
IPv6-Adressen können in ihrer üblichen Form mit oder ohne angehängte Netzmaske eingegeben werden. Für IPv6-Netzmasken sind nur Bitanzahlen zulässig. Um Probleme mit zufällig aufgelösten IP-Adressen auszuschließen, sind Hostnamen in IPv6-Mustern niemals erlaubt.
HAProxy kann in den folgenden Fällen auch IPv4-Adressen mit IPv6-Adressen abgleichen:
- Die geprüfte Adresse ist IPv4, die Musteradresse ebenfalls IPv4: Der Abgleich erfolgt in IPv4 unter Verwendung der angegebenen Maske, sofern vorhanden.
- Die geprüfte Adresse ist IPv6, die Musteradresse ebenfalls IPv6: Der Abgleich erfolgt in IPv6 unter Verwendung der angegebenen Maske, sofern vorhanden.
- Die geprüfte Adresse ist IPv6, die Musteradresse IPv4: Der Abgleich erfolgt in IPv4 mit der Maske des Musters, wenn die IPv6-Adresse auf 2002:IPV4::, ::IPV4 oder ::ffff:IPV4 passt. Andernfalls schlägt er fehl.
- Die geprüfte Adresse ist IPv4, die Musteradresse IPv6: Zuerst wird die IPv4-Adresse durch Voranstellen von ::ffff: in IPv6 umgewandelt. Anschließend erfolgt der Abgleich in IPv6 mit der angegebenen IPv6-Maske.
7.2. Bedingungen aus ACLs bilden
Einige Aktionen werden nur ausgeführt, wenn eine Bedingung erfüllt ist. Eine Bedingung besteht aus einer Kombination von ACLs mit Operatoren. Es werden 3 Operatoren unterstützt:
- AND (implizit)
- OR (explizit mit dem Schlüsselwort “or” oder dem Operator “||”)
- Negation mit dem Ausrufezeichen ("!")
Eine Bedingung wird in disjunktiver Form gebildet:
Solche Bedingungen werden im Allgemeinen nach einer “if”- oder “unless”-Anweisung verwendet. Sie geben an, wann die Bedingung die Aktion auslöst.
Beispielsweise lassen sich HTTP-Anfragen an die URL “*” mit anderen Methoden als “OPTIONS” blockieren, ebenso POST-Anfragen ohne content-length, GET- oder HEAD-Anfragen mit einem content-length größer als 0 und schließlich alle Anfragen, die weder GET/HEAD/POST/OPTIONS sind!
Um ein anderes Backend für Anfragen nach statischen Inhalten auf der Website “www” sowie für jede Anfrage an die Hosts “img”, “video”, “download” und “ftp” auszuwählen:
Regeln können auch mit „anonymen ACLs“ gebildet werden. Dies sind unbenannte ACL-Ausdrücke, die bei Bedarf erstellt werden, ohne zuvor deklariert werden zu müssen. Sie müssen in geschweifte Klammern eingeschlossen werden, wobei vor und hinter jeder Klammer ein Leerzeichen stehen muss, damit die Klammern als eigenständige Wörter erkannt werden. Beispiel:
Von dieser Schreibweise wird generell abgeraten, da sich damit viel leichter Fehler in die Konfiguration einschleichen. Bei sehr einfachen Regeln, die beispielsweise nur eine Quell-IP-Adresse abgleichen, kann ihre Verwendung jedoch sinnvoller sein als das Deklarieren von ACLs mit beliebigen Namen. Ein weiteres Beispiel für eine sinnvolle Verwendung:
Ausführliche Hilfe zu den Schlüsselwörtern “http-request deny” und “use_backend” finden Sie in Abschnitt 4.2 .
7.3. Sample-Abrufe
Ursprünglich dienten Sample-Abrufmethoden nur dazu, Daten abzurufen und mit ACLs gegen Muster abzugleichen. Mit der Einführung von Stick Tables entstand eine neue Klasse von Sample-Abrufmethoden, deren Syntax meist derjenigen ihrer ACL-Entsprechung gleicht. Diese Sample-Abrufmethoden werden auch „Abrufe“ genannt. Inzwischen sind ACLs und Abrufe zusammengewachsen: Alle ACL-Abrufmethoden stehen auch als allgemeine Abrufmethoden zur Verfügung, und ACLs können ihrerseits jede Sample-Abrufmethode verwenden.
Dieser Abschnitt beschreibt alle verfügbaren Sample-Abrufmethoden und deren Ausgabetyp. Einige Sample-Abrufmethoden besitzen veraltete Aliase, um die Kompatibilität mit bestehenden Konfigurationen zu erhalten. Diese sind ausdrücklich als veraltet gekennzeichnet und sollten in neuen Installationen nicht verwendet werden.
Samples sind typisiert. Der Typ eines Samples bestimmt, mit welchen Mustern es abgeglichen werden kann, welche Konverter darauf angewendet werden können und wie es umgewandelt wird, wenn ein anderer Typ erwartet wird. Folgende Typen werden verwendet:
-
boolean: ein wahrer oder falscher Wert, wie ihn Abrufmethoden zurückgeben, die nur eine Bedingung melden. Solche Samples werden ohne die Option “-m” abgeglichen. Eine Ganzzahl gilt als wahr, wenn sie nicht null ist; eine Zeichenfolge wird zunächst als Ganzzahl eingelesen.
-
integer: eine vorzeichenbehaftete 64-Bit-Ganzzahl, also ein Wert zwischen -2^63 und 2^63-1 (-9223372036854775808 und 9223372036854775807). Bei der Umwandlung einer Zeichenfolge in eine Ganzzahl endet die Konvertierung am ersten Zeichen, das keine Ziffer und kein führendes Vorzeichen (’+’ oder ‘-’) ist. Verwendet wird der Wert der eingelesenen Ziffern; ohne Ziffern ist er null, leere Zeichenfolgen können jedoch nicht umgewandelt werden. Werte außerhalb des darstellbaren Bereichs werden auf die kleinste oder größte darstellbare Ganzzahl begrenzt.
-
IPv4-Adresse und IPv6-Adresse: Dies sind zwei unterschiedliche Typen, obwohl die meisten Stellen, die einen davon akzeptieren, auch den anderen akzeptieren und einfach als Stellen für eine Adresse dokumentiert sind. Eine IPv4-Adresse kann in eine Ganzzahl umgewandelt werden, die dem 32-Bit-Wert der Adresse entspricht, oder in eine IPv6-Adresse in IPv4-mapped-Form ("::ffff:a.b.c.d"). Die umgekehrten Konvertierungen sind eingeschränkter: Für eine IPv6-Adresse gibt es keine Ganzzahldarstellung, und sie kann nur dann in eine IPv4-Adresse umgewandelt werden, wenn es sich um eine IPv4-mapped-, IPv4-compatible- oder 6to4-Adresse handelt.
-
string: eine Folge von Bytes, die am ersten NUL-Zeichen (0x00) endet; dieses gehört nicht zur Zeichenfolge. Wenn ein eingebettetes NUL-Zeichen benötigt wird, ist der Typ binary zu verwenden. Es wird keine Kodierung angenommen: HAProxy versucht nicht, diese Bytes als Zeichen zu interpretieren. Ob sie überhaupt Text darstellen, in welchem Zeichensatz und wie sie angezeigt werden, hängt allein von der Verwendung der Zeichenfolge ab. Die explizite oder implizite Umwandlung eines binary-Samples in eine Zeichenfolge verwirft daher stillschweigend alles ab dem ersten NUL-Zeichen.
-
binary: ein Block von Bytes bekannter Länge; jedes Byte kann jeden Wert von 0 bis 255 einschließlich NUL annehmen. Diesen Typ liefern Abrufmethoden für Rohdaten, etwa einen Anfrage-Body oder den Inhalt eines Binärprotokolls. Ein solches Sample kann weder in boolean noch in eine Ganzzahl oder eine Adresse umgewandelt werden. Es muss entweder mit “-m bin” als Binärblock abgeglichen werden (siehe Abschnitt 7.1.5 ) oder zunächst in eine druckbare Form umgewandelt werden, etwa mit dem Konverter “hex”. Die umgekehrte Konvertierung ist uneingeschränkt möglich, da eine Zeichenfolge immer ein gültiger Binärblock ist.
-
method: eine HTTP-Methode. HAProxy bekannte Methoden werden durch einen Bezeichner dargestellt; die anderen behalten ihre ursprüngliche Zeichenfolge.
Die folgende Konvertertabelle verwendet außerdem “any” für Konverter, die jeden Eingabetyp akzeptieren.
Sofern vorhanden, werden auch die ACL-Varianten mit ihren jeweiligen Abgleichsmethoden angegeben. Sie besitzen alle eine klar definierte Standardmethode zum Musterabgleich. Daher ist es nie erforderlich, mit der Option “-m” anzugeben, wie das Sample mit ACLs abgeglichen werden soll; zulässig ist es jedoch.
Wie die obige Kompatibilitätsmatrix zwischen Sample-Typ und Abgleichsmethode zeigt, ist bei Verwendung einer allgemeinen Sample-Abrufmethode in einer ACL die Option “-m” zwingend erforderlich, sofern das Sample nicht vom Typ boolean, integer, IPv4 oder IPv6 ist. Existiert dasselbe Schlüsselwort sowohl als ACL-Schlüsselwort als auch als Standardabrufmethode, wählt die ACL-Engine standardmäßig automatisch die reine ACL-Variante.
Einige dieser Schlüsselwörter unterstützen ein oder mehrere Pflichtargumente sowie ein oder mehrere optionale Argumente. Diese Argumente sind streng typisiert und werden beim Einlesen der Konfiguration geprüft, damit kein Betrieb mit einem fehlerhaften Argument möglich ist, etwa einem nicht aufgelösten Backend-Namen. Argumente von Abruffunktionen werden in runden Klammern übergeben und durch Kommas getrennt. Optionale Argumente sind im Folgenden durch eckige Klammern (’[ ]’) gekennzeichnet. Sind alle Argumente optional, können die runden Klammern entfallen.
Die Syntax einer Standard-Sample-Abrufmethode hat somit eine der folgenden Formen:
- name
- name(arg1)
- name(arg1,arg2)
7.3.1. Konverter
Sample-Abrufmethoden können mit Transformationen kombiniert werden, die auf das abgerufene Sample angewendet werden und auch „Konverter“ heißen. Diese Kombinationen bilden sogenannte „Sample-Ausdrücke“; das Ergebnis ist ein „Sample“. Anfangs wurde dies nur von den Direktiven “stick on” und “stick store-request” unterstützt. Inzwischen wurde die Unterstützung auf alle Stellen ausgeweitet, an denen Samples verwendet werden können (ACLs, log-format, unique-id-format, add-header, …).
Diese Transformationen werden als Folge bestimmter Schlüsselwörter nach der Sample-Abrufmethode aufgeführt. Sie können auch unmittelbar nach dem Argument des Abrufschlüsselworts angehängt werden, jeweils durch ein Komma getrennt. Die Schlüsselwörter können ihrerseits Argumente unterstützen, etwa eine Netzmaske, die in runden Klammern übergeben werden müssen.
Eine bestimmte Gruppe von Konvertern bilden bitweise und arithmetische Operatoren, mit denen sich Grundoperationen auf Ganzzahlen ausführen lassen. Unterstützt werden einige bitweise Operationen (and, or, xor, cpl) und einige arithmetische Operationen (add, sub, mul, div, mod, neg). Einige Vergleichsoperatoren (odd, even, not, bool) ermöglichen es, einen Treffer zu melden, ohne dafür eine ACL schreiben zu müssen.
Die folgenden Schlüsselwörter werden unterstützt:
Es folgt die ausführliche Liste der Konverterschlüsselwörter:
51d.single(<prop>[,<prop>*])
Gibt die Werte der angeforderten Eigenschaften als Zeichenkette zurück. Die Werte werden durch das mit “51degrees-property-separator” angegebene Trennzeichen getrennt. Das Gerät wird anhand des an den Konverter übergebenen User-Agent-Headers erkannt. Der Funktion können bis zu fünf Eigenschaftsnamen übergeben werden. Wird ein Eigenschaftsname nicht gefunden, wird der Wert “NoData” zurückgegeben.
Beispiel:
add(<value>)
Addiert <value> zum Eingabewert vom Typ vorzeichenbehaftete Ganzzahl und gibt das Ergebnis als vorzeichenbehaftete Ganzzahl zurück. <value> kann ein Zahlenwert oder ein Variablenname sein. Einzelheiten zu Variablen finden Sie in Abschnitt 2.8
.
add_item(<delim>[,<var>[,<suff>]])
Hängt mindestens 2 und höchstens 3 Felder an das aktuelle Sample an, das dabei in eine Zeichenkette umgewandelt wird. Das erste Feld, <delim>, ist eine konstante Zeichenkette. Sie wird unmittelbar an das vorhandene Sample angehängt, wenn dieses nicht leer ist und entweder <var> oder <suff> nicht leer ist. Das zweite Feld, <var>, ist ein Variablenname. Die Variable wird nachgeschlagen, ihr Inhalt in eine Zeichenkette umgewandelt und unmittelbar an den Teil <delim> angehängt. Wird die Variable nicht gefunden, wird nichts angehängt. Sie ist optional; ihr kann außerdem eine konstante Zeichenkette <suff> folgen. Wird <var> jedoch weggelassen, ist <suff> zwingend erforderlich. Dieser Konverter ähnelt dem Konverter concat und kann neue Variablen aus einer Folge anderer Variablen bilden. Der wesentliche Unterschied besteht darin, dass er prüft, ob das Hinzufügen eines Trennzeichens sinnvoll ist. Dies wäre beispielsweise bei einem leeren aktuellen Sample nicht der Fall. Mit dem Konverter concat wären dafür 2 getrennte Regeln nötig, wobei die erste vor dem Hinzufügen eines Trennzeichens prüfen müsste, ob die aktuelle Sample-Zeichenkette leer ist. Werden Kommas oder schließende Klammern als Trennzeichen benötigt, müssen sie durch Anführungszeichen oder Backslashes geschützt werden. Diese müssen ihrerseits geschützt werden, damit der Parser der ersten Ebene sie nicht entfernt; siehe Abschnitt 2.2
zu Anführungszeichen und Maskierung. Beispiele folgen unten.
Beispiel:
aes_cbc_dec(<bits>,<nonce>,<key>[,<aad>])
Entschlüsselt die Eingabe aus Rohbytes je nach Parameter <bits> mit dem Algorithmus AES128-CBC, AES192-CBC oder AES256-CBC. Alle anderen Parameter müssen base64-kodiert sein; das Ergebnis wird als Rohbytes zurückgegeben. Der Parameter <aad> ist optional. Schlägt die Prüfung von <aad> fehl, gibt der Konverter keine Daten zurück. <nonce>, <key> und <aad> können Zeichenketten oder Variablen sein. Dieser Konverter benötigt mindestens OpenSSL 1.0.1.
Beispiel:
aes_cbc_enc(<bits>,<nonce>,<key>[,<aad>])
Verschlüsselt die Eingabe aus Rohbytes je nach Parameter <bits> mit dem Algorithmus AES128-CBC, AES192-CBC oder AES256-CBC. Die Parameter <nonce>, <key> und <aad> müssen base64-kodiert sein. Der Parameter <aad> ist optional. Das Ergebnis wird als Rohbytes zurückgegeben. <nonce>, <key> und <aad> können Zeichenketten oder Variablen sein. Dieser Konverter benötigt mindestens OpenSSL 1.0.1.
Beispiel:
aes_gcm_dec(<bits>,<nonce>,<key>,<aead_tag>[,<aad>])
Entschlüsselt die Eingabe aus Rohbytes je nach Parameter <bits> mit dem Algorithmus AES128-GCM, AES192-GCM oder AES256-GCM. Alle anderen Parameter müssen base64-kodiert sein; das Ergebnis wird als Rohbytes zurückgegeben. Schlägt die Prüfung von <aead_tag> oder <aad> fehl, gibt der Konverter keine Daten zurück. Der Parameter <aad> ist optional. <nonce>, <key>, <aead_tag> und <aad> können Zeichenketten oder Variablen sein. Dieser Konverter benötigt mindestens OpenSSL 1.0.1.
Beispiel:
aes_gcm_enc(<bits>,<nonce>,<key>,<aead_tag>[,<aad>])
Verschlüsselt die Eingabe aus Rohbytes je nach Parameter <bits> mit dem Algorithmus AES128-GCM, AES192-GCM oder AES256-GCM. Die Parameter <nonce>, <key> und <aad> müssen base64-kodiert sein. Der Parameter <aead_tag> muss eine Variable sein. Das AEAD-Tag wird base64-kodiert in dieser Variablen gespeichert. Der Parameter <aad> ist optional. Das Ergebnis wird als Rohbytes zurückgegeben. <nonce>, <key> und <aad> können Zeichenketten oder Variablen sein. Dieser Konverter benötigt mindestens OpenSSL 1.0.1.
Beispiel:
and(<value>)
Führt eine bitweise “AND”-Verknüpfung zwischen <value> und dem Eingabewert vom Typ vorzeichenbehaftete Ganzzahl aus und gibt das Ergebnis als vorzeichenbehaftete Ganzzahl zurück. <value> kann ein Zahlenwert oder ein Variablenname sein. Einzelheiten zu Variablen finden Sie in Abschnitt 2.8
.
b64dec
Wandelt eine base64-kodierte Eingabezeichenkette in ihre Binärdarstellung um (Dekodierung). Dies ist die Umkehrung von base64(). Zur Variante base64url (“URL and Filename Safe Alphabet” (RFC 4648)) siehe “ub64dec”.
base2
Wandelt ein binäres Eingabe-Sample in eine binäre Zeichenkette mit acht Binärziffern je Eingabebyte um. Damit lässt sich der Abgleich mit dem längsten passenden Präfix auch für Typen durchführen, deren native Darstellung keinen Präfixabgleich erlaubt, beispielsweise für IP-Präfixe.
base64
Wandelt ein binäres Eingabe-Sample in eine base64-Zeichenkette um. Damit lassen sich binäre Inhalte in einer zuverlässig übertragbaren Form protokollieren oder übertragen; beispielsweise kann eine SSL-ID in einen Header kopiert werden. Zur Variante base64url (“URL and Filename Safe Alphabet” (RFC 4648)) siehe “ub64enc”.
be2dec(<separator>,<chunk_size>[,<truncate>])
Wandelt ein binäres Eingabe-Sample im Big-Endian-Format in eine Zeichenkette um, die je <chunk_size> Eingabebytes eine vorzeichenlose Ganzzahl enthält. Sofern angegeben, wird <separator> nach jeweils <chunk_size> Bytes der binären Eingabe eingefügt. Das <truncate>-Flag gibt an, ob die binäre Eingabe an <chunk_size>-Grenzen abgeschnitten wird. Der maximale Wert für <chunk_size> ist durch die Größe von long long int (8 Bytes) begrenzt.
Beispiel:
le2dec(<separator>,<chunk_size>[,<truncate>])
Wandelt ein binäres Eingabe-Sample im Little-Endian-Format in eine Zeichenkette um, die je <chunk_size> Eingabebytes eine vorzeichenlose Ganzzahl enthält. Sofern angegeben, wird <separator> nach jeweils <chunk_size> Bytes der binären Eingabe eingefügt. Das <truncate>-Flag gibt an, ob die binäre Eingabe an <chunk_size>-Grenzen abgeschnitten wird. Der maximale Wert für <chunk_size> ist durch die Größe von long long int (8 Bytes) begrenzt.
Beispiel:
be2hex([<separator>[,<chunk_size>[,<truncate>]]])
Wandelt ein binäres Eingabe-Sample im Big-Endian-Format in eine Hexadezimalzeichenkette mit zwei Hexadezimalziffern je Eingabebyte um. Damit lassen sich Hex-Dumps binärer Eingabedaten in einer zuverlässig übertragbaren Form protokollieren oder übertragen; beispielsweise kann eine SSL-ID in einen Header kopiert werden. Sofern angegeben, wird <separator> nach jeweils <chunk_size> Bytes der binären Eingabe eingefügt. Das <truncate>-Flag gibt an, ob die binäre Eingabe an <chunk_size>-Grenzen abgeschnitten wird.
Beispiel:
bool
Gibt den booleschen Wert TRUE zurück, wenn der vorzeichenbehaftete ganzzahlige Eingabewert ungleich null ist, andernfalls FALSE. Zusammen mit and() kann damit bei Bitprüfungen an Eingabewerten true/false zurückgegeben werden, etwa um zu prüfen, ob ein Flag gesetzt ist.
bytes(<offset>[,<length>])
Extrahiert einige Bytes aus einem binären Eingabe-Sample. Das Ergebnis ist ein binäres Sample, das an einem Offset in Bytes innerhalb des ursprünglichen Samples beginnt und optional auf die angegebene Länge gekürzt wird. <offset> und <length> können Zahlenwerte oder Variablennamen sein. Der Konverter gibt ein leeres Sample zurück, wenn entweder <offset> oder <length> ungültig ist. <offset> ist ungültig, wenn der Wert negativ oder >= der Länge des Eingabe-Samples ist. <length> ist ungültig, wenn der Wert negativ ist.
Beispiel:
capture-req(<id>)
Erfasst den Zeichenketteneintrag im Anfrage-Slot <id> und gibt den Eintrag unverändert zurück. Falls der Slot nicht existiert, schlägt die Erfassung ohne Meldung fehl.
Siehe auch: “declare capture”, “http-request capture”, “http-response capture”, “capture.req.hdr” und “capture.res.hdr” (Sample-Abrufe).
capture-res(<id>)
Erfasst den Zeichenketteneintrag im Antwort-Slot <id> und gibt den Eintrag unverändert zurück. Falls der Slot nicht existiert, schlägt die Erfassung ohne Meldung fehl.
Siehe auch: “declare capture”, “http-request capture”, “http-response capture”, “capture.req.hdr” und “capture.res.hdr” (Sample-Abrufe).
concat([<start>[,<var>[,<end>]]])
Hängt bis zu 3 Felder an das aktuelle Sample an, das dabei in eine Zeichenkette umgewandelt wird. Das erste Feld, <start>, ist eine konstante Zeichenkette, die unmittelbar an das vorhandene Sample angehängt wird. Sie kann weggelassen werden, wenn sie nicht verwendet wird. Das zweite Feld, <var>, ist ein Variablenname. Die Variable wird nachgeschlagen, ihr Inhalt in eine Zeichenkette umgewandelt und unmittelbar an den Teil <first> angehängt. Wird die Variable nicht gefunden, wird nichts angehängt. Auch dieses Feld kann weggelassen werden. Das dritte Feld, <end>, ist eine konstante Zeichenkette, die nach der Variablen angehängt wird und ebenfalls weggelassen werden kann. Zusammen ermöglichen diese Elemente, Variablen mit Trennzeichen an einen vorhandenen Satz von Variablen anzuhängen. Damit lassen sich neue Variablen aus einer Folge anderer Variablen bilden, beispielsweise durch Doppelpunkte getrennte Werte. Werden Kommas oder schließende Klammern als Trennzeichen benötigt, müssen sie durch Anführungszeichen oder Backslashes geschützt werden. Diese müssen ihrerseits geschützt werden, damit der Parser der ersten Ebene sie nicht entfernt. Dies wird oft verwendet, um zusammengesetzte Variablen aus anderen Variablen zu bilden; manchmal ist jedoch eine Formatzeichenkette mit mehreren Feldern praktischer. Beispiele folgen unten.
Beispiel:
cpl
Bildet das Einerkomplement des vorzeichenbehafteten ganzzahligen Eingabewerts, kehrt also alle Bits um, und gibt das Ergebnis als vorzeichenbehaftete Ganzzahl zurück.
crc32([<avalanche>])
Bildet mit der Hashfunktion CRC32 aus einem binären Eingabe-Sample einen vorzeichenlosen 32-Bit-Wert. Ist das optionale Argument <avalanche> gleich 1, kann auf die Ausgabe zusätzlich eine Hashfunktion mit vollständigem Avalanche-Effekt angewendet werden. Dieser Konverter verwendet dieselben Funktionen wie die verschiedenen hashbasierten Algorithmen zur Lastverteilung und liefert daher exakt dieselben Ergebnisse. Er dient der Kompatibilität mit anderer Software, die CRC32-Werte für Eingabeschlüssel berechnen möchte, und folgt deshalb der gängigsten Implementierung, wie sie in Ethernet, Gzip, PNG usw. verwendet wird. Er ist langsamer als die anderen Algorithmen, kann aber eine bessere oder zumindest weniger vorhersehbare Verteilung liefern. Er darf nicht für Sicherheitszwecke eingesetzt werden, da sich ein 32-Bit-Hash trivial knacken lässt. Siehe auch “djb2”, “sdbm”, “wt6”, “crc32c” sowie die Direktive “hash-type”.
crc32c([<avalanche>])
Bildet mit der Hashfunktion CRC32C aus einem binären Eingabe-Sample einen vorzeichenlosen 32-Bit-Wert. Ist das optionale Argument <avalanche> gleich 1, kann auf die Ausgabe zusätzlich eine Hashfunktion mit vollständigem Avalanche-Effekt angewendet werden. Dieser Konverter verwendet dieselben Funktionen, die in RFC4960, Anhang B [8], beschrieben werden. Er dient der Kompatibilität mit anderer Software, die CRC32C-Werte für Eingabeschlüssel berechnen möchte. Er ist langsamer als die anderen Algorithmen und darf nicht für Sicherheitszwecke eingesetzt werden, da sich ein 32-Bit-Hash trivial knacken lässt. Siehe auch “djb2”, “sdbm”, “wt6”, “crc32” sowie die Direktive “hash-type”.
cut_crlf
Schneidet die Zeichenkettendarstellung des Eingabe-Samples beim ersten gefundenen Wagenrücklauf (’\r’) oder Zeilenumbruch (’\n’) ab. Dabei wird nur die Länge der Zeichenkette aktualisiert.
da-csv-conv(<prop>[,<prop>*])
Weist den DeviceAtlas-Konverter an, die übergebene User-Agent-Zeichenkette zu identifizieren und eine Zeichenkette aus den als Argumente aufgeführten Eigenschaften auszugeben. Die Eigenschaften werden miteinander verkettet und durch das mit dem globalen Schlüsselwort “deviceatlas-property-separator” festgelegte Trennzeichen getrennt, standardmäßig durch den senkrechten Strich (’|’). Die Konfigurationssprache von HAProxy begrenzt die Anzahl auf 12 verschiedene Eigenschaften.
Beispiel:
date
Dieser Konverter wandelt ein Datum aus einem HTTP-Header um. Es kann im Format IMF, ASCTIME oder RFC850 vorliegen. Ausgegeben wird ein Unix-Zeitstempel.
Beispiel:
debug([<prefix][,<destination>])
Dieser Konverter dient als Werkzeug zur Fehlersuche. Er erfasst das Eingabe-Sample und sendet es an das Ereignisziel <destination>. Dieses kann einen Ringpuffer wie “buf0” sowie “stdout” oder “stderr” bezeichnen. Die verfügbaren Ziele lassen sich zur Laufzeit mit “show events” auf der CLI prüfen. Ohne Angabe erfolgt die Ausgabe an “buf0”, dessen Inhalt mit dem CLI-Befehl “show events” eingesehen werden kann. Ein optionales Präfix <prefix> hilft, Ausgaben mehrerer Ausdrücke zu unterscheiden. Es erscheint vor dem Doppelpunkt in der Ausgabemeldung. Das Eingabe-Sample wird unverändert an die Ausgabe weitergegeben. Deshalb kann der Konverter debug gefahrlos an beliebiger Stelle einer Kette eingefügt werden, auch bei nicht druckbaren Sample-Typen.
Beispiel:
digest(<algorithm>)
Wandelt ein binäres Eingabe-Sample in einen Message Digest um. Das Ergebnis ist ein binäres Sample. <algorithm> muss der Name eines OpenSSL-Message-Digests sein, beispielsweise sha256.
Dieser Konverter ist nur verfügbar, wenn HAProxy mit USE_OPENSSL kompiliert wurde.
div(<value>)
Dividiert den vorzeichenbehafteten ganzzahligen Eingabewert durch <value> und gibt das Ergebnis als vorzeichenbehaftete Ganzzahl zurück. Ist <value> null, wird die größte vorzeichenlose Ganzzahl zurückgegeben, üblicherweise 2^63-1. <value> kann ein Zahlenwert oder ein Variablenname sein. Einzelheiten zu Variablen finden Sie in Abschnitt 2.8
.
djb2([<avalanche>])
Bildet mit der Hashfunktion DJB2 aus einem binären Eingabe-Sample einen vorzeichenlosen 32-Bit-Wert. Ist das optionale Argument <avalanche> gleich 1, kann auf die Ausgabe zusätzlich eine Hashfunktion mit vollständigem Avalanche-Effekt angewendet werden. Dieser Konverter verwendet dieselben Funktionen wie die verschiedenen hashbasierten Algorithmen zur Lastverteilung und liefert daher exakt dieselben Ergebnisse. Er ist hauptsächlich zur Fehlersuche vorgesehen, kann aber als Eintrag einer Stick Table zum Erfassen grober Statistiken verwendet werden. Er darf nicht für Sicherheitszwecke eingesetzt werden, da sich ein 32-Bit-Hash leicht knacken lässt. Siehe auch “crc32”, “sdbm”, “wt6”, “crc32c” sowie die Direktive “hash-type”.
eth.data
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “2” gesetzten bind-Option “tcp-ss” zurückgibt. Überspringt den gesamten Ethernet-Header einschließlich möglicher VLANs und gibt einen binären Datenblock zurück, der beim Protokoll der Schicht 3 beginnt, üblicherweise IPv4 oder IPv6. Siehe auch “fc_saved_syn” und “tcp-ss”.
eth.dst
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “2” gesetzten bind-Option “tcp-ss” zurückgibt. Gibt die 6 Bytes des Ethernet-Headers, die der Zieladresse des Frames entsprechen, als Binärblock zurück. Siehe auch “fc_saved_syn” und “tcp-ss”.
eth.hdr
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “2” gesetzten bind-Option “tcp-ss” zurückgibt. Schneidet alles hinter dem Ethernet-Header ab, behält jedoch mögliche VLANs bei und gibt diesen Header als binären Datenblock zurück. Siehe auch “fc_saved_syn” und “tcp-ss”.
eth.proto
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “2” gesetzten bind-Option “tcp-ss” zurückgibt. Gibt die Protokollnummer, auch EtherType genannt, aus dem Ethernet-Header hinter optionalen VLANs als Ganzzahl zurück. Normalerweise sollte sie entweder 0x800 für IPv4 oder 0x86DD für IPv6 sein. Siehe auch “fc_saved_syn” und “tcp-ss”.
eth.src
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “2” gesetzten bind-Option “tcp-ss” zurückgibt. Gibt die 6 Bytes des Ethernet-Headers, die der Quelladresse des Frames entsprechen, als Binärblock zurück. Siehe auch “fc_saved_syn” und “tcp-ss”.
eth.vlan
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “2” gesetzten bind-Option “tcp-ss” zurückgibt. Gibt die letzte im Ethernet-Header gefundene VLAN-ID als Ganzzahl zurück. Siehe auch “fc_saved_syn” und “tcp-ss”.
even
Gibt den booleschen Wert TRUE zurück, wenn der vorzeichenbehaftete ganzzahlige Eingabewert gerade ist, andernfalls FALSE. Dies ist funktional gleichbedeutend mit “not,and(1),bool”.
field(<index>,<delimiters>[,<count>])
Extrahiert unter Berücksichtigung der angegebenen Trennzeichen die Teilzeichenkette am angegebenen Index aus einer Eingabezeichenkette. Bei einem positiven Index wird vom Anfang gezählt, bei einem negativen vom Ende. Die Indizes beginnen bei 1 beziehungsweise -1; die Trennzeichen werden als Zeichenkette mit einer Liste von Zeichen angegeben. Optional kann mit <count> die Anzahl der zu extrahierenden Felder festgelegt werden (Standard: 1). Der Wert 0 bedeutet, dass alle verbleibenden Felder extrahiert werden.
Beispiel:
fe_exists
Nimmt einen Frontend-Namen als Eingabewert entgegen und gibt den booleschen Wert TRUE zurück, wenn in der aktuellen Konfiguration ein Frontend mit diesem Namen existiert, andernfalls FALSE. Dies kann dort verwendet werden, wo es sinnvoll ist, anhand eines dynamischen Namens auf das Vorhandensein eines Frontends zu prüfen, etwa bei Map-Abfragen oder beim Beantworten einer externen Prüfung.
Beispiel:
fix_is_valid
Analysiert eine binäre Nutzlast und führt Plausibilitätsprüfungen für FIX (Financial Information eXchange) durch:
- prüft, dass alle Tag-IDs und Werte nicht leer und die Tag-IDs numerisch sind
- prüft, dass das Tag BeginString an erster Stelle steht und eine gültige FIX-Version enthält
- prüft, dass das Tag BodyLength an zweiter Stelle steht und die richtige Länge des Nachrichtenkörpers enthält
- prüft, dass das Tag MsgType an dritter Stelle steht.
- prüft, dass das letzte Tag der Nachricht CheckSum ist und eine gültige Prüfsumme enthält
Aufgrund des derzeitigen Designs von HAProxy kann nur die erste vom Client und vom Server gesendete Nachricht analysiert werden.
Dieser Konverter gibt einen booleschen Wert zurück: true, wenn die Nutzlast eine gültige FIX-Nachricht enthält, andernfalls false.
Siehe auch den Konverter fix_tag_value.
Beispiel:
fix_tag_value(<tag>)
Analysiert eine FIX-Nachricht (Financial Information eXchange) und extrahiert den Wert des Tags <tag>. <tag> kann eine Zeichenkette oder eine Ganzzahl sein, die das gewünschte Tag angibt. Jeder Ganzzahlwert ist zulässig; jedoch werden nur die folgenden Zeichenketten in ihre ganzzahlige Entsprechung umgewandelt: BeginString, BodyLength, MsgType, SenderCompID, TargetCompID, CheckSum. Weitere Tagnamen lassen sich leicht ergänzen.
Aufgrund des derzeitigen Designs von HAProxy kann nur die erste vom Client und vom Server gesendete Nachricht analysiert werden. Dieser Konverter führt keine Validierung der Nachricht durch. Es wird dringend empfohlen, die Nachricht zuvor mit dem Konverter fix_is_valid zu validieren.
Siehe auch den Konverter fix_is_valid.
Beispiel:
has_ctl([mask])
Prüft das binäre Eingabe-Sample auf die durch das Maskenargument festgelegten Steuerzeichen. Die Maske ist eine 33-Bit-Zahl, entweder dezimal oder hexadezimal mit dem Präfix “0x”. Für jedes zu erkennende Zeichen im Bereich 0x00 bis 0x1F ist das entsprechende Bit gesetzt; Bit 32 dient zum Erkennen des Zeichens DEL (0x7F). Ohne Maskenangabe verwendet der Konverter den Wert 0x1FFFFFDFF. Damit werden alle Steuerzeichen außer TAB (0x09) erkannt, das häufig in HTTP-Headern verwendet wird. Die spezielle Maske “any” entspricht 0x1FFFFFFFF und erkennt alle Steuerzeichen einschließlich TAB. Die spezielle Maske “http” entspricht 0x2401 und erkennt nur die in HTTP-Headerwerten verbotenen Steuerzeichen: CR (0x0D), LF (0x0A) und NUL (0x00).
Beispiele:
hex
Wandelt ein binäres Eingabe-Sample in eine Hexadezimalzeichenkette mit zwei Hexadezimalziffern je Eingabebyte um. Damit lassen sich Hex-Dumps binärer Eingabedaten in einer zuverlässig übertragbaren Form protokollieren oder übertragen; beispielsweise kann eine SSL-ID in einen Header kopiert werden.
hex2i
Wandelt eine Hexadezimalzeichenkette mit zwei Hexadezimalziffern je Eingabebyte in eine Ganzzahl um. Enthält der Eingabewert ein Zeichen, das keine Hexadezimalziffer ist, schlägt der Konverter fehl und gibt nichts zurück. So lässt sich eine ungültige Eingabe von einem gültigen Nullwert unterscheiden.
hmac(<algorithm>,<key>)
Wandelt ein binäres Eingabe-Sample mit dem angegebenen Schlüssel in einen Nachrichtenauthentifizierungscode um. Das Ergebnis ist ein binäres Sample. <algorithm> muss einer der registrierten OpenSSL-Message-Digest-Namen sein, beispielsweise sha256. Der Parameter <key> muss base64-kodiert sein und kann eine Zeichenkette oder eine Variable sein.
Dieser Konverter ist nur verfügbar, wenn HAProxy mit USE_OPENSSL kompiliert wurde.
host_only
Wandelt eine Zeichenkette mit dem Wert eines Host-Headers um und entfernt daraus den Port. Die Eingabe muss dem Format des Host-Headerwerts entsprechen (rfc9110#section-7.2). Unterstützt werden Eingaben dieser Art: hostname, hostname:80, 127.0.0.1, 127.0.0.1:80, [::1], [::1]:80.
Dieser Konverter wandelt die Zeichenkette außerdem in Kleinbuchstaben um.
Siehe auch den Konverter “port_only”, der den Port zurückgibt.
htonl
Wandelt den ganzzahligen Eingabewert in seine binäre 32-Bit-Darstellung in Netzwerk-Byte-Reihenfolge um. Da Sample-Abrufe vorzeichenbehaftete 64-Bit-Ganzzahlen verwenden, wird der Eingabewert bei diesem Konverter zunächst in eine vorzeichenlose 32-Bit-Ganzzahl umgewandelt.
http_date([<offset[,<unit>]])
Wandelt eine Ganzzahl, die ein Datum seit der Epoche darstellen soll, in eine Zeichenkette mit einem für HTTP-Headerfelder geeigneten Datumsformat um. Ist ein Offset angegeben, wird dieser vor der Umwandlung zum Datum addiert. Dies ist besonders nützlich für die Ausgabe von Date-Headerfeldern, von Expires-Werten in Antworten mit einem positiven Offset oder von Last-Modified-Werten mit einem negativen Offset. Bei Angabe einer Einheit wird der Zeitstempel als “s” für Sekunden (Standard), “ms” für Millisekunden oder “us” für Mikrosekunden seit der Epoche interpretiert. Für den Offset wird dieselbe Einheit wie für den Eingabezeitstempel angenommen.
iif(<true>,<false>)
Gibt die Zeichenkette <true> zurück, wenn der Eingabewert true ist. Andernfalls wird die Zeichenkette <false> zurückgegeben.
Beispiel:
in_table([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird der boolesche Wert false zurückgegeben, andernfalls true. Damit lässt sich prüfen, ob ein bestimmter Schlüssel in einer Tabelle vorhanden ist, die Elemente verfolgt, beispielsweise ob eine Quell-IP-Adresse oder ein Authorization-Header bereits beobachtet wurde.
ip.data
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “1” gesetzten bind-Option “tcp-ss” zurückgibt, oder mit der Ausgabe von “eth.data”. Überspringt den IP-Header sowie etwaige Optionen oder Erweiterungen und gibt einen binären Datenblock zurück, der beim Transportprotokoll beginnt, üblicherweise TCP oder UDP. Siehe auch “fc_saved_syn”, “tcp-ss” und “eth.data”.
ip.df
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “1” gesetzten bind-Option “tcp-ss” zurückgibt, oder mit der Ausgabe von “eth.data”. Gibt die Ganzzahl 1 zurück, wenn das DF-Flag (nicht fragmentieren) im IP-Header gesetzt ist, andernfalls 0. IPv6 besitzt kein DF-Flag und fragmentiert standardmäßig nicht; daher wird immer 1 zurückgegeben. Siehe auch “fc_saved_syn”, “tcp-ss” und “eth.data”.
ip.dst
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “1” gesetzten bind-Option “tcp-ss” zurückgibt, oder mit der Ausgabe von “eth.data”. Gibt die IPv4- oder IPv6-Zieladresse aus dem IPv4/v6-Header zurück. Siehe auch “fc_saved_syn”, “tcp-ss” und “eth.data”.
ip.fp([<mode>])
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “1” gesetzten bind-Option “tcp-ss” zurückgibt, oder mit der Ausgabe von “eth.data”. Untersucht verschiedene Teile des IP- und des TCP-Headers, um aus unveränderlichen Teilen eine Art Fingerabdruck zu erstellen. Dieser kann zur Unterscheidung mehrerer scheinbar identischer Hosts dienen. In der Praxis lässt sich damit ein sich fehlerhaft verhaltender Host unter mehreren Hosts mit gemeinsamer IP-Adresse genauer identifizieren, sodass legitime Nutzer nicht blockiert werden, wenn nur ein einzelner Host auffällig ist und blockiert werden muss. Der Konverter erzeugt aus der Eingabe einen binären Block mit mindestens 8 Bytes. Die Bytes des Fingerabdrucks sind wie folgt angeordnet: - Byte 0: IP-TOS-Feld (siehe ip.tos) - Byte 1: - Bit 7: IPv6 (1) / IPv4 (0) - Bit 6: ip.df - Bit 5..4: 0:ip.ttl<=32; 1:ip.ttl<=64; 2:ip.ttl<=128; 3:ip.ttl<=255 - Bit 3: IP-Optionen vorhanden (1) / nicht vorhanden (0) - Bit 2: TCP-Daten vorhanden (1) / nicht vorhanden (0) - Bit 1: CWR in TCP.flags gesetzt (1) / gelöscht (0) - Bit 0: ECE in TCP.flags gesetzt (1) / gelöscht (0) - Byte 2: - Bits 7..4: TCP-Headerlänge in Wörtern zu 4 Bytes - Bits 3..0: TCP-Fensterskalierung + 1 (1..15) / 0 (keine WS angekündigt) - Byte 3..4: tcp.win - Byte 5..6: tcp.options.mss oder null, falls nicht vorhanden - Byte 7: 1 Bit je vorhandener TCP-Option; die Optionen 2 bis 8 werden auf die Bits 0..6 abgebildet, und Bit 7 zeigt das Vorhandensein einer beliebigen Option von 9 bis 255 an.
Mit dem Argument <mode> lassen sich weitere Informationen an den Fingerabdruck anhängen. Standardmäßig, wenn <mode> nicht gesetzt oder null ist, besteht der Fingerabdruck ausschließlich aus den oben beschriebenen 8 Bytes. Ein anderer Wert für <mode> entspricht der Summe der folgenden Werte; die jeweiligen Bestandteile werden in der nachstehenden Reihenfolge an den Fingerabdruck angehängt: - 1: Der empfangene TTL-Wert wird angehängt (1 Byte). - 2: Die von “tcp.options_list” zurückgegebene Liste der TCP-Optionstypen mit 0 bis 40 zusätzlichen Bytes wird angehängt. - 4: Die Quell-IP-Adresse wird angehängt; dies fügt bei IPv4 4 Bytes und bei IPv6 16 Bytes hinzu.
Beispiel: Einen 13..25 Bytes langen Fingerabdruck aus dem Basis-FP, der TTL und der Quelladresse erstellen (1+4=5):
frontend test
mode http
bind :4445 tcp-ss 1
tcp-request connection set-var(sess.syn) fc_saved_syn
http-request return status 200 content-type text/plain lf-string \
"src=%[var(sess.syn),ip.src] fp=%[var(sess.syn),ip.fp(5),hex]\n"
Siehe auch “fc_saved_syn”, “tcp-ss”, “eth.data”, “ip.df”, “ip.ttl”, “tcp.win”, “tcp.options.mss” und “tcp.options_list”.
ip.hdr
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “1” gesetzten bind-Option “tcp-ss” zurückgibt, oder mit der Ausgabe von “eth.data”. Gibt einen binären Datenblock zurück, der mit dem IP-Header beginnt und nach der letzten Option oder Erweiterung, vor dem Header des Transportprotokolls, endet. Siehe auch “fc_saved_syn”, “tcp-ss” und “eth.data”.
ip.proto
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “1” gesetzten bind-Option “tcp-ss” zurückgibt, oder mit der Ausgabe von “eth.data”. Gibt die Nummer des Transportprotokolls zurück, üblicherweise 6 für TCP oder 17 für UDP. Siehe auch “fc_saved_syn”, “tcp-ss” und “eth.data”.
ip.src
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “1” gesetzten bind-Option “tcp-ss” zurückgibt, oder mit der Ausgabe von “eth.data”. Gibt die IPv4- oder IPv6-Quelladresse aus dem IPv4/v6-Header zurück. Siehe auch “fc_saved_syn”, “tcp-ss” und “eth.data”.
ip.tos
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “1” gesetzten bind-Option “tcp-ss” zurückgibt, oder mit der Ausgabe von “eth.data”. Gibt eine Ganzzahl zurück, die dem Wert des Felds Type of Service (TOS) im IPv4-Header oder Traffic Class (TC) im IPv6-Header entspricht. Im heutigen Internet enthalten die oberen 6 Bits dieses Felds meist einen DSCP-Wert (Differentiated Services Codepoint); die beiden unteren Bits werden entweder nicht oder für IP ECN verwendet. DSCP-Werte sind in RFC2474 und RFC8436 beschrieben, IP-ECN-Felder in RFC3168. Siehe auch “fc_saved_syn”, “tcp-ss” und “eth.data”.
ip.ttl
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “1” gesetzten bind-Option “tcp-ss” zurückgibt, oder mit der Ausgabe von “eth.data”. Gibt eine Ganzzahl zurück, die dem Feld TTL (Time To Live) oder HL (Hop Limit) im IPv4/IPv6-Header entspricht. Dieser Wert wird üblicherweise auf einen festen Anfangswert gesetzt und von jedem Router, den das Paket passiert, verringert. Ist der Anfangswert bekannt, lässt sich daraus abschätzen, aus welcher Entfernung ein Client eine Verbindung herstellt. Die meisten modernen Betriebssysteme beginnen mit einem Wert von 64. Siehe auch “fc_saved_syn”, “tcp-ss” und “eth.data”.
ip.ver
Wird mit einem Eingabe-Sample verwendet, das einen binären Ethernet-Frame darstellt, wie ihn “fc_saved_syn” in Verbindung mit der auf “1” gesetzten bind-Option “tcp-ss” zurückgibt, oder mit der Ausgabe von “eth.data”. Gibt die IP-Version aus dem IP-Header zurück, normalerweise entweder 4 oder 6. Dabei wird nicht geprüft, ob die Protokollnummer im darüberliegenden Ethernet-Frame übereinstimmt. Da der Konverter für gültige Pakete vorgesehen ist, wird davon ausgegangen, dass das Betriebssystem dies bereits überprüft hat. Siehe auch “fc_saved_syn”, “tcp-ss” und “eth.data”.
ipmask(<mask4>[,<mask6>])
Wendet eine Maske auf eine IP-Adresse an und verwendet das Ergebnis für Suchen und zum Speichern. Damit können alle Hosts innerhalb einer bestimmten Maske dieselben Tabelleneinträge und damit denselben Server verwenden. mask4 kann in Punktnotation (z. B. 255.255.255.0) oder in CIDR-Notation (z. B. 24) angegeben werden. mask6 kann in Vierergruppen (z. B. ffff:ffff::) oder in CIDR-Notation (z. B. 64) angegeben werden. Wird keine mask6 angegeben, schlägt die Umwandlung von IPv6-Adressen aus Gründen der Rückwärtskompatibilität fehl.
json([<input-code>])
Maskiert die Eingabezeichenkette und erzeugt eine ASCII-Ausgabezeichenkette, die als JSON-Zeichenkette verwendet werden kann. Der Konverter versucht, die Eingabezeichenkette gemäß dem Parameter <input-code> zu dekodieren. Dieser kann “ascii”, “utf8”, “utf8s”, “utf8p” oder “utf8ps” sein. Der Dekoder “ascii” schlägt niemals fehl. Der Dekoder “utf8” erkennt 3 Fehlerarten:
- fehlerhafte UTF-8-Sequenz (einzelnes Fortsetzungsbyte, falsche Anzahl von Fortsetzungsbytes, …)
- ungültiger Bereich (der dekodierte Wert liegt in einem für UTF-8 verbotenen Bereich),
- überlange Kodierung (der Wert ist mit mehr Bytes als nötig kodiert).
Die UTF-8-JSON-Kodierung kann den Fehler “too long value” erzeugen, wenn das UTF-8-Zeichen größer als 0xffff ist, da die Spezifikation für Escape-Sequenzen in JSON-Zeichenketten nur 4 Hexadezimalziffern zur Kodierung des Werts zulässt. Den UTF-8-Dekoder gibt es in 4 Varianten, die durch die Kombination zweier Suffixbuchstaben bezeichnet werden: “p” für “permissive” (tolerant) und “s” für “silently ignore” (stillschweigend ignorieren). Die Dekoder verhalten sich wie folgt:
- “ascii” : schlägt niemals fehl;
- “utf8” : schlägt bei jedem erkannten Fehler fehl;
- “utf8s” : schlägt niemals fehl, entfernt aber die fehlerhaften Zeichen;
- “utf8p” : akzeptiert und korrigiert überlange Kodierungen, schlägt aber bei jedem anderen Fehler fehl;
- “utf8ps”: schlägt niemals fehl, akzeptiert und korrigiert überlange Kodierungen, entfernt aber Zeichen, die anderen Fehlern entsprechen.
Dieser Konverter eignet sich besonders zum Erstellen korrekt maskierter JSON-Daten für die Protokollierung auf Servern, die Verkehrsprotokolle im JSON-Format verarbeiten.
Beispiel:
Eingehende Anfrage vom Client 127.0.0.1:
Ausgegebenes Protokoll:
json_query(<json_path>[,<output_type>])
Der Konverter json_query unterstützt die JSON-Typen string, boolean, number und array. Gleitkommazahlen werden als Zeichenkette zurückgegeben. Mit der Angabe ‘int’ für output_type wird der Wert in eine Ganzzahl umgewandelt. Arrays werden als Zeichenkette zurückgegeben, die mit einer eckigen Klammer beginnt und endet. Der Inhalt ist eine CSV-Liste. Je nach Datentyp können die Array-Werte in Anführungszeichen stehen. Sind die Array-Werte komplexe Typen, enthält die Zeichenkette die vollständige JSON-Darstellung jedes Werts, durch Kommas getrennt. Beispielergebnis einer roles-Abfrage für ein JWT:
Ist eine Umwandlung nicht möglich, schlägt der Konverter json_query fehl.
<json_path> muss eine gültige JSON-Path-Zeichenkette gemäß
https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/
sein.
Hinweis: Abhängig vom Kontext und der zugrunde liegenden Implementierung ist das Verhalten beim Extrahieren mehrfach vorhandener JSON-Schlüssel undefiniert. Es kann das erste, letzte oder ein anderes Vorkommen desselben Schlüssels aus dem Eingabeinhalt zurückgegeben werden; kodiert übergebene Schlüsselnamen werden möglicherweise nicht immer erkannt. Dieser Konverter eignet sich daher nicht zur Bereinigung von Inhalten.
Beispiel:
jwt_decrypt_cert(<cert>)
Prüft die Signatur eines als Eingabe übergebenen JSON Web Token im Format JSON Web Encryption (siehe RFC 7516) und gibt dessen mit dem bereitgestellten Zertifikat entschlüsselten Inhalt zurück. Der Parameter <cert> muss der Pfad zu einem bereits geladenen Zertifikat sein, das sich über den CLI-Befehl “dump ssl cert” ausgeben lässt. Die Option “jwt” des Zertifikats muss ausdrücklich auf “on” gesetzt sein (siehe die crt-list-Option “jwt”). Der Pfad kann direkt oder über eine Variable übergeben werden. Derzeit werden nur Token im Format Compact Serialization unterstützt: fünf durch Punkte getrennte, mit base64-url kodierte Zeichenketten.
Dieser Konverter kann für Token verwendet werden, deren Algorithmus (Feld “alg” des JOSE-Headers) einer der folgenden ist: RSA-OAEP, RSA-OAEP-256, ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A192KW oder ECDH-ES+A256KW. Der Algorithmus RSA1_5 ist implementiert, aber entsprechend der Empfehlung in Abschnitt 3.2 von RFC 8725 standardmäßig deaktiviert. Bei Bedarf lässt er sich mit der globalen Option ‘jwt.decrypt_alg_list’ wieder aktivieren.
Die unterstützten Algorithmen und Verschlüsselungsalgorithmen (Felder “alg” bzw. “enc” des JOSE-Headers) lassen sich mit den globalen Optionen ‘jwt.decrypt_alg_list’ und ‘jwt.decrypt_enc_list’ ändern.
Das JWE-Token muss base64url-kodiert übergeben werden; die Ausgabe erfolgt “raw”, also als Rohdaten. Tritt beim Analysieren des Tokens, beim Prüfen der Signatur oder beim Entschlüsseln des Inhalts ein Fehler auf, wird eine leere Zeichenkette zurückgegeben.
Beispiel:
jwt_decrypt_jwk(<jwk>)
Prüft die Signatur eines als Eingabe übergebenen JSON Web Token im Format JSON Web Encryption (siehe RFC 7516) und gibt dessen mit dem bereitgestellten JSON Web Key (RFC7517) entschlüsselten Inhalt zurück. Der Parameter <jwk> muss ein gültiger JWK des Typs ‘oct’, ‘EC’ oder ‘RSA’ sein (Feld ‘kty’ des JSON-Schlüssels) und kann als Zeichenkette oder über eine Variable übergeben werden.
Derzeit werden nur Token im Format Compact Serialization unterstützt: fünf durch Punkte getrennte, mit base64-url kodierte Zeichenketten.
Dieser Konverter kann Token entschlüsseln, deren symmetrischer Algorithmus (Feld “alg” des JOSE-Headers) einer der folgenden ist: A128KW, A192KW, A256KW, A128GCMKW, A192GCMKW, A256GCMKW, dir. In diesem Fall muss der bereitgestellte JWK vom Typ ‘oct’ sein.
Dieser Konverter unterstützt außerdem Token, deren Algorithmus (Feld “alg” des JOSE-Headers) zur RSA-Familie gehört (RSA-OAEP oder RSA-OAEP-256), wenn ein JWK vom Typ ‘RSA’ übergeben wird, oder zur ECDH-Familie (ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A192KW oder ECDH-ES+A256KW), wenn ein JWK vom Typ ‘EC’ übergeben wird. Der Algorithmus RSA1_5 ist implementiert, aber entsprechend der Empfehlung in Abschnitt 3.2 von RFC 8725 standardmäßig deaktiviert. Bei Bedarf lässt er sich mit der globalen Option ‘jwt.decrypt_alg_list’ wieder aktivieren.
Die Algorithmen A128KW und A192KW stehen unter AWS-LC nicht zur Verfügung. Daher funktionieren die Algorithmen A128KW, A192KW, ECDH-ES+A128KW und ECDH-ES+A192KW dort nicht.
Die unterstützten Algorithmen und Verschlüsselungsalgorithmen (Felder “alg” bzw. “enc” des JOSE-Headers) lassen sich mit den globalen Optionen ‘jwt.decrypt_alg_list’ und ‘jwt.decrypt_enc_list’ ändern.
Das JWE-Token muss base64url-kodiert übergeben werden; die Ausgabe erfolgt “raw”, also als Rohdaten. Tritt beim Analysieren des Tokens, beim Prüfen der Signatur oder beim Entschlüsseln des Inhalts ein Fehler auf, wird eine leere Zeichenkette zurückgegeben.
Aufgrund der Behandlung einfacher Anführungszeichen, Kommas und doppelter Anführungszeichen in der Konfiguration muss der Inhalt des JWK korrekt maskiert werden, damit dieser Konverter richtig funktioniert (weitere Informationen stehen in Abschnitt 2.2 ).
Beispiel:
jwt_decrypt_secret(<secret>)
Prüft die Signatur eines als Eingabe übergebenen JSON Web Token im Format JSON Web Encryption (siehe RFC 7516) und gibt dessen mit dem bereitgestellten base64-kodierten Geheimnis entschlüsselten Inhalt zurück. Das Geheimnis kann als Zeichenkette oder über eine Variable übergeben werden. Derzeit werden nur Token im Format Compact Serialization unterstützt: fünf durch Punkte getrennte, mit base64-url kodierte Zeichenketten.
Dieser Konverter kann für Token verwendet werden, deren Algorithmus (Feld “alg” des JOSE-Headers) einer der folgenden ist: A128KW, A192KW, A256KW, A128GCMKW, A192GCMKW, A256GCMKW, dir. Die Algorithmen A128KW und A192KW stehen unter AWS-LC nicht zur Verfügung; die Entschlüsselung funktioniert dort nicht.
Das JWE-Token muss base64url-kodiert übergeben werden; die Ausgabe erfolgt “raw”, also als Rohdaten. Tritt beim Analysieren des Tokens, beim Prüfen der Signatur oder beim Entschlüsseln des Inhalts ein Fehler auf, wird eine leere Zeichenkette zurückgegeben.
Beispiel:
jwt_header_query([<json_path>[,<output_type>]])
Bei Eingabe eines JSON Web Token (JWT) wird entweder der dekodierte Header-Teil des Tokens (der erste base64-url-kodierte Teil des JWT) zurückgegeben, wenn kein Parameter angegeben ist, oder eine json_query auf dem dekodierten Header-Teil ausgeführt. Einzelheiten zu den zulässigen Parametern json_path und output_type stehen beim Konverter “json_query”. Dieser Konverter unterstützt sowohl JWS- als auch JWE-Token, sofern sie im Format Compact Serialization vorliegen.
Dieser Konverter ist nur verfügbar, wenn HAProxy mit USE_OPENSSL kompiliert wurde.
jwt_payload_query([<json_path>[,<output_type>]])
Bei Eingabe eines JSON Web Token (JWT) im Format JSON Web Signed (JWS) wird entweder der dekodierte Nutzlast-Teil des Tokens (der zweite base64-url-kodierte Teil des JWT) zurückgegeben, wenn kein Parameter angegeben ist, oder eine json_query auf dem dekodierten Nutzlast-Teil ausgeführt. Einzelheiten zu den zulässigen Parametern json_path und output_type stehen beim Konverter “json_query”.
Dieser Konverter ist nur verfügbar, wenn HAProxy mit USE_OPENSSL kompiliert wurde.
jwt_verify(<alg>,<key>)
Prüft die Signatur des als Eingabe übergebenen JSON Web Token (JWT) mit dem Algorithmus <alg> und dem Parameter <key>. Derzeit können nur JWS-Token im Format Compact Serialization verarbeitet werden: drei durch Punkte getrennte, mit base64-url kodierte Zeichenketten. Dieser Konverter prüft ausschließlich die Signatur des Tokens und führt keine vollständige JWT-Validierung gemäß Abschnitt 7.2
von RFC7519 durch. Beispielsweise wird nicht sichergestellt, dass Header und Nutzlast nach dem Dekodieren vollständig gültiges JSON enthalten; auch ihre jeweiligen Inhalte werden nicht geprüft.
-
<alg>kann eine Zeichenkette oder der Name einer Variablen sein (siehe auch “set-var”), die den Namen des zur Überprüfung verwendeten Algorithmus enthält.Unterstützt werden die in Abschnitt 3.1 von RFC7518 genannten Algorithmen:
Der Algorithmus “none” ist standardmäßig nicht erlaubt, um den Empfehlungen in RFC8725 Abschnitt 3.2 zu folgen. Setzen Sie die globale Option ‘jwt.allow_none_alg’, um ihn ausdrücklich zu erlauben.
-
<key>kann eine Zeichenkette oder der Name einer Variablen sein (siehe auch “set-var”), die ein Geheimnis oder den Pfad zu einem öffentlichen Schlüssel enthält.Geheimnisse sind nur bei HMAC-Algorithmen anwendbar.
Öffentliche Schlüssel müssen entweder im Format PKCS#1 vorliegen (bei RSA-Schlüsseln, beginnend mit BEGIN RSA PUBLIC KEY) oder im SPKI-Format (Subject Public Key Info, beginnend mit BEGIN PUBLIC KEY). Öffentliche Schlüssel müssen beim Einlesen der Konfiguration verfügbar sein und lassen sich zur Laufzeit weder aktualisieren noch laden. Zur JWT-Token-Validierung anhand vollständiger PEM-Zertifikate siehe den Konverter “jwt_verify_cert”.
Alle öffentlichen Schlüssel, die zur Überprüfung von JWTs verwendet werden könnten, müssen bei der Initialisierung bekannt sein. Sie werden in einen eigenen Cache aufgenommen, damit zur Laufzeit keine Festplattenzugriffe nötig sind.
Gibt bei erfolgreicher Überprüfung 1, bei fehlgeschlagener Überprüfung 0 und bei jedem anderen Fehler einen strikt negativen Wert zurück. Wegen dieser von null verschiedenen Fehler-Rückgabewerte sollte das Ergebnis dieses Konverters niemals in einen booleschen Wert umgewandelt werden. Eine vollständige Liste der möglichen Rückgabewerte folgt unten.
Die möglichen Rückgabewerte sind:
Dieser Konverter ist nur verfügbar, wenn HAProxy mit USE_OPENSSL kompiliert wurde.
Beispiel:
jwt_verify_cert(<alg>,<cert>)
Prüft die Signatur des als Eingabe übergebenen JSON Web Token (JWT) mit dem Algorithmus <alg> und dem Parameter <cert>. Derzeit können nur JWS-Token im Format Compact Serialization verarbeitet werden: drei durch Punkte getrennte, mit base64-url kodierte Zeichenketten. Dieser Konverter prüft ausschließlich die Signatur des Tokens und führt keine vollständige JWT-Validierung gemäß Abschnitt 7.2
von RFC7519 durch. Beispielsweise wird nicht sichergestellt, dass Header und Nutzlast nach dem Dekodieren vollständig gültiges JSON enthalten; auch ihre jeweiligen Inhalte werden nicht geprüft.
-
<alg>kann eine Zeichenkette oder der Name einer Variablen sein (siehe auch “set-var”), die den Namen des zur Überprüfung verwendeten Algorithmus enthält. Anders als der Konverter “jwt_verify” erwartet dieser Konverter als zweiten Parameter ausschließlich ein Zertifikat. Er sollte daher nicht für Token mit HMAC-Algorithmen verwendet werden.Unterstützt werden die in Abschnitt 3.1 von RFC7518 genannten Algorithmen (außer den HMAC-Algorithmen):
-
<key>kann eine Zeichenkette oder der Name einer Variablen sein (siehe auch “set-var”), die einen Zertifikatspfad enthält.Zertifikate müssen Standard-PEM-Zertifikate sein (beginnend mit BEGIN CERTIFICATE). Ihr Pfad kann dem Konverter direkt übergeben oder über eine Variable referenziert werden. Bei Verwendung einer Variablen können die entsprechenden Zertifikate entweder in einem crt-store deklariert oder dynamisch über den Stats-Socket geladen werden. Wird ein Pfad direkt angegeben und ist das entsprechende Zertifikat noch nicht im internen Zertifikatsspeicher geladen, wird es beim Einlesen der Konfiguration geladen. Es muss daher bereits vorhanden sein, andernfalls wird ein Fehler ausgelöst.
Verwendet werden können nur Zertifikate, die ausdrücklich für die JWT-Validierung freigegeben sind. Siehe die crt-store-Option “jwt”.
Zertifikate lassen sich dynamisch aktualisieren und neue Zertifikate über den Stats-Socket hinzufügen. Siehe auch “set ssl cert” und “new ssl cert” im Verwaltungshandbuch.
Gibt bei erfolgreicher Überprüfung 1, bei fehlgeschlagener Überprüfung 0 und bei jedem anderen Fehler einen strikt negativen Wert zurück. Wegen dieser von null verschiedenen Fehler-Rückgabewerte sollte das Ergebnis dieses Konverters niemals in einen booleschen Wert umgewandelt werden. Eine vollständige Liste der möglichen Rückgabewerte folgt unten.
Die möglichen Rückgabewerte sind:
Dieser Konverter ist nur verfügbar, wenn HAProxy mit USE_OPENSSL kompiliert wurde.
Beispiel:
language(<value>[,<default>])
Gibt aus einer mit “req.fhdr” aus dem Header “accept-language” extrahierten Liste den Wert mit dem höchsten q-Faktor zurück. Werte ohne q-Faktor haben den q-Faktor 1. Werte mit dem q-Faktor 0 werden verworfen. Es werden nur Werte berücksichtigt, die in der durch Semikolons getrennten Liste <values> enthalten sind. Die Syntax des Arguments <value> lautet “lang[;lang[;lang[;…]]]”. Passt kein Wert zur angegebenen Liste und ist ein Standardwert angegeben, wird dieser zurückgegeben. Sprachnamen können nach einem Bindestrich (’-’) eine Variante enthalten. Ist diese Variante in der Liste vorhanden, wird sie abgeglichen; andernfalls wird nur die Basissprache geprüft. Beim Abgleich wird Groß-/Kleinschreibung beachtet, und die ausgegebene Zeichenkette ist stets einer der in den Argumenten angegebenen Werte. Die Reihenfolge der Argumente spielt keine Rolle. Es zählt nur die Reihenfolge der Werte in der Anfrage, da bei mehreren Werten mit demselben q-Faktor der erste verwendet wird.
Beispiel:
length
Ermittelt die Länge der Zeichenkette. Kann nur hinter einer Sample-Abruffunktion für Zeichenketten oder hinter einem Transformationsschlüsselwort stehen, das den Typ string zurückgibt. Das Ergebnis hat den Typ integer.
lower
Wandelt ein Zeichenketten-Sample in Kleinbuchstaben um. Kann nur hinter einer Sample-Abruffunktion für Zeichenketten oder hinter einem Transformationsschlüsselwort stehen, das den Typ string zurückgibt. Das Ergebnis hat den Typ string.
ltime(<format>[,<offset>])
Wandelt eine Ganzzahl, die ein Datum seit der Epoche darstellen soll, in eine Zeichenkette um, die dieses Datum in Ortszeit wiedergibt. Das Format wird durch die Zeichenkette <format> mit strftime(3) festgelegt. Damit lassen sich beliebige Datumsformate in Protokollen verwenden. Ein optionaler <offset> in Sekunden kann auf das Eingabedatum angewendet werden (positiv oder negativ). Die von Ihrem Betriebssystem unterstützten Formate stehen in der Handbuchseite zu strftime(). Siehe auch den Konverter utime.
Beispiel:
ltrim(<chars>)
Überspringt am Anfang der Zeichenkettendarstellung des Eingabe-Samples alle Zeichen aus <chars>.
map(<map_name>[,<default_value>])
Sucht den Eingabewert in <map_name> mit der Abgleichmethode <match_type> und gibt den zugeordneten Wert zurück, umgewandelt in den Typ <output_type>. Wird der Eingabewert in <map_name> nicht gefunden, gibt der Konverter <default_value> zurück. Ist <default_value> nicht gesetzt, schlägt der Konverter fehl und verhält sich so, als ließe sich kein Eingabewert abrufen. Ist <match_type> nicht gesetzt, wird “str” verwendet. Ebenso wird bei nicht gesetztem <output_type> der Wert “str” verwendet. Das Schlüsselwort “map” ist der Einfachheit halber ein Alias für “map_str” und bildet eine Zeichenkette auf eine andere ab. <map_name> muss dem in 2.7. beschriebenen Namensformat für Maps und ACLs entsprechen.
Überschneidungen zwischen Schlüsseln sollten unbedingt vermieden werden: IP-Adressen und Zeichenketten werden in Bäumen gespeichert, sodass die erste der spezifischsten Übereinstimmungen verwendet wird. Andere Schlüssel werden in Listen gespeichert; hier wird das erste passende Vorkommen verwendet.
Die folgende Tabelle enthält alle verfügbaren Map-Funktionen, geordnet nach Eingabetyp, Abgleichmethode und Ausgabetyp.
Die spezielle Map “map_regm” erwartet eine Erfassungsgruppe im regulären Ausdruck und ändert die Ausgabe, indem Rückverweise (wie “\1”) durch den entsprechenden übereinstimmenden Text ersetzt werden.
Der Ausgabetyp “key” bedeutet, dass der Schlüssel des passenden Eintrags (wie in der Map-Datei vorhanden) als Zeichenkette zurückgegeben wird, anstelle des Werts. Das optionale Argument <default_value> wird beim Ausgabetyp “key” nicht unterstützt.
Die durch <map_name> referenzierten Dateien enthalten je Zeile einen Schlüssel und einen Wert. Zeilen, die mit ‘#’ beginnen, werden ebenso wie Leerzeilen ignoriert. Führende Tabulatoren und Leerzeichen werden entfernt. Der Schlüssel ist dann das erste “Wort”, also eine Folge von Zeichen ohne Leerzeichen oder Tabulatoren. Der Wert ist der auf die anschließende Folge von Leerzeichen oder Tabulatoren folgende Text bis zum Zeilenende, ohne abschließende Leerzeichen oder Tabulatoren.
Beispiel:
mod(<value>)
Dividiert den vorzeichenbehafteten ganzzahligen Eingabewert durch <value> und gibt den Rest als vorzeichenbehaftete Ganzzahl zurück. Ist <value> null, wird null zurückgegeben. <value> kann ein numerischer Wert oder ein Variablenname sein. Einzelheiten zu Variablen stehen in Abschnitt 2.8
.
mqtt_field_value(<packettype>,<fieldname_or_property_ID>)
Gibt den Wert von <fieldname> zurück, der in der MQTT-Eingabenutzlast vom Typ <packettype> gefunden wird. <packettype> kann eine Zeichenkette (Abgleich ohne Beachtung der Groß-/Kleinschreibung) oder ein numerischer Wert sein, der dem Pakettyp entspricht, aus dem Daten extrahiert werden sollen. Die unterstützten Zeichenketten und Ganzzahlen stehen hier:
https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718021
https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901022
<fieldname> hängt von <packettype> ab und kann einer der unten aufgeführten Werte sein. Beim Abgleich von <fieldname> wird die Groß-/Kleinschreibung nicht beachtet. <property id> kommt nur in MQTT-v5.0-Datenströmen vor. Siehe diese Tabelle: https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901029
- CONNECT (oder 1): flags, protocol_name, protocol_version, client_identifier, will_topic, will_payload, username, password, keepalive ODER eine beliebige Eigenschafts-ID als numerischer Wert (nur für MQTT-v5.0-Pakete):
Noch nicht unterstützt:
- CONNACK (oder 2): flags, protocol_version, reason_code ODER eine beliebige Eigenschafts-ID als numerischer Wert (nur für MQTT-v5.0-Pakete):
Noch nicht unterstützt:
Aufgrund des derzeitigen Designs von HAProxy kann nur die erste vom Client und vom Server gesendete Nachricht analysiert werden. Daher kann dieser Konverter nur Daten aus den Pakettypen CONNECT und CONNACK extrahieren. CONNECT ist die erste vom Client gesendete Nachricht und CONNACK die erste vom Server gesendete Antwort.
Beispiel:
mqtt_is_valid
Prüft, ob die binäre Eingabe ein gültiges MQTT-Paket ist. Gibt einen booleschen Wert zurück.
Aufgrund des derzeitigen Designs von HAProxy kann nur die erste vom Client und vom Server gesendete Nachricht analysiert werden. Daher kann dieser Konverter nur Daten aus den Pakettypen CONNECT und CONNACK extrahieren. CONNECT ist die erste vom Client gesendete Nachricht und CONNACK die erste vom Server gesendete Antwort.
Es werden nur MQTT 3.1, 3.1.1 und 5.0 unterstützt.
Beispiel:
ms_ltime(<format>[,<offset>])
Funktioniert wie “ltime”, erwartet die Eingabe aber in Millisekunden. Unterstützt außerdem das von date(1) inspirierte Konvertierungskennzeichen %N. Wandelt eine Ganzzahl, die ein Datum seit der Epoche darstellen soll, in eine Zeichenkette um, die dieses Datum in Ortszeit wiedergibt. Das Format wird durch die Zeichenkette <format> mit strftime(3) festgelegt. Damit lassen sich beliebige Datumsformate in Protokollen verwenden. Ein optionaler <offset> in Millisekunden kann auf das Eingabedatum angewendet werden (positiv oder negativ). Die von Ihrem Betriebssystem unterstützten Formate stehen in der Handbuchseite zu strftime().
Mit dem Konvertierungskennzeichen %N lässt sich der Nanosekundenanteil des Datums ausgeben. Da die Eingabe in Millisekunden erfolgt, ist die Genauigkeit begrenzt (000000000..999000000). %N kann zwischen % und N eine Breitenangabe enthalten. Dies ist nützlich zur Darstellung von Millisekunden (%3N) oder Mikrosekunden (%6N). Die voreingestellte und maximale Breite ist 9 (%N = %9N).
Siehe auch den Konverter utime für UTC sowie die Konverter “ltime” und “us_ltime”.
Beispiel:
ms_utime(<format>[,<offset>])
Funktioniert wie “utime”, erwartet die Eingabe aber in Millisekunden. Unterstützt außerdem das von date(1) inspirierte Konvertierungskennzeichen %N. Wandelt eine Ganzzahl, die ein Datum seit der Epoche darstellen soll, in eine Zeichenkette um, die dieses Datum in UTC-Zeit wiedergibt. Das Format wird durch die Zeichenkette <format> mit strftime(3) festgelegt. Damit lassen sich beliebige Datumsformate in Protokollen verwenden. Ein optionaler <offset> in Millisekunden kann auf das Eingabedatum angewendet werden (positiv oder negativ). Die von Ihrem Betriebssystem unterstützten Formate stehen in der Handbuchseite zu strftime().
Mit dem Konvertierungskennzeichen %N lässt sich der Nanosekundenanteil des Datums ausgeben. Da die Eingabe in Millisekunden erfolgt, ist die Genauigkeit begrenzt (000000000..999000000). %N kann zwischen % und N eine Breitenangabe enthalten. Dies ist nützlich zur Darstellung von Millisekunden (%3N) oder Mikrosekunden (%6N). Die voreingestellte und maximale Breite ist 9 (%N = %9N).
Siehe auch den Konverter ltime für Ortszeit sowie die Konverter “utime” und “us_utime”.
Beispiel:
mul(<value>)
Multipliziert den vorzeichenbehafteten ganzzahligen Eingabewert mit <value> und gibt das Produkt als vorzeichenbehaftete Ganzzahl zurück. Bei einem Überlauf wird der für das Vorzeichen größtmögliche Wert zurückgegeben, sodass die Operation nicht umläuft. <value> kann ein numerischer Wert oder ein Variablenname sein. Einzelheiten zu Variablen stehen in Abschnitt 2.8
.
nbsrv
Nimmt einen Eingabewert vom Typ string, interpretiert ihn als Backend-Namen und gibt die Anzahl der nutzbaren Server in diesem Backend zurück. Dies eignet sich für Stellen, an denen ein Backend anhand eines dynamischen Namens gesucht werden soll, beispielsweise anhand des Ergebnisses einer Map-Suche.
neg
Nimmt den vorzeichenbehafteten ganzzahligen Eingabewert, berechnet den entgegengesetzten Wert und gibt den Rest als vorzeichenbehaftete Ganzzahl zurück. 0 bleibt unverändert. Dieser Operator ist für Subtraktionen mit umgekehrter Operandenreihenfolge vorgesehen: Um die Eingabe von einer Konstanten abzuziehen, genügt “neg,add(value)”.
not
Gibt den booleschen Wert FALSE zurück, wenn der vorzeichenbehaftete ganzzahlige Eingabewert ungleich null ist, andernfalls TRUE. In Verbindung mit and() kann dies dazu dienen, bei Bitprüfungen von Eingabewerten true/false zurückzugeben, beispielsweise um das Fehlen eines Flags zu prüfen.
odd
Gibt den booleschen Wert TRUE zurück, wenn der vorzeichenbehaftete ganzzahlige Eingabewert ungerade ist, andernfalls FALSE. Dies ist funktional gleichbedeutend mit “and(1),bool”.
or(<value>)
Führt ein bitweises “OR” zwischen <value> und dem vorzeichenbehafteten ganzzahligen Eingabewert aus und gibt das Ergebnis als vorzeichenbehaftete Ganzzahl zurück. <value> kann ein numerischer Wert oder ein Variablenname sein. Einzelheiten zu Variablen stehen in Abschnitt 2.8
.
param(<name>[,<delim>])
Extrahiert das erste Vorkommen des Parameters <name> aus der Eingabezeichenkette. Die Parameter werden durch <delim> getrennt, standardmäßig “&”; Name und Wert eines Parameters werden durch “=” getrennt. Gibt es vor dem Ende des Parameterabschnitts kein “=” und keinen Wert, entspricht dies dem Wert einer leeren Zeichenkette.
Dies kann zum Extrahieren von Parametern aus einer Abfragezeichenkette oder gegebenenfalls aus einem x-www-form-urlencoded-Nachrichtenkörper nützlich sein. Insbesondere kann query,param(<name>) als Alternative zu urlp(<name>) verwendet werden, die nur “&” als Trennzeichen nutzt, während “urlp” auch “?” und “;” verwendet.
Dieser Konverter behandelt URL-kodierte Zeichen nicht gesondert. Zum Dekodieren des Werts können Sie den Konverter url_dec auf die Ausgabe anwenden. Kann der Parametername in der Eingabe kodierte Zeichen enthalten, sollten Sie die Eingabe vermutlich vor dem Aufruf von “param” normalisieren. Dies ist mit “http-request normalize-uri” möglich, insbesondere mit den Optionen percent-decode-unreserved und percent-to-uppercase.
Beispiel:
port_only
Wandelt eine Zeichenkette mit dem Wert eines Host-Headers in eine Ganzzahl um, indem der enthaltene Port zurückgegeben wird. Die Eingabe muss dem Format des Host-Headerwerts entsprechen (rfc9110#section-7.2). Unterstützt werden Eingaben dieser Art: hostname, hostname:80, 127.0.0.1, 127.0.0.1:80, [::1], [::1]:80.
Enthält die Eingabe keinen Port, wird 0 zurückgegeben.
Siehe auch den Konverter “host_only”, der den Host zurückgibt.
protobuf(<field_number>[,<field_type>])
Extrahiert aus einem binären Eingabe-Sample, das eine Protocol-Buffers-Nachricht darstellt, das Nachrichtenfeld mit der Feldnummer <field_number> (Punktnotation). Ist <field_type> nicht angegeben, erfolgt die Extraktion als Rohdaten; andernfalls als ganzzahliges Sample (siehe auch “ungrpc” weiter unten). Zulässig sind folgende Typen: “int32”, “int64”, “uint32”, “uint64”, “sint32”, “sint64”, “bool”, “enum” für den Wire-Typ “varint” 0; “fixed64”, “sfixed64”, “double” für den 64bit-Wire-Typ 1; “fixed32”, “sfixed32”, “float” für den Wire-Typ 5. “string” gilt als längenbegrenzter Typ und benötigt daher zur Extraktion kein Argument <field_type>. Weitere Informationen zu den Feldtypen von Protocol-Buffers-Nachrichten stehen hier: https://developers.google.com/protocol-buffers/docs/encoding
regsub(<regex>,<subst>[,<flags>])
Wendet eine Ersetzung anhand eines regulären Ausdrucks auf die Eingabezeichenkette an. Führt dieselbe Operation aus wie das bekannte Programm “sed” mit “s/<regex>/<subst>/”. Standardmäßig wird in der Eingabezeichenkette das erste Vorkommen des längsten auf den regulären Ausdruck <regex> passenden Teils durch die Ersetzungszeichenkette <subst> ersetzt. Mit dem Flag “g” im dritten Argument <flags> lassen sich stattdessen alle Vorkommen ersetzen. Mit dem Flag “i” in <flags> lässt sich außerdem die Beachtung der Groß-/Kleinschreibung beim regulären Ausdruck ausschalten. Da <flags> eine Zeichenkette ist, werden alle gewünschten Flags aneinandergehängt. Sind sowohl “i” als auch “g” gewünscht, haben “gi” und “ig” somit dieselbe Wirkung. Der wichtigste Anwendungsfall dieses Konverters ist das Ersetzen bestimmter Zeichen oder Zeichenfolgen durch andere.
Es wird dringend empfohlen, den regulären Ausdruck in geschützte Anführungszeichen einzuschließen. Dies verbessert die Lesbarkeit und verhindert, dass eine schließende Klammer im regulären Ausdruck mit der Funktionsklammer verwechselt wird. Wie in der Bourne-Shell wird die erste Ebene von Anführungszeichen beim Abgrenzen von Wortgruppen in der Zeile verarbeitet; eine zweite Ebene kann für Argumente verwendet werden. Für die äußere Ebene werden einfache Anführungszeichen empfohlen, da darin weder Rückstriche noch Dollarzeichen aufgelöst werden.
Beispiele:
reverse
Kehrt die Eingabezeichenkette Byte für Byte um.
Dieser Konverter arbeitet unabhängig von der Kodierung und kehrt Bytes statt Zeichen um. Er eignet sich daher nicht zum Umkehren von menschlichem Text in UTF-8-Kodierung.
Damit lassen sich Suffixsuchen in der ursprünglichen Zeichenkette in Präfixsuchen in der umgekehrten Zeichenkette umwandeln. Dadurch können bei großen Maps indizierte Präfix-Abgleichfunktionen wie “map_beg” verwendet werden.
Beispiele:
reverse_dom
Wandelt eine Zeichenkette mit einem FQDN-artigen Hostnamen in eine Form mit umgekehrter Reihenfolge der Labels um. Ein einzelner abschließender Punkt in der Eingabe wird ignoriert. Leere Labels lassen den Konverter fehlschlagen.
Dieser Konverter wandelt seine Eingabe weder in Kleinbuchstaben um noch entfernt er einen Port. Bei Bedarf soll er mit vorhandenen Konvertern wie “lower” oder “host_only” kombiniert werden.
Die Behandlung des abschließenden Punkts bleibt bewusst dem Aufrufer überlassen. So können Aufrufer entscheiden, ob sie auch die Stammdomain oder nur Subdomains abgleichen möchten.
Die Form mit umgekehrter Labelreihenfolge ist für große Domain-Maps nützlich, weil sie Domain-Suffixsuchen in Präfixsuchen umwandelt. Damit lassen sich indizierte Präfix-Abgleichfunktionen wie “map_beg” verwenden.
Beispiele:
rfc7239_field(<field>)
Extrahiert ein einzelnes Feld bzw. einen einzelnen Parameter aus einem als Eingabe übergebenen, RFC-7239-konformen Headerwert.
Unterstützte Felder sind: - proto: entweder ‘http’ oder ‘https’ - host: HTTP-konformer Host - for: RFC7239-Knoten - by: RFC7239-Knoten
Weitere Informationen stehen hier:
Beispiel:
rfc7239_is_valid
Gibt true zurück, wenn der eingegebene Header einen RFC-7239-konformen Headerwert enthält, andernfalls false.
Beispiel:
rfc7239_n2nn
Wandelt einen RFC7239-Knoten (aus den 7239-Headerfeldern ‘for’ oder ‘by’) in seine entsprechende endgültige Knotennamensform um: - ipv4-Adresse - ipv6-Adresse - ‘unknown’ - Bezeichner ‘_obfs’
Beispiel:
rfc7239_n2np
Wandelt einen RFC7239-Knoten (aus den 7239-Headerfeldern ‘for’ oder ‘by’) in seine entsprechende endgültige Knotenportform um: - vorzeichenlose Ganzzahl - Bezeichner ‘_obfs’
Beispiel:
rfc7239_nn
Wandelt die übergebene Adresse oder Zeichenkette in einen RFC7239-konformen Knotennamen um. Dies kann verwendet werden, um die 7239-Headerfelder ‘for’ oder ‘by’ manuell zu erstellen.
Ist die übergebene Eingabe eine Zeichenkette, wird ihr automatisch das Zeichen ‘_’ vorangestellt, um einen verschleierten Bezeichner darzustellen. Die Zeichenkette muss dem Zeichensatz von RFC7239 entsprechen. Ist die Zeichenkette leer, wird sie in den Bezeichner “unknown” umgewandelt.
Beispiel:
Siehe auch: “rfc7239_np”
rfc7239_np
Wandelt die übergebene vorzeichenlose Ganzzahl oder Zeichenkette in einen RFC7239-konformen Knotenport um. Dies kann verwendet werden, um die 7239-Headerfelder ‘for’ oder ‘by’ manuell zu erstellen.
Ist die übergebene Eingabe eine Zeichenkette, wird ihr automatisch das Zeichen ‘_’ vorangestellt, um einen verschleierten Bezeichner darzustellen. Die Zeichenkette muss dem Zeichensatz von RFC7239 entsprechen und darf nicht leer sein.
Beispiel:
Siehe auch: “rfc7239_nn”
rtrim(<chars>)
Überspringt am Ende der Zeichenkettendarstellung des Eingabe-Samples alle Zeichen aus <chars>.
sdbm([<avalanche>])
Bildet mit der SDBM-Hashfunktion aus einem binären Eingabe-Sample einen vorzeichenlosen 32-Bit-Wert. Ist das optionale Argument <avalanche> gleich 1, kann zusätzlich eine vollständige Avalanche-Hashfunktion auf die Ausgabe angewendet werden. Dieser Konverter verwendet dieselben Funktionen wie die verschiedenen Hash-basierten Algorithmen zur Lastverteilung und liefert daher exakt dieselben Ergebnisse. Er ist hauptsächlich zur Fehlersuche gedacht, kann aber als Eintrag in einer Stick Table zum Erfassen grober Statistiken verwendet werden. Er darf nicht für Sicherheitszwecke verwendet werden, da ein 32-Bit-Hash leicht zu brechen ist. Siehe auch “crc32”, “djb2”, “wt6”, “crc32c” und die Direktive “hash-type”.
secure_memcmp(<var>)
Vergleicht den Inhalt von <var> mit dem Eingabewert. Beide Werte werden als binäre Zeichenketten behandelt. Gibt einen booleschen Wert zurück, der angibt, ob beide binären Zeichenketten übereinstimmen.
Haben beide binären Zeichenketten dieselbe Länge, wird der Vergleich in konstanter Zeit ausgeführt.
Dieser Konverter ist nur verfügbar, wenn HAProxy mit USE_OPENSSL kompiliert wurde.
Beispiel:
set-var(<var>[,<cond>...])
Setzt eine Variable auf den Eingabeinhalt und gibt diesen Inhalt unverändert aus, wenn alle angegebenen Bedingungen wahr sind (eine Liste der möglichen Bedingungen folgt unten). Die Variable behält den Wert und den zugehörigen Eingabetyp. Einzelheiten zu Variablen stehen in Abschnitt 2.8 .
Sie können dem Konverter höchstens vier der folgenden Bedingungen übergeben:
- “ifexists”/“ifnotexists”:
- “ifempty”/“ifnotempty”:
- “ifset”/“ifnotset”:
- “ifgt”/“iflt”:
sha1
Wandelt ein binäres Eingabe-Sample in einen SHA-1-Digest um. Das Ergebnis ist ein binäres Sample mit einer Länge von 20 Bytes.
sha2([<bits>])
Wandelt ein binäres Eingabe-Sample in einen Digest der SHA-2-Familie um. Das Ergebnis ist ein binäres Sample mit einer Länge von <bits>/8 Bytes.
Gültige Werte für <bits> sind 224, 256, 384 und 512; sie entsprechen jeweils SHA-<bits>. Der Standardwert ist 256.
Dieser Konverter ist nur verfügbar, wenn HAProxy mit USE_OPENSSL kompiliert wurde.
srv_is_up
Nimmt einen Eingabewert vom Typ string, entweder einen Servernamen oder im Format <backend>/<server>, und gibt true zurück, wenn der bezeichnete Server derzeit UP ist. Dies eignet sich für Stellen, an denen der Serverstatus anhand eines dynamischen Namens abgefragt werden soll, beispielsweise anhand eines Cookie-Werts (z. B. req.cook(SRVID),srv_is_up), um anschließend zu entscheiden, ob eine Anfrage an ein anderes Ziel geleitet werden soll. Beachten Sie vor der Verwendung, dass dieser Konverter bei unkontrollierten Eingabedaten einem externen Beobachter ermöglichen könnte, den Zustand jedes Servers in der gesamten Konfiguration abzufragen. Dies ist in manchen Umgebungen möglicherweise nicht akzeptabel.
srv_queue
Nimmt einen Eingabewert vom Typ string, entweder einen Servernamen oder im Format <backend>/<server>, und gibt die Anzahl der Streams in der Warteschlange dieses Servers zurück. Dies eignet sich für Stellen, an denen wartende Streams anhand eines dynamischen Namens abgefragt werden sollen, beispielsweise anhand eines Cookie-Werts (z. B. req.cook(SRVID),srv_queue), um anschließend zu entscheiden, ob die Persistenz aufgehoben oder eine Anfrage an ein anderes Ziel geleitet werden soll. Beachten Sie vor der Verwendung, dass dieser Konverter bei unkontrollierten Eingabedaten einem externen Beobachter ermöglichen könnte, den Zustand jedes Servers in der gesamten Konfiguration abzufragen. Dies ist in manchen Umgebungen möglicherweise nicht akzeptabel.
strcmp(<var>)
Vergleicht den Inhalt von <var> mit dem Eingabewert vom Typ string. Gibt das Ergebnis als vorzeichenbehaftete Ganzzahl entsprechend strcmp(3) zurück: 0, wenn beide Zeichenketten identisch sind. Einen Wert kleiner als 0, wenn die linke Zeichenkette lexikografisch kleiner als die rechte oder die linke Zeichenkette kürzer ist. Andernfalls einen Wert größer als 0 (rechte Zeichenkette größer als linke Zeichenkette oder rechte Zeichenkette kürzer).
Siehe auch den Konverter secure_memcmp, wenn Sie zwei binäre Zeichenketten in konstanter Zeit vergleichen müssen.
Beispiel:
sub(<value>)
Subtrahiert <value> vom vorzeichenbehafteten ganzzahligen Eingabewert und gibt das Ergebnis als vorzeichenbehaftete Ganzzahl zurück. Hinweis: Um die Eingabe von einer Konstanten abzuziehen, genügt “neg,add(value)”. <value> kann ein numerischer Wert oder ein Variablenname sein. Einzelheiten zu Variablen stehen in Abschnitt 2.8
.
table_bytes_in_rate([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die dem Eingabe-Sample in der angegebenen Tabelle zugeordnete durchschnittliche Byterate vom Client zum Server zurück, gemessen als Anzahl von Bytes über den in der Tabelle konfigurierten Zeitraum. Siehe auch das Sample-Abruf-Schlüsselwort sc_bytes_in_rate.
table_bytes_out_rate([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die durchschnittliche Byterate vom Server zum Client zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Diese wird als Anzahl von Bytes über den in der Tabelle konfigurierten Zeitraum gemessen. Siehe auch das Sample-Abruf-Schlüsselwort sc_bytes_out_rate.
table_clr_gpc(<idx>[,<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Setzt den Allzweckzähler am Index <idx> des Arrays gpc zurück und gibt seinen vorherigen Wert zurück. <idx> ist eine Ganzzahl zwischen 0 und 99. Wird der Eintrag nicht gefunden, wird ein Eintrag erstellt und 0 zurückgegeben. Dieser Konverter gilt nur für den Array-data_type ‘gpc’, nicht für die älteren data_types ‘gpc0’ oder ‘gpc1’. Siehe auch das Sample-Abruf-Schlüsselwort sc_clr_gpc.
table_clr_gpc0([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Setzt den ersten Allzweckzähler ‘0’ zurück und gibt seinen vorherigen Wert zurück. Wird der Eintrag nicht gefunden, wird ein Eintrag erstellt und 0 zurückgegeben. Dies wird typischerweise als zweite ACL in einem Ausdruck verwendet, um eine Verbindung zu markieren, wenn eine erste ACL zutraf:
Beispiel:
Siehe auch das Sample-Abruf-Schlüsselwort sc_clr_gpc0.
table_clr_gpc1([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Setzt den ersten Allzweckzähler ‘1’ zurück und gibt seinen vorherigen Wert zurück. Wird der Eintrag nicht gefunden, wird ein Eintrag erstellt und 0 zurückgegeben. Dies wird typischerweise als zweite ACL in einem Ausdruck verwendet, um eine Verbindung zu markieren, wenn eine erste ACL zutraf. Siehe auch das Sample-Abruf-Schlüsselwort sc_clr_gpc1.
table_conn_cnt([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die kumulierte Anzahl eingehender Verbindungen zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Siehe auch das Sample-Abruf-Schlüsselwort sc_conn_cnt.
table_conn_cur([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die aktuelle Anzahl gleichzeitig verfolgter Verbindungen zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Siehe auch das Sample-Abruf-Schlüsselwort sc_conn_cur.
table_conn_rate([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die durchschnittliche Rate eingehender Verbindungen zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Siehe auch das Sample-Abruf-Schlüsselwort sc_conn_rate.
table_expire([<table>[,<default_value>]])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, schlägt der Konverter fehl, außer wenn <default_value> gesetzt ist: Dann ist der Konverter erfolgreich und gibt <default_value> zurück. Wird der Schlüssel gefunden, gibt der Konverter die verbleibende Zeit bis zum Ablauf des Schlüssels zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Siehe auch das Sample-Abruf-Schlüsselwort table_idle.
table_glitch_cnt([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die kumulierte Anzahl von Störungen der Frontend-Verbindung zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Siehe auch das Sample-Abruf-Schlüsselwort sc_glitch_cnt und fc_glitches für den auf der aktuellen Frontend-Verbindung gemessenen Wert.
table_glitch_rate([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die durchschnittliche Störungsrate der Frontend-Verbindung zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Siehe auch das Sample-Abruf-Schlüsselwort sc_glitch_rate.
table_gpc(<idx>[,<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter den aktuellen Wert des Allzweckzählers am Index <idx> des Arrays zurück, das dem Eingabe-Sample in der angegebenen <table> zugeordnet ist. <idx> ist eine Ganzzahl zwischen 0 und 99. Ist an diesem Index kein GPC gespeichert, wird ebenfalls die Ganzzahl 0 zurückgegeben. Dies gilt nur für den Array-data_type ‘gpc’, nicht für die älteren data_types ‘gpc0’ oder ‘gpc1’. Siehe auch das Sample-Abruf-Schlüsselwort sc_get_gpc.
table_gpc0([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter den aktuellen Wert des ersten Allzweckzählers zurück, der dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Siehe auch das Sample-Abruf-Schlüsselwort sc_get_gpc0.
table_gpc0_rate([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die Häufigkeit zurück, mit der der dem Eingabe-Sample zugeordnete Zähler gpc0 über den in der angegebenen Tabelle konfigurierten Zeitraum erhöht wurde. Siehe auch das Sample-Abruf-Schlüsselwort sc_get_gpc0_rate.
table_gpc1([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter den aktuellen Wert des zweiten Allzweckzählers zurück, der dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Siehe auch das Sample-Abruf-Schlüsselwort sc_get_gpc1.
table_gpc1_rate([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die Häufigkeit zurück, mit der der dem Eingabe-Sample zugeordnete Zähler gpc1 über den in der angegebenen Tabelle konfigurierten Zeitraum erhöht wurde. Siehe auch das Sample-Abruf-Schlüsselwort sc_get_gpc1_rate.
table_gpc_rate(<idx>[,<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die Häufigkeit zurück, mit der der Allzweckzähler am Index <idx> des Arrays über den konfigurierten Zeitraum erhöht wurde. Das Array ist dem Eingabe-Sample in der angegebenen Stick Table <table> zugeordnet. <idx> ist eine Ganzzahl zwischen 0 und 99. Ist an diesem Index kein gpc_rate gespeichert, wird ebenfalls die Ganzzahl 0 zurückgegeben. Dies gilt nur für den Array-data_type ‘gpc_rate’, nicht für die älteren data_types ‘gpc0_rate’ oder ‘gpc1_rate’. Siehe auch das Sample-Abruf-Schlüsselwort sc_gpc_rate.
table_gpt(<idx>[,<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter den aktuellen Wert des Allzweck-Tags am Index <idx> des Arrays zurück, das dem Eingabe-Sample in der angegebenen <table> zugeordnet ist. <idx> ist eine Ganzzahl zwischen 0 und 99. Ist an diesem Index kein GPT gespeichert, wird ebenfalls die Ganzzahl 0 zurückgegeben. Dies gilt nur für den Array-data_type ‘gpt’, nicht für den älteren data-type ‘gpt0’. Siehe auch das Sample-Abruf-Schlüsselwort sc_get_gpt.
table_gpt0([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter den aktuellen Wert des ersten Allzweck-Tags zurück, das dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Siehe auch das Sample-Abruf-Schlüsselwort sc_get_gpt0.
table_http_err_cnt([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die kumulierte Anzahl von HTTP-Fehlern zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Siehe auch das Sample-Abruf-Schlüsselwort sc_http_err_cnt.
table_http_err_rate([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die durchschnittliche Rate von HTTP-Fehlern zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Diese wird als Anzahl von Fehlern über den in der Tabelle konfigurierten Zeitraum gemessen. Siehe auch das Sample-Abruf-Schlüsselwort sc_http_err_rate.
table_http_fail_cnt([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die kumulierte Anzahl von HTTP-Fehlschlägen zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Siehe auch das Sample-Abruf-Schlüsselwort sc_http_fail_cnt.
table_http_fail_rate([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die durchschnittliche Rate von HTTP-Fehlschlägen zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Diese wird als Anzahl von Fehlschlägen über den in der Tabelle konfigurierten Zeitraum gemessen. Siehe auch das Sample-Abruf-Schlüsselwort sc_http_fail_rate.
table_http_req_cnt([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die kumulierte Anzahl von HTTP-Anfragen zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Siehe auch das Sample-Abruf-Schlüsselwort sc_http_req_cnt.
table_http_req_rate([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die durchschnittliche Rate von HTTP-Anfragen zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Diese wird als Anzahl von Anfragen über den in der Tabelle konfigurierten Zeitraum gemessen. Siehe auch das Sample-Abruf-Schlüsselwort sc_http_req_rate.
table_idle([<table>[,<default_value>]])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, schlägt der Konverter fehl, außer wenn <default_value> gesetzt ist: Dann ist der Konverter erfolgreich und gibt <default_value> zurück. Wird der Schlüssel gefunden, gibt der Konverter die Zeit zurück, die der dem Eingabe-Sample in der angegebenen Tabelle zugeordnete Schlüsseleintrag seit seiner letzten Aktualisierung inaktiv geblieben ist. Siehe auch das Sample-Abruf-Schlüsselwort table_expire.
table_inc_gpc(<idx>[,<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Erhöht den Allzweckzähler am Index <idx> des Arrays und gibt seinen neuen Wert zurück. <idx> ist eine Ganzzahl zwischen 0 und 99. Wird der Eintrag nicht gefunden, wird ein Eintrag erstellt und 1 zurückgegeben. Dieser Konverter gilt nur für den Array-data_type ‘gpc’, nicht für die älteren data_types ‘gpc0’ oder ‘gpc1’. Siehe auch sc_inc_gpc.
table_inc_gpc0([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Erhöht den Allzweckzähler ‘0’ und gibt seinen neuen Wert zurück. Wird der Eintrag nicht gefunden, wird ein Eintrag erstellt und 1 zurückgegeben. Siehe auch sc0/sc2/sc2_inc_gpc0. Dies wird typischerweise als zweite ACL in einem Ausdruck verwendet, um eine Verbindung zu markieren, wenn eine erste ACL zutraf:
Beispiel:
table_inc_gpc1([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Erhöht den Allzweckzähler ‘1’ und gibt seinen neuen Wert zurück. Wird der Eintrag nicht gefunden, wird ein Eintrag erstellt und 1 zurückgegeben. Siehe auch sc0/sc2/sc2_inc_gpc1. Dies wird typischerweise als zweite ACL in einem Ausdruck verwendet, um eine Verbindung zu markieren, wenn eine erste ACL zutraf.
table_kbytes_in([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die kumulierte Datenmenge vom Client zum Server zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist, gemessen in Kilobytes. Die Prüfung erfolgt derzeit mit 32-Bit-Ganzzahlen, wodurch die Werte auf 4 Terabytes begrenzt sind. Siehe auch das Sample-Abruf-Schlüsselwort sc_kbytes_in.
table_kbytes_out([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die kumulierte Datenmenge vom Server zum Client zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist, gemessen in Kilobytes. Die Prüfung erfolgt derzeit mit 32-Bit-Ganzzahlen, wodurch die Werte auf 4 Terabytes begrenzt sind. Siehe auch das Sample-Abruf-Schlüsselwort sc_kbytes_out.
table_server_id([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die Server-ID zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Eine Server-ID wird einem Sample durch eine “stick”-Regel zugeordnet, wenn eine Verbindung zu einem Server erfolgreich hergestellt wird. Eine Server-ID von null bedeutet, dass diesem Schlüssel kein Server zugeordnet ist.
table_sess_cnt([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die kumulierte Anzahl eingehender Sitzungen zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Eine Sitzung bezeichnet hier eine eingehende Verbindung, die von den Regelsätzen “tcp-request connection” akzeptiert wurde. Siehe auch das Sample-Abruf-Schlüsselwort sc_sess_cnt.
table_sess_rate([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die durchschnittliche Rate eingehender Sitzungen zurück, die dem Eingabe-Sample in der angegebenen Tabelle zugeordnet ist. Eine Sitzung bezeichnet hier eine eingehende Verbindung, die von den Regelsätzen “tcp-request connection” akzeptiert wurde. Siehe auch das Sample-Abruf-Schlüsselwort sc_sess_rate.
table_trackers([<table>])
Verwendet das Eingabe-Sample für eine Suche in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Wird der Schlüssel in der Tabelle nicht gefunden, wird die Ganzzahl null zurückgegeben. Andernfalls gibt der Konverter die aktuelle Anzahl gleichzeitiger Verbindungen zurück, die in der angegebenen Tabelle denselben Schlüssel wie das Eingabe-Sample verfolgen. Anders als table_conn_cur beruht dies nicht auf gespeicherten Informationen, sondern auf dem Referenzzähler der Tabelle (dem Wert “use”, den “show table” auf der CLI zurückgibt). Dies kann für das Tracking auf layer7 manchmal besser geeignet sein. So lässt sich einem Server beispielsweise mitteilen, wie viele gleichzeitige Verbindungen von einer bestimmten Adresse bestehen. Siehe auch das Sample-Abruf-Schlüsselwort sc_trackers.
tcp.dst
Wird mit einem Eingabe-Sample verwendet, das einen binären TCP-Header darstellt, wie ihn “ip.data” zurückgibt. Gibt eine Ganzzahl zurück, die den Zielport im TCP-Header darstellt. Siehe auch “fc_saved_syn”, “tcp-ss” und “ip.data”.
tcp.flags
Wird mit einem Eingabe-Sample verwendet, das einen binären TCP-Header darstellt, wie ihn “ip.data” zurückgibt. Gibt eine Ganzzahl zurück, die die TCP-Flags dieses TCP-Headers darstellt. Alle 8 Flags von FIN bis CWR werden abgerufen. Jedes Flag kann mit dem Konverter “and()” geprüft werden. Die Werte der einzelnen Flags sind in RFC9293 beschrieben. Siehe auch “fc_saved_syn”, “tcp-ss” und “ip.data”.
tcp.options.mss
Wird mit einem Eingabe-Sample verwendet, das einen binären TCP-Header darstellt, wie ihn “ip.data” zurückgibt. Sucht nach einer TCP-Option vom Typ “MSS”. Wird sie gefunden, wird eine Ganzzahl mit dem darin angekündigten Wert zurückgegeben, andernfalls null. MSS steht für Maximum Segment Size und gibt die maximale Segmentgröße in Bytes an, die die Gegenstelle empfangen kann. Siehe auch “fc_saved_syn”, “tcp-ss” und “ip.data”.
tcp.options.sack
Wird mit einem Eingabe-Sample verwendet, das einen binären TCP-Header darstellt, wie ihn “ip.data” zurückgibt. Sucht nach einer TCP-Option vom Typ “Sack-Permitted”. Wird sie gefunden, wird 1 zurückgegeben, andernfalls null. Siehe auch “fc_saved_syn”, “tcp-ss” und “ip.data”.
tcp.options.tsopt
Wird mit einem Eingabe-Sample verwendet, das einen binären TCP-Header darstellt, wie ihn “ip.data” zurückgibt. Sucht nach einer TCP-Option vom Typ “Timestamp”. Wird sie gefunden, wird 1 zurückgegeben, andernfalls null. Siehe auch “fc_saved_syn”, “tcp-ss” und “ip.data”.
tcp.options.tsval
Wird mit einem Eingabe-Sample verwendet, das einen binären TCP-Header darstellt, wie ihn “ip.data” zurückgibt. Sucht nach einer TCP-Option vom Typ “Timestamp”. Wird sie gefunden, wird der von der Gegenstelle gesendete Zeitstempelwert zurückgegeben; andernfalls wird nichts zurückgegeben. Zeitstempel sind vorzeichenlose 32-Bit-Werte ohne festgelegte Einheit, die allein die Gegenstelle bestimmt. Zeitstempel verschiedener Verbindungen sollten voneinander unabhängig sein. Siehe auch “fc_saved_syn”, “tcp-ss” und “ip.data”.
tcp.options.wscale
Wird mit einem Eingabe-Sample verwendet, das einen binären TCP-Header darstellt, wie ihn “ip.data” zurückgibt. Sucht nach einer TCP-Option vom Typ “Window Scale”. Wird sie gefunden, wird der von der Gegenstelle gesendete Fensterskalierungswert zurückgegeben, andernfalls null. Werte über 14 sind nicht zu erwarten, obwohl keine technische Einschränkung ihr Senden verhindert. Um festzustellen, ob die Fensterskalierungsoption verwendet wurde, verwenden Sie “tcp.options.wsopt”. Siehe auch “tcp-ss”, “fc_saved_syn”, “ip.data” und “tcp.options.wsopt”.
tcp.options.wsopt
Wird mit einem Eingabe-Sample verwendet, das einen binären TCP-Header darstellt, wie ihn “ip.data” zurückgibt. Sucht nach einer TCP-Option vom Typ “Window Scale”. Wird sie gefunden, wird 1 zurückgegeben, andernfalls 0. Siehe auch “fc_saved_syn”, “tcp-ss”, “ip.data” und “tcp.options.wscale”.
tcp.options_list
Wird mit einem Eingabe-Sample verwendet, das einen binären TCP-Header darstellt, wie ihn “ip.data” zurückgibt. Erzeugt eine binäre Folge aller TCP-Optionstypen in derselben Reihenfolge, in der sie im TCP-Header erscheinen. Dies kann 0 bis 60 Bytes ergeben (im ungünstigsten Fall). Die Option End-of-options wird nicht ausgegeben. Siehe auch “fc_saved_syn”, “tcp-ss” und “ip.data”.
tcp.seq
Wird mit einem Eingabe-Sample verwendet, das einen binären TCP-Header darstellt, wie ihn “ip.data” zurückgibt. Gibt eine Ganzzahl zurück, die die von der Gegenstelle im TCP-Header verwendete Sequenznummer darstellt. Sequenznummern sind vorzeichenlose 32-Bit-Werte. Siehe auch “fc_saved_syn”, “tcp-ss” und “ip.data”.
tcp.src
Wird mit einem Eingabe-Sample verwendet, das einen binären TCP-Header darstellt, wie ihn “ip.data” zurückgibt. Gibt eine Ganzzahl zurück, die den Quellport im TCP-Header darstellt. Siehe auch “fc_saved_syn”, “tcp-ss” und “ip.data”.
tcp.win
Wird mit einem Eingabe-Sample verwendet, das einen binären TCP-Header darstellt, wie ihn “ip.data” zurückgibt. Gibt eine Ganzzahl zurück, die die von der Gegenstelle im TCP-Header angekündigte Fenstergröße darstellt. Der Wert wird unverändert als vorzeichenloser 16-Bit-Wert zurückgegeben, ohne den Fensterskalierungsfaktor anzuwenden. Siehe auch “fc_saved_syn”, “tcp-ss” und “ip.data”.
ub64dec
Dieser Konverter ist die base64url-Variante des Konverters b64dec. Die base64url-Kodierung ist die für URLs und Dateinamen geeignete Variante (“URL and Filename Safe Alphabet”) der base64-Kodierung. Diese Kodierung wird auch im JWT-Standard (JSON Web Token) verwendet.
Beispiel:
ub64enc
Dieser Konverter ist die base64url-Variante des Konverters base64.
ungrpc(<field_number>[,<field_type>])
Extrahiert aus einem binären Eingabe-Sample, das eine gRPC-Nachricht darstellt, das Protocol-Buffers-Nachrichtenfeld mit der Feldnummer <field_number> (Punktnotation). Ist <field_type> nicht angegeben, erfolgt die Extraktion als Rohdaten; andernfalls als ganzzahliges Sample. Zulässig sind folgende Typen: “int32”, “int64”, “uint32”, “uint64”, “sint32”, “sint64”, “bool”, “enum” für den Wire-Typ “varint” 0; “fixed64”, “sfixed64”, “double” für den 64bit-Wire-Typ 1; “fixed32”, “sfixed32”, “float” für den Wire-Typ 5. “string” gilt als längenbegrenzter Typ und benötigt daher zur Extraktion kein Argument <field_type>. Weitere Informationen zu den Feldtypen von Protocol-Buffers-Nachrichten stehen hier:
https://developers.google.com/protocol-buffers/docs/encoding
Beispiel:
Angenommen, der Anfragekörper besteht aus dem Wert eines Objekts “Rectangle” (zwei Protocol-Buffers-Nachrichten vom Typ PPoint). Die vier Protocol-Buffers-Felder könnten dann mit diesen “ungrpc”-Direktiven extrahiert werden:
Das dazwischenliegende Feld 48.59 könnte auch wie folgt als binäres Sample extrahiert werden:
Da eine gRPC-Nachricht stets aus einem gRPC-Header und darauf folgenden Protocol-Buffers-Nachrichten besteht, könnte im vorherigen Beispiel “latitude” des ersten PPoint “lo” mit diesen gleichwertigen Direktiven extrahiert werden:
Der erste Konverter muss “ungrpc” sein, die übrigen müssen “protobuf” sein. Nur der letzte darf optional ein zweites Argument enthalten, um das vorherige binäre Sample zu interpretieren.
unset-var(<var>)
Setzt eine Variable zurück, wenn der Eingabeinhalt definiert ist. Der Name der Variablen beginnt mit einer Angabe ihres Gültigkeitsbereichs. Einzelheiten zu Variablen stehen in Abschnitt 2.8 .
upper
Wandelt ein Zeichenketten-Sample in Großbuchstaben um. Kann nur hinter einer Sample-Abruffunktion für Zeichenketten oder hinter einem Transformationsschlüsselwort stehen, das den Typ string zurückgibt. Das Ergebnis hat den Typ string.
url_dec([<in_form>])
Nimmt eine URL-kodierte Zeichenkette als Eingabe und gibt deren dekodierte Fassung aus. Eingabe und Ausgabe haben den Typ string. Ist das Argument <in_form> auf eine Ganzzahl ungleich null gesetzt, wird die Eingabezeichenkette als Teil eines Formulars oder einer Abfragezeichenkette betrachtet, und das Zeichen ‘+’ wird in ein Leerzeichen (’ ‘) umgewandelt. Andernfalls geschieht dies nur nach einem Fragezeichen (’?’), das eine Abfragezeichenkette anzeigt.
url_enc([<enc_type>])
Nimmt eine Zeichenkette als Eingabe und gibt deren kodierte Fassung aus. Eingabe und Ausgabe haben den Typ string. Standardmäßig ist die Kodierung für den Typ query vorgesehen. Derzeit wird kein anderer Typ unterstützt; das optionale Argument ist für künftige Änderungen vorgesehen.
us_ltime(<format>[,<offset>])
Funktioniert wie “ltime”, erwartet die Eingabe aber in Mikrosekunden. Unterstützt außerdem das von date(1) inspirierte Konvertierungskennzeichen %N. Wandelt eine Ganzzahl, die ein Datum seit der Epoche darstellen soll, in eine Zeichenkette um, die dieses Datum in Ortszeit wiedergibt. Das Format wird durch die Zeichenkette <format> mit strftime(3) festgelegt. Damit lassen sich beliebige Datumsformate in Protokollen verwenden. Ein optionaler <offset> in Mikrosekunden kann auf das Eingabedatum angewendet werden (positiv oder negativ). Die von Ihrem Betriebssystem unterstützten Formate stehen in der Handbuchseite zu strftime().
Mit dem Konvertierungskennzeichen %N lässt sich der Nanosekundenanteil des Datums ausgeben. Da die Eingabe in Mikrosekunden erfolgt, ist die Genauigkeit begrenzt (000000000..999999000). %N kann zwischen % und N eine Breitenangabe enthalten. Dies ist nützlich zur Darstellung von Millisekunden (%3N) oder Mikrosekunden (%6N). Die voreingestellte und maximale Breite ist 9 (%N = %9N).
Siehe auch den Konverter “utime” für UTC sowie die Konverter “ltime” und “ms_ltime”.
Beispiel:
us_utime(<format>[,<offset>])
Funktioniert wie “utime”, erwartet die Eingabe aber in Mikrosekunden. Unterstützt außerdem das von date(1) inspirierte Konvertierungskennzeichen %N. Wandelt eine Ganzzahl, die ein Datum seit der Epoche darstellen soll, in eine Zeichenkette um, die dieses Datum in UTC-Zeit wiedergibt. Das Format wird durch die Zeichenkette <format> mit strftime(3) festgelegt. Damit lassen sich beliebige Datumsformate in Protokollen verwenden. Ein optionaler <offset> in Mikrosekunden kann auf das Eingabedatum angewendet werden (positiv oder negativ). Die von Ihrem Betriebssystem unterstützten Formate stehen in der Handbuchseite zu strftime().
Mit dem Konvertierungskennzeichen %N lässt sich der Nanosekundenanteil des Datums ausgeben. Da die Eingabe in Mikrosekunden erfolgt, ist die Genauigkeit begrenzt (000000000..999999000). %N kann zwischen % und N eine Breitenangabe enthalten. Dies ist nützlich zur Darstellung von Millisekunden (%3N) oder Mikrosekunden (%6N). Die voreingestellte und maximale Breite ist 9 (%N = %9N).
Siehe auch den Konverter “ltime” für Ortszeit sowie die Konverter “utime” und “ms_utime”.
Beispiel:
utime(<format>[,<offset>])
Wandelt eine Ganzzahl, die ein Datum seit der Epoche darstellen soll, in eine Zeichenkette um, die dieses Datum in UTC-Zeit wiedergibt. Das Format wird durch die Zeichenkette <format> mit strftime(3) festgelegt. Damit lassen sich beliebige Datumsformate in Protokollen verwenden. Ein optionaler <offset> in Sekunden kann auf das Eingabedatum angewendet werden (positiv oder negativ). Die von Ihrem Betriebssystem unterstützten Formate stehen in der Handbuchseite zu strftime(). Siehe auch den Konverter “ltime” sowie “ms_utime” und “us_utime”.
Beispiel:
when(<condition>[,<args>...])
Wertet die Bedingung aus und gibt bei einem wahren Ergebnis das Eingabe-Sample unverändert aus; andernfalls wird nichts zurückgegeben. Dies ist speziell für selten benötigte Daten gedacht, die nur unter bestimmten Bedingungen ausgegeben werden sollen, beispielsweise Debug-Informationen beim Auftreten eines Fehlers.
Die Bedingung besteht aus einem Schlüsselwort aus der folgenden Liste. Optional kann ihr ein Ausrufezeichen (’!’) zur Negation vorangestellt werden, und es können für diese Bedingung spezifische Argumente folgen:
- "error" gibt true zurück, wenn während der Verarbeitung der Anfrage oder des Streams ein Fehler aufgetreten ist. Es gelten dieselben Regeln wie für "dontlog-normal" (beispielsweise zählt ein erfolgreiches Redispatch als Fehler).
- "forwarded" gibt true zurück, wenn die Anfrage an einen Backend-Server weitergeleitet wurde.
- "normal" gibt true zurück, wenn kein Fehler aufgetreten ist (gleichbedeutend mit "!error").
- "processed" gibt true zurück, wenn die Anfrage entweder an einen Backend-Server weitergeleitet oder von einem Applet verarbeitet wurde.
- "stopping" gibt true zurück, wenn der Prozess zum Zeitpunkt der Regelauswertung gerade beendet wird.
- "toapplet" gibt true zurück, wenn die Anfrage von einem Applet verarbeitet wurde.
- "acl" gibt true zurück, wenn die im nächsten Argument angegebene ACL zu true ausgewertet wird. Die ACL wird direkt vom Konverter ausgewertet; ihre Bezugsgrößen müssen daher in diesem Kontext gültig sein. Ein Anwendungsfall ist die Prüfung, ob die gesamte Übertragungszeit zu lang ist, bevor entschieden wird, ob Details ungewöhnlich langer Übertragungen protokolliert werden sollen.
Der Inhalt wird in jedem Fall ausgewertet; dieses Vorgehen verhindert daher nicht die Erzeugung dieser Informationen. Es soll lediglich deren Ausgabe vermeiden.
Ein Beispiel wäre, Debug-Informationen zum Backend-Stream nur dann zu protokollieren, wenn während der Verarbeitung ein Fehler aufgetreten ist, oder beim Beenden zusätzliche Informationen zu protokollieren.
Beispiel:
Beispiel
Beispiel
Da die Auswertung des Ausdrucks beendet wird, wenn die Bedingung nicht wahr ist, lässt sich damit auch verhindern, dass ein nachfolgender Konverter aufgerufen wird. Beispielsweise könnte der Konverter debug() nur bei einem Fehler aufgerufen werden, um ein Element nur dann zu protokollieren, wenn dies unbedingt nötig ist.
Beispiel:
Siehe auch: Konverter debug
word(<index>,<delimiters>[,<count>])
Extrahiert unter Berücksichtigung der angegebenen Trennzeichen das n-te Wort aus einer Eingabezeichenkette, vom Anfang (positiver Index) oder vom Ende (negativer Index) gezählt. Indizes beginnen bei 1 oder -1; die Trennzeichen werden als Zeichenliste in einer Zeichenkette angegeben. Leere Wörter werden übersprungen. Trennzeichen am Anfang oder Ende der Eingabezeichenkette werden daher ignoriert, und aufeinanderfolgende Trennzeichen innerhalb der Eingabe gelten als ein einziges Trennzeichen. Optional können Sie mit <count> die Anzahl zu extrahierender Wörter angeben (Standard: 1). Der Wert 0 bedeutet, dass alle verbleibenden Wörter extrahiert werden.
Beispiel:
wt6([<avalanche>])
Bildet mit der WT6-Hashfunktion aus einem binären Eingabe-Sample einen vorzeichenlosen 32-Bit-Wert. Ist das optionale Argument <avalanche> gleich 1, kann zusätzlich eine vollständige Avalanche-Hashfunktion auf die Ausgabe angewendet werden. Dieser Konverter verwendet dieselben Funktionen wie die verschiedenen Hash-basierten Algorithmen zur Lastverteilung und liefert daher exakt dieselben Ergebnisse. Er ist hauptsächlich zur Fehlersuche gedacht, kann aber als Eintrag in einer Stick Table zum Erfassen grober Statistiken verwendet werden. Er darf nicht für Sicherheitszwecke verwendet werden, da ein 32-Bit-Hash leicht zu brechen ist. Siehe auch “crc32”, “djb2”, “sdbm”, “crc32c” und die Direktive “hash-type”.
x509_v_err_str
Wandelt einen numerischen Wert in den entsprechenden Namen einer X509_V_ERR-Konstante um. Dies ist in ACLs nützlich, damit eine Konfiguration mit mehreren OpenSSL-Versionen funktioniert, da sich einige Codes beim Wechsel der Version ändern können.
Wird der entsprechende Konstantenname nicht gefunden, wird der numerische Wert als Zeichenkette ausgegeben.
Die Liste der von OpenSSL bereitgestellten Konstanten steht unter https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html#ERROR-CODES . Achten Sie darauf, die Seite für die richtige OpenSSL-Version zu lesen.
Beispiel:
xor(<value>)
Führt ein bitweises “XOR” (exklusives OR) zwischen <value> und dem vorzeichenbehafteten ganzzahligen Eingabewert aus und gibt das Ergebnis als vorzeichenbehaftete Ganzzahl zurück. <value> kann ein numerischer Wert oder ein Variablenname sein. Einzelheiten zu Variablen stehen in Abschnitt 2.8
.
xxh3([<seed>])
Bildet aus einem binären Eingabe-Sample mit der XXH3-64-Bit-Variante der XXhash-Hashfunktion einen vorzeichenbehafteten 64-Bit-Wert. Dieser Hash unterstützt einen Startwert, der standardmäßig null ist; über das Argument <seed> kann ein anderer Wert übergeben werden. Dieser Hash gilt als sehr gut und sehr schnell. Daher kann er URLs und/oder URL-Parameter für die Verwendung als Schlüssel in Stick Tables hashen, um Statistiken mit niedriger Kollisionsrate zu erfassen. Dabei ist jedoch Vorsicht geboten, da der Algorithmus nicht als kryptografisch sicher gilt.
xxh32([<seed>])
Bildet aus einem binären Eingabe-Sample mit der 32-Bit-Variante der XXHash-Hashfunktion einen vorzeichenlosen 32-Bit-Wert. Dieser Hash unterstützt einen Startwert, der standardmäßig null ist; über das Argument <seed> kann ein anderer Wert übergeben werden. Dieser Hash gilt als sehr gut und sehr schnell. Daher kann er URLs und/oder URL-Parameter für die Verwendung als Schlüssel in Stick Tables hashen, um Statistiken mit niedriger Kollisionsrate zu erfassen. Dabei ist jedoch Vorsicht geboten, da der Algorithmus nicht als kryptografisch sicher gilt.
xxh64([<seed>])
Bildet aus einem binären Eingabe-Sample mit der 64-Bit-Variante der XXHash-Hashfunktion einen vorzeichenbehafteten 64-Bit-Wert. Dieser Hash unterstützt einen Startwert, der standardmäßig null ist; über das Argument <seed> kann ein anderer Wert übergeben werden. Dieser Hash gilt als sehr gut und sehr schnell. Daher kann er URLs und/oder URL-Parameter für die Verwendung als Schlüssel in Stick Tables hashen, um Statistiken mit niedriger Kollisionsrate zu erfassen. Dabei ist jedoch Vorsicht geboten, da der Algorithmus nicht als kryptografisch sicher gilt.
7.3.2. Sample-Abruf aus internen Zuständen
Eine erste Gruppe von Sample-Abrufmethoden bezieht sich auf interne Informationen, die keinerlei Bezug zu Client-Informationen haben. Diese Methoden werden gelegentlich mit Direktiven “monitor fail” verwendet, um externen Überwachungsinstanzen einen internen Zustand zu melden. Die in diesem Abschnitt beschriebenen Sample-Abrufmethoden können überall verwendet werden.
Übersicht über die Sample-Abrufmethoden in diesem Abschnitt und ihre jeweiligen Typen:
Ausführliche Liste:
acl([!]<name>[,...]): boolean
Gibt true zurück, wenn die Auswertung aller benannten ACLs true ergibt, andernfalls false. Es können bis zu 12 ACLs angegeben werden, jeweils durch Kommas getrennt. Jeder benannten ACL kann ein “!” vorangestellt werden, um das Ergebnis zu negieren. Führt eine Auswertung zu einem Fehler, gibt auch das Sample einen Fehler zurück. HAProxy führt keine Validierungsprüfungen der referenzierten ACLs durch. Beispielsweise wird nicht geprüft, ob eine ACL, die ein HTTP-Anfrage-Sample verwendet, im Antwortkontext eingesetzt wird. Dieses Verhalten kann sich künftig ändern.
act_conn: integer Gibt die Gesamtzahl der aktiven gleichzeitigen Verbindungen des Prozesses zurück.
always_false: boolean Gibt stets den booleschen Wert “false” zurück. Kann beim Anpassen von Konfigurationen in ACLs vorübergehend als Ersatz für eine andere ACL verwendet werden.
always_true: boolean Gibt stets den booleschen Wert “true” zurück. Kann beim Anpassen von Konfigurationen in ACLs vorübergehend als Ersatz für eine andere ACL verwendet werden.
avg_queue([<backend>]): integer
Gibt die Gesamtzahl der wartenden Verbindungen des angegebenen Backends geteilt durch die Anzahl aktiver Server zurück. Wird kein Backend angegeben, wird das aktuelle verwendet. Dies ist “queue” sehr ähnlich, berücksichtigt aber die Größe der Servergruppe, um die voraussichtliche Wartezeit bis zur Verarbeitung einer neuen Verbindung genauer zu messen. Die Hauptanwendung besteht darin, mit einer ACL neuen Nutzern eine Entschuldigungsseite zurückzugeben, wenn feststeht, dass sie nur eingeschränkten Dienst erhalten würden. Der Wert kann auch in einem Header an die Backend-Server weitergegeben werden, damit diese entscheiden können, in einem eingeschränkten Modus zu arbeiten oder einige Funktionen zu deaktivieren, um die Verarbeitung etwas zu beschleunigen. Ist kein aktiver Server mehr vorhanden, wird die doppelte Anzahl wartender Verbindungen als Messwert verwendet. Dies ist eine angemessene Schätzung, da ohnehin erwartet wird, dass bald ein Server zurückkehrt; neuer Verkehr soll dennoch bevorzugt an ein anderes Backend geleitet werden, wenn dieses in besserem Zustand ist. Siehe auch die Sample-Abrufe “queue”, “be_conn” und “be_sess_rate”.
be_conn([<backend>]): integer
Bezieht sich auf die Anzahl der derzeit hergestellten Verbindungen des Backends, gegebenenfalls einschließlich der gerade ausgewerteten Verbindung. Wird kein Backend-Name angegeben, wird das aktuelle Backend verwendet. Es kann aber auch ein anderes Backend geprüft werden. Damit lässt sich eine bestimmte Servergruppe verwenden, wenn die normalerweise vorgesehene voll ist. Siehe auch die Kriterien “fe_conn”, “queue”, “be_conn_free” und “be_sess_rate”.
be_conn_free([<backend>]): integer
Gibt eine Ganzzahl zurück, die der Anzahl verfügbarer Verbindungen über die verfügbaren Server im Backend entspricht. Warteschlangenplätze sind nicht enthalten. Backup-Server werden ebenfalls nicht berücksichtigt, sofern nicht alle anderen Server ausgefallen sind. Wird kein Backend-Name angegeben, wird das aktuelle Backend verwendet. Es kann aber auch ein anderes Backend geprüft werden. Damit lässt sich eine bestimmte Servergruppe verwenden, wenn die normalerweise vorgesehene voll ist. Siehe auch die Kriterien “be_conn”, “connslots” und “srv_conn_free”.
Weitere Einschränkungen und Hinweise: Ist maxconn oder maxqueue eines Servers gleich 0 (also unbegrenzt), ist dieser Abruf nicht sinnvoll; in diesem Fall wird -1 zurückgegeben.
be_sess_rate([<backend>]): integer
Gibt eine Ganzzahl zurück, die der Rate neu angelegter Sitzungen im Backend entspricht, gemessen als Anzahl neuer Sitzungen pro Sekunde. Dies wird mit ACLs verwendet, um auf ein alternatives Backend umzuschalten, wenn ein ressourcenintensives oder empfindliches Backend eine zu hohe Sitzungsrate erreicht, oder um den Missbrauch eines Diensts zu begrenzen (beispielsweise das massenhafte Auslesen eines Online-Wörterbuchs zu verhindern). Es kann auch nützlich sein, diesen Wert mit einer log-format-Direktive in Protokolle aufzunehmen.
Beispiel:
bin(<hex>): bin
Gibt eine binäre Zeichenfolge zurück. Die Eingabe ist die hexadezimale Darstellung der Zeichenkette.
bool(<bool>): bool
Gibt einen booleschen Wert zurück. <bool> kann ’true’, ‘false’, ‘1’ oder ‘0’ sein. ‘false’ und ‘0’ sind gleichbedeutend. ’true’ und ‘1’ sind gleichbedeutend.
connslots([<backend>]): integer
Gibt eine Ganzzahl zurück, die der Anzahl noch verfügbarer Verbindungsplätze im Backend entspricht. Dazu werden die maximale Verbindungszahl aller Server und die maximale Warteschlangengröße aufsummiert. Dies wird vermutlich nur mit ACLs verwendet.
Die Grundidee besteht darin, die Anzahl noch verfügbarer Verbindungsplätze (Verbindungen und Warteschlange) zu messen, sodass darüber hinausgehender Verkehr an ein anderes Backend umgeleitet werden kann (vorgesehene Verwendung; siehe das Schlüsselwort “use_backend”).
‘connslots’ = Anzahl verfügbarer Server-Verbindungsplätze + Anzahl verfügbarer Server-Warteschlangenplätze.
Zwar kann “fe_conn” verwendet werden, doch ist “connslots” besonders nützlich, wenn der Verkehr an eine einzige IP-Adresse geht und auf mehrere Backends aufgeteilt wird (etwa mit ACLs zur namensbasierten Lastverteilung) und Sie die verschiedenen Backends und ihre verfügbaren “connslots” unterscheiden möchten. Während “nbsrv” nur Server erfasst, die tatsächlich ausgefallen sind, arbeitet dieser Abruf feiner und betrachtet auch die Anzahl verfügbarer Verbindungsplätze. Siehe auch “queue” und “avg_queue”.
Weitere Einschränkungen und Hinweise: Der Code berücksichtigt derzeit keine dynamischen Verbindungen. Ist außerdem maxconn oder maxqueue eines Servers gleich 0, ist dieser Abruf nicht sinnvoll; in diesem Fall wird -1 zurückgegeben.
cpu_calls: integer Gibt die Anzahl der Aufrufe der Aufgabe zurück, die den Stream oder die aktuelle Anfrage verarbeitet, seit diese Aufgabe angelegt wurde. Bei HTTP-Keep-Alive wird dieser Zähler für jede neue Anfrage auf derselben Verbindung zurückgesetzt. Der Wert sollte normalerweise niedrig und stabil sein (bei einer typischen einfachen Anfrage etwa 2 Aufrufe), kann aber bei zusätzlicher Verarbeitung wie Komprimierung, Caching oder Analyse hoch werden. Er dient ausschließlich der Leistungsüberwachung.
cpu_ns_avg: integer Gibt die durchschnittliche Anzahl von Nanosekunden zurück, die in jedem Aufruf der Aufgabe verbracht werden, welche den Stream oder die aktuelle Anfrage verarbeitet. Bei HTTP-Keep-Alive wird dieser Wert für jede neue Anfrage auf derselben Verbindung zurückgesetzt. Er zeigt die gesamten Verarbeitungskosten der Anfrage oder Verbindung pro Aufruf. Es gibt keinen grundsätzlich guten oder schlechten Wert; die in einem Aufruf verbrachte Zeit verursacht jedoch automatisch Verzögerungen anderer Verarbeitungsvorgänge (siehe lat_ns_avg weiter unten) und kann die beobachtete Antwortzeit anderer Verbindungen beeinflussen. Bestimmte Operationen wie Komprimierung, komplexer Regex-Abgleich oder aufwendige Lua-Operationen können diesen Wert direkt beeinflussen. Seine Aufnahme in Protokolle erleichtert es, problematische Verarbeitungsschritte zu finden, die zur Wiederherstellung einer angemessenen Leistung korrigiert werden müssen. Hinweis: Dieser Wert entspricht genau cpu_ns_tot geteilt durch cpu_calls.
cpu_ns_tot: integer Gibt die Gesamtzahl der Nanosekunden zurück, die in den Aufrufen der Aufgabe verbracht werden, welche den Stream oder die aktuelle Anfrage verarbeitet. Bei HTTP-Keep-Alive wird dieser Wert für jede neue Anfrage auf derselben Verbindung zurückgesetzt. Er zeigt die gesamten Verarbeitungskosten der Anfrage oder Verbindung pro Aufruf. Es gibt keinen grundsätzlich guten oder schlechten Wert; die in einem Aufruf verbrachte Zeit verursacht jedoch automatisch Verzögerungen anderer Verarbeitungsvorgänge (siehe lat_ns_avg weiter unten), erzeugt CPU-Last auf dem Rechner und kann die beobachtete Antwortzeit anderer Verbindungen beeinflussen. Bestimmte Operationen wie Komprimierung, komplexer Regex-Abgleich oder aufwendige Lua-Operationen können diesen Wert direkt beeinflussen. Seine Aufnahme in Protokolle erleichtert es, problematische Verarbeitungsschritte zu finden, die zur Wiederherstellung einer angemessenen Leistung korrigiert werden müssen. Der Wert kann durch eine hohe Anzahl cpu_calls künstlich hoch sein, beispielsweise bei der Verarbeitung vieler HTTP-Chunks. Daher wird häufig bevorzugt, stattdessen cpu_ns_avg zu protokollieren.
cpu_usage_grp: integer Gibt die während des letzten Abfragezyklus gemessene CPU-Auslastung zwischen 0 und 100 zurück, gemittelt über alle Threads der aktuellen Thread-Gruppe. Dies kann zur Fehlersuche und zur Protokollierung verwendet werden. Die Messung schwankt sehr stark, bleibt bei dauerhafter Last aber genau, da jeder Thread sie über einige Dutzend bis Hunderte von Anfragen ermittelt.
cpu_usage_proc: integer Gibt die während des letzten Abfragezyklus gemessene CPU-Auslastung zwischen 0 und 100 zurück, gemittelt über alle laufenden Threads. Dies kann zur Fehlersuche und zur Protokollierung verwendet werden. Die Messung schwankt sehr stark, bleibt bei dauerhafter Last aber genau, da jeder Thread sie über einige Dutzend bis Hunderte von Anfragen ermittelt. Der Wert entspricht 100 minus dem auf der Statistikseite und in “show info” gemeldeten Leerlaufanteil.
cpu_usage_thr: integer Gibt die während des letzten Abfragezyklus gemessene CPU-Auslastung zwischen 0 und 100 für den aufrufenden Thread zurück. Dies kann zur Fehlersuche und zur Protokollierung verwendet werden. Die Messung schwankt sehr stark, bleibt bei dauerhafter Last aber genau, da sie über einige Dutzend bis Hunderte von Anfragen ermittelt wird. Derselbe Wert wird verwendet, um bei zu vielen Störungen das Beenden von Verbindungen zu aktivieren oder die Komprimierung zu deaktivieren. Siehe auch “tune.glitches.kill.cpu-usage” und “maxcompcpuusage”.
date([<offset>[,<unit>]]): integer
Gibt das aktuelle Datum als Epochenzeit zurück (Anzahl der Sekunden seit dem 01/01/1970).
Ist ein Offset angegeben, wird er vor der Rückgabe zum aktuellen Datum addiert. Dies ist besonders nützlich zur Berechnung relativer Daten, da sowohl positive als auch negative Offsets erlaubt sind. Nützlich ist die Kombination mit dem Konverter http_date.
<unit> ist optional und kann auf “s” für Sekunden (Standardverhalten), “ms” für Millisekunden oder “us” für Mikrosekunden gesetzt werden. Ist die Einheit angegeben, ist der Rückgabewert eine Ganzzahl, die Sekunden, Millisekunden oder Mikrosekunden seit der Epoche zuzüglich Offset angibt. Dies ist nützlich, wenn eine Zeitauflösung unter einer Sekunde benötigt wird.
Beispiel:
date_us: integer Gibt den Mikrosekundenanteil des Datums zurück; den Sekundenanteil liefert das Sample date. Dieses Sample ist mit dem Sample date konsistent, da es aus derselben timeval-Struktur stammt.
env(<name>): string
Gibt eine Zeichenkette mit dem Wert der Umgebungsvariablen <name> zurück. Zur Erinnerung: Umgebungsvariablen gelten pro Prozess und werden beim Prozessstart erfasst. Damit lassen sich Informationen an den nächsten Server weitergeben oder mit ACLs bestimmte Aktionen auslösen, wenn der Prozess auf eine bestimmte Weise gestartet wurde.
Beispiele:
fe_conn([<frontend>]): integer
Gibt die Anzahl der derzeit hergestellten Verbindungen des Frontends zurück, gegebenenfalls einschließlich der gerade ausgewerteten Verbindung. Wird kein Frontend-Name angegeben, wird das aktuelle Frontend verwendet. Es kann aber auch ein anderes Frontend geprüft werden. Damit lässt sich vor einer vollständigen Sperre eine Entschuldigungsseite zurückgeben oder ein bestimmtes Backend zum Ableiten neuer Anfragen verwenden, wenn die Servergruppe als voll gilt. Dies wird überwiegend mit ACLs verwendet, kann aber auch Statistiken in HTTP-Headern an Server weitergeben. Siehe auch die Abrufe “dst_conn”, “be_conn” und “fe_sess_rate”.
fe_req_rate([<frontend>]): integer
Gibt eine Ganzzahl zurück, die der Anzahl der pro Sekunde an ein Frontend gesendeten HTTP-Anfragen entspricht. Dieser Wert kann von “fe_sess_rate” abweichen, wenn Keep-Alive auf der Client-Seite aktiviert ist.
fe_sess_rate([<frontend>]): integer
Gibt eine Ganzzahl zurück, die der Rate neu angelegter Sitzungen im Frontend entspricht, gemessen als Anzahl neuer Sitzungen pro Sekunde. Dies wird mit ACLs verwendet, um die eingehende Sitzungsrate auf einen akzeptablen Bereich zu begrenzen und Missbrauch eines Diensts möglichst früh zu verhindern. Beispielsweise können Clients in Verbindung mit anderen ACLs auf Schicht 4 dazu gezwungen werden, etwas zu warten, bis die Rate wieder unter den Grenzwert sinkt. Es kann auch nützlich sein, diesen Wert mit einer log-format-Direktive in Protokolle aufzunehmen. Siehe auch die Direktive “rate-limit sessions” zur Verwendung in Frontends.
Beispiel:
hostname: string Gibt den Hostnamen des Systems zurück.
int(<integer>): signed integer
Gibt eine vorzeichenbehaftete Ganzzahl zurück.
ipv4(<ipv4>): ipv4
Gibt eine IPv4-Adresse zurück.
ipv6(<ipv6>): ipv6
Gibt eine IPv6-Adresse zurück.
last_entity: string Gibt die Identität der letzten Entität zurück, die während der Stream-Analyse ausgewertet wurde. Dies kann die letzte zutreffende abschließende Regel oder der Filter sein, der die Verarbeitung unterbrochen hat.
Eine abschließende Regel beendet die Auswertung des Regelsatzes, beispielsweise “accept”, “deny” oder “redirect”. Dies funktioniert für TCP-Anfrage- und Antwortregeln in den Regelsätzen “content” sowie für HTTP-Regeln in “http-request”, “http-response” und “http-after-response”. Die älteren Regelsätze “redirect” werden nicht unterstützt, da diese Informationen dort nicht gespeichert werden. Auch “tcp-request connection” und “tcp-request session” werden nicht unterstützt, weil die Informationen auf Stream-Ebene gespeichert werden und während dieser Regeln noch keine Streams existieren. In diesem Fall entspricht der Rückgabewert “last_rule_file:last_rule_line”. Siehe auch “last_rule_file” und “last_rule_line”.
Bei einem Filter wird der von den Entwicklern festgelegte Bezeichner zurückgegeben. Ist dieser Bezeichner nicht definiert, wird ein Hexadezimalwert zurückgegeben, der einem eindeutigen internen Bezeichner entspricht.
Der Hauptzweck dieser Funktion besteht darin, die letzte Entität, die eine Verarbeitung unterbrochen hat, zur Unterstützung der Fehlersuche in Protokollen zu melden. Die zu Entitäten zurückgegebenen Informationen können sich im Laufe der Zeit ändern und dürfen ausschließlich zur Fehlersuche verwendet werden.
Beispiel:
last_rule_file: string Gibt den Namen der Konfigurationsdatei zurück, die die letzte während der Stream-Analyse zutreffende abschließende Regel enthält. Eine abschließende Regel beendet die Auswertung des Regelsatzes, beispielsweise “accept”, “deny” oder “redirect”. Dies funktioniert für TCP-Anfrage- und Antwortregeln in den Regelsätzen “content” sowie für HTTP-Regeln in “http-request”, “http-response” und “http-after-response”. Die älteren Regelsätze “redirect” werden nicht unterstützt, da diese Informationen dort nicht gespeichert werden. Auch “tcp-request connection” und “tcp-request session” werden nicht unterstützt, weil die Informationen auf Stream-Ebene gespeichert werden und während dieser Regeln noch keine Streams existieren. Der Hauptzweck dieser Funktion besteht darin, die Position der Regel, die die endgültige Entscheidung getroffen hat, in Protokollen zu melden. Dies hilft beispielsweise zu klären, warum eine Anfrage abgelehnt wurde. Siehe auch “last_rule_line”.
last_rule_line: integer Gibt die Zeilennummer in der Konfigurationsdatei zurück, an der die letzte während der Stream-Analyse zutreffende abschließende Regel steht. Eine abschließende Regel beendet die Auswertung des Regelsatzes, beispielsweise “accept”, “deny” oder “redirect”. Dies funktioniert für TCP-Anfrage- und Antwortregeln in den Regelsätzen “content” sowie für HTTP-Regeln in “http-request”, “http-response” und “http-after-response”. Die älteren Regelsätze “redirect” werden nicht unterstützt, da diese Informationen dort nicht gespeichert werden. Auch “tcp-request connection” und “tcp-request session” werden nicht unterstützt, weil die Informationen auf Stream-Ebene gespeichert werden und während dieser Regeln noch keine Streams existieren. Der Hauptzweck dieser Funktion besteht darin, die Position der Regel, die die endgültige Entscheidung getroffen hat, in Protokollen zu melden. Dies hilft beispielsweise zu klären, warum eine Anfrage abgelehnt wurde. Siehe auch “last_rule_file”.
lat_ns_avg: integer Gibt die durchschnittliche Anzahl der Nanosekunden zwischen dem Aufwecken der den Stream bearbeitenden Aufgabe und ihrem tatsächlichen Aufruf zurück. Bei HTTP-Keep-Alive wird dieser Wert für jede neue Anfrage auf derselben Verbindung zurückgesetzt. Er zeigt die gesamte Verzögerung, die alle anderen parallel verarbeiteten Anfragen der aktuellen Anfrage auferlegen, und ist ein direkter Indikator für die durch ressourcenintensive Nachbarn wahrgenommene Leistung. Um den Wert niedrig zu halten, können Sie die Tiefe der Ausführungswarteschlange des Schedulers mit “tune.runqueue-depth” verringern, mit “tune.maxpollevents” die Anzahl gleichzeitig verarbeiteter Ereignisse reduzieren, den nice-Wert des Streams mit der Option “nice” in den “bind”-Zeilen oder im Frontend senken oder mit “tune.sched.low-latency” eine Planung mit geringer Latenz aktivieren. Sie können auch in den Protokollen nach anderen aufwendigen Anfragen mit hohen Werten von “cpu_ns_avg” suchen, deren Verarbeitung angepasst oder korrigiert werden muss. Mögliche Ursachen sind die Komprimierung großer Puffer, aufwendige reguläre Ausdrücke oder lange Listen regulärer Ausdrücke. Hinweis: Dieser Wert entspricht genau lat_ns_tot geteilt durch cpu_calls.
lat_ns_tot: integer Gibt die Gesamtzahl der Nanosekunden zwischen dem Aufwecken der den Stream bearbeitenden Aufgabe und ihrem tatsächlichen Aufruf zurück. Bei HTTP-Keep-Alive wird dieser Wert für jede neue Anfrage auf derselben Verbindung zurückgesetzt. Er zeigt die gesamte Verzögerung, die alle anderen parallel verarbeiteten Anfragen der aktuellen Anfrage auferlegen, und ist ein direkter Indikator für die durch ressourcenintensive Nachbarn wahrgenommene Leistung. Um den Wert niedrig zu halten, können Sie die Tiefe der Ausführungswarteschlange des Schedulers mit “tune.runqueue-depth” verringern, mit “tune.maxpollevents” die Anzahl gleichzeitig verarbeiteter Ereignisse reduzieren, den nice-Wert des Streams mit der Option “nice” in den “bind”-Zeilen oder im Frontend senken oder mit “tune.sched.low-latency” eine Planung mit geringer Latenz aktivieren. Sie können auch in den Protokollen nach anderen aufwendigen Anfragen mit hohen Werten von “cpu_ns_avg” suchen, deren Verarbeitung angepasst oder korrigiert werden muss. Mögliche Ursachen sind die Komprimierung großer Puffer, aufwendige reguläre Ausdrücke oder lange Listen regulärer Ausdrücke. Hinweis: Auch wenn intuitiv der Eindruck entstehen kann, dass die gesamte Latenz zur Übertragungszeit hinzukommt, ist dies fast nie der Fall. Während eine Aufgabe auf die CPU wartet, füllen sich die Netzwerkpuffer weiter, sodass beim nächsten Aufruf mehr auf einmal verarbeitet wird. Der Wert kann durch eine hohe Anzahl cpu_calls künstlich hoch sein, beispielsweise bei der Verarbeitung vieler HTTP-Chunks. Daher wird häufig bevorzugt, stattdessen lat_ns_avg zu protokollieren, da dies ein aussagekräftigerer Leistungsindikator ist.
meth(<method>): method
Gibt eine Methode zurück.
nbsrv([<backend>]): integer
Gibt eine Ganzzahl zurück, die der Anzahl nutzbarer Server des aktuellen oder des benannten Backends entspricht. Dies wird überwiegend mit ACLs verwendet, kann aber auch in Protokollen nützlich sein. Üblicherweise wird damit auf ein alternatives Backend umgeschaltet, wenn die Anzahl der Server zu niedrig ist, um eine bestimmte Last zu bewältigen. In Verbindung mit “monitor fail” eignet es sich zum Melden eines Ausfalls.
pid: integer Gibt die PID des aktuellen Prozesses zurück. In den meisten Fällen ist dies die PID des Worker-Prozesses.
prio_class: integer Gibt die Prioritätsklasse des aktuellen Streams im Modus http oder der aktuellen Verbindung im Modus tcp zurück. Der Wert entspricht dem letzten Aufruf von “http-request set-priority-class” oder “tcp-request content set-priority-class”.
prio_offset: integer Gibt den Prioritäts-Offset des aktuellen Streams im Modus http oder der aktuellen Verbindung im Modus tcp zurück. Der Wert entspricht dem letzten Aufruf von “http-request set-priority-offset” oder “tcp-request content set-priority-offset”.
proc: integer Gibt immer den Wert 1 zurück; früher wurde die Nummer des aufrufenden Prozesses zurückgegeben.
queue([<backend>]): integer
Gibt die Gesamtzahl wartender Verbindungen des angegebenen Backends zurück, einschließlich aller Verbindungen in Server-Warteschlangen. Wird kein Backend-Name angegeben, wird das aktuelle Backend verwendet; es kann aber auch ein anderes geprüft werden. Dies ist mit ACLs oder zur Weitergabe von Statistiken an Backend-Server nützlich. Damit lassen sich Aktionen auslösen, wenn die Warteschlangen einen bekannten Schwellenwert überschreiten, was in der Regel auf einen starken Verkehrszuwachs oder eine massive Verlangsamung der Server hindeutet. Eine mögliche Aktion wäre, neue Nutzer abzulehnen, bestehende aber weiterhin zu akzeptieren. Siehe auch die Abrufe “avg_queue”, “be_conn” und “be_sess_rate”.
quic_enabled: boolean Gibt true zurück, wenn die Unterstützung für das Transportprotokoll QUIC einkompiliert wurde und QUIC-Listener nicht durch die globale Option “tune.quic.listen” deaktiviert sind. Siehe auch die globale Option “tune.quic.listen”.
rand([<range>]): integer
Gibt eine zufällige Ganzzahl aus einem Bereich mit <range> möglichen Werten zurück, beginnend bei null. Wird der Bereich nicht angegeben, ist der Standardwert 2^32, wodurch Zahlen zwischen 0 und 4294967295 entstehen. Dies kann beispielsweise zum Bereitstellen von Werten für Routing-Entscheidungen oder einfach zur Fehlersuche nützlich sein. Diese Zufallswerte dürfen nicht für Sicherheitszwecke verwendet werden.
srv_conn([<backend>/]<server>): integer
Gibt eine Ganzzahl zurück, die der Anzahl derzeit hergestellter Verbindungen des angegebenen Servers entspricht, gegebenenfalls einschließlich der gerade ausgewerteten Verbindung. Wird <backend> weggelassen, wird der Server im aktuellen Backend gesucht. Damit lässt sich eine bestimmte Servergruppe verwenden, wenn ein Server voll ist, oder dem Server unsere Sicht auf die Anzahl aktiver Verbindungen mit ihm mitteilen. Siehe auch die Abrufmethoden “fe_conn”, “be_conn”, “queue” und “srv_conn_free”.
srv_conn_free([<backend>/]<server>): integer
Gibt eine Ganzzahl zurück, die der Anzahl verfügbarer Verbindungen des angegebenen Servers entspricht, gegebenenfalls einschließlich der gerade ausgewerteten Verbindung. Warteschlangenplätze sind nicht enthalten. Wird <backend> weggelassen, wird der Server im aktuellen Backend gesucht. Damit lässt sich eine bestimmte Servergruppe verwenden, wenn ein Server voll ist, oder dem Server unsere Sicht auf die Anzahl aktiver Verbindungen mit ihm mitteilen. Siehe auch die Abrufmethoden “be_conn_free” und “srv_conn”.
Weitere Einschränkungen und Hinweise: Ist maxconn des Servers gleich 0, ist dieser Abruf nicht sinnvoll; in diesem Fall wird -1 zurückgegeben.
srv_is_up([<backend>/]<server>): boolean
Gibt true zurück, wenn der angegebene Server UP ist, und false, wenn er DOWN oder im Wartungsmodus ist. Wird <backend> weggelassen, wird der Server im aktuellen Backend gesucht. Dies wird hauptsächlich verwendet, um anhand eines externen, über einen Health Check gemeldeten Zustands zu handeln, etwa der Verfügbarkeit eines geografischen Standorts. Eine weitere, eher behelfsmäßige Verwendung besteht darin, Dummy-Server als boolesche Variablen einzusetzen, die über die CLI aktiviert oder deaktiviert werden können. So lassen sich Regeln, die von diesen ACLs abhängen, in Echtzeit anpassen.
srv_iweight([<backend>/]<server>): integer
Gibt eine Ganzzahl zurück, die dem anfänglichen Gewicht des Servers entspricht. Wird <backend> weggelassen, wird der Server im aktuellen Backend gesucht. Siehe auch “srv_weight” und “srv_uweight”.
srv_queue([<backend>/]<server>): integer
Gibt eine Ganzzahl zurück, die der Anzahl derzeit in der Warteschlange des angegebenen Servers wartender Verbindungen entspricht. Wird <backend> weggelassen, wird der Server im aktuellen Backend gesucht. Mit der Direktive “use-server” kann dies gelegentlich dazu dienen, die Verwendung eines bekanntermaßen schnelleren Servers zu erzwingen, wenn dieser nur wenig ausgelastet ist. Siehe auch die Sample-Abrufmethoden “srv_conn”, “avg_queue” und “queue”.
srv_sess_rate([<backend>/]<server>): integer
Gibt eine Ganzzahl zurück, die der Rate neu angelegter Sitzungen des angegebenen Servers entspricht, gemessen als Anzahl neuer Sitzungen pro Sekunde. Wird <backend> weggelassen, wird der Server im aktuellen Backend gesucht. Dies wird überwiegend mit ACLs verwendet, kann aber auch für Protokolle sinnvoll sein. Damit wird auf ein alternatives Backend umgeschaltet, wenn ein ressourcenintensives oder empfindliches Backend eine zu hohe Sitzungsrate erreicht, oder der Missbrauch eines Diensts begrenzt, beispielsweise um eine Überlastung der Server durch verzögerte Anfragen zu verhindern.
Beispiel:
srv_uweight([<backend>/]<server>): integer
Gibt eine Ganzzahl zurück, die dem für den Benutzer sichtbaren Gewicht des Servers entspricht. Wird <backend> weggelassen, wird der Server im aktuellen Backend gesucht. Siehe auch “srv_weight” und “srv_iweight”.
srv_weight([<backend>/]<server>): integer
Gibt eine Ganzzahl zurück, die dem aktuellen bzw. effektiven Gewicht des Servers entspricht. Wird <backend> weggelassen, wird der Server im aktuellen Backend gesucht. Siehe auch “srv_iweight” und “srv_uweight”.
stopping: boolean Gibt TRUE zurück, wenn der Prozess, der die Funktion aufruft, gerade beendet wird. Dies kann für die Protokollierung nützlich sein, aber auch zum Lockern bestimmter Prüfungen oder zum Schließen bestimmter Verbindungen beim geordneten Herunterfahren.
str(<string>): string
Gibt eine Zeichenkette zurück.
table_avl([<table>]): integer
Gibt die Gesamtzahl verfügbarer Einträge in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table zurück. Siehe auch “table_cnt”.
table_cnt([<table>]): integer
Gibt die Gesamtzahl der derzeit verwendeten Einträge in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table zurück. Weitere Methoden zum Zählen von Einträgen stehen unter “table_conn_cnt” und table_avl.
term_events: string Gibt alle bekannten Beendigungsereignisse für alle einem Stream zugeordneten Entitäten auf Client- und Server-Seite zurück. Ein Tupel aus sieben Elementen mit folgenden Informationen wird zurückgegeben:
- die Beendigungsereignisse der Frontend-Verbindung
- die Beendigungsereignisse der Frontend-Mux-Verbindung
- die Beendigungsereignisse des Frontend-Stream-Endpunktdeskriptors
(des Mux-Streams oder des Applets)
- die Beendigungsereignisse des Streams
- die Beendigungsereignisse des Backend-Stream-Endpunktdeskriptors
(des Mux-Streams oder des Applets)
- die Beendigungsereignisse der Backend-Mux-Verbindung
- die Beendigungsereignisse der Backend-Verbindung
Auf jeder Ebene werden die ersten vier Ereignisse gemeldet. Wurde für eine bestimmte Ebene noch kein Ereignis gemeldet, wird eine leere Zeichenkette zurückgegeben. Werden Beendigungsereignisse nicht unterstützt, wird “-” zurückgegeben.
Dies darf ausschließlich zur Fehlersuche verwendet werden. Das genaue Format ist nicht dokumentiert, da es sich je nach Anforderungen der Entwickler ändern kann.
tgroup: integer Gibt eine Ganzzahl zurück, die der Position der Thread-Gruppe entspricht, welche die Funktion aufruft, zwischen 0 und (global.thread-groups - 1). Dies ist für die Protokollierung und Fehlersuche nützlich.
thread: integer Gibt eine Ganzzahl zurück, die der Position des Threads entspricht, der die Funktion aufruft, zwischen 0 und (global.nbthread-1). Dies ist für die Protokollierung und Fehlersuche nützlich.
txn.id32: integer Gibt die interne Transaktions-ID zurück. Sie ist eine 32bits-Ganzzahl. Ihr Wert ist daher nicht uneingeschränkt eindeutig; Transaktions-IDs können umlaufen. Wie oft dies geschieht, hängt von der Anfragerate ab. In der Praxis sollte dies kein Problem sein. Für eine tatsächlich eindeutige ID siehe die Direktive “unique-id-format”.
txn.sess_term_state: string Gibt den im Protokoll gemeldeten Beendigungszustand des TCP- oder HTTP-Streams zurück. Dies ist eine Zeichenkette aus 2 Zeichen: der abschließende Stream-Zustand, gefolgt vom Ereignis, das seine Beendigung verursacht hat. Die Liste möglicher Ereignisse steht in Abschnitt 8.5 zum Stream-Zustand beim Verbindungsabbau. Zurückgegeben wird der aktuelle Wert zum Zeitpunkt der Auswertung des Sample-Abrufs. Dieser kann sich noch ändern. Außer bei Verwendung mit ACLs in “http-after-response”-Regelsätzen oder in Protokollmeldungen ist der Wert stets “–”.
Beispiel:
uptime: integer Gibt die Laufzeit des aktuellen HAProxy-Workers in Sekunden zurück.
uuid([<version>]): string
Gibt eine UUID gemäß RFC 9562 zurück. Ist keine Version angegeben, wird eine UUID der Version 4 (vollständig zufällig) zurückgegeben.
Unterstützt werden die Versionen 4 und 7.
var(<var-name>[,<default>]): undefined
Gibt eine Variable mit dem gespeicherten Typ zurück. Ist die Variable nicht gesetzt, schlägt der Sample-Abruf fehl, sofern kein Standardwert angegeben ist. Ist ein Standardwert angegeben, wird dieser als Zeichenkette zurückgegeben. Leere Zeichenketten sind zulässig. Einzelheiten zu Variablen stehen in Abschnitt 2.8 .
dump_all_vars([<scope>][,<prefix>][,<delimiter>]): string
Gibt eine Liste aller Variablen im angegebenen Gültigkeitsbereich zurück, optional nach Namenspräfix gefiltert und mit anpassbarem Trennzeichen.
Ausgabeformat: var1=value1<delim>var2=value2<delim>…
Wertkodierung nach Typ:
- Zeichenketten: in Anführungszeichen und maskiert (", \, \r, \n, \b, \0). Beispiel: txn.name=“John \“Doe\””
- Binärdaten: hexadezimal kodiert mit dem Präfix ‘x’, ohne Anführungszeichen. Beispiel: txn.data=x48656c6c6f
- Ganzzahlen: dezimal, ohne Anführungszeichen. Beispiel: txn.count=42
- Boolesche Werte: “true” oder “false”, ohne Anführungszeichen. Beispiel: txn.active=true
- Adressen: IP-Adresszeichenkette, ohne Anführungszeichen. Beispiel: txn.client=192.168.1.1
- HTTP-Methoden: Zeichenkette in Anführungszeichen. Beispiel: req.method=“GET”
Argumente:
-
<scope>(optional): sess, txn, req, res oder proc. Wird es weggelassen, werden alle diese Gültigkeitsbereiche in der hier angegebenen Reihenfolge durchlaufen. -
<prefix>(optional): Filtert Variablen, deren Namen mit dem angegebenen Präfix beginnen, nachdem das Präfix des Gültigkeitsbereichs entfernt wurde. Hinweis zur Leistung: Bei der Präfixfilterung werden weiterhin alle Variablen des Gültigkeitsbereichs durchlaufen. Dies sollte nicht in Konfigurationen mit Tausenden von Variablen verwendet werden. -
<delimiter>(optional): Zeichenkette zur Trennung der Variablen. Standardmäßig “, " (Komma und Leerzeichen). Jede beliebige Zeichenkette ist möglich. Zur Erinnerung: Kommas oder Leerzeichen müssen zum Übergeben in einem Funktionsargument in einfache oder doppelte Anführungszeichen eingeschlossen werden. Steht der Ausdruck selbst bereits in Anführungszeichen, verwenden Sie die jeweils andere Art.
Rückgabewert:
- Bei Erfolg: Zeichenkette mit allen passenden Variablen
- Bei einem Fehler: leer (der Sample-Abruf schlägt fehl), wenn der Ausgabepuffer zu klein ist. Die Funktion schneidet die Ausgabe nicht ab, sondern schlägt vollständig fehl, um Teildaten zu vermeiden.
Dies ist besonders für die Fehlersuche, Protokollierung oder den Export von Variablenzuständen nützlich.
Beispiele:
wait_end: boolean Dieser Abruf gibt entweder true zurück, wenn die Prüfzeit abgelaufen ist, oder liefert kein Sample. Er wird nur in ACLs in Verbindung mit der Inhaltsanalyse verwendet, um eine verfrühte falsche Entscheidung zu vermeiden. Er kann auch Aktionen verzögern, beispielsweise die verzögerte Ablehnung bestimmter Adressen. Da er entweder die Regelauswertung anhält oder sofort true zurückgibt, wird empfohlen, diese ACL als letzte in einer Regel zu verwenden. Die vordefinierte ACL “WAIT_END” ist stets ohne vorherige Deklaration verfügbar. Diese Prüfung wurde für die Inhaltsprüfung von TCP-Anfragen entwickelt.
Beispiele:
waiting_entity: string Gibt die Identität der Entität zurück, die auf die Fortsetzung ihrer Verarbeitung wartete, als ein Fehler oder eine Zeitüberschreitung auftrat. Dies kann beispielsweise eine Regel oder ein Filter sein. Diese Liste ist jedoch nicht vollständig, und das Format aller möglichen Entitäten ist nicht zwingend dokumentiert.
Ist die Entität eine Regel, wird ihre Position zurückgegeben: die Konfigurationsdatei, die die Regel enthält, gefolgt von der Zeile, in der sie in dieser Datei definiert ist, getrennt durch einen Doppelpunkt.
Bei einem Filter wird der von den Entwicklern festgelegte Bezeichner zurückgegeben. Ist dieser Bezeichner nicht definiert, wird ein Hexadezimalwert zurückgegeben, der einem eindeutigen internen Bezeichner entspricht.
Der Hauptzweck dieser Funktion besteht darin, die Entität in Protokollen zu melden, die die Stream-Analyse blockierte, als ein Fehler oder eine Zeitüberschreitung die Verarbeitung unterbrach. Dies unterstützt die Fehlersuche. Die zu Entitäten zurückgegebenen Informationen können sich im Laufe der Zeit ändern und dürfen ausschließlich zur Fehlersuche verwendet werden.
Beispiel:
7.3.3. Sample-Abruf auf Schicht 4
Schicht 4 beschreibt üblicherweise nur die Transportschicht, die in HAProxy der Verbindung am nächsten liegt und auf der noch keine Inhalte verfügbar sind. Die hier beschriebenen Abrufmethoden können bereits in den Regelsätzen “tcp-request connection” verwendet werden, sofern sie keine erst später verfügbaren Informationen benötigen. Dazu gehören im Allgemeinen TCP/IP-Adressen und Ports sowie Elemente aus Stick Tables, die sich auf die eingehende Verbindung beziehen. Beim Abruf eines Werts aus einem Sticky-Zähler kann die Zählernummer mit den vordefinierten Präfixen “sc0_”, “sc1_” oder “sc2_” ausdrücklich auf 0, 1 oder 2 gesetzt werden. Diese drei vordefinierten Präfixe können nur verwendet werden, wenn der globale Wert “tune.stick-counters” nicht größer als 3 ist. Andernfalls kann die Zählernummer als erstes ganzzahliges Argument bei Verwendung des Präfixes “sc_” angegeben werden, von “sc_0” bis “sc_N”, wobei N gleich (tune.stick-counters-1) ist. Mit der Form “sc*” kann optional eine Tabelle angegeben werden. In diesem Fall wird der derzeit verfolgte Schlüssel in dieser alternativen Tabelle gesucht, anstelle der aktuell verfolgten Tabelle.
Übersicht über die Sample-Abrufmethoden in diesem Abschnitt und ihre jeweiligen Typen:
Ausführliche Liste:
accept_date([<unit>]): integer
Dies ist der genaue Zeitpunkt, zu dem HAProxy die Verbindung empfangen hat. Er kann geringfügig von dem im Netzwerk beobachteten Zeitpunkt abweichen, wenn die Verbindung in der Backlog-Warteschlange des Systems warten musste. Üblicherweise ist dies derselbe Zeitpunkt, der in den Protokollen vorgelagerter Firewalls erscheinen kann. Im HTTP-Modus wird das Feld accept_date auf den ersten Zeitpunkt zurückgesetzt, zu dem die Verbindung für eine neue Anfrage bereit ist: bei HTTP/1 am Ende der vorherigen Antwort, bei HTTP/2 unmittelbar nach der vorherigen Anfrage.
Gibt einen Wert als Anzahl von Sekunden seit der Epoche zurück.
<unit> ist optional und kann auf “s” für Sekunden (Standardverhalten), “ms” für Millisekunden oder “us” für Mikrosekunden gesetzt werden. Ist die Einheit angegeben, ist der Rückgabewert eine Ganzzahl, die Sekunden, Millisekunden oder Mikrosekunden seit der Epoche angibt. Dies ist nützlich, wenn eine Zeitauflösung unter einer Sekunde benötigt wird.
bc.timer.connect: integer Gesamtzeit zum Aufbau der TCP-Verbindung zum Server. Entspricht %Tc in log-format und wird in Millisekunden (ms) angegeben. Weitere Informationen stehen in Abschnitt 8.4 „Zeitereignisse“.
bc_be_queue: integer Anzahl der aus der Warteschlange entnommenen Streams während des Wartens auf einen Verbindungsplatz im Ziel-Backend. Entspricht %bq in log-format.
bc_dst: ip Die Ziel-IP-Adresse der Verbindung auf der Server-Seite, also die Serveradresse, zu der HAProxy die Verbindung aufgebaut hat. Sie hat den Typ IP und funktioniert sowohl mit IPv4- als auch mit IPv6-Tabellen. In IPv6-Tabellen wird eine IPv4-Adresse gemäß RFC 4291 auf ihre IPv6-Entsprechung abgebildet.
bc_dst_port: integer Gibt eine Ganzzahl zurück, die dem TCP-Zielport der Verbindung auf der Server-Seite entspricht, also dem Port, zu dem HAProxy die Verbindung aufgebaut hat.
bc_err: integer Gibt die ID des Fehlers zurück, der möglicherweise auf der aktuellen Backend-Verbindung aufgetreten ist. Eine vollständige Liste der Fehlercodes mit den zugehörigen Fehlermeldungen steht beim Abruf “fc_err_str”.
bc_err_name: string Gibt den internen Fehlernamen zurück, der das auf der Backend-Verbindung aufgetretene Problem beschreibt, das zum Fehlschlagen der Verbindung führte. Diese Zeichenkette besteht aus einem einzigen Wort und ist leer, wenn kein Fehler vorliegt. Sie entspricht der Spalte “name” in der beim Schlüsselwort “fc_err_str” gezeigten Tabelle.
bc_err_str: string Gibt eine Fehlermeldung zurück, die das auf der aktuellen Backend-Verbindung aufgetretene Problem beschreibt, das zum Fehlschlagen der Verbindung führte. Eine vollständige Liste der Fehlercodes mit den zugehörigen Fehlermeldungen steht beim Abruf “fc_err_str”.
bc_glitches: integer Gibt die Anzahl der auf der Backend-Verbindung gezählten Protokollstörungen zurück. Dazu gehören üblicherweise Protokollverletzungen sowie kleine Anomalien, die auf einen fehlerhaften oder sich falsch verhaltenden Server hindeuten und Probleme in der Infrastruktur verursachen können, etwa vorzeitige Verbindungsabbrüche oder häufige TLS-Neuverhandlungen. Auch Antworten, die zu groß für einen einzelnen Puffer sind, können solche Störungen verursachen und HTTP-502-Fehler erklären. Idealerweise sollte dieser Wert null bleiben; im Allgemeinen ist jedoch ein sehr niedriger Wert im Verhältnis zur Gesamtzahl der Anfragen unproblematisch. Diese Werte sollten normalerweise nicht als alarmierend gelten, insbesondere kleine Werte. Ein plötzlicher Anstieg kann allerdings auf eine Anomalie hinweisen. Nicht alle Protokoll-Multiplexer erfassen diese Kennzahl. Weitere Einzelheiten zu den Ereignissen lassen sich nur durch aktivierte Traces erhalten, die den gesamten Austausch erfassen.
bc_http_major: integer Gibt die HTTP-Hauptversionskodierung der Backend-Verbindung zurück: 1 für HTTP/0.9 bis HTTP/1.1 oder 2 für HTTP/2. Dies beruht auf der Kodierung auf der Leitung und nicht auf der im Anfrage-Header angegebenen Version.
bc_nb_streams: integer Gibt die Anzahl der auf der Backend-Verbindung geöffneten Streams zurück.
bc_reused: boolean Gibt true zurück, wenn die Übertragung über eine wiederverwendete Backend-Verbindung erfolgte.
bc_rtt(<unit>): integer
Gibt die vom Kernel gemessene Round Trip Time (RTT) der Backend-Verbindung zurück. <unit> ist optional; die Standardeinheit ist Millisekunden. <unit> kann auf “ms” für Millisekunden oder “us” für Mikrosekunden gesetzt werden. Ist die Serververbindung nicht hergestellt, handelt es sich nicht um TCP oder unterstützt das Betriebssystem TCP_INFO nicht, beispielsweise bei Linux-Kernels vor 2.4, schlägt der Sample-Abruf fehl.
bc_rttvar(<unit>): integer
Gibt die vom Kernel gemessene Varianz der Round Trip Time (RTT) der Backend-Verbindung zurück. <unit> ist optional; die Standardeinheit ist Millisekunden. <unit> kann auf “ms” für Millisekunden oder “us” für Mikrosekunden gesetzt werden. Ist die Serververbindung nicht hergestellt, handelt es sich nicht um TCP oder unterstützt das Betriebssystem TCP_INFO nicht, beispielsweise bei Linux-Kernels vor 2.4, schlägt der Sample-Abruf fehl.
bc_settings_streams_limit: integer Gibt die maximal zulässige Anzahl von Streams auf der Backend-Verbindung zurück. Bei TCP- und HTTP/1.1-Verbindungen ist dies stets 1. Bei anderen Protokollen hängt der Wert von den mit dem Server ausgehandelten Einstellungen ab.
bc_src: ip Die Quell-IP-Adresse der Verbindung auf der Server-Seite, also die Adresse, von der aus HAProxy die Verbindung aufgebaut hat. Sie hat den Typ IP und funktioniert sowohl mit IPv4- als auch mit IPv6-Tabellen. In IPv6-Tabellen werden IPv4-Adressen gemäß RFC 4291 auf ihre IPv6-Entsprechung abgebildet.
bc_src_port: integer Gibt eine Ganzzahl zurück, die dem TCP-Quellport der Verbindung auf der Server-Seite entspricht, also dem Port, von dem aus HAProxy die Verbindung aufgebaut hat.
bc_srv_queue: integer Anzahl der aus der Warteschlange entnommenen Streams während des Wartens auf einen Verbindungsplatz auf dem Zielserver. Entspricht %sq in log-format.
be_id: integer Gibt eine Ganzzahl mit der ID des aktuellen Backends zurück. Kann in Frontends bei Antworten verwendet werden, um zu prüfen, welches Backend die Anfrage verarbeitet hat. Wird der Abruf in einem Frontend verwendet und wurde kein Backend benutzt, wird die ID des aktuellen Frontends zurückgegeben. Kann auch in einem tcp-check- oder http-check-Regelsatz verwendet werden.
be_connect_timeout: integer Gibt den konfigurierten Wert der Zeitüberschreitung für den Verbindungsaufbau des aktuellen Backends in Millisekunden zurück. Diese Zeitüberschreitung kann durch eine Regel “set-timeout” überschrieben werden. Siehe auch “cur_connect_timeout”.
be_name: string Gibt eine Zeichenkette mit dem Namen des aktuellen Backends zurück. Kann in Frontends bei Antworten verwendet werden, um zu prüfen, welches Backend die Anfrage verarbeitet hat. Wird der Abruf in einem Frontend verwendet und wurde kein Backend benutzt, wird der Name des aktuellen Frontends zurückgegeben. Kann auch in einem tcp-check- oder http-check-Regelsatz verwendet werden.
be_queue_timeout: integer Gibt den konfigurierten Wert der Zeitüberschreitung für die Warteschlange des aktuellen Backends in Millisekunden zurück. Diese Zeitüberschreitung kann durch eine Regel “set-timeout” überschrieben werden. Siehe auch “cur_queue_timeout”.
be_server_timeout: integer Gibt den konfigurierten Wert der Zeitüberschreitung für den Server des aktuellen Backends in Millisekunden zurück. Diese Zeitüberschreitung kann durch eine Regel “set-timeout” überschrieben werden. Siehe auch “cur_server_timeout”.
be_tarpit_timeout: integer Gibt den konfigurierten Wert der Zeitüberschreitung für die Warteschlange des aktuellen Backends in Millisekunden zurück. Diese Zeitüberschreitung kann durch eine Regel “set-timeout” überschrieben werden. Siehe auch “cur_tarpit_timeout”.
be_tunnel_timeout: integer Gibt den konfigurierten Wert der Zeitüberschreitung für den Tunnel des aktuellen Backends in Millisekunden zurück. Diese Zeitüberschreitung kann durch eine Regel “set-timeout” überschrieben werden. Siehe auch “cur_tunnel_timeout”.
bytes_in: integer Siehe “req.bytes_in”.
bytes_out: integer Siehe “res.bytes_in”.
cur_connect_timeout: integer Gibt die aktuell für den Stream geltende Zeitüberschreitung für den Verbindungsaufbau in Millisekunden zurück. Standardmäßig entspricht dies be_connect_timeout, sofern keine Regel “set-timeout” angewendet wurde. Siehe auch “be_connect_timeout”.
cur_client_timeout: integer Gibt die aktuell für den Stream geltende Zeitüberschreitung für den Client in Millisekunden zurück. Standardmäßig entspricht dies fe_client_timeout, sofern keine Regel “set-timeout” angewendet wurde. Siehe auch “fe_client_timeout”.
cur_queue_timeout: integer Gibt die aktuell für den Stream geltende Zeitüberschreitung für die Warteschlange in Millisekunden zurück. Standardmäßig entspricht dies be_queue_timeout, sofern keine Regel “set-timeout” angewendet wurde. Siehe auch “be_queue_timeout”.
cur_server_timeout: integer Gibt die aktuell für den Stream geltende Zeitüberschreitung für den Server in Millisekunden zurück. Standardmäßig entspricht dies be_server_timeout, sofern keine Regel “set-timeout” angewendet wurde. Siehe auch “be_server_timeout”.
cur_tarpit_timeout: integer Gibt die aktuell für den Stream geltende Zeitüberschreitung für die Tarpit in Millisekunden zurück. Standardmäßig entspricht dies fe_tarpit_timeout/be_tarpit_timeout, sofern keine Regel “set-timeout” angewendet wurde. Siehe auch “fe_tarpit_timeout” und “be_tarpit_timeout”.
cur_tunnel_timeout: integer Gibt die aktuell für den Stream geltende Zeitüberschreitung für den Tunnel in Millisekunden zurück. Standardmäßig entspricht dies be_tunnel_timeout, sofern keine Regel “set-timeout” angewendet wurde. Siehe auch “be_tunnel_timeout”.
dst: ip Die Ziel-IP-Adresse der Verbindung auf der Client-Seite, also die Adresse, zu der der Client die Verbindung aufgebaut hat. Beliebige tcp/http-Regeln können diese Adresse ändern. Dies kann im transparenten Modus nützlich sein. Sie hat den Typ IP und funktioniert sowohl mit IPv4- als auch mit IPv6-Tabellen. In IPv6-Tabellen wird eine IPv4-Adresse gemäß RFC 4291 auf ihre IPv6-Entsprechung abgebildet. Hat die eingehende Verbindung eine Adressübersetzung oder Umleitung mit Verbindungsverfolgung durchlaufen, wird die ursprüngliche Zieladresse vor der Umleitung gemeldet. Auf Linux-Systemen können Quelle und Ziel in seltenen Fällen vertauscht erscheinen, wenn der sysctl-Wert nf_conntrack_tcp_loose gesetzt ist: Eine verspätete Antwort kann eine abgelaufene Verbindung erneut öffnen und dabei vertauschen, was als Quelle und Ziel angesehen wird.
dst_conn: integer Gibt eine Ganzzahl zurück, die der Anzahl derzeit auf demselben Socket hergestellter Verbindungen entspricht, einschließlich der gerade ausgewerteten Verbindung. Dies wird normalerweise mit ACLs verwendet, kann aber auch Informationen in einem HTTP-Header oder in Protokollen an Server weitergeben. Damit lässt sich vor einer vollständigen Sperre eine Entschuldigungsseite zurückgeben oder ein bestimmtes Backend zum Ableiten neuer Anfragen verwenden, wenn der Socket als ausgelastet gilt. So lassen sich verschiedenen lauschenden Ports oder Adressen unterschiedliche Grenzwerte zuweisen. Siehe auch die Abrufe “fe_conn” und “be_conn”.
dst_is_local: boolean Gibt true zurück, wenn die Zieladresse der eingehenden Verbindung lokal auf dem System liegt, oder false, wenn die Adresse auf dem System nicht vorhanden ist, die Verbindung also im transparenten Modus abgefangen wurde. Damit lassen sich standardmäßig bestimmte Regeln auf weitergeleiteten Verkehr und andere Regeln auf Verkehr zur tatsächlichen Adresse des Rechners anwenden. Beispielsweise könnte die Statistikseite nur an dieser Adresse bereitgestellt oder SSH-Zugriff lokal umgeleitet werden. Die Prüfung benötigt einige Systemaufrufe und sollte daher möglichst nur einmal pro Verbindung erfolgen.
dst_port: integer Gibt eine Ganzzahl zurück, die dem TCP-Zielport der Verbindung auf der Client-Seite entspricht, also dem Port, zu dem der Client die Verbindung aufgebaut hat. Beliebige tcp/http-Regeln können diese Adresse ändern. Dies kann im transparenten Modus verwendet werden, beim Zuweisen dynamischer Ports an bestimmte Clients für eine gesamte Anwendungssitzung, um alle Benutzer an denselben Server zu binden, oder um einem Server die Zielportinformationen in einem HTTP-Header mitzuteilen.
fc.timer.handshake: integer Gesamtzeit zum Akzeptieren einer TCP-Verbindung und zum Ausführen der Handshakes für Protokolle niedriger Ebenen. Derzeit sind dies proxy-protocol und SSL. Entspricht %Th in log-format und wird in Millisekunden (ms) angegeben. Weitere Informationen stehen in Abschnitt 8.4 „Zeitereignisse“.
fc.timer.total: integer Gesamtdauer des Streams, vom Zeitpunkt der Annahme durch den Proxy bis zum Schließen beider Enden. Entspricht %Tt in log-format und wird in Millisekunden (ms) angegeben. Weitere Informationen stehen in Abschnitt 8.4 „Zeitereignisse“.
fc_dst: ip Die ursprüngliche Ziel-IP-Adresse der Verbindung auf der Client-Seite. Nur Regeln “tcp-request connection” können diese Adresse ändern. Einzelheiten stehen unter “dst”.
fc_dst_is_local: boolean Gibt true zurück, wenn die ursprüngliche Zieladresse der eingehenden Verbindung lokal auf dem System liegt, oder false, wenn die Adresse auf dem System nicht vorhanden ist. Einzelheiten stehen unter “dst_is_local”.
fc_dst_port: integer Gibt eine Ganzzahl zurück, die dem ursprünglichen TCP-Zielport der Verbindung auf der Client-Seite entspricht. Nur Regeln “tcp-request connection” können diese Adresse ändern. Einzelheiten stehen unter “dst-port”.
fc_err: integer Gibt die ID des Fehlers zurück, der möglicherweise auf der aktuellen Verbindung aufgetreten ist. Jeder strikt positive Wert dieses Abrufs zeigt an, dass die Verbindung nicht erfolgreich war und ein Fehlerprotokolleintrag ausgegeben würde, wie in Abschnitt 8.2.5 beschrieben. Eine vollständige Liste der Fehlercodes mit den zugehörigen Fehlermeldungen steht beim Abruf “fc_err_str”.
fc_err_name: string Gibt den internen Fehlernamen zurück, der das auf der Frontend-Verbindung aufgetretene Problem beschreibt, das zum Fehlschlagen der Verbindung führte. Diese Zeichenkette besteht aus einem einzigen Wort und ist leer, wenn kein Fehler vorliegt. Sie entspricht der Spalte “name” in der beim Schlüsselwort “fc_err_str” gezeigten Tabelle.
fc_err_str: string Gibt eine Fehlermeldung zurück, die das auf der aktuellen Verbindung aufgetretene Problem beschreibt, das zum Fehlschlagen der Verbindung führte. Diese Zeichenkette entspricht dem Teil “message” des Fehlerprotokollformats (siehe Abschnitt 8.2.5 ). Eine vollständige Liste der Fehlercodes mit den zugehörigen Fehlermeldungen folgt unten:
fc_fackets: integer Gibt den vom Kernel für die Client-Verbindung gemessenen fack-Zähler zurück. Ist die Serververbindung nicht hergestellt, handelt es sich nicht um TCP oder unterstützt das Betriebssystem TCP_INFO nicht, beispielsweise bei Linux-Kernels vor 2.4, schlägt der Sample-Abruf fehl.
fc_glitches: integer Gibt die Anzahl der auf der Frontend-Verbindung gezählten Protokollstörungen zurück. Dazu gehören üblicherweise Protokollverletzungen sowie kleine Anomalien, die auf einen fehlerhaften oder sich falsch verhaltenden Client hindeuten und Probleme in der Infrastruktur verursachen können. Beispiele sind übermäßig viele Fehler in den Protokollen oder zahlreiche vorzeitige Verbindungsabbrüche, die häufige TLS-Neuverhandlungen auslösen. Auch Anfragen, die zu groß für einen einzelnen Puffer sind, können solche Störungen verursachen und HTTP-400-Fehler erklären. Idealerweise sollte dieser Wert null bleiben; manche Browser können jedoch gelegentlich eine Störung auslösen, wenn sie die Grenzen des Protokolls ausreizen. Diese Werte sollten normalerweise nicht als alarmierend gelten, insbesondere kleine Werte. Ein plötzlicher Anstieg kann allerdings auf eine Anomalie hinweisen. Große Werte, etwa Hunderte bis Tausende pro Verbindung oder so viele wie Anfragen, können auf einen eigens entwickelten Client hindeuten, der den Protokoll-Stack identifizieren oder angreifen will. Nicht alle Protokoll-Multiplexer erfassen diese Kennzahl. Weitere Einzelheiten zu den Ereignissen lassen sich nur durch aktivierte Traces erhalten, die den gesamten Austausch erfassen.
fc_http_major: integer Meldet die HTTP-Hauptversionskodierung der Frontend-Verbindung: 1 für HTTP/0.9 bis HTTP/1.1 oder 2 für HTTP/2. Dies beruht auf der Kodierung auf der Leitung und nicht auf der im Anfrage-Header angegebenen Version.
fc_lost: integer Handelt es sich bei der Verbindung weder um TCP noch um QUIC, schlägt der Sample-Abruf fehl. Bei QUIC wird die Anzahl verlorener QUIC-Pakete der Client-Verbindung zurückgegeben. Bei TCP wird der vom Kernel für die Client-Verbindung gemessene lost-Zähler zurückgegeben. Ist die Serververbindung nicht hergestellt oder unterstützt das Betriebssystem TCP_INFO nicht, beispielsweise bei Linux-Kernels vor 2.4, schlägt der Sample-Abruf fehl.
fc_nb_streams: integer Gibt die Anzahl der auf der Frontend-Verbindung geöffneten Streams zurück.
fc_pp_authority: string Gibt das erste vom Client im PROXY-Protokoll-Header gesendete Authority-TLV zurück, sofern vorhanden.
fc_pp_tlv(<id>): string
Gibt den TLV-Wert für die angegebene TLV-ID zurück. Die ID muss entweder ein numerischer Wert zwischen 0 und 255 oder einer der folgenden unterstützten symbolischen Namen sein, die den Suffixen der TLV-Konstanten in der PPv2-Spezifikation entsprechen: “ALPN”: PP2_TYPE_ALPN, “AUTHORITY”: PP2_TYPE_AUTHORITY, “CRC32”: PP2_TYPE_CRC32C, “NETNS”: PP2_TYPE_NETNS, “NOOP: PP2_TYPE_NOOP”, “SSL”: PP2_TYPE_SSL, “SSL_CIPHER”: PP2_SUBTYPE_SSL_CIPHER, “SSL_CN”: PP2_SUBTYPE_SSL_CN, “SSL_KEY_ALG”: PP2_SUBTYPE_SSL_KEY_ALG, “SSL_SIG_ALG”: PP2_SUBTYPE_SSL_SIG_ALG, “SSL_VERSION”: PP2_SUBTYPE_SSL_VERSION, “UNIQUE_ID”: PP2_TYPE_UNIQUE_ID.
Der empfangene Wert darf höchstens 1024 Bytes groß sein. Dies dient der Verhinderung möglicher DoS-Angriffe. Werte mit höchstens 256 Bytes können aus einem Speicherpool zugewiesen werden. Begrenzen Sie daher für optimale Leistung die Länge gesendeter Werte möglichst auf 256 Bytes.
Anders als fc_pp_authority und fc_pp_unique_id kann fc_pp_tlv alle Vorkommen eines angeforderten TLV durchlaufen, falls TLV-IDs mehrfach vorhanden sind. Die Reihenfolge entspricht den Positionen im PROXY-Protokoll-Header. Auf Duplikate sollte man sich jedoch möglichst nicht verlassen, da TLVs üblicherweise als eindeutig vorausgesetzt werden. Doppelte TLV-IDs deuten im Allgemeinen auf einen Fehler auf der Senderseite des PROXY-Protokoll-Headers hin.
fc_pp_unique_id: string Gibt das erste vom Client im PROXY-Protokoll-Header gesendete Unique-ID-TLV zurück, sofern vorhanden.
fc_rcvd_proxy: boolean Gibt true zurück, wenn der Client die Verbindung mit einem PROXY-Protokoll-Header begonnen hat.
fc_reordering: integer Handelt es sich bei der Verbindung weder um TCP noch um QUIC, schlägt der Sample-Abruf fehl. Bei QUIC wird die Anzahl umgeordneter QUIC-Pakete der Client-Verbindung zurückgegeben. Bei TCP wird der vom Kernel für die Client-Verbindung gemessene reordering-Zähler zurückgegeben. Ist die Serververbindung nicht hergestellt oder unterstützt das Betriebssystem TCP_INFO nicht, beispielsweise bei Linux-Kernels vor 2.4, schlägt der Sample-Abruf fehl.
fc_retrans: integer Gibt den vom Kernel für die Client-Verbindung gemessenen retransmits-Zähler zurück. Ist die Serververbindung nicht hergestellt, handelt es sich nicht um TCP oder unterstützt das Betriebssystem TCP_INFO nicht, beispielsweise bei Linux-Kernels vor 2.4, schlägt der Sample-Abruf fehl.
fc_rtt(<unit>): integer
Handelt es sich bei der Verbindung weder um TCP noch um QUIC, schlägt der Sample-Abruf fehl. Bei QUIC wird die geglättete Round Trip Time der Client-Verbindung zurückgegeben. Bei TCP wird die vom Kernel für die Client-Verbindung gemessene Round Trip Time (RTT) zurückgegeben. <unit> ist optional; die Standardeinheit ist Millisekunden. <unit> kann auf “ms” für Millisekunden oder “us” für Mikrosekunden gesetzt werden. Ist die Serververbindung nicht hergestellt oder unterstützt das Betriebssystem TCP_INFO nicht, beispielsweise bei Linux-Kernels vor 2.4, schlägt der Sample-Abruf fehl.
fc_rttvar(<unit>): integer
Handelt es sich bei der Verbindung weder um TCP noch um QUIC, schlägt der Sample-Abruf fehl. Bei QUIC wird die Varianz der geglätteten Round Trip Time der Client-Verbindung zurückgegeben. Bei TCP wird die vom Kernel für die Client-Verbindung gemessene Varianz der Round Trip Time (RTT) zurückgegeben. <unit> ist optional; die Standardeinheit ist Millisekunden. <unit> kann auf “ms” für Millisekunden oder “us” für Mikrosekunden gesetzt werden. Ist die Serververbindung nicht hergestellt oder unterstützt das Betriebssystem TCP_INFO nicht, beispielsweise bei Linux-Kernels vor 2.4, schlägt der Sample-Abruf fehl.
fc_sacked: integer Gibt den vom Kernel für die Client-Verbindung gemessenen sacked-Zähler zurück. Ist die Serververbindung nicht hergestellt, handelt es sich nicht um TCP oder unterstützt das Betriebssystem TCP_INFO nicht, beispielsweise bei Linux-Kernels vor 2.4, schlägt der Sample-Abruf fehl.
fc_saved_syn: binary Gibt eine Kopie des gespeicherten SYN-Pakets zurück, das das System beim Aufbau der eingehenden Verbindung aufbewahrt hat. Dies erfordert die Option “tcp-ss” in der “bind”-Zeile sowie mindestens Linux-Kernel 4.3. Ist “tcp-ss” auf 1 gesetzt, sind nur die IP- und TCP-Header enthalten. Bei “tcp-ss” gleich 2 steht zusätzlich der Ethernet-Header vor dem IP-Header. Damit lassen sich beispielsweise die Quell-MAC-Adresse oder VLANs prüfen oder protokollieren. Es ist nicht garantiert, dass ein SYN gespeichert wird. Werden etwa SYN-Cookies verwendet, wird das SYN-Paket nicht aufbewahrt; die Verbindung wird stattdessen anhand des passenden ACK-Pakets hergestellt. Außerdem garantiert das System nicht, die Kopie über den ersten Lesezugriff hinaus aufzubewahren. Es wird daher dringend empfohlen, sie in einer Regel “tcp-request connection” in eine Variable im Gültigkeitsbereich “sess” zu kopieren und für weitere Verarbeitung ausschließlich diese Variable zu verwenden. Auf der Loopback-Schnittstelle erzeugt das System einen künstlichen Ethernet-Header mit 14 Bytes, in dem Quell- und Zieladresse null sind und nur das Protokoll gesetzt ist. Zur Fehlersuche ist es praktisch, solche Samples mit dem Konverter “hex” in die hexadezimale Darstellung umzuwandeln. Beispiel (Felder unten manuell getrennt und kommentiert):
Der Konverter “bytes()” hilft beim Extrahieren bestimmter Felder aus dem Paket. Mit be2dec() lassen sich auch Abschnitte lesen und als Ganzzahlen ausgeben. Für eine genauere Extraktion siehe die Konverter “eth.XXX”.
Beispiel mit IPv4-Eingabe:
Siehe auch die “set-var”-Aktion, die “be2dec”, “bytes”, “hex”, “eth.XXX”, “ip.XXX” und “tcp.XXX”-Konverter.
fc_settings_streams_limit: integer Gibt die maximale Anzahl von Streams zurück, die auf der Frontend-Verbindung zulässig sind. Bei TCP- und HTTP/1.1-Verbindungen ist dieser Wert stets 1. Bei anderen Protokollen hängt er von den mit dem Client vereinbarten Einstellungen ab.
fc_src: ip Dies ist die ursprüngliche Quell-IP-Adresse der Verbindung auf der Client-Seite. Nur Regeln vom Typ “tcp-request connection” können diese Adresse ändern. Weitere Details siehe “src”.
fc_src_is_local: boolean Gibt true zurück, wenn die Quelladresse der eingehenden Verbindung lokal zum System ist, oder false, wenn die Adresse nicht auf dem System existiert. Weitere Details siehe “src_is_local”.
fc_src_port: integer Gibt einen Ganzzahlwert zurück, der dem TCP-Quellport der Verbindung auf der Client-Seite entspricht. Nur Regeln vom Typ “tcp-request connection” können diese Adresse ändern. Weitere Details siehe “src-port”.
fc_unacked: integer Gibt den vom Kernel für die Client-Verbindung gemessenen unacked-Zähler zurück. Wenn die Server-Verbindung nicht hergestellt ist, wenn die Verbindung kein TCP ist oder wenn das Betriebssystem TCP_INFO nicht unterstützt, beispielsweise Linux-Kerne vor 2.4, schlägt der Sample-Abruf fehl.
fe_client_timeout: integer Gibt den Konfigurationswert in Millisekunden für den Client-Timeout des aktuellen Frontends zurück. Dieser Timeout kann durch eine “set-timeout”-Regel überschrieben werden.
fe_defbe: string Gibt eine Zeichenkette zurück, die den Namen des Standard-Backends des Frontends enthält. Sie kann in Frontends verwendet werden, um zu überprüfen, welches Backend Anfragen standardmäßig behandelt.
fe_id: integer Gibt einen Ganzzahlwert zurück, der die ID des aktuellen Frontends enthält. Er kann in Backends verwendet werden, um zu überprüfen, von welchem Frontend aus aufgerufen wurde, oder um alle Benutzer, die über dasselbe Frontend kommen, an denselben Server zu binden.
fe_name: string Gibt eine Zeichenkette zurück, die den Namen des aktuellen Frontends enthält. Sie kann in Backends verwendet werden, um zu überprüfen, von welchem Frontend aus aufgerufen wurde, oder um alle Benutzer, die über dasselbe Frontend kommen, an denselben Server zu binden.
fe_tarpit_timeout: integer Gibt den Konfigurationswert in Millisekunden für den Tarpit-Timeout des aktuellen Frontends zurück. Dieser Timeout kann durch eine “set-timeout”-Regel überschrieben werden.
req.bytes_in: integer Gibt die Anzahl der vom Client empfangenen Bytes zurück. Der Wert entspricht dem, was von HAProxy empfangen wurde, einschließlich einiger Header und eines gewissen internen Kodierungsaufwands. Anfragekompression beeinflusst den hier gemeldeten Wert nicht.
req.bytes_out: integer Gibt die Anzahl der an den Server gesendeten Bytes zurück. Der Wert entspricht dem, was von HAProxy gesendet wurde, einschließlich einiger Header und eines gewissen internen Kodierungsaufwands. Anfragekompression beeinflusst den hier gemeldeten Wert.
res.bytes_in: integer Gibt die Anzahl der vom Server empfangenen Bytes zurück. Der Wert entspricht dem, was von HAProxy empfangen wurde, einschließlich einiger Header und eines gewissen internen Kodierungsaufwands. Antwortkompression beeinflusst den hier gemeldeten Wert nicht.
res.bytes_out: integer Gibt die Anzahl der an den Client gesendeten Bytes zurück. Der Wert entspricht dem, was von HAProxy gesendet wurde, einschließlich einiger Header und eines gewissen internen Kodierungsaufwands. Antwortkompression beeinflusst den hier gemeldeten Wert.
res.timer.data: integer Gibt die gesamte Übertragungszeit der Antwortnutzlast bis zum Senden des letzten Bytes an den Client zurück. Bei HTTP beginnt dies nach dem letzten Antwort-Header (nach Tr). Dies entspricht %Td im Log-Format und wird in Millisekunden (ms) angegeben. Weitere Informationen siehe Abschnitt 8.4 „Zeitereignisse“
sc_bytes_in_rate(<ctr>[,<table>]): integer
Gibt die durchschnittliche Byterate vom Client zum Server aus den aktuell verfolgten Zählern zurück, gemessen in Bytes über den in der Tabelle konfigurierten Zeitraum. Siehe auch “table_bytes_in_rate”.
sc_bytes_out_rate(<ctr>[,<table>]): integer
Gibt die durchschnittliche Byterate vom Server zum Client aus den aktuell verfolgten Zählern zurück, gemessen in Bytes über den in der Tabelle konfigurierten Zeitraum. Siehe auch “table_bytes_out_rate”.
sc_clr_gpc(<idx>,<ctr>[,<table>]): integer
Setzt den Allzweckzähler am Index <idx> des Arrays zurück, das dem angegebenen verfolgten Zähler mit der ID <ctr> in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table <table> zugeordnet ist, und gibt seinen vorherigen Wert zurück. <idx> ist eine Ganzzahl zwischen 0 und 99 und <ctr> eine Ganzzahl zwischen 0 und 2. Vor dem ersten Aufruf ist der gespeicherte Wert null; der erste Aufruf gibt daher stets null zurück. Dieser Abruf gilt nur für den Array-data_type ‘gpc’, nicht für die älteren data_types ‘gpc0’ oder ‘gpc1’.
sc_clr_gpc0(<ctr>[,<table>]): integer
Setzt den ersten Allzweckzähler zurück, der den aktuell verfolgten Zählern zugeordnet ist, und gibt seinen vorherigen Wert zurück. Vor der ersten Ausführung ist der gespeicherte Wert null, sodass die erste Ausführung stets null zurückgibt. Dies wird typischerweise als zweite ACL in einem Ausdruck verwendet, um eine Verbindung zu markieren, wenn eine erste ACL zutraf:
Beispiel:
sc_clr_gpc1(<ctr>[,<table>]): integer
Setzt den zweiten Allzweckzähler zurück, der den aktuell verfolgten Zählern zugeordnet ist, und gibt seinen vorherigen Wert zurück. Vor der ersten Ausführung ist der gespeicherte Wert null, sodass die erste Ausführung stets null zurückgibt. Dies wird typischerweise als zweite ACL in einem Ausdruck verwendet, um eine Verbindung zu markieren, wenn eine erste ACL zutraf.
sc_conn_cnt(<ctr>[,<table>]): integer
Gibt die kumulierte Anzahl eingehender Verbindungen aus den derzeit verfolgten Zählern zurück. Siehe auch “table_conn_cnt”.
sc_conn_cur(<ctr>[,<table>]): integer
Gibt die aktuelle Anzahl gleichzeitiger Verbindungen zurück, die die gleichen verfolgten Zähler verfolgen. Diese Zahl wird automatisch erhöht, wenn die Verfolgung beginnt, und verringert, wenn die Verfolgung beendet wird. Siehe auch “table_conn_cur”.
sc_conn_rate(<ctr>[,<table>]): integer
Gibt die durchschnittliche Verbindungsrate aus den derzeit verfolgten Zählern zurück, gemessen in Anzahl von Verbindungen über den in der Tabelle konfigurierten Zeitraum. Siehe auch “table_conn_rate”.
sc_get_gpc(<idx>,<ctr>[,<table>]): integer
Gibt den Wert des Allzweckzählers am Index <idx> im GPC-Array zurück, das dem derzeit verfolgten Zähler mit der ID <ctr> in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table <table> zugeordnet ist. <idx> ist eine Ganzzahl zwischen 0 und 99 und <ctr> eine Ganzzahl zwischen 0 und 2. Ist an diesem Index kein gpc gespeichert, wird null zurückgegeben. Dieser Abruf gilt nur für den Array-data_type ‘gpc’, nicht für die älteren data_types ‘gpc0’ oder ‘gpc1’. Siehe auch “table_gpc” und “sc_inc_gpc”.
sc_get_gpc0(<ctr>[,<table>]): integer
Gibt den Wert des ersten Allzweckzählers zurück, der den derzeit verfolgten Zählern zugeordnet ist. Siehe auch “table_gpc0” und sc/sc0/sc1/sc2_inc_gpc0.
sc_get_gpc1(<ctr>[,<table>]): integer
Gibt den Wert des zweiten Allzweckzählers zurück, der den derzeit verfolgten Zählern zugeordnet ist. Siehe auch “table_gpc1” und sc/sc0/sc1/sc2_inc_gpc1.
sc_get_gpt(<idx>,<ctr>[,<table>]): integer
Gibt den Wert des ersten Allzweck-Tags am Index <idx> des Arrays zurück, das dem verfolgten Zähler mit der ID <ctr> in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table <table> zugeordnet ist. <idx> ist eine Ganzzahl zwischen 0 und 99 und <ctr> eine Ganzzahl zwischen 0 und
2. Ist an diesem Index kein GPT gespeichert, wird null zurückgegeben. Dieser Abruf gilt nur für den Array-data_type ‘gpt’, nicht für den älteren data-type ‘gpt0’. Siehe auch “table_gpt”.
sc_get_gpt0(<ctr>[,<table>]): integer
Gibt den Wert des ersten Allzweck-Tags zurück, der den derzeit verfolgten Zählern zugeordnet ist. Siehe auch “table_gpt0”.
sc_glitch_cnt(<ctr>[,<table>]): integer
Gibt die kumulierte Anzahl an Störungen der Frontend-Verbindung zurück, die bei Verbindungen beobachtet wurden, die den derzeit verfolgten Zählern zugeordnet sind. Diese Störungen führen in der Regel dazu, dass Anfragen oder Verbindungen abgebrochen werden, sodass der zurückgegebene Wert oft auf vergangene Verbindungen verweist. Es gibt keinen guten oder schlechten Wert, doch ein fehleranfälliger Client kann gelegentlich einige Störungen pro Verbindung verursachen, während ein sehr fehlerhafter oder böswilliger Client schnell Tausende Ereignisse pro Verbindung verursachen kann. Siehe auch fc_glitches für die Anzahl, die die aktuelle Verbindung betrifft, src_glitch_cnt zum Nachschlagen pro Quelle und sc_glitch_rate für die Ereignisratenmessung.
sc_glitch_rate(<ctr>[,<table>]): integer
Gibt die durchschnittliche Rate zurück, mit der Störungen der Frontend-Verbindung für die derzeit verfolgten Zähler beobachtet wurden, gemessen in Anzahl von Ereignissen über den in der Tabelle konfigurierten Zeitraum. Diese Störungen führen in der Regel dazu, dass Anfragen oder Verbindungen abgebrochen werden, sodass der zurückgegebene Wert oft mit vergangenen Verbindungen verknüpft ist. Es gibt keinen guten oder schlechten Wert, doch ein fehleranfälliger Client kann gelegentlich einige Störungen pro Verbindung verursachen, weshalb eine niedrige Rate im Allgemeinen erwartet wird. Ein sehr fehlerhafter oder böswilliger Client kann jedoch schnell Tausende Ereignisse pro Verbindung verursachen und eine hohe Rate aufrechterhalten. Siehe auch “table_glitch_rate” und “sc_glitch_cnt”.
sc_gpc_rate(<idx>,<ctr>[,<table>]): integer
Gibt die durchschnittliche Erhöhungsrate des Allzweckzählers am Index <idx> des Arrays zurück, das dem verfolgten Zähler mit der ID <ctr> in der Tabelle des aktuellen Proxys oder in der angegebenen Stick Table <table> zugeordnet ist. Gibt die Häufigkeit an, mit der der Zähler gpc über den konfigurierten Zeitraum erhöht wurde. <idx> ist eine Ganzzahl zwischen 0 und 99 und <ctr> eine Ganzzahl zwischen 0 und 2. Das Zählerarray ‘gpc_rate’ muss in der Stick Table gespeichert sein, damit ein Wert zurückgegeben wird, da ‘gpc’ nur die Ereignisanzahl enthält. Dieser Abruf gilt nur für den Array-data_type ‘gpc_rate’, nicht für die älteren data_types ‘gpc0_rate’ oder ‘gpc1_rate’. Siehe auch “table_gpc_rate”, “sc_get_gpc” und “sc_inc_gpc”.
sc_gpc0_rate(<ctr>[,<table>]): integer
Gibt die durchschnittliche Inkrementrate des ersten Allzweckzählers zurück, der den derzeit verfolgten Zählern zugeordnet ist. Es wird die Häufigkeit zurückgegeben, mit der der Zähler gpc0 im konfigurierten Zeitraum inkrementiert wurde. Siehe auch src_gpc0_rate, sc/sc0/sc1/sc2_get_gpc0, und sc/sc0/sc1/sc2_inc_gpc0. Beachten Sie, dass der Zähler “gpc0_rate” in der Stick Table gespeichert sein muss, damit ein Wert zurückgegeben wird, da “gpc0” nur die Ereignisanzahl speichert.
sc_gpc1_rate(<ctr>[,<table>]): integer
Gibt die durchschnittliche Inkrementrate des zweiten Allzweckzählers zurück, der den derzeit verfolgten Zählern zugeordnet ist. Es wird die Häufigkeit zurückgegeben, mit der der Zähler gpc1 im konfigurierten Zeitraum inkrementiert wurde. Siehe auch src_gpc1_rate, sc/sc0/sc1/sc2_get_gpc1, und sc/sc0/sc1/sc2_inc_gpc1. Beachten Sie, dass der Zähler “gpc1_rate” in der Stick Table gespeichert sein muss, damit ein Wert zurückgegeben wird, da “gpc1” nur die Ereignisanzahl speichert.
sc_http_err_cnt(<ctr>[,<table>]): integer
Gibt die kumulierte Anzahl von HTTP-Fehlern aus den derzeit verfolgten Zählern zurück. Dazu gehören sowohl Anfragefehler als auch 4xx-Fehlerantworten. Siehe auch “table_http_err_cnt”.
sc_http_err_rate(<ctr>[,<table>]): integer
Gibt die durchschnittliche Rate von HTTP-Fehlern aus den aktuell verfolgten Zählern zurück, gemessen als Anzahl von Fehlern über den in der Tabelle konfigurierten Zeitraum. Dazu zählen sowohl Anfragefehler als auch 4xx-Fehlerantworten. Siehe auch src_http_err_rate.
sc_http_fail_cnt(<ctr>[,<table>]): integer
Gibt die kumulierte Anzahl fehlgeschlagener HTTP-Antworten aus den aktuell verfolgten Zählern zurück. Dazu zählen sowohl Antwortfehler als auch 5xx-Statuscodes, die nicht 501 oder 505 sind. Siehe auch “table_http_fail_cnt”.
sc_http_fail_rate(<ctr>[,<table>]): integer
Gibt die durchschnittliche Rate fehlgeschlagener HTTP-Antworten aus den aktuell verfolgten Zählern zurück, gemessen als Anzahl von Fehlern über den in der Tabelle konfigurierten Zeitraum. Dazu zählen sowohl Antwortfehler als auch 5xx-Statuscodes, die nicht 501 oder 505 sind. Siehe auch “table_http_fail_rate”.
sc_http_req_cnt(<ctr>[,<table>]): integer
Gibt die kumulierte Anzahl von HTTP-Anfragen aus den aktuell verfolgten Zählern zurück. Dazu zählen alle gestarteten Anfragen, unabhängig davon, ob sie gültig waren. Siehe auch src_http_req_cnt.
sc_http_req_rate(<ctr>[,<table>]): integer
Gibt die durchschnittliche Rate von HTTP-Anfragen aus den aktuell verfolgten Zählern zurück, gemessen als Anzahl von Anfragen über den in der Tabelle konfigurierten Zeitraum. Dazu zählen alle gestarteten Anfragen, unabhängig davon, ob sie gültig waren. Siehe auch src_http_req_rate.
sc_inc_gpc(<idx>,<ctr>[,<table>]): integer
Erhöht den Allzweckzähler am Index <idx> des Arrays, das dem angegebenen verfolgten Zähler mit der ID <ctr> aus der Stick Table des aktuellen Proxys oder aus der angegebenen Stick Table <table> zugeordnet ist, und gibt seinen neuen Wert zurück. <idx> ist eine Ganzzahl zwischen 0 und 99 und <ctr> eine Ganzzahl zwischen 0 und 2. Vor dem ersten Aufruf ist der gespeicherte Wert null; der erste Aufruf erhöht ihn daher auf 1 und gibt 1 zurück. Dieser Abruf gilt nur für den Array-data_type ‘gpc’, nicht für die älteren data_types ‘gpc0’ oder ‘gpc1’.
sc_inc_gpc0(<ctr>[,<table>]): integer
Erhöht den ersten Allzweckzähler, der den aktuell verfolgten Zählern zugeordnet ist, und gibt seinen neuen Wert zurück. Vor dem ersten Aufruf ist der gespeicherte Wert null; der erste Aufruf erhöht ihn daher auf 1 und gibt 1 zurück. Dies wird typischerweise als zweite ACL in einem Ausdruck verwendet, um eine Verbindung zu markieren, wenn eine erste ACL zutraf:
Beispiel:
sc_inc_gpc1(<ctr>[,<table>]): integer
Erhöht den zweiten Allzweckzähler, der den aktuell verfolgten Zählern zugeordnet ist, und gibt seinen neuen Wert zurück. Vor dem ersten Aufruf ist der gespeicherte Wert null; der erste Aufruf erhöht ihn daher auf 1 und gibt 1 zurück. Dies wird typischerweise als zweite ACL in einem Ausdruck verwendet, um eine Verbindung zu markieren, wenn eine erste ACL zutraf.
sc_kbytes_in(<ctr>[,<table>]): integer
Gibt die Gesamtmenge an Client-zu-Server-Daten aus den aktuell verfolgten Zählern zurück, gemessen in Kilobyte. Der Test wird derzeit auf 32-Bit-Ganzzahlen durchgeführt, was Werte auf 4 Terabyte begrenzt. Siehe auch “table_kbytes_in”.
sc_kbytes_out(<ctr>[,<table>]): integer
Gibt die Gesamtmenge an Server-zu-Client-Daten aus den aktuell verfolgten Zählern zurück, gemessen in Kilobyte. Der Test wird derzeit auf 32-Bit-Ganzzahlen durchgeführt, was Werte auf 4 Terabyte begrenzt. Siehe auch “table_kbytes_out”.
sc_key(<ctr>): any sc0_key: any sc1_key: any sc2_key: any Gibt den Schlüssel zurück, der zum Musterabgleich des aktuell verfolgten Zählers verwendet wird.
sc_sess_cnt(<ctr>[,<table>]): integer
Gibt aus den aktuell verfolgten Zählern die kumulierte Anzahl eingehender Verbindungen zurück, die in Sitzungen umgewandelt wurden, also von einer Regel “tcp-request connection” akzeptiert wurden. Ein Backend kann mehr Sitzungen als Verbindungen zählen, da jede Verbindung bei Verwendung von HTTP-Keep-Alive auf der Verbindung zum Client zu mehreren Backend-Sitzungen führen kann. Siehe auch “table_sess_cnt”.
sc_sess_rate(<ctr>[,<table>]): integer
Gibt die durchschnittliche Sitzungsrate aus den aktuell verfolgten Zählern zurück, gemessen als Anzahl von Sitzungen über den in der Tabelle konfigurierten Zeitraum. Eine Sitzung ist eine Verbindung, die die frühen “tcp-request connection”-Regeln erfolgreich überstanden hat. Ein Backend kann mehr Sitzungen als Verbindungen zählen, da jede Verbindung bei Verwendung von HTTP-Keep-Alive auf der Verbindung zum Client mehrere Backend-Sitzungen erzeugen kann. Siehe auch “table_sess_rate”.
sc_tracked(<ctr>[,<table>]): boolean
Gibt true zurück, wenn der angegebene Sitzungszähler derzeit von der aktuellen Sitzung verfolgt wird. Dies kann nützlich sein, um zu entscheiden, ob bestimmte Werte in einem Header, der an den Server übergeben wird, gesetzt werden sollen.
sc_trackers(<ctr>[,<table>]): integer
Gibt die aktuelle Anzahl gleichzeitiger Verbindungen zurück, die dieselben Zähler verfolgen. Diese Anzahl wird beim Beginn des Trackings automatisch erhöht und beim Ende verringert. Anders als sc0_conn_cur beruht dies nicht auf gespeicherten Informationen, sondern auf dem Referenzzähler der Tabelle (dem Wert “use”, den “show table” auf der CLI zurückgibt). Dies kann für das Tracking auf layer7 manchmal besser geeignet sein. So lässt sich einem Server beispielsweise mitteilen, wie viele gleichzeitige Verbindungen von einer bestimmten Adresse bestehen.
so_id: integer Gibt eine Ganzzahl mit der ID des aktuellen lauschenden Sockets zurück. Dies ist in Frontends mit vielen “bind”-Zeilen nützlich oder um alle Benutzer, die über denselben Socket kommen, an denselben Server zu binden.
so_name: string Gibt eine Zeichenkette mit dem Namen des aktuellen lauschenden Sockets zurück, wie er mit name in einer “bind”-Zeile definiert ist. Dies kann denselben Zwecken wie so_id dienen, verwendet aber Zeichenketten statt Ganzzahlen.
src: ip Die Quell-IP-Adresse des Clients der Sitzung. Beliebige tcp/http-Regeln können diese Adresse ändern. Sie hat den Typ IP und funktioniert sowohl mit IPv4- als auch mit IPv6-Tabellen. In IPv6-Tabellen werden IPv4-Adressen gemäß RFC 4291 auf ihre IPv6-Entsprechung abgebildet. Verwendet wird die Quelladresse auf TCP-Ebene und nicht die Adresse eines Clients hinter einem Proxy. Wird jedoch die bind-Direktive “accept-proxy” oder “accept-netscaler-cip” verwendet, kann dies die Adresse eines Clients hinter einer anderen mit dem PROXY-Protokoll kompatiblen Komponente sein. Dies gilt für alle Regelsätze außer “tcp-request connection”, der die tatsächliche Adresse sieht. Hat die eingehende Verbindung eine Adressübersetzung oder Umleitung mit Verbindungsverfolgung durchlaufen, wird die ursprüngliche Zieladresse vor der Umleitung gemeldet. Auf Linux-Systemen können Quelle und Ziel in seltenen Fällen vertauscht erscheinen, wenn der sysctl-Wert nf_conntrack_tcp_loose gesetzt ist: Eine verspätete Antwort kann eine abgelaufene Verbindung erneut öffnen und dabei vertauschen, was als Quelle und Ziel angesehen wird.
Beispiel:
src_bytes_in_rate([<table>]): integer
Entspricht dem Konverter “table_bytes_in_rate”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_bytes_in_rate([<table>])
src_bytes_out_rate([<table>]): integer
Entspricht dem Konverter “table_bytes_out_rate”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_bytes_out_rate([<table>])
src_clr_gpc(<idx>[,<table>]): integer
Entspricht dem Konverter “table_clr_gpc”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_clr_gpc(<idx>[,<table>])
src_clr_gpc0([<table>]): integer
Entspricht dem Konverter “table_clr_gpc0”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_clr_gpc0([<table>])
src_clr_gpc1([<table>]): integer
Entspricht dem Konverter “table_clr_gpc1”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_clr_gpc1([<table>])
src_conn_cnt([<table>]): integer
Entspricht dem Konverter “table_conn_cnt”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_conn_cnt([<table>])
src_conn_cur([<table>]): integer
Entspricht dem Konverter “table_conn_cur”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_conn_cur([<table>])
src_conn_rate([<table>]): integer
Entspricht dem Konverter “table_conn_rate”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_conn_rate([<table>])
src_get_gpc(<idx>[,<table>]): integer
Entspricht dem Konverter “table_gpc”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_gpc(<idx>[,<table>])
src_get_gpc0([<table>]): integer
Entspricht dem Konverter “table_gpc0”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_gpc0([<table>])
src_get_gpc1([<table>]): integer
Entspricht dem Konverter “table_gpc1”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_gpc1([<table>])
src_get_gpt(<idx>[,<table>]): integer
Entspricht dem Konverter “table_gpt”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_gpt(<idx>[,<table>])
src_get_gpt0([<table>]): integer
Entspricht dem Konverter “table_gpt0”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_gpt0([<table>])
src_glitch_cnt([<table>]): integer
Entspricht dem Konverter “table_glitch_cnt”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_glitch_cnt([<table>])
src_glitch_rate([<table>]): integer
Entspricht dem Konverter “table_glitch_rate”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_glitch_rate([<table>])
src_gpc_rate(<idx>[,<table>]): integer
Entspricht dem Konverter “table_gpc_rate”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_gpc_rate(<idx>[,<table>])
src_gpc0_rate([<table>]): integer
Entspricht dem Konverter “table_gpc0_rate”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_gpc0_rate([<table>])
src_gpc1_rate([<table>]): integer
Entspricht dem Konverter “table_gpc1_rate”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_gpc1_rate([<table>])
src_http_err_cnt([<table>]): integer
Entspricht dem Konverter “table_http_err_cnt”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_http_err_cnt([<table>])
src_http_err_rate([<table>]): integer
Entspricht dem Konverter “table_http_err_rate”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_http_err_rate([<table>])
src_http_fail_cnt([<table>]): integer
Entspricht dem Konverter “table_http_fail_cnt”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_http_fail_cnt([<table>])
src_http_fail_rate([<table>]): integer
Entspricht dem Konverter “table_http_fail_rate”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_http_fail_rate([<table>])
src_http_req_cnt([<table>]): integer
Entspricht dem Konverter “table_http_req_cnt”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_http_req_cnt([<table>])
src_http_req_rate([<table>]): integer
Entspricht dem Konverter “table_http_req_rate”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_http_req_rate([<table>])
src_inc_gpc(<idx>[,<table>]): integer
Entspricht dem Konverter “src_inc_gpc”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_inc_gpc(<idx>[,<table>])
src_inc_gpc0([<table>]): integer
Entspricht dem Konverter “src_inc_gpc0”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_inc_gpc0([<table>])
src_inc_gpc1([<table>]): integer
Entspricht dem Konverter “src_inc_gpc1”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_inc_gpc1([<table>])
src_is_local: boolean Gibt true zurück, wenn die Quelladresse der eingehenden Verbindung lokal auf dem System liegt, oder false, wenn die Adresse auf dem System nicht vorhanden ist, die Verbindung also von einem entfernten Rechner kommt. UNIX-Adressen gelten als lokal. Damit lassen sich bestimmte Zugriffsbeschränkungen anhand der Herkunft des Clients anwenden, beispielsweise die Forderung nach Authentifizierung oder https für entfernte Rechner. Die Prüfung benötigt einige Systemaufrufe und sollte daher möglichst nur einmal pro Verbindung erfolgen.
src_kbytes_in([<table>]): integer
Entspricht dem Konverter “table_kbytes_in”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_kbytes_in([<table>])
src_kbytes_out([<table>]): integer
Entspricht dem Konverter “table_kbytes_out”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_kbytes_out([<table>])
src_port: integer Gibt eine Ganzzahl zurück, die dem TCP-Quellport der Verbindung auf der Client-Seite entspricht, also dem Port, von dem aus der Client die Verbindung aufgebaut hat. Beliebige tcp/http-Regeln können diese Adresse ändern. Diese Funktion ist nur begrenzt nützlich, da moderne Protokolle Quellports heute kaum berücksichtigen.
src_sess_cnt([<table>]): integer
Entspricht dem Konverter “table_sess_cnt”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_sess_cnt([<table>])
src_sess_rate([<table>]): integer
Entspricht dem Konverter “table_sess_rate”, wobei der Schlüssel auf die Quelladresse der eingehenden Verbindung gesetzt ist.
Entspricht: src,table_sess_rate([<table>])
src_updt_conn_cnt([<table>]): integer
Erstellt oder aktualisiert den der Quelladresse der eingehenden Verbindung zugeordneten Eintrag in der Stick Table des aktuellen Proxys oder in der angegebenen Stick Table. Diese Tabelle muss zum Speichern des Datentyps “conn_cnt” konfiguriert sein, andernfalls wird der Abgleich ignoriert. Der aktuelle Zähler wird um eins erhöht und der Ablaufzeitgeber aufgefrischt. Der aktualisierte Zählerwert wird zurückgegeben; dieser Abgleich kann daher nicht null zurückgeben. Dies wurde verwendet, um Dienstmissbrauch anhand der Quelladresse abzuweisen. Hinweis: Es wird empfohlen, stattdessen die umfassenderen Aktionen “track-sc*” in “tcp-request”-Regeln zu verwenden.
Beispiel:
srv_id: integer Gibt bei der Verarbeitung der Antwort eine Ganzzahl mit der ID des Servers zurück. Obwohl dies fast ausschließlich mit ACLs verwendet wird, ist es auch für die Protokollierung oder Fehlersuche einsetzbar. Kann auch in einem tcp-check- oder http-check-Regelsatz verwendet werden.
srv_name: string Gibt bei der Verarbeitung der Antwort eine Zeichenkette mit dem Namen des Servers zurück. Obwohl dies fast ausschließlich mit ACLs verwendet wird, ist es auch für die Protokollierung oder Fehlersuche einsetzbar. Kann auch in einem tcp-check- oder http-check-Regelsatz verwendet werden.
txn.conn_retries: integer Gibt die Anzahl der Verbindungswiederholungen zurück, die dieser Stream beim Verbindungsaufbau zum Server durchlaufen hat. Der Wert kann sich ändern, solange die Verbindung nicht vollständig hergestellt ist. Bei HTTP-Verbindungen kann der Wert durch L7-Wiederholungen beeinflusst werden.
txn.redispatched: boolean Gibt true zurück, wenn die Verbindung bei einer Wiederholung gemäß der Konfiguration von “option redispatch” einem Redispatch unterzogen wurde. Der Wert kann sich ändern, solange die Verbindung nicht vollständig hergestellt ist. Bei HTTP-Verbindungen kann der Wert durch L7-Wiederholungen beeinflusst werden.
7.3.4. Sample-Abruf auf Schicht 5
Schicht 5 beschreibt üblicherweise nur die Sitzungsschicht, die in HAProxy der Sitzung am nächsten liegt, nachdem alle Verbindungs-Handshakes abgeschlossen sind, aber noch keine Inhalte verfügbar sind. Die hier beschriebenen Abrufmethoden können bereits in den Regelsätzen “tcp-request content” verwendet werden, sofern sie keine erst später verfügbaren Informationen benötigen. Dazu gehören im Allgemeinen die Ergebnisse von SSL-Aushandlungen.
Übersicht über die Sample-Abrufmethoden in diesem Abschnitt und ihre jeweiligen Typen:
Ausführliche Liste:
51d.all(<prop>[,<prop>*]): string
Gibt die Werte der angeforderten Eigenschaften als Zeichenkette zurück. Die Werte werden durch das mit “51degrees-property-separator” angegebene Trennzeichen getrennt. Das Gerät wird anhand aller wichtigen HTTP-Header der Anfrage identifiziert. Der Funktion können bis zu fünf Eigenschaftsnamen übergeben werden. Kann ein Eigenschaftsname nicht gefunden werden, wird der Wert “NoData” zurückgegeben.
Beispiel:
bs.aborted: boolean Gibt true zurück, wenn für den aktuellen Stream ein Abbruch vom Server empfangen wurde. Andernfalls wird false zurückgegeben.
bs.debug_str([<bitmap>]): string
Diese Funktion ist für Entwickler bei bestimmten komplexen Fehlersuchen gedacht. Sie extrahiert interne Zustände aus den unteren Ebenen des Backend-Streams und der Verbindung und ordnet sie als Zeichenkette an, üblicherweise als Folge durch Leerzeichen getrennter “name=value”-Einträge. Das optionale Argument <bitmap> legt fest, aus welchen Ebenen Informationen extrahiert werden, und ist ein arithmetisches OR oder die Summe der folgenden Werte: - Socket-Ebene: 16 - Verbindungsebene: 8 - Transportebene (z. B. SSL): 4 - Mux-Verbindung: 2 - Mux-Stream: 1
Diese Werte können sich zwischen Versionen ändern. Der Standardwert null hat eine besondere Bedeutung und aktiviert alle Ebenen. Verlassen Sie sich für eine langfristige Produktionsüberwachung nicht auf die Ausgabe dieser Funktion. Sie kann sich bei Bedarf an weiteren Details auch innerhalb eines stabilen Zweigs weiterentwickeln. Ein typischer Anwendungsfall besteht darin, diese Informationen zusammen mit fs.debug_str() ganz am Ende eines log-format anzuhängen. Beispiel:
bs.id: integer Gibt die Stream-ID des Multiplexers auf der Server-Seite zurück. Der Multiplexer ist dafür verantwortlich, die passenden Informationen zurückzugeben.
bs.rst_code: integer Gibt den vom Server für den aktuellen Stream empfangenen Reset-Code zurück. Zurückgegeben wird der Code des vom Server empfangenen H2-Frames RST_STREAM oder QUIC-Frames STOP_SENDING. Der Sample-Abruf schlägt fehl, wenn kein Abbruch empfangen wurde oder der Server-Stream kein H2/QUIC-Stream ist.
fs.aborted: boolean Gibt true zurück, wenn für den aktuellen Stream ein Abbruch vom Client empfangen wurde. Andernfalls wird false zurückgegeben.
fs.debug_str([<bitmap>]): string
Diese Funktion ist für Entwickler bei bestimmten komplexen Fehlersuchen gedacht. Sie extrahiert interne Zustände aus den unteren Ebenen des Frontend-Streams und der Verbindung und ordnet sie als Zeichenkette an, üblicherweise als Folge durch Leerzeichen getrennter “name=value”-Einträge. Das optionale Argument <bitmap> legt fest, aus welchen Ebenen Informationen extrahiert werden, und ist ein arithmetisches OR oder die Summe der folgenden Werte: - Socket-Ebene: 16 - Verbindungsebene: 8 - Transportebene (z. B. SSL): 4 - Mux-Verbindung: 2 - Mux-Stream: 1
Diese Werte können sich zwischen Versionen ändern. Der Standardwert null hat eine besondere Bedeutung und aktiviert alle Ebenen. Verlassen Sie sich für eine langfristige Produktionsüberwachung nicht auf die Ausgabe dieser Funktion. Sie kann sich bei Bedarf an weiteren Details auch innerhalb eines stabilen Zweigs weiterentwickeln. Ein typischer Anwendungsfall besteht darin, diese Informationen zusammen mit bs.debug_str() ganz am Ende eines log-format anzuhängen. Beispiel:
fs.id: integer Gibt die Stream-ID des Multiplexers auf der Client-Seite zurück. Der Multiplexer ist dafür verantwortlich, die passenden Informationen zurückzugeben. Bei reinem TCP wird beispielsweise stets 0 zurückgegeben, da kein Stream vorhanden ist.
fs.rst_code: integer Gibt den vom Client für den aktuellen Stream empfangenen Reset-Code zurück. Zurückgegeben wird der Code des vom Client empfangenen H2-Frames RST_STREAM oder QUIC-Frames STOP_SENDING. Der Sample-Abruf schlägt fehl, wenn kein Abbruch empfangen wurde oder der Client-Stream kein H2/QUIC-Stream ist.
ssl_bc: boolean Gibt true zurück, wenn die Backend-Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde und lokal entschlüsselt wird. Das bedeutet, dass die ausgehende Verbindung zu einem Server mit der Option “ssl” hergestellt wurde. Kann in einem tcp-check- oder http-check-Regelsatz verwendet werden.
ssl_bc_alg_keysize: integer Gibt die unterstützte Schlüssellänge des symmetrischen Verschlüsselungsverfahrens in Bits zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Kann in einem tcp-check- oder http-check-Regelsatz verwendet werden.
ssl_bc_alpn: string Extrahiert das Feld Application Layer Protocol Negotiation aus einer ausgehenden Verbindung über eine TLS-Transportschicht. Das Ergebnis ist eine Zeichenkette mit dem mit dem Server ausgehandelten Protokollnamen. Die SSL-Bibliothek muss mit aktivierter Unterstützung für TLS-Erweiterungen gebaut worden sein (mit haproxy -vv prüfen). Die TLS-Erweiterung ALPN wird nur angekündigt, wenn das Schlüsselwort “alpn” in der “server”-Zeile eine Protokollliste festlegt. Der Server ist außerdem nicht gezwungen, ein Protokoll aus dieser Liste zu wählen; ein beliebiges anderes kann angefordert werden. Die TLS-Erweiterung ALPN soll die TLS-Erweiterung NPN ersetzen. Siehe auch “ssl_bc_npn”. Kann in einem tcp-check- oder http-check-Regelsatz verwendet werden.
ssl_bc_cipher: string Gibt den Namen des verwendeten Verschlüsselungsverfahrens zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Kann in einem tcp-check- oder http-check-Regelsatz verwendet werden.
ssl_bc_client_early_traffic_secret: string Gibt CLIENT_EARLY_TRAFFIC_SECRET als hexadezimale Zeichenkette für die Backend-Verbindung zurück, wenn die ausgehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_bc_client_handshake_traffic_secret: string Gibt CLIENT_HANDSHAKE_TRAFFIC_SECRET als hexadezimale Zeichenkette für die Backend-Verbindung zurück, wenn die ausgehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_bc_client_random: binary Gibt den Client-Zufallswert der Backend-Verbindung zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Dies ist zum Entschlüsseln von Verkehr nützlich, der mit Verfahren mit kurzlebigen Schlüsseln gesendet wurde. Erfordert OpenSSL >= 1.1.0 oder BoringSSL. Kann in einem tcp-check- oder http-check-Regelsatz verwendet werden.
ssl_bc_client_traffic_secret_0: string Gibt CLIENT_TRAFFIC_SECRET_0 als hexadezimale Zeichenkette für die Backend-Verbindung zurück, wenn die ausgehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_bc_curve: string Gibt den Namen der beim Schlüsselaustausch verwendeten Kurve zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 3.0.0 oder AWS-LC >= 1.57.0.
ssl_bc_early_exporter_secret: string Gibt EARLY_EXPORTER_SECRET als hexadezimale Zeichenkette für die Backend-Verbindung zurück, wenn die ausgehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_bc_err: integer Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten ausgehenden Verbindung die ID des letzten Fehlers im ersten auf der Backend-Seite aufgetretenen Fehlerstapel zurück. Dies kann Handshake-Fehler sowie andere während der Lebensdauer der Verbindung auftretende Lese- oder Schreibfehler umfassen. Eine Textbeschreibung dieses Fehlercodes erhalten Sie mit dem Sample-Abruf “ssl_bc_err_str” oder dem Befehl “openssl errstr”, der einen Fehlercode in hexadezimaler Darstellung als Parameter erwartet. Die vollständige Liste der Fehlercodes finden Sie in der Dokumentation Ihrer SSL-Bibliothek.
ssl_bc_err_str: string Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten ausgehenden Verbindung eine Zeichenkettendarstellung des letzten Fehlers im ersten Fehlerstapel zurück, der aus Sicht des Backends auf der Verbindung aufgetreten ist. Siehe auch “ssl_fc_err”.
ssl_bc_exporter_secret: string Gibt EXPORTER_SECRET als hexadezimale Zeichenkette für die Backend-Verbindung zurück, wenn die ausgehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_bc_is_resumed: boolean Gibt true zurück, wenn die Backend-Verbindung über eine SSL/TLS-Transportschicht hergestellt und die neu angelegte SSL-Sitzung mithilfe einer zwischengespeicherten Sitzung oder eines TLS-Tickets wiederaufgenommen wurde. Kann in einem tcp-check- oder http-check-Regelsatz verwendet werden.
ssl_bc_npn: string Extrahiert das Feld Next Protocol Negotiation aus einer ausgehenden Verbindung über eine TLS-Transportschicht. Das Ergebnis ist eine Zeichenkette mit dem mit dem Server ausgehandelten Protokollnamen. Die SSL-Bibliothek muss mit aktivierter Unterstützung für TLS-Erweiterungen gebaut worden sein (mit haproxy -vv prüfen). Die TLS-Erweiterung NPN wird nur angekündigt, wenn das Schlüsselwort “npn” in der “server”-Zeile eine Protokollliste festlegt. Der Server ist außerdem nicht gezwungen, ein Protokoll aus dieser Liste zu wählen; jedes andere kann ebenfalls verwendet werden. Die TLS-Erweiterung NPN wurde durch ALPN ersetzt. Kann in einem tcp-check- oder http-check-Regelsatz verwendet werden.
ssl_bc_protocol: string Gibt den Namen des verwendeten Protokolls zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Kann in einem tcp-check- oder http-check-Regelsatz verwendet werden.
ssl_bc_server_handshake_traffic_secret: string Gibt SERVER_HANDSHAKE_TRAFFIC_SECRET als hexadezimale Zeichenkette für die Backend-Verbindung zurück, wenn die ausgehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_bc_server_random: binary Gibt den Server-Zufallswert der Backend-Verbindung zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Dies ist zum Entschlüsseln von Verkehr nützlich, der mit Verfahren mit kurzlebigen Schlüsseln gesendet wurde. Erfordert OpenSSL >= 1.1.0 oder BoringSSL. Kann in einem tcp-check- oder http-check-Regelsatz verwendet werden.
ssl_bc_server_traffic_secret_0: string Gibt SERVER_TRAFFIC_SECRET_0 als hexadezimale Zeichenkette für die Backend-Verbindung zurück, wenn die ausgehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_bc_session_id: binary Gibt die SSL-ID der Backend-Verbindung zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Die Protokollierung ist nützlich, um festzustellen, ob eine Sitzung wiederverwendet wurde. Kann in einem tcp-check- oder http-check-Regelsatz verwendet werden.
ssl_bc_session_key: binary Gibt den SSL-Sitzungs-Master-Schlüssel der Backend-Verbindung zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Dies ist zum Entschlüsseln von Verkehr nützlich, der mit Verfahren mit kurzlebigen Schlüsseln gesendet wurde. Erfordert OpenSSL >= 1.1.0 oder BoringSSL. Kann in einem tcp-check- oder http-check-Regelsatz verwendet werden.
ssl_bc_sni: string Ruft das Feld der TLS-Erweiterung Server Name Indication (SNI) ab, das auf der Verbindung zum Server verwendet wurde. Das Ergebnis ist, sofern vorhanden, typischerweise eine Zeichenkette, die dem HTTPS-Hostnamen entspricht (253 Zeichen oder weniger). Der Hauptanwendungsfall ist die Protokollierung und Fehlersuche, etwa um festzustellen, welches SNI beim Verbindungsaufbau verwendet wurde, und es mit dem vom Server gesehenen Wert abzugleichen.
ssl_bc_unique_id: binary Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten ausgehenden Verbindung die eindeutige TLS-ID gemäß RFC5929 Abschnitt 3 zurück. Die eindeutige ID kann mit dem Konverter “ssl_bc_unique_id,base64” base64-kodiert werden. Kann in einem tcp-check- oder http-check-Regelsatz verwendet werden.
ssl_bc_use_keysize: integer Gibt die verwendete Schlüssellänge des symmetrischen Verschlüsselungsverfahrens in Bits zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Kann in einem tcp-check- oder http-check-Regelsatz verwendet werden.
ssl_c_ca_err: integer Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten eingehenden Verbindung die ID des ersten bei der Prüfung des Client-Zertifikats in einer Tiefe > 0 erkannten Fehlers zurück, oder 0, wenn bei dieser Prüfung kein Fehler auftrat. Die vollständige Liste der Fehlercodes finden Sie in der Dokumentation Ihrer SSL-Bibliothek.
ssl_c_ca_err_depth: integer Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten eingehenden Verbindung die Tiefe in der CA-Kette zurück, in der der erste Fehler bei der Prüfung des Client-Zertifikats erkannt wurde. Trat kein Fehler auf, wird 0 zurückgegeben.
ssl_c_chain_der: binary Gibt die vom Client vorgelegte Zertifikatskette im DER-Format zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Bei Verwendung in einer ACL können die abzugleichenden Werte in hexadezimaler Form angegeben werden. Das Ergebnis lässt sich mit jeder Bibliothek analysieren, die ASN.1-DER-Daten akzeptiert. Wiederaufgenommene Sitzungen werden derzeit nicht unterstützt.
ssl_c_der: binary Gibt das vom Client vorgelegte Zertifikat im DER-Format zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Bei Verwendung in einer ACL können die abzugleichenden Werte in hexadezimaler Form angegeben werden.
ssl_c_err: integer Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten eingehenden Verbindung die ID des ersten bei der Prüfung in Tiefe 0 erkannten Fehlers zurück, oder 0, wenn bei dieser Prüfung kein Fehler auftrat. Die vollständige Liste der Fehlercodes finden Sie in der Dokumentation Ihrer SSL-Bibliothek.
ssl_c_i_dn([<entry>[,<occ>[,<format>]]]): string
Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten eingehenden Verbindung den vollständigen Distinguished Name des Ausstellers des vom Client vorgelegten Zertifikats zurück, wenn kein <entry> angegeben ist. Andernfalls wird der Wert des ersten angegebenen Eintrags vom Anfang des DN aus zurückgegeben. Wird als optionales zweites Argument eine positive oder negative Vorkommensnummer angegeben, wird der Wert des n-ten angegebenen Eintrags vom Anfang bzw. Ende des DN aus zurückgegeben. Beispielsweise liefert “ssl_c_i_dn(OU,2)” die zweite Organisationseinheit und “ssl_c_i_dn(CN)” den Common Name. Mit dem Parameter <format> erhalten Sie den DN in einer für verschiedene Protokolle geeigneten Form. Derzeit wird rfc2253 für LDAP v3 unterstützt. Soll nur das Format geändert werden, können Sie für die ersten beiden Parameter eine leere Zeichenkette und null angeben. Beispiel: ssl_c_i_dn(,0,rfc2253). Enthält der ASN.1-Wert des angeforderten Eintrags (oder, wenn kein <entry> angegeben ist, der Wert eines beliebigen Eintrags im DN) ein eingebettetes NUL-Byte mit darauf folgenden weiteren Daten, gilt er als fehlerhaft und es werden keine Daten zurückgegeben.
ssl_c_key_alg: string Gibt den Namen des Algorithmus zurück, mit dem der Schlüssel des vom Client vorgelegten Zertifikats erzeugt wurde, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_c_notafter: string Gibt das vom Client vorgelegte Enddatum als formatierte Zeichenkette YYMMDDhhmmss[Z] zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_c_notbefore: string Gibt das vom Client vorgelegte Anfangsdatum als formatierte Zeichenkette YYMMDDhhmmss[Z] zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_c_r_dn([<entry>[,<occ>[,<format>]]]): string
Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten und mit der konfigurierten ca-file erfolgreich validierten eingehenden Verbindung den vollständigen Distinguished Name der Root-CA des vom Client vorgelegten Zertifikats zurück, wenn kein <entry> angegeben ist. Andernfalls wird der Wert des ersten angegebenen Eintrags vom Anfang des DN aus zurückgegeben. Wird als optionales zweites Argument eine positive oder negative Vorkommensnummer angegeben, wird der Wert des n-ten angegebenen Eintrags vom Anfang bzw. Ende des DN aus zurückgegeben. Beispielsweise liefert “ssl_c_r_dn(OU,2)” die zweite Organisationseinheit und “ssl_c_r_dn(CN)” den Common Name. Mit dem Parameter <format> erhalten Sie den DN in einer für verschiedene Protokolle geeigneten Form. Derzeit wird rfc2253 für LDAP v3 unterstützt. Soll nur das Format geändert werden, können Sie für die ersten beiden Parameter eine leere Zeichenkette und null angeben. Beispiel: ssl_c_r_dn(,0,rfc2253). Enthält der ASN.1-Wert des angeforderten Eintrags (oder, wenn kein <entry> angegeben ist, der Wert eines beliebigen Eintrags im DN) ein eingebettetes NUL-Byte mit darauf folgenden weiteren Daten, gilt er als fehlerhaft und es werden keine Daten zurückgegeben.
ssl_c_s_dn([<entry>[,<occ>[,<format>]]]): string
Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten eingehenden Verbindung den vollständigen Distinguished Name des Subjekts des vom Client vorgelegten Zertifikats zurück, wenn kein <entry> angegeben ist. Andernfalls wird der Wert des ersten angegebenen Eintrags vom Anfang des DN aus zurückgegeben. Wird als optionales zweites Argument eine positive oder negative Vorkommensnummer angegeben, wird der Wert des n-ten angegebenen Eintrags vom Anfang bzw. Ende des DN aus zurückgegeben. Beispielsweise liefert “ssl_c_s_dn(OU,2)” die zweite Organisationseinheit und “ssl_c_s_dn(CN)” den Common Name. Mit dem Parameter <format> erhalten Sie den DN in einer für verschiedene Protokolle geeigneten Form. Derzeit wird rfc2253 für LDAP v3 unterstützt. Soll nur das Format geändert werden, können Sie für die ersten beiden Parameter eine leere Zeichenkette und null angeben. Beispiel: ssl_c_s_dn(,0,rfc2253). Enthält der ASN.1-Wert des angeforderten Eintrags (oder, wenn kein <entry> angegeben ist, der Wert eines beliebigen Eintrags im DN) ein eingebettetes NUL-Byte mit darauf folgenden weiteren Daten, gilt er als fehlerhaft und es werden keine Daten zurückgegeben.
ssl_c_san: string Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten eingehenden Verbindung mit Client-Zertifikat eine Zeichenkette mit den durch Kommas getrennten Subject-Alt-Name-Feldern des vorgelegten Zertifikats zurück.
Damit lässt sich das Client-Zertifikat untersuchen.
Beispiel:
ergibt:
ssl_c_serial: binary Gibt die Seriennummer des vom Client vorgelegten Zertifikats zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Bei Verwendung in einer ACL können die abzugleichenden Werte in hexadezimaler Form angegeben werden.
ssl_c_sha1: binary Gibt den SHA-1-Fingerabdruck des vom Client vorgelegten Zertifikats zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Damit lässt sich ein Client an einen Server binden oder diese Information an einen Server weitergeben. Die Ausgabe ist binär; zur Weitergabe dieser Signatur an den Server muss sie daher hexadezimal oder mit base64 kodiert werden, wie im folgenden Beispiel:
Beispiel:
ssl_c_sig_alg: string Gibt den Namen des Algorithmus zurück, mit dem das vom Client vorgelegte Zertifikat signiert wurde, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_c_used: boolean Gibt true zurück, wenn die aktuelle SSL-Sitzung ein Client-Zertifikat verwendet, auch wenn die aktuelle Verbindung eine SSL-Sitzungswiederaufnahme nutzt. Siehe auch “ssl_fc_has_crt”.
ssl_c_verify: integer Gibt die Fehler-ID des Prüfergebnisses zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde, andernfalls null, wenn kein Fehler auftritt. Die vollständige Liste der Fehlercodes finden Sie in der Dokumentation Ihrer SSL-Bibliothek.
ssl_c_version: integer Gibt die Version des vom Client vorgelegten Zertifikats zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_f_der: binary Gibt das vom Frontend vorgelegte Zertifikat im DER-Format zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Bei Verwendung in einer ACL können die abzugleichenden Werte in hexadezimaler Form angegeben werden.
ssl_f_i_dn([<entry>[,<occ>[,<format>]]]): string
Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten eingehenden Verbindung den vollständigen Distinguished Name des Ausstellers des vom Frontend vorgelegten Zertifikats zurück, wenn kein <entry> angegeben ist. Andernfalls wird der Wert des ersten angegebenen Eintrags vom Anfang des DN aus zurückgegeben. Wird als optionales zweites Argument eine positive oder negative Vorkommensnummer angegeben, wird der Wert des n-ten angegebenen Eintrags vom Anfang bzw. Ende des DN aus zurückgegeben. Beispielsweise liefert “ssl_f_i_dn(OU,2)” die zweite Organisationseinheit und “ssl_f_i_dn(CN)” den Common Name. Mit dem Parameter <format> erhalten Sie den DN in einer für verschiedene Protokolle geeigneten Form. Derzeit wird rfc2253 für LDAP v3 unterstützt. Soll nur das Format geändert werden, können Sie für die ersten beiden Parameter eine leere Zeichenkette und null angeben. Beispiel: ssl_f_i_dn(,0,rfc2253). Enthält der ASN.1-Wert des angeforderten Eintrags (oder, wenn kein <entry> angegeben ist, der Wert eines beliebigen Eintrags im DN) ein eingebettetes NUL-Byte mit darauf folgenden weiteren Daten, gilt er als fehlerhaft und es werden keine Daten zurückgegeben.
ssl_f_key_alg: string Gibt den Namen des Algorithmus zurück, mit dem der Schlüssel des vom Frontend vorgelegten Zertifikats erzeugt wurde, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_f_notafter: string Gibt das vom Frontend vorgelegte Enddatum als formatierte Zeichenkette YYMMDDhhmmss[Z] zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_f_notbefore: string Gibt das vom Frontend vorgelegte Anfangsdatum als formatierte Zeichenkette YYMMDDhhmmss[Z] zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_f_s_dn([<entry>[,<occ>[,<format>]]]): string
Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten eingehenden Verbindung den vollständigen Distinguished Name des Subjekts des vom Frontend vorgelegten Zertifikats zurück, wenn kein <entry> angegeben ist. Andernfalls wird der Wert des ersten angegebenen Eintrags vom Anfang des DN aus zurückgegeben. Wird als optionales zweites Argument eine positive oder negative Vorkommensnummer angegeben, wird der Wert des n-ten angegebenen Eintrags vom Anfang bzw. Ende des DN aus zurückgegeben. Beispielsweise liefert “ssl_f_s_dn(OU,2)” die zweite Organisationseinheit und “ssl_f_s_dn(CN)” den Common Name. Mit dem Parameter <format> erhalten Sie den DN in einer für verschiedene Protokolle geeigneten Form. Derzeit wird rfc2253 für LDAP v3 unterstützt. Soll nur das Format geändert werden, können Sie für die ersten beiden Parameter eine leere Zeichenkette und null angeben. Beispiel: ssl_f_s_dn(,0,rfc2253). Enthält der ASN.1-Wert des angeforderten Eintrags (oder, wenn kein <entry> angegeben ist, der Wert eines beliebigen Eintrags im DN) ein eingebettetes NUL-Byte mit darauf folgenden weiteren Daten, gilt er als fehlerhaft und es werden keine Daten zurückgegeben.
ssl_f_serial: binary Gibt die Seriennummer des vom Frontend vorgelegten Zertifikats zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Bei Verwendung in einer ACL können die abzugleichenden Werte in hexadezimaler Form angegeben werden.
ssl_f_sha1: binary Gibt den SHA-1-Fingerabdruck des vom Frontend vorgelegten Zertifikats zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Damit lässt sich feststellen, welches Zertifikat mittels SNI ausgewählt wurde.
ssl_f_sig_alg: string Gibt den Namen des Algorithmus zurück, mit dem das vom Frontend vorgelegte Zertifikat signiert wurde, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_f_version: integer Gibt die Version des vom Frontend vorgelegten Zertifikats zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_fc: boolean Gibt true zurück, wenn die Frontend-Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde und lokal entschlüsselt wird. Das bedeutet, dass sie einem Socket entspricht, der mit einer “bind”-Zeile mit der Option “ssl” deklariert wurde.
Beispiel:
ssl_fc_alg_keysize: integer Gibt die unterstützte Schlüssellänge des symmetrischen Verschlüsselungsverfahrens in Bits zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_fc_alpn: string Extrahiert das Feld Application Layer Protocol Negotiation aus einer eingehenden Verbindung über eine TLS-Transportschicht, die HAProxy lokal entschlüsselt. Das Ergebnis ist eine Zeichenkette mit dem vom Client angekündigten Protokollnamen. Die SSL-Bibliothek muss mit aktivierter Unterstützung für TLS-Erweiterungen gebaut worden sein (mit haproxy -vv prüfen). Die TLS-Erweiterung ALPN wird nur angekündigt, wenn das Schlüsselwort “alpn” in der “bind”-Zeile eine Protokollliste festlegt. Der Client ist außerdem nicht gezwungen, ein Protokoll aus dieser Liste zu wählen; ein beliebiges anderes kann angefordert werden. Die TLS-Erweiterung ALPN soll die TLS-Erweiterung NPN ersetzen. Siehe auch “ssl_fc_npn”.
ssl_fc_cipher: string Gibt den Namen des verwendeten Verschlüsselungsverfahrens zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_fc_cipherlist_bin([<filter_option>]): binary
Gibt die binäre Form der Verschlüsselungsverfahrensliste aus dem ClientHello zurück. Die maximale Länge des Rückgabewerts wird durch die Größe des gemeinsamen Erfassungspuffers begrenzt, die mit “tune.ssl.capture-buffer-size” gesteuert wird. Mit <filter_option> lassen sich die zurückgegebenen Daten filtern. Zulässige Werte:
Beispiel:
ssl_fc_cipherlist_hex([<filter_option>]): string
Gibt die binäre Form der Verschlüsselungsverfahrensliste aus dem ClientHello hexadezimal kodiert zurück. Die maximale Länge des Rückgabewerts wird durch die Größe des gemeinsamen Erfassungspuffers begrenzt, die mit “tune.ssl.capture-buffer-size” gesteuert wird. Mit <filter_option> lassen sich die zurückgegebenen Daten filtern. Zulässige Werte:
ssl_fc_cipherlist_str([<filter_option>]): string
Gibt die dekodierte Textform der Verschlüsselungsverfahrensliste aus dem ClientHello zurück. Die maximale Länge des Rückgabewerts wird durch die Größe des gemeinsamen Erfassungspuffers begrenzt, die mit “tune.ssl.capture-buffer-size” gesteuert wird. Mit <filter_option> lassen sich die zurückgegebenen Daten filtern. Zulässige Werte:
Dieser Sample-Abruf ist nur mit OpenSSL >= 1.0.2 verfügbar. Ist die Funktion nicht aktiviert, gibt dieser Sample-Abruf wie “ssl_fc_cipherlist_xxh” den Hash zurück.
ssl_fc_cipherlist_xxh: integer Gibt einen xxh64-Hash der Verschlüsselungsverfahrensliste zurück. Dieser Hash kann nur zurückgegeben werden, wenn “tune.ssl.capture-buffer-size” größer als 0 ist. Der Hash berücksichtigt dennoch sämtliche Daten der Verschlüsselungsverfahrensliste.
ssl_fc_client_early_traffic_secret: string Gibt CLIENT_EARLY_TRAFFIC_SECRET als hexadezimale Zeichenkette für die Frontend-Verbindung zurück, wenn die eingehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_fc_client_handshake_traffic_secret: string Gibt CLIENT_HANDSHAKE_TRAFFIC_SECRET als hexadezimale Zeichenkette für die Frontend-Verbindung zurück, wenn die eingehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_fc_client_random: binary Gibt den Client-Zufallswert der Frontend-Verbindung zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Dies ist zum Entschlüsseln von Verkehr nützlich, der mit Verfahren mit kurzlebigen Schlüsseln gesendet wurde. Erfordert OpenSSL >= 1.1.0 oder BoringSSL.
ssl_fc_client_traffic_secret_0: string Gibt CLIENT_TRAFFIC_SECRET_0 als hexadezimale Zeichenkette für die Frontend-Verbindung zurück, wenn die eingehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_fc_crtname: string Gibt den Namen des Zertifikats zurück, das für die eingehende SSL/TLS-Verbindung ausgewählt wurde. Dies ist der Name, wie er in “show ssl cert” erscheint: je nach Deklaration des Zertifikats in der Konfiguration ein Dateiname mit relativem oder absolutem Pfad oder ein Alias.
Beispiel:
ssl_fc_curve: string Gibt den Namen der beim Schlüsselaustausch verwendeten Kurve zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 3.0.0.
ssl_fc_early_rcvd: boolean Gibt true zurück, wenn auf dieser Verbindung frühzeitige Daten empfangen wurden, unabhängig davon, ob der Handshake inzwischen abgeschlossen ist. Für die Verkehrsverarbeitung hat dies keinen praktischen Anwendungsfall, ist aber praktisch die einzige Möglichkeit, zu erkennen, dass ein Client 0-RTT zum Senden frühzeitiger Daten verwendet hat. Das kann bei der Fehlersuche nützlich sein, da die einzigen Alternativen Netzwerkmitschnitte oder das Protokollieren der Flags der Frontend-Verbindung und deren Abgleich mit dem Code sind. Auch zum Erfassen von Statistiken über Client-Fähigkeiten kann dies nützlich sein. Siehe auch “ssl_fc_has_early”.
ssl_fc_early_exporter_secret: string Gibt EARLY_EXPORTER_SECRET als hexadezimale Zeichenkette für die Frontend-Verbindung zurück, wenn die eingehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_fc_ecformats_bin: binary Gibt die binäre Form der im ClientHello angegebenen unterstützten Punktformate elliptischer Kurven zurück. Die maximale Länge des Rückgabewerts wird durch die Größe des gemeinsamen Erfassungspuffers begrenzt, die mit “tune.ssl.capture-buffer-size” gesteuert wird.
Beispiel:
ssl_fc_eclist_bin([<filter_option>]): binary
Gibt die binäre Form der im ClientHello angegebenen unterstützten elliptischen Kurven zurück. Die maximale Länge des Rückgabewerts wird durch die Größe des gemeinsamen Erfassungspuffers begrenzt, die mit “tune.ssl.capture-buffer-size” gesteuert wird. Mit <filter_option> lassen sich die zurückgegebenen Daten filtern. Zulässige Werte:
Beispiel:
ssl_fc_err: integer Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten eingehenden Verbindung die ID des letzten Fehlers im ersten auf der Frontend-Seite aufgetretenen Fehlerstapel zurück, oder 0, wenn kein Fehler auftrat. Damit lassen sich Handshake-Fehler außerhalb der Zertifikatsprüfung, etwa nicht passende Verschlüsselungsverfahren, sowie andere während der Lebensdauer der Verbindung auftretende Lese- oder Schreibfehler erkennen. Fehler bei der Prüfung des Client-Zertifikats werden nicht über diesen Abruf gemeldet, sondern über die vorhandenen Abrufe “ssl_c_err”, “ssl_c_ca_err” und “ssl_c_ca_err_depth”. Eine Textbeschreibung dieses Fehlercodes erhalten Sie mit dem Sample-Abruf “ssl_fc_err_str” oder dem Befehl “openssl errstr”, der einen Fehlercode in hexadezimaler Darstellung als Parameter erwartet. Die vollständige Liste der Fehlercodes finden Sie in der Dokumentation Ihrer SSL-Bibliothek.
ssl_fc_err_str: string Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten eingehenden Verbindung eine Zeichenkettendarstellung des letzten Fehlers im ersten auf der Frontend-Seite aufgetretenen Fehlerstapel zurück. Fehler bei der Prüfung des Client-Zertifikats werden nicht über diesen Abruf gemeldet. Siehe auch “ssl_fc_err”.
ssl_fc_exporter_secret: string Gibt EXPORTER_SECRET als hexadezimale Zeichenkette für die Frontend-Verbindung zurück, wenn die eingehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_fc_extlist_bin([<filter_option>]): binary
Gibt die binäre Form der Erweiterungsliste aus dem ClientHello zurück. Die maximale Länge des Rückgabewerts wird durch die Größe des gemeinsamen Erfassungspuffers begrenzt, die mit “tune.ssl.capture-buffer-size” gesteuert wird. Mit <filter_option> lassen sich die zurückgegebenen Daten filtern. Zulässige Werte:
Beispiel:
ssl_fc_has_crt: boolean Gibt true zurück, wenn in einer eingehenden Verbindung über eine SSL/TLS-Transportschicht ein Client-Zertifikat vorhanden ist. Dies ist nützlich, wenn die Anweisung ‘verify’ auf ‘optional’ gesetzt ist. Hinweis: Bei der Wiederaufnahme einer SSL-Sitzung mit Session ID oder TLS-Ticket ist das Client-Zertifikat in der aktuellen Verbindung nicht vorhanden, kann aber aus dem Cache oder Ticket abgerufen werden. Verwenden Sie daher bevorzugt “ssl_c_used”, wenn Sie prüfen möchten, ob die aktuelle SSL-Sitzung ein Client-Zertifikat verwendet.
ssl_fc_has_early: boolean Gibt true zurück, wenn frühzeitige Daten gesendet wurden und der Handshake noch nicht abgeschlossen ist. Da dies Auswirkungen auf die Sicherheit hat, ist es nützlich, solche Daten ablehnen oder bis zum Abschluss des Handshakes warten zu können, etwa mit der Aktion “wait-for-handshake”. Siehe auch “ssl_fc_early_rcvd”.
ssl_fc_has_sni: boolean Prüft, ob in einer über eine SSL/TLS-Transportschicht hergestellten eingehenden Verbindung die TLS-Erweiterung Server Name Indication (SNI) vorhanden ist. Gibt true zurück, wenn die eingehende Verbindung ein TLS-SNI-Feld enthält. Die SSL-Bibliothek muss mit aktivierter Unterstützung für TLS-Erweiterungen gebaut worden sein (mit haproxy -vv prüfen).
ssl_fc_is_resumed: boolean Gibt true zurück, wenn die SSL/TLS-Sitzung einer eingehenden Verbindung über eine SSL/TLS-Transportschicht mithilfe des SSL-Sitzungscaches oder von TLS-Tickets wiederaufgenommen wurde.
ssl_fc_npn: string Extrahiert das Feld Next Protocol Negotiation aus einer eingehenden Verbindung über eine TLS-Transportschicht, die HAProxy lokal entschlüsselt. Das Ergebnis ist eine Zeichenkette mit dem vom Client angekündigten Protokollnamen. Die SSL-Bibliothek muss mit aktivierter Unterstützung für TLS-Erweiterungen gebaut worden sein (mit haproxy -vv prüfen). Die TLS-Erweiterung NPN wird nur angekündigt, wenn das Schlüsselwort “npn” in der “bind”-Zeile eine Protokollliste festlegt. Der Client ist außerdem nicht gezwungen, ein Protokoll aus dieser Liste zu wählen; ein beliebiges anderes kann angefordert werden. Die TLS-Erweiterung NPN wurde durch ALPN ersetzt.
ssl_fc_protocol: string Gibt den Namen des verwendeten Protokolls zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_fc_protocol_hello_id: integer Die Version des TLS-Protokolls, mit der der Client laut ClientHello-Nachricht während der Sitzung kommunizieren möchte. Dieser Wert kann nur zurückgegeben werden, wenn “tune.ssl.capture-buffer-size” größer als 0 ist.
Beispiel:
ssl_fc_server_handshake_traffic_secret: string Gibt SERVER_HANDSHAKE_TRAFFIC_SECRET als hexadezimale Zeichenkette für die Frontend-Verbindung zurück, wenn die eingehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_fc_server_random: binary Gibt den Server-Zufallswert der Frontend-Verbindung zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Dies ist zum Entschlüsseln von Verkehr nützlich, der mit Verfahren mit kurzlebigen Schlüsseln gesendet wurde. Erfordert OpenSSL >= 1.1.0 oder BoringSSL.
ssl_fc_server_traffic_secret_0: string Gibt SERVER_TRAFFIC_SECRET_0 als hexadezimale Zeichenkette für die Frontend-Verbindung zurück, wenn die eingehende Verbindung über eine TLS-1.3-Transportschicht hergestellt wurde. Erfordert OpenSSL >= 1.1.1. Dies ist einer der Schlüssel, die der OpenSSL-Keylog-Callback zur Erzeugung der SSLKEYLOGFILE ausgibt. Die SSL-Schlüsselprotokollierung muss mit “tune.ssl.keylog on” im Abschnitt global aktiviert werden. Siehe auch “tune.ssl.keylog”.
ssl_fc_session_id: binary Gibt die SSL-ID der Frontend-Verbindung zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Damit lässt sich ein bestimmter Client an einen Server binden. Beachten Sie, dass einige Browser ihre Sitzungs-ID alle paar Minuten erneuern.
ssl_fc_session_key: binary Gibt den SSL-Sitzungs-Master-Schlüssel der Frontend-Verbindung zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Dies ist zum Entschlüsseln von Verkehr nützlich, der mit Verfahren mit kurzlebigen Schlüsseln gesendet wurde. Erfordert OpenSSL >= 1.1.0 oder BoringSSL.
ssl_fc_sigalgs_bin([<filter_option>]): binary
Gibt den Inhalt der TLS-Erweiterung signatures_algorithms (13) zurück, die im ClientHello übermittelt wurde. Liefert eine binäre Liste von jeweils 2 Bytes langen Algorithmuskennungen gemäß dem TLS-RFC: https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.3 .
Dieser Wert kann nur zurückgegeben werden, wenn “tune.ssl.capture-buffer-size” größer als 0 ist. Mit <filter_option> lassen sich die zurückgegebenen Daten filtern. Zulässige Werte: 0: vollständige Liste der Verschlüsselungsverfahren zurückgeben (Standard); 1: GREASE-Werte (RFC8701) aus der Ausgabe ausschließen.
ssl_fc_sni: string Extrahiert das Feld der TLS-Erweiterung Server Name Indication (SNI) aus einer eingehenden Verbindung über eine SSL/TLS-Transportschicht, die HAProxy lokal entschlüsselt. Das Ergebnis ist, sofern vorhanden, typischerweise eine Zeichenkette, die dem HTTPS-Hostnamen entspricht (253 Zeichen oder weniger). Die SSL-Bibliothek muss mit aktivierter Unterstützung für TLS-Erweiterungen gebaut worden sein (mit haproxy -vv prüfen).
Dieser Abruf unterscheidet sich vom obigen “req.ssl_sni” dadurch, dass er sich auf die von HAProxy entschlüsselte Verbindung bezieht und nicht auf unverändert weitergeleitete SSL-Inhalte. Siehe auch “ssl_fc_sni_end” und “ssl_fc_sni_reg” weiter unten. Die SSL-Bibliothek muss mit aktivierter Unterstützung für TLS-Erweiterungen gebaut worden sein (mit haproxy -vv prüfen).
ACHTUNG! Außer unter sehr speziellen Bedingungen ist es normalerweise nicht korrekt, dieses Feld als Ersatz für das HTTP-Headerfeld “Host” zu verwenden. Beispielsweise muss beim Weiterleiten einer HTTPS-Verbindung an einen Server das SNI-Feld mithilfe von “req.hdr(host)” aus dem HTTP-Host-Headerfeld gesetzt werden und nicht aus dem SNI-Wert der Frontend-Verbindung. SNI dient ausschließlich dazu, das von der Server-Seite vorgelegte Zertifikat auszuwählen. Clients dürfen anschließend Anfragen mit unterschiedlichen Host-Werten senden, solange diese mit den Namen im Zertifikat übereinstimmen. Daher sollte “ssl_fc_sni” normalerweise nicht als Argument des Server-Schlüsselworts “sni” verwendet werden, sofern das Backend nicht im TCP-Modus arbeitet.
Abgeleitete ACLs:
ssl_fc_supported_versions_bin([<filter_option>]): binary
Gibt den Inhalt der TLS-Erweiterung supported_versions (43) zurück, die im ClientHello übermittelt wurde. Liefert eine binäre Liste von jeweils 2 Bytes langen Versionskennungen: TLSv1.3 (0x0304), TLSv1.2 (0x0303).
Dieser Wert kann nur zurückgegeben werden, wenn “tune.ssl.capture-buffer-size” größer als 0 ist. Mit <filter_option> lassen sich die zurückgegebenen Daten filtern. Zulässige Werte: 0: vollständige Liste der Verschlüsselungsverfahren zurückgeben (Standard); 1: GREASE-Werte (RFC8701) aus der Ausgabe ausschließen.
ssl_fc_unique_id: binary Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten eingehenden Verbindung die eindeutige TLS-ID gemäß RFC5929 Abschnitt 3 zurück. Die eindeutige ID kann mit dem Konverter “ssl_fc_unique_id,base64” base64-kodiert werden.
ssl_fc_use_keysize: integer Gibt die verwendete Schlüssellänge des symmetrischen Verschlüsselungsverfahrens in Bits zurück, wenn die eingehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_s_chain_der: binary Gibt die vom Server vorgelegte Zertifikatskette im DER-Format zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Bei Verwendung in einer ACL können die abzugleichenden Werte in hexadezimaler Form angegeben werden. Das Ergebnis lässt sich mit jeder Bibliothek analysieren, die ASN.1-DER-Daten akzeptiert. Wiederaufgenommene Sitzungen werden derzeit nicht unterstützt.
ssl_s_der: binary Gibt das vom Server vorgelegte Zertifikat im DER-Format zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Bei Verwendung in einer ACL können die abzugleichenden Werte in hexadezimaler Form angegeben werden.
ssl_s_i_dn([<entry>[,<occ>[,<format>]]]): string
Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten ausgehenden Verbindung den vollständigen Distinguished Name des Ausstellers des vom Server vorgelegten Zertifikats zurück, wenn kein <entry> angegeben ist. Andernfalls wird der Wert des ersten angegebenen Eintrags vom Anfang des DN aus zurückgegeben. Wird als optionales zweites Argument eine positive oder negative Vorkommensnummer angegeben, wird der Wert des n-ten angegebenen Eintrags vom Anfang bzw. Ende des DN aus zurückgegeben. Beispielsweise liefert “ssl_s_i_dn(OU,2)” die zweite Organisationseinheit und “ssl_s_i_dn(CN)” den Common Name. Mit dem Parameter <format> erhalten Sie den DN in einer für verschiedene Protokolle geeigneten Form. Derzeit wird rfc2253 für LDAP v3 unterstützt. Soll nur das Format geändert werden, können Sie für die ersten beiden Parameter eine leere Zeichenkette und null angeben. Beispiel: ssl_s_i_dn(,0,rfc2253). Enthält der ASN.1-Wert des angeforderten Eintrags (oder, wenn kein <entry> angegeben ist, der Wert eines beliebigen Eintrags im DN) ein eingebettetes NUL-Byte mit darauf folgenden weiteren Daten, gilt er als fehlerhaft und es werden keine Daten zurückgegeben.
ssl_s_key_alg: string Gibt den Namen des Algorithmus zurück, mit dem der Schlüssel des vom Server vorgelegten Zertifikats erzeugt wurde, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_s_notafter: string Gibt das vom Server vorgelegte Enddatum als formatierte Zeichenkette YYMMDDhhmmss[Z] zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_s_notbefore: string Gibt das vom Server vorgelegte Anfangsdatum als formatierte Zeichenkette YYMMDDhhmmss[Z] zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_s_s_dn([<entry>[,<occ>[,<format>]]]): string
Gibt bei einer über eine SSL/TLS-Transportschicht hergestellten ausgehenden Verbindung den vollständigen Distinguished Name des Subjekts des vom Server vorgelegten Zertifikats zurück, wenn kein <entry> angegeben ist. Andernfalls wird der Wert des ersten angegebenen Eintrags vom Anfang des DN aus zurückgegeben. Wird als optionales zweites Argument eine positive oder negative Vorkommensnummer angegeben, wird der Wert des n-ten angegebenen Eintrags vom Anfang bzw. Ende des DN aus zurückgegeben. Beispielsweise liefert “ssl_s_s_dn(OU,2)” die zweite Organisationseinheit und “ssl_s_s_dn(CN)” den Common Name. Mit dem Parameter <format> erhalten Sie den DN in einer für verschiedene Protokolle geeigneten Form. Derzeit wird rfc2253 für LDAP v3 unterstützt. Soll nur das Format geändert werden, können Sie für die ersten beiden Parameter eine leere Zeichenkette und null angeben. Beispiel: ssl_s_s_dn(,0,rfc2253). Enthält der ASN.1-Wert des angeforderten Eintrags (oder, wenn kein <entry> angegeben ist, der Wert eines beliebigen Eintrags im DN) ein eingebettetes NUL-Byte mit darauf folgenden weiteren Daten, gilt er als fehlerhaft und es werden keine Daten zurückgegeben.
ssl_s_serial: binary Gibt die Seriennummer des vom Server präsentierten Zertifikats zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Bei Verwendung in einer ACL können die Vergleichswerte in hexadezimaler Form angegeben werden.
ssl_s_sha1: binary Gibt den SHA-1-Fingerabdruck des vom Server präsentierten Zertifikats zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde. Damit lässt sich feststellen, welches Zertifikat anhand von SNI ausgewählt wurde.
ssl_s_sig_alg: string Gibt den Namen des Algorithmus zurück, mit dem das vom Server präsentierte Zertifikat signiert wurde, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
ssl_s_version: integer Gibt die Version des vom Server präsentierten Zertifikats zurück, wenn die ausgehende Verbindung über eine SSL/TLS-Transportschicht hergestellt wurde.
txn.timer.user: integer Geschätzte Gesamtdauer aus Sicht des Clients vom Annehmen der Verbindung durch den Proxy bis zum Schließen beider Enden, ohne Leerlaufzeit. Dies entspricht %Tu im log-format und wird in Millisekunden (ms) angegeben. Weitere Einzelheiten finden Sie in Abschnitt 8.4 „Zeitereignisse“.
7.3.5. Sample-Abruf aus Pufferinhalten (Schicht 6)
Der Sample-Abruf aus Pufferinhalten unterscheidet sich etwas von den zuvor beschriebenen Abrufmethoden, da die abgerufenen Daten nur vorübergehend vorhanden sind. Sie können nur verwendet werden, solange sie verfügbar sind, und gehen beim Weiterleiten verloren. Deshalb können etwa Samples, die während einer Anfrage aus Pufferinhalten abgerufen wurden, nicht in einer Antwort verwendet werden. Selbst während des Abrufs können sich die Daten ändern. Manchmal müssen Verzögerungen eingerichtet oder mehrere Methoden zum Sample-Abruf kombiniert werden, damit die erwarteten Daten vollständig und verwendbar sind, beispielsweise durch die Inhaltsprüfung von TCP-Anfragen. Weitere Einzelheiten hierzu finden Sie beim Schlüsselwort “tcp-request content”.
Warnung: Die folgenden Methoden zum Sample-Abruf werden bei Verwendung in HTTP-Proxys ignoriert. Sie verarbeiten ausschließlich die Rohinhalte der Puffer. HTTP-Proxys verwenden dagegen strukturierte Inhalte, deren Rohdarstellung daher bedeutungslos ist. Wenn eine ACL eine der folgenden Abrufmethoden verwendet, wird eine Warnung ausgegeben. Es lassen sich jedoch nicht alle ungültigen Verwendungen erkennen, etwa in einem benutzerdefinierten Protokollformat oder einem Sample-Ausdruck. Seien Sie deshalb vorsichtig.
Übersicht der Methoden zum Sample-Abruf in diesem Abschnitt und ihrer jeweiligen Typen:
Ausführliche Liste:
distcc_body(<token>[,<occ>]): binary
Analysiert eine distcc-Nachricht und gibt den zum Vorkommen #<occ> des Tokens <token> gehörenden
Inhalt zurück. Die Zählung der Vorkommen beginnt bei 1. Ohne Angabe kann ein beliebiges Vorkommen
passen, auch wenn derzeit in der Praxis nur das erste geprüft wird. Damit lassen sich Dateinamen
oder Argumente aus Dateien extrahieren, die mit distcc über HAProxy erstellt werden. Die vollständige
Liste der unterstützten Tokens finden Sie in der Protokolldokumentation von distcc.
distcc_param(<token>[,<occ>]): integer
Analysiert eine distcc-Nachricht und gibt den zum Vorkommen #<occ> des Tokens <token> gehörenden
Parameter zurück. Die Zählung der Vorkommen beginnt bei 1. Ohne Angabe kann ein beliebiges Vorkommen
passen, auch wenn derzeit in der Praxis nur das erste geprüft wird. Damit lassen sich bestimmte
Informationen wie die Protokollversion, die Dateigröße oder das Argument aus Dateien extrahieren,
die mit distcc über HAProxy erstellt werden. Eine weitere Anwendung besteht darin, vor dem
Verbindungsaufbau zum Server auf den Beginn des vorverarbeiteten Dateiinhalts zu warten, um
ungenutzte Verbindungen zu vermeiden. Die vollständige Liste der unterstützten Tokens finden Sie
in der Protokolldokumentation von distcc.
Beispiel:
payload(<offset>,<length>): binary (deprecated)
Dies ist ein Alias für “req.payload” im Kontext einer Anfrage, etwa bei “stick on” oder “stick match”, und für “res.payload” im Kontext einer Antwort, etwa bei “stick store response”.
payload_lv(<offset1>,<length>[,<offset2>]): binary (deprecated)
Dies ist ein Alias für “req.payload_lv” im Kontext einer Anfrage, etwa bei “stick on” oder “stick match”, und für “res.payload_lv” im Kontext einer Antwort, etwa bei “stick store response”.
req.len: integer req_len: integer (veraltet) Gibt eine Ganzzahl zurück, die der Anzahl der Bytes im Anfragepuffer entspricht. Dies wird vor allem in ACL verwendet. Beachten Sie, dass dieser Test nicht false zurückgibt, solange sich der Puffer noch verändert. Eine Prüfung auf Gleichheit mit null trifft daher am Sitzungsbeginn fast immer sofort zu, während ein Test auf mehr Daten auf deren Eingang wartet und erst dann false zurückgibt, wenn HAProxy sicher ist, dass keine weiteren Daten eintreffen werden. Dieser Test wurde für die Inhaltsprüfung von TCP-Anfragen entwickelt.
req.payload(<offset>,<length>): binary
Extrahiert einen Binärblock mit <length> Bytes, der bei Byte <offset> im Anfragepuffer beginnt.
Ist das Argument <length> null, wird als Sonderfall der gesamte Puffer ab <offset> bis zum Ende
extrahiert. Damit lässt sich in ACLs prüfen, ob bestimmte Inhalte an einer beliebigen Stelle im
Puffer vorhanden sind.
ACL-Varianten:
req.payload_lv(<offset1>,<length>[,<offset2>]): binary
Extrahiert einen Binärblock, dessen Größe im Anfragepuffer bei <offset1> über <length> Bytes
angegeben ist. Der Block beginnt bei <offset2>, sofern angegeben, andernfalls direkt nach dem
Längenfeld. Der Parameter <offset2> unterstützt auch relative Versätze, wenn ein ‘+’ oder ‘-’
vorangestellt wird.
ACL-Varianten:
Beispiel: Siehe das Beispiel beim Schlüsselwort “stick store-response”.
req.proto_http: boolean req_proto_http: boolean (veraltet) Gibt true zurück, wenn die Daten im Anfragepuffer wie HTTP aussehen und sich korrekt als HTTP analysieren lassen. Dafür wird derselbe Parser wie für gewöhnliche HTTP-Anfragen verwendet, sodass keine Überraschungen zu erwarten sind. Der Test trifft erst zu, wenn die Anfrage vollständig ist, fehlgeschlagen ist oder eine Zeitüberschreitung vorliegt. Er kann das Protokoll in TCP-Protokolleinträgen angeben; hauptsächlich wird er jedoch verwendet, um die Analyse von TCP-Anfragen anzuhalten, bis eine vollständige HTTP-Anfrage im Puffer liegt, etwa um einen Header nachzuverfolgen.
Beispiel:
req.rdp_cookie([<name>]): string
Wenn der Anfragepuffer wie das RDP-Protokoll aussieht, wird das RDP-Cookie <name> extrahiert;
ohne Namensangabe ein beliebiges Cookie. Wie in der RDP-Protokollspezifikation dargestellt, prüft
der Parser nur das erste Cookie. Beim Cookie-Namen wird nicht zwischen Groß- und Kleinschreibung
unterschieden. In der Regel wird der Cookie-Name “MSTS” verwendet, da dieses Cookie bei passender
Client-Konfiguration den Benutzernamen des Clients enthalten kann, der sich mit dem Server
verbindet. Auch das Cookie “MSTSHASH” wird häufig für die Sitzungsbindung an Server verwendet.
Der Unterschied zu “balance rdp-cookie” besteht darin, dass ein beliebiger Algorithmus zur Lastverteilung verwendet werden kann und die Verteilung der Clients auf Backend-Server deshalb nicht an einen Hash des RDP-Cookies gebunden ist. Es wird erwartet, dass ein Algorithmus wie “balance roundrobin” oder “balance leastconn” die Clients gleichmäßiger auf Backend-Server verteilt als der von “balance rdp-cookie” verwendete Hash.
ACL-Varianten:
Beispiel:
Siehe auch: “balance rdp-cookie”, “persist rdp-cookie”, “tcp-request” und die ACL “req.rdp_cookie”.
req.rdp_cookie_cnt([name]): integer
Versucht, den Anfragepuffer als RDP-Protokoll zu analysieren, und gibt dann eine Ganzzahl zurück, die der Anzahl der gefundenen RDP-Cookies entspricht. Wird optional ein Cookie-Name angegeben, werden nur Cookies mit diesem Namen berücksichtigt. Dies wird vor allem in ACL verwendet.
ACL-Varianten:
req.ssl_alpn: string Gibt eine Zeichenfolge mit den Werten der TLS-Erweiterung Application-Layer Protocol Negotiation (ALPN, RFC7301) zurück, die der Client in der SSL-ClientHello-Nachricht gesendet hat. Dies gilt nur für die Rohinhalte im Anfragepuffer und nicht für Inhalte, die über eine SSL-Datenschicht entschlüsselt wurden. Daher funktioniert es nicht bei “bind”-Zeilen mit der Option “ssl”. In ACL kann damit anhand der ALPN-Präferenzen eines TLS-Clients eine Routingentscheidung getroffen werden, wie im folgenden Beispiel. Siehe auch “ssl_fc_alpn”. Diese Abrufmethode analysiert nur die erste ClientHello-Nachricht im Anfragepuffer. Einzelheiten zu den Folgen dieser Einschränkung (HelloRetryRequest, Neuaushandlung, Encrypted Client Hello) finden Sie in der Dokumentation zum Schlüsselwort “req.ssl_sni”.
Beispiele:
req.ssl_cipherlist binary
Gibt die binäre Darstellung der vom Client unterstützten symmetrischen Verschlüsselungsoptionen zurück, wie sie im Inhalt einer TLS-ClientHello-Nachricht angegeben sind. Dies gilt nur für die Rohinhalte im Anfragepuffer und nicht für Inhalte, die über eine SSL-Datenschicht entschlüsselt wurden. Daher funktioniert es nicht bei “bind”-Zeilen mit der Option “ssl”. Das entsprechende Gegenstück für eine SSL-Bindung ist “ssl_fc_cipherlist_bin”; es kann verwendet werden, wenn die Option “ssl” angegeben ist. Diese Abrufmethode analysiert nur die erste ClientHello-Nachricht im Anfragepuffer. Einzelheiten zu den Folgen dieser Einschränkung (HelloRetryRequest, Neuaushandlung, Encrypted Client Hello) finden Sie in der Dokumentation zum Schlüsselwort “req.ssl_sni”.
Beispiele:
req.ssl_ec_ext: boolean Gibt einen booleschen Wert zurück, der angibt, ob der Client die in RFC4492, Abschnitt 5.1 definierte Erweiterung Supported Elliptic Curves in der SSL-ClientHello-Nachricht gesendet hat. Damit kann auf derselben IP-Adresse ECC-kompatiblen Clients ein EC-Zertifikat präsentiert und für alle anderen RSA verwendet werden. Dies gilt nur für die Rohinhalte im Anfragepuffer und nicht für Inhalte, die über eine SSL-Datenschicht entschlüsselt wurden. Daher funktioniert es nicht bei “bind”-Zeilen mit der Option “ssl”. Diese Abrufmethode analysiert nur die erste ClientHello-Nachricht im Anfragepuffer. Einzelheiten zu den Folgen dieser Einschränkung (HelloRetryRequest, Neuaushandlung, Encrypted Client Hello) finden Sie in der Dokumentation zum Schlüsselwort “req.ssl_sni”.
req.ssl_hello_type: integer req_ssl_hello_type: integer (veraltet) Gibt eine Ganzzahl mit dem Typ der SSL-Hello-Nachricht im Anfragepuffer zurück, wenn dessen Daten als vollständige SSL-Client-Hello- Nachricht (v3 oder höher) analysiert werden können. Dies gilt nur für die Rohinhalte im Anfragepuffer und nicht für Inhalte, die über eine SSL-Datenschicht entschlüsselt wurden. Daher funktioniert es nicht bei “bind”-Zeilen mit der Option “ssl”. Dies wird vor allem in ACL verwendet, um eine SSL-Hello-Nachricht zu erkennen, die eine zur Sitzungsbindung verwendbare SSL-Sitzungs-ID enthalten soll. Diese Abrufmethode analysiert nur die erste ClientHello-Nachricht im Anfragepuffer. Einzelheiten zu den Folgen dieser Einschränkung (HelloRetryRequest, Neuaushandlung, Encrypted Client Hello) finden Sie in der Dokumentation zum Schlüsselwort “req.ssl_sni”.
req.ssl_keyshare_groups binary
Gibt die binäre Darstellung der Liste kryptografischer Parameter für den Schlüsselaustausch zurück, die der Client laut TLS-ClientHello unterstützt. In TLS v1.3 ist keyshare Bestandteil der ClientHello-Nachricht und deren letzte Erweiterung. Dies gilt nur für die Rohinhalte im Anfragepuffer und nicht für Inhalte, die über eine SSL-Datenschicht entschlüsselt wurden. Daher funktioniert es nicht bei “bind”-Zeilen mit der Option “ssl”. Diese Abrufmethode analysiert nur die erste ClientHello-Nachricht im Anfragepuffer. Einzelheiten zu den Folgen dieser Einschränkung (HelloRetryRequest, Neuaushandlung, Encrypted Client Hello) finden Sie in der Dokumentation zum Schlüsselwort “req.ssl_sni”.
Beispiele:
req.ssl_sigalgs binary
Gibt die binäre Darstellung der Liste der Signaturalgorithmen zurück, die der Client laut TLS-ClientHello unterstützt. Diese Information ist als Client-Hello-Erweiterung verfügbar. Dies gilt nur für die Rohinhalte im Anfragepuffer und nicht für Inhalte, die über eine SSL-Datenschicht entschlüsselt wurden. Daher funktioniert es nicht bei “bind”-Zeilen mit der Option “ssl”. Das entsprechende Gegenstück für eine SSL-Bindung ist “ssl_fc_sigalgs_bin”; es kann verwendet werden, wenn die Option “ssl” angegeben ist. Diese Abrufmethode analysiert nur die erste ClientHello- Nachricht im Anfragepuffer. Einzelheiten zu den Folgen dieser Einschränkung (HelloRetryRequest, Neuaushandlung, Encrypted Client Hello) finden Sie in der Dokumentation zum Schlüsselwort “req.ssl_sni”.
Beispiele:
req.ssl_sni: string req_ssl_sni: string (veraltet) Gibt eine Zeichenfolge mit dem Wert der TLS-Erweiterung Server Name zurück, die ein Client in einem durch den Anfragepuffer laufenden TLS-Datenstrom gesendet hat, sofern die Pufferdaten als vollständige SSL-Client-Hello-Nachricht (v3 oder höher) analysiert werden können. Dies gilt nur für die Rohinhalte im Anfragepuffer und nicht für Inhalte, die über eine SSL-Datenschicht entschlüsselt wurden. Daher funktioniert es nicht bei “bind”-Zeilen mit der Option “ssl”. Es funktioniert nur bei Protokollen mit implizitem TLS wie HTTPS (443), IMAPS (993) oder SMTPS (465), jedoch nicht bei Protokollen mit explizitem TLS wie SMTP (25/587) oder IMAP (143). SNI enthält normalerweise den Namen des Hosts, mit dem der Client sich verbinden möchte (bei neueren Browsern). Dieser Test wurde für die Inhaltsprüfung von TCP-Anfragen entwickelt. Wenn eine inhaltsabhängige Weiterleitung erforderlich ist, sollte zuerst auf eine vollständige Client-Hello-Nachricht (Typ 1) gewartet werden, wie im folgenden Beispiel. Siehe auch “ssl_fc_sni”. Beachten Sie, dass der zurückgegebene Wert aus den nachfolgend erläuterten Gründen (HelloRetryRequest, Neuaushandlung, Encrypted Client Hello) nicht zuverlässig genug ist, um allein darauf gestützt den Zugriff auf bestimmte Hosts zu erlauben oder zu verweigern.
Diese Abrufmethode analysiert nur die erste ClientHello-Nachricht im Anfragepuffer. Sendet der Client mehrere ClientHello-Nachrichten im selben TCP-Datenstrom, etwa weil der Server im Rahmen von TLS 1.3 einen HelloRetryRequest (HRR) angefordert hat oder weil der Client eine TLS-Neuaushandlung beginnt, wird nur der SNI-Wert aus der allerersten ClientHello-Nachricht zurückgegeben. Bei der Neuaushandlung wird später im selben TCP-Datenstrom eine neue ClientHello-Nachricht gesendet, die möglicherweise einen anderen SNI-Wert enthält. Der Inhalt aller nachfolgenden ClientHello- Nachrichten wird ignoriert.
Bei Verwendung von Encrypted Client Hello (ECH) ist die auf der Leitung sichtbare ClientHello- Nachricht nur das äußere ClientHello (“Outer”), das das eigentliche, verschlüsselte innere ClientHello (“Inner”) enthält. Der hier extrahierte SNI-Wert stammt in diesem Fall aus dem äußeren ClientHello und dient als Tarnung; er bezeichnet nicht den Host, den der Client tatsächlich erreichen möchte. Diese Abrufmethode kann das innere ClientHello derzeit weder entschlüsseln noch analysieren. Bei Verwendung von ECH dürfen Entscheidungen zur Weiterleitung oder Zugriffskontrolle daher nicht auf diese Methode gestützt werden.
ACL-Varianten:
Beispiele:
req.ssl_st_ext: integer Gibt 0 zurück, wenn der Client keine TLS-Erweiterung SessionTicket (RFC5077) gesendet hat, 1, wenn der Client die TLS-Erweiterung SessionTicket gesendet hat, und 2, wenn er zusätzlich ein TLS-SessionTicket mit einer Länge ungleich null gesendet hat. Dies gilt nur für die Rohinhalte im Anfragepuffer und nicht für Inhalte, die über eine SSL-Datenschicht entschlüsselt wurden. Daher funktioniert es nicht bei “bind”-Zeilen mit der Option “ssl”. Damit lässt sich etwa erkennen, ob der Client ein SessionTicket gesendet hat, und die Sitzungsbindung entsprechend festlegen: Ohne SessionTicket kann die Bindung anhand der SessionID erfolgen; bei Verwendung von SessionTickets kann darauf verzichtet werden, da kein serverseitiger Zustand vorliegt. Diese Abrufmethode analysiert nur die erste ClientHello-Nachricht im Anfragepuffer. Einzelheiten zu den Folgen dieser Einschränkung (HelloRetryRequest, Neuaushandlung, Encrypted Client Hello) finden Sie in der Dokumentation zum Schlüsselwort “req.ssl_sni”.
req.ssl_supported_groups binary
Gibt die binäre Darstellung der Liste der vom Client laut TLS-ClientHello unterstützten Gruppen für den Schlüsselaustausch zurück. Dies kann sowohl Schlüsselaustausch mit elliptischen Kurven als auch ohne EC umfassen. Dies gilt nur für die Rohinhalte im Anfragepuffer und nicht für Inhalte, die über eine SSL-Datenschicht entschlüsselt wurden. Daher funktioniert es nicht bei “bind”-Zeilen mit der Option “ssl”. Das entsprechende Gegenstück für eine SSL-Bindung ist “ssl_fc_eclist_bin”; es kann verwendet werden, wenn die Option “ssl” angegeben ist. Diese Abrufmethode analysiert nur die erste ClientHello-Nachricht im Anfragepuffer. Einzelheiten zu den Folgen dieser Einschränkung (HelloRetryRequest, Neuaushandlung, Encrypted Client Hello) finden Sie in der Dokumentation zum Schlüsselwort “req.ssl_sni”.
Beispiele:
req.ssl_ver: integer req_ssl_ver: integer (veraltet) Gibt eine Ganzzahl mit der Version des SSL/TLS-Protokolls eines Datenstroms im Anfragepuffer zurück. Sowohl SSLv2-Hello-Nachrichten als auch SSLv3-Nachrichten werden unterstützt. TLSv1 wird als SSL-Version 3.1 angegeben. Der Wert besteht aus der mit 65536 multiplizierten Hauptversion zuzüglich der Nebenversion. Dies gilt nur für die Rohinhalte im Anfragepuffer und nicht für Inhalte, die über eine SSL-Datenschicht entschlüsselt wurden. Daher funktioniert es nicht bei “bind”-Zeilen mit der Option “ssl”. Die ACL-Variante des Tests vergleicht mit einer Dezimalschreibweise der Form MAJOR.MINOR (etwa 3.1). Diese Abrufmethode wird vor allem in ACL verwendet. Sie analysiert nur die erste ClientHello- Nachricht im Anfragepuffer. Einzelheiten zu den Folgen dieser Einschränkung (HelloRetryRequest, Neuaushandlung, Encrypted Client Hello) finden Sie in der Dokumentation zum Schlüsselwort “req.ssl_sni”.
ACL-Varianten:
res.len: integer Gibt eine Ganzzahl zurück, die der Anzahl der Bytes im Antwortpuffer entspricht. Dies wird vor allem in ACL verwendet. Beachten Sie, dass dieser Test nicht false zurückgibt, solange sich der Puffer noch verändert. Eine Prüfung auf Gleichheit mit null trifft daher am Anfang des Datenstroms fast immer sofort zu, während ein Test auf mehr Daten auf deren Eingang wartet und erst dann false zurückgibt, wenn HAProxy sicher ist, dass keine weiteren Daten eintreffen werden. Dieser Test wurde für die Inhaltsprüfung von TCP-Antworten entwickelt. Er kann aber auch in expect-Regeln auf Basis von tcp-check verwendet werden.
res.payload(<offset>,<length>): binary
Extrahiert einen Binärblock mit <length> Bytes, der bei Byte <offset> im Antwortpuffer beginnt.
Ist das Argument <length> null, wird als Sonderfall der gesamte Puffer ab <offset> bis zum Ende
extrahiert. Damit lässt sich in ACLs prüfen, ob bestimmte Inhalte an einer beliebigen Stelle im
Puffer vorhanden sind. Dies kann auch in expect-Regeln auf Basis von tcp-check verwendet werden.
res.payload_lv(<offset1>,<length>[,<offset2>]): binary
Extrahiert einen Binärblock, dessen Größe im Antwortpuffer bei <offset1> über <length> Bytes
angegeben ist. Der Block beginnt bei <offset2>, sofern angegeben, andernfalls direkt nach dem
Längenfeld. Der Parameter <offset2> unterstützt auch relative Versätze, wenn ein ‘+’ oder ‘-’
vorangestellt wird. Dies kann auch in expect-Regeln auf Basis von tcp-check verwendet werden.
Beispiel: Siehe das Beispiel beim Schlüsselwort “stick store-response”.
res.ssl_hello_type: integer rep_ssl_hello_type: integer (veraltet) Gibt eine Ganzzahl mit dem Typ der SSL-Hello-Nachricht im Antwortpuffer zurück, wenn dessen Daten als vollständige SSL-Hello-Nachricht (v3 oder höher) analysiert werden können. Dies gilt nur für die Rohinhalte im Antwortpuffer und nicht für Inhalte, die über eine SSL-Datenschicht entschlüsselt wurden. Daher funktioniert es nicht bei “server”-Zeilen mit der Option “ssl”. Dies wird vor allem in ACL verwendet, um eine SSL-Hello-Nachricht zu erkennen, die eine zur Sitzungsbindung verwendbare SSL-Sitzungs-ID enthalten soll.
7.3.6. HTTP-Sample-Abruf (Schicht 7)
Samples können aus HTTP-Inhalten, Anfragen und Antworten abgerufen werden. Diese Anwendungsschicht wird auch als Schicht 7 bezeichnet. Die Daten in diesem Abschnitt können erst abgerufen werden, wenn eine vollständige HTTP-Anfrage oder -Antwort aus dem jeweiligen Anfrage- oder Antwortpuffer analysiert wurde. Dies ist bei allen HTTP-spezifischen Regeln und in Abschnitten mit “mode http” immer der Fall. Bei der TCP-Inhaltsprüfung muss möglicherweise eine Prüfverzögerung vorgesehen werden, damit die Anfrage oder Antwort zunächst eintreffen kann. Diese Abrufmethoden benötigen unter Umständen etwas mehr CPU-Ressourcen als die Methoden für Schicht 4, jedoch nicht viel mehr, da Anfrage und Antwort indiziert sind.
Hinweis: Die HTTP-Verarbeitung in tcp-request content-Regeln funktioniert in einem HTTP-Proxy wie erwartet. In einem TCP-Proxy funktioniert sie ohne HTTP-Upgrade hingegen nur für HTTP/1-Inhalte. Bei HTTP/2-Inhalten ist nur die Präambel sichtbar. Deshalb können hier nur die Methoden “req.proto_http”, “req.ver” und gegebenenfalls “method” zum Sample-Abruf verwendet werden. Alle anderen L7-Abrufmethoden schlagen fehl. Nach einem HTTP-Upgrade funktionieren sie ebenso wie in einem HTTP-Proxy.
Übersicht der Methoden zum Sample-Abruf in diesem Abschnitt und ihrer jeweiligen Typen:
Ausführliche Liste:
base: string Gibt die Verkettung des ersten Host-Headers mit dem Pfadteil der Anfrage zurück. Der Pfad beginnt beim ersten Schrägstrich und endet vor dem Fragezeichen. Dies kann in Umgebungen mit virtuellen Hosts nützlich sein, um URL-Missbrauch zu erkennen und die Effizienz gemeinsam genutzter Caches zu verbessern. Zusammen mit einer Stick Table begrenzter Größe lassen sich damit auch Statistiken über die nach Host/Pfad am häufigsten angeforderten Objekte erfassen. In ACLs ermöglicht dies einfache Regeln zur inhaltsabhängigen Weiterleitung, die Host und Pfad gleichzeitig berücksichtigen, etwa “www.example.com/favicon.ico ”. Siehe auch “path” und “uri”.
ACL-Varianten:
Hinweis: Auf ACL-Varianten darf kein Konverter folgen; sie dürfen auch nicht in ACLs mit einer Mustervergleichsmethode “-m” verwendet werden.
base32: integer Gibt einen 32-Bit-Hash des Werts zurück, den die oben beschriebene Abrufmethode “base” liefert. Damit kann auf stark besuchten Websites die Aktivität je URL verfolgt werden, ohne sämtliche URLs speichern zu müssen. Stattdessen wird ein kürzerer Hash gespeichert, was viel Speicher spart. Der Ausgabetyp ist eine vorzeichenlose Ganzzahl. Verwendet wird die Hashfunktion SDBM mit vollständigem Lawineneffekt auf die Ausgabe. Technisch entspricht base32 exakt “base,sdbm(1)”.
base32+src: binary Gibt die Verkettung des oben beschriebenen Abrufs base32 mit dem unten beschriebenen Abruf src zurück. Das Ergebnis ist vom Typ binary und je nach Adressfamilie der Quelladresse 8 oder 20 Bytes groß. Damit lassen sich Zähler je IP und je URL führen.
baseq: string Gibt die Verkettung des ersten Host-Headers mit dem Pfadteil der Anfrage einschließlich der Abfragezeichenfolge zurück. Der Pfad beginnt beim ersten Schrägstrich. Mit dieser Methode anstelle von “base” lässt sich die Zielressource für Statistiken oder Caching korrekt identifizieren. Siehe auch “path”, “pathq” und “base”.
capture.req.hdr(<idx>): string
Extrahiert den Inhalt des mit “capture request header” erfassten Headers. idx bezeichnet die Position des Schlüsselworts capture in der Konfiguration. Der erste Eintrag hat den Index 0. Siehe auch: “capture request header”.
capture.req.method: string Extrahiert die Methode (METHOD) einer HTTP-Anfrage. Sie kann sowohl in der Anfrage als auch in der Antwort verwendet werden. Anders als bei “method” ist dies möglich, weil der Wert in gesondert zugewiesenem Speicher vorliegt.
capture.req.uri: string Extrahiert die URI der Anfrage, die beim ersten Schrägstrich beginnt und vor dem ersten Leerzeichen in der Anfrage endet, ohne den Hostteil. Anders als “path” und “url” kann dieser Wert sowohl in der Anfrage als auch in der Antwort verwendet werden, weil er in gesondert zugewiesenem Speicher vorliegt.
capture.req.ver: string Extrahiert die HTTP-Version der Anfrage und gibt sie im Format
“HTTP/<major>.<minor>” zurück. Da die Information dauerhaft gespeichert ist, kann sie sowohl in
Anfragen und Antworten als auch in Protokolleinträgen verwendet werden. Ist die Version der Anfrage
ungültig, schlägt dieser Sample-Abruf fehl.
capture.res.hdr(<idx>): string
Extrahiert den Inhalt des mit “capture response header” erfassten Headers. idx bezeichnet die Position des Schlüsselworts capture in der Konfiguration. Der erste Eintrag hat den Index 0. Siehe auch: “capture response header”.
capture.res.ver: string Extrahiert die HTTP-Version der Antwort und gibt sie im Format
“HTTP/<major>.<minor>” zurück. Da die Information dauerhaft gespeichert ist, kann sie in
Protokolleinträgen verwendet werden. Ist die Version der Antwort ungültig, schlägt dieser
Sample-Abruf fehl.
cookie([<name>]): string (deprecated)
Extrahiert das letzte Vorkommen des Cookie-Namens <name> aus einer “Cookie”-Headerzeile der
Anfrage oder einem “Set-Cookie”-Header der Antwort und gibt dessen Wert als Zeichenfolge zurück.
Eine typische Anwendung besteht darin, mehrere Clients mit demselben Profil denselben Server
verwenden zu lassen. Dies ähnelt der früheren Funktion von “appsession” mit der Anweisung
“request-learn”, unterstützt aber die Synchronisierung zwischen mehreren Peers und die Erhaltung
des Zustands über Neustarts hinweg. Ohne Namensangabe wird der Wert des ersten Cookies
zurückgegeben. Diese Abrufmethode sollte nicht mehr verwendet und durch req.cook() oder res.cook()
ersetzt werden, da sie die Richtung abhängig vom Verwendungskontext mehrdeutig bestimmt.
hdr([<name>[,<occ>]]): string
Dies entspricht bei Verwendung in Anfragen req.hdr() und bei Verwendung in Antworten res.hdr(). Einzelheiten finden Sie bei den jeweiligen Abrufmethoden. Verwenden Sie bei Zweifeln an der Abrufrichtung die expliziten Varianten. Beachten Sie, dass sich die ACL-Schlüsselwörter hdr_* im Gegensatz zur Sample-Abrufmethode hdr() eindeutig auf die Anfrageheader beziehen.
http_auth(<userlist>): boolean
Gibt einen booleschen Wert zurück, der angibt, ob die vom Client empfangenen Authentifizierungsdaten mit einem in der angegebenen userlist gespeicherten Benutzernamen samt Passwort übereinstimmen. Außerhalb von ACLs ist diese Abruffunktion kaum nützlich. Derzeit wird nur die HTTP-Basic- Authentifizierung unterstützt.
http_auth_bearer([<header>]): string
Gibt bei Verwendung des Bearer-Schemas das vom Client gelieferte Token aus den
Autorisierungsdaten zurück, beispielsweise beim Senden von JSON Web Tokens. Die vom Client
gesendeten Daten werden nicht geprüft. Wird ein bestimmter <header> angegeben, wird dieser
anstelle des Headers Authorization analysiert.
http_auth_group(<userlist>): string
Gibt eine Zeichenfolge mit dem Benutzernamen aus den vom Client empfangenen Authentifizierungsdaten zurück, wenn sowohl der Benutzername als auch das Passwort gemäß der angegebenen userlist gültig sind. Dies ist hauptsächlich für ACLs vorgesehen, die anschließend prüfen, ob der Benutzer zu mindestens einer Gruppe aus einer Liste gehört. Außerhalb von ACLs ist diese Abruffunktion kaum nützlich. Derzeit wird nur die HTTP-Basic-Authentifizierung unterstützt.
ACL-Varianten:
http_auth_pass: string Gibt das Passwort des Benutzers aus den vom Client empfangenen Authentifizierungsdaten zurück, wie es im Header Authorization angegeben ist. Dieser Sample-Abruf führt keine Prüfungen durch. Nur Basic-Authentifizierung wird unterstützt.
http_auth_type: string Gibt die Authentifizierungsmethode aus den vom Client empfangenen Authentifizierungsdaten zurück, wie sie im Header Authorization angegeben ist. Dieser Sample-Abruf führt keine Prüfungen durch. Nur Basic-Authentifizierung wird unterstützt.
http_auth_user: string Gibt den Benutzernamen aus den vom Client empfangenen Authentifizierungsdaten zurück, wie er im Header Authorization angegeben ist. Dieser Sample-Abruf führt keine Prüfungen durch. Nur Basic-Authentifizierung wird unterstützt.
http_first_req: boolean Gibt true zurück, wenn die gerade verarbeitete Anfrage die erste auf der Verbindung ist. Damit lassen sich Header hinzufügen oder entfernen, die bei manchen späteren Anfragen fehlen können, oder Anfragen in den Protokolleinträgen leichter gruppieren.
method: integer + string Gibt eine Ganzzahl zurück, die der Methode in der HTTP-Anfrage entspricht. Beispielsweise entspricht “GET” dem Wert 1; die Zuordnung lässt sich im Quellcode nachsehen. Der Wert 9 bedeutet „andere Methode“ und kann in eine aus dem Datenstrom extrahierte Zeichenfolge umgewandelt werden. Dies sollte nicht direkt als Sample verwendet werden, sondern ausschließlich in ACLs, die Methoden in Mustern transparent in diese Werte aus Ganzzahl und Zeichenfolge umwandeln. Einige vordefinierte ACL prüfen bereits die gängigsten Methoden.
ACL-Varianten:
Beispiel:
path: string Extrahiert den URL-Pfad der Anfrage, der beim ersten Schrägstrich beginnt und vor dem Fragezeichen endet, ohne den Hostteil. Typische Anwendungen sind Caches mit Vorabrufunterstützung sowie Portale, die mehrere Informationen aus Datenbanken zusammenführen und in Caches vorhalten müssen. Bei Caches für ausgehenden Verkehr wäre “url” die bessere Wahl. In ACLs wird dies meist zum Vergleich exakter Dateinamen wie “/login.php” oder, über die abgeleiteten Varianten, von Verzeichnisteilen verwendet. Siehe auch die Abrufmethoden “url” und “base”. Beachten Sie, dass der HTTP-Standard jeglichen Fragmentverweis in der URI (’#’ nach dem Pfad) strikt verbietet und dieser daher abgewiesen wird. Hat das Frontend, das die Anfrage empfängt, jedoch “option accept-unsafe-violations-in-http-request” gesetzt, wird dieser Fragmentteil akzeptiert und erscheint auch im Pfad.
ACL-Varianten:
Hinweis: Auf ACL-Varianten darf kein Konverter folgen; sie dürfen auch nicht in ACLs mit einer Mustervergleichsmethode “-m” verwendet werden.
pathq: string Extrahiert den URL-Pfad der Anfrage einschließlich der Abfragezeichenfolge, beginnend beim ersten Schrägstrich. Diese Abrufmethode eignet sich dazu, stets eine relative URI ohne Schema und gegebenenfalls vorhandenen Autoritätsteil zu erhalten. Während dies die übliche Darstellung eines HTTP/1.1-Anfrageziels ist, wird bei HTTP/2 häufig eine absolute URI verwendet. Diese Abrufmethode liefert in beiden Fällen dasselbe Ergebnis. Beachten Sie, dass der HTTP-Standard jeglichen Fragmentverweis in der URI (’#’ nach dem Pfad) strikt verbietet und dieser daher abgewiesen wird. Hat das Frontend, das die Anfrage empfängt, jedoch “option accept-unsafe-violations-in-http-request” gesetzt, wird dieser Fragmentteil akzeptiert und erscheint auch im Pfad.
query([<options>]): string
Extrahiert die Abfragezeichenfolge der Anfrage, die nach dem ersten Fragezeichen beginnt. Ohne Fragezeichen liefert dieser Abruf nichts zurück. Ist ein Fragezeichen vorhanden, auf das nichts folgt, wird eine leere Zeichenfolge zurückgegeben. Mit der Vergleichsmethode “found” lässt sich daher einfach feststellen, ob eine Abfragezeichenfolge vorhanden ist. Diese Abrufmethode ergänzt “path”, das vor dem Fragezeichen endet, und “query_string”, das das Fragezeichen einschließt.
Mit einem optionalen Parameter lässt sich der Rückgabewert anpassen. Folgende Optionen werden unterstützt:
- with_qm: Das Fragezeichen am Anfang der Abfragezeichenfolge einschließen,
sofern diese nicht leer ist.
req.body: binary Gibt den verfügbaren Inhalt der HTTP-Anfrage als Datenblock zurück. Es wird empfohlen, “option http-buffer-request” zu verwenden, damit so weit wie möglich auf den Anfrageinhalt gewartet wird.
req.body_len: integer Gibt die Länge des verfügbaren Inhalts der HTTP-Anfrage in Bytes zurück. Sie kann geringer als die angekündigte Länge sein, wenn der Inhalt größer als der Puffer ist. Es wird empfohlen, “option http-buffer-request” zu verwenden, damit so weit wie möglich auf den Anfrageinhalt gewartet wird.
req.body_param([<name>[,i]]): string
Diese Abrufmethode setzt voraus, dass der Inhalt der POST-Anfrage URL-kodiert ist. Der Benutzer
kann prüfen, ob “content-type” den Wert “application/x-www-form-urlencoded” enthält. Extrahiert
wird das erste Vorkommen des Parameters <name> im Inhalt, das vor ‘&’ endet. Beim Parameternamen
wird zwischen Groß- und Kleinschreibung unterschieden, sofern nicht “i” als zweites Argument
angegeben ist. Ohne Namensangabe passt jeder Parameter, und der erste wird zurückgegeben. Das
Ergebnis ist eine Zeichenfolge mit dem Wert des Parameters <name> in seiner Darstellung im
Anfrageinhalt; eine URL-Dekodierung erfolgt nicht. Beachten Sie, dass die ACL-Variante dieser
Abrufmethode mehrere Parameter durchläuft und ohne Namensangabe nacheinander alle Parameterwerte
liefert.
req.body_size: integer Gibt die angekündigte Länge des Inhalts der HTTP-Anfrage in Bytes zurück. Dies entspricht dem angekündigten Content-Length-Header oder, bei Chunked-Kodierung, der Größe der verfügbaren Daten.
req.cook([<name>]): string
Extrahiert das letzte Vorkommen des Cookie-Namens <name> aus einer “Cookie”-Headerzeile der
Anfrage und gibt dessen Wert als Zeichenfolge zurück. Ohne Namensangabe wird der Wert des ersten
Cookies zurückgegeben. In ACLs werden alle passenden Cookies ausgewertet. Leerzeichen um Namen
und Wert werden gemäß der Spezifikation des Cookie-Headers (RFC6265) ignoriert. Beim Cookie-Namen
wird zwischen Groß- und Kleinschreibung unterschieden. Leere Cookies sind gültig, sodass ein
vorhandenes leeres Cookie durchaus einen leeren Wert zurückgeben kann. Mit dem Vergleich “found”
lässt sich das Vorhandensein erkennen. Verwenden Sie für vom Server gesendete Antwort-Cookies
die Variante res.cook().
ACL-Varianten:
Hinweis: Auf ACL-Varianten darf kein Konverter folgen; sie dürfen auch nicht in ACLs mit einer Mustervergleichsmethode “-m” verwendet werden.
req.cook_cnt([<name>]): integer
Gibt eine Ganzzahl zurück, die der Anzahl der Vorkommen des Cookies <name> in der Anfrage
entspricht, oder aller Cookies, wenn <name> nicht angegeben ist.
req.cook_names([<delim>]): string
Bildet eine Zeichenfolge durch Verkettung aller Cookie-Namen, wie sie beim Auswerten der Regel
in der Anfrage im Cookie-Header erscheinen. Das Standardtrennzeichen ist das Komma (’,’); es kann
jedoch über das optionale Argument <delim> überschrieben werden. Dabei wird nur das erste
Zeichen von <delim> berücksichtigt.
req.cook_val([<name>]): integer
Extrahiert das letzte Vorkommen des Cookie-Namens <name> aus einer “Cookie”-Headerzeile der
Anfrage, wandelt dessen Wert in eine Ganzzahl um und gibt sie zurück. Ohne Namensangabe wird der
Wert des ersten Cookies zurückgegeben. In ACLs werden alle passenden Namen durchlaufen, bis ein
Wert übereinstimmt.
req.fhdr(<name>[,<occ>]): string
Gibt den vollständigen Wert des letzten Vorkommens des Headers <name> in einer HTTP-Anfrage
zurück. Anders als bei req.hdr() werden im Wert vorhandene Kommata mit zurückgegeben und nicht
als Trennzeichen verwendet. Bei Headern wie User-Agent kann dies nützlich sein.
Bei Verwendung in einer ACL werden alle Vorkommen durchlaufen, bis eine Übereinstimmung gefunden wird.
Optional kann ein bestimmtes Vorkommen durch eine Positionsnummer angegeben werden. Positive Werte zählen vom ersten Vorkommen an, wobei 1 das erste bezeichnet. Negative Werte geben die Position relativ zum letzten Vorkommen an, wobei -1 das letzte bezeichnet.
req.fhdr_cnt([<name>]): integer
Gibt eine Ganzzahl zurück, die der Anzahl der Vorkommen des Anfrageheader-Feldnamens <name>
entspricht, oder der Gesamtzahl der Headerfelder, wenn <name> nicht angegeben ist. Wie req.fhdr()
unterscheidet sich dies von res.hdr_cnt() dadurch, dass Header nicht an Kommata aufgeteilt werden.
req.hdr([<name>[,<occ>]]): string
Gibt den letzten durch Kommata getrennten Wert des Headers <name> in einer HTTP-Anfrage zurück.
Diese Abrufmethode behandelt jedes Komma als Trennzeichen zwischen einzelnen Werten. Dies ist
nützlich zur Verarbeitung von Headern, die als Wertelisten definiert sind, etwa Accept oder
X-Forwarded-For. Wenn stattdessen vollständige Headerzeilen benötigt werden, verwenden Sie
req.fhdr(). Prüfen Sie sorgfältig in RFC 7231, wie bestimmte Header zu analysieren sind. Bei
einigen, beispielsweise Connection, wird außerdem nicht zwischen Groß- und Kleinschreibung
unterschieden.
Bei Verwendung in einer ACL werden alle Vorkommen durchlaufen, bis eine Übereinstimmung gefunden wird.
Optional kann ein bestimmtes Vorkommen durch eine Positionsnummer angegeben werden. Positive Werte zählen vom ersten Vorkommen an, wobei 1 das erste bezeichnet. Negative Werte geben die Position relativ zum letzten Vorkommen an, wobei -1 das letzte bezeichnet.
Eine typische Anwendung ist der in eine IP-Adresse umgewandelte X-Forwarded-For-Header in Verbindung mit einer Stick Table für IP-Adressen.
ACL-Varianten:
Hinweis: Auf ACL-Varianten darf kein Konverter folgen; sie dürfen auch nicht in ACLs mit einer Mustervergleichsmethode “-m” verwendet werden.
req.hdr_cnt([<name>]): integer
Gibt eine Ganzzahl zurück, die der Anzahl der Vorkommen des Anfrageheader-Feldnamens <name>
entspricht, oder der Gesamtzahl der Headerfeldwerte, wenn <name> nicht angegeben ist. Wie req.hdr()
zählt dies jeden durch Kommata getrennten Teil des Headerwerts. Sollen vollständige Headerzeilen
gezählt werden, ist stattdessen req.fhdr_cnt() zu verwenden.
In ACLs kann damit das Vorhandensein, Fehlen oder der Missbrauch eines bestimmten Headers erkannt werden. Außerdem lassen sich Request-Smuggling-Angriffe abwehren, indem Anfragen mit mehreren Vorkommen bestimmter Header abgewiesen werden.
Weitere Informationen zum Headervergleich finden Sie unter req.hdr().
req.hdr_ip([<name>[,<occ>]]): ip
Extrahiert das letzte Vorkommen des Headers <name> in einer HTTP-Anfrage, wandelt es in eine
IPv4- oder IPv6-Adresse um und gibt diese zurück. In ACLs werden alle Vorkommen geprüft; wenn
<name> fehlt, wird jeder Wert jedes Headers geprüft. Der Parser hält sich strikt an das in
RFC7239 beschriebene Format, mit der Erweiterung, dass auf IPv4-Adressen optional ein Doppelpunkt
(’:’) und eine gültige dezimale Portnummer von 0 bis 65535 folgen dürfen. Die Portnummer wird
stillschweigend verworfen. Alle anderen Formen passen nicht und führen dazu, dass die Adresse
ignoriert wird.
Der Parameter <occ> wird wie bei req.hdr() verarbeitet.
Typische Anwendungen sind die Header X-Forwarded-For und X-Client-IP.
req.hdr_names([<delim>]): string
Bildet eine Zeichenfolge durch Verkettung aller Headernamen, wie sie beim Auswerten der Regel in
der Anfrage erscheinen. Das Standardtrennzeichen ist das Komma (’,’); es kann jedoch über das
optionale Argument <delim> überschrieben werden. Dabei wird nur das erste Zeichen von <delim>
berücksichtigt.
req.hdr_val([<name>[,<occ>]]): integer
Extrahiert das letzte Vorkommen des Headers <name> in einer HTTP-Anfrage und wandelt es in eine
Ganzzahl um. In ACLs werden alle Vorkommen geprüft; wenn <name> fehlt, wird jeder Wert jedes
Headers geprüft.
Der Parameter <occ> wird wie bei req.hdr() verarbeitet.
Eine typische Anwendung ist der Header X-Forwarded-For.
req.hdrs: string Gibt die aktuellen Anfrageheader als Zeichenfolge zurück, einschließlich der abschließenden Leerzeile, die die Header vom Anfrageinhalt trennt. Anhand dieser Leerzeile lässt sich ein abgeschnittener Headerblock erkennen. Dieser Sample-Abruf ist für bestimmte SPOE-Headeranalysatoren und für erweiterte Protokollierung nützlich.
req.hdrs_bin: binary Gibt die aktuellen Anfrageheader in voranalysierter Binärform zurück. Damit lässt sich ein Teil der Verarbeitung über SPOE auslagern. Jede Zeichenfolge wird durch eine Längenangabe gefolgt von der darin angegebenen Anzahl Bytes beschrieben. Die Länge wird mit der in der SPOE-Dokumentation beschriebenen variablen Ganzzahlkodierung dargestellt. Das Ende der Liste wird durch ein Paar aus leerem Headernamen und leerem Wert markiert, beide mit der Länge 0.
*(<str:header-name>``<str:header-value>)<empty string>``<empty string>
int: Zur Kodierung siehe die SPOE-Dokumentation. str: <int:length>``<bytes>
req.timer.hdr: integer Gesamtdauer bis zum Empfang der Client-Anfrage, nur im HTTP-Modus. Dies ist die Zeit vom Empfang der ersten Bytes bis zum Empfang der Leerzeile, die das Ende der HTTP-Header markiert, durch den Proxy. Sie wird in Millisekunden (ms) angegeben und entspricht %TR in log-format. Einzelheiten finden Sie in Abschnitt 8.4 „Zeitereignisse“.
req.timer.idle: integer Leerlaufzeit vor der HTTP-Anfrage, nur im HTTP-Modus. Dieser Zeitgeber zählt vom Ende der Handshakes bis zum ersten Byte der HTTP-Anfrage. Der Wert wird in Millisekunden angegeben und entspricht %Ti in log-format. Einzelheiten finden Sie in Abschnitt 8.4 „Zeitereignisse“.
req.timer.queue: integer Gesamtdauer in den Warteschlangen beim Warten auf einen Verbindungsplatz. Sie wird in Millisekunden angegeben und entspricht %Tw in log-format. Einzelheiten finden Sie in Abschnitt 8.4 „Zeitereignisse“.
req.timer.tq: integer Gesamtdauer bis zum Empfang der Client-Anfrage ab dem Annahmezeitpunkt oder seit dem Senden des letzten Bytes der vorherigen Antwort. Sie wird in Millisekunden angegeben und entspricht %Tq in log-format. Einzelheiten finden Sie in Abschnitt 8.4 „Zeitereignisse“.
req.ver: string req_ver: string (veraltet) Gibt die Versionszeichenfolge aus der HTTP-Anfrage im
Format “<major>.<minor>” zurück. Dies kann für ACL nützlich sein. Einige vordefinierte ACL prüfen
bereits gängige Versionen. Da die Information dauerhaft gespeichert ist, kann sie sowohl in
Anfragen und Antworten als auch in Protokolleinträgen verwendet werden. Ist die Version der Anfrage
ungültig, schlägt dieser Sample-Abruf fehl.
Gängige Werte sind “1.0”, “1.1”, “2.0” oder “3.0”.
ACL-Varianten:
request_date([<unit>]): integer
Dies ist der genaue Zeitpunkt, zu dem HAProxy das erste Byte der HTTP-Anfrage empfangen hat (log-format-Alias %tr). Er wird aus accept_date + Handshake-Dauer (%Th) + Leerlaufzeit (%Ti) berechnet.
Gibt die Anzahl der Sekunden seit der Unix-Epoche zurück.
<unit> ist optional und kann auf “s” für Sekunden (Standardverhalten), “ms” für Millisekunden
oder “us” für Mikrosekunden gesetzt werden. Bei angegebener Einheit ist der Rückgabewert eine
Ganzzahl, die die Sekunden, Millisekunden oder Mikrosekunden seit der Unix-Epoche angibt. Dies ist
nützlich, wenn eine Zeitauflösung von weniger als einer Sekunde benötigt wird.
res.body: binary Gibt den verfügbaren Inhalt der HTTP-Antwort als Datenblock zurück. Anders als auf der Anfrageseite gibt es keine Direktive, um auf den Antwortinhalt zu warten. Dieser Sample-Abruf ist im Kontext von Health Checks besonders nützlich und verwendbar.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
res.body_len: integer Gibt die Länge des verfügbaren Inhalts der HTTP-Antwort in Bytes zurück. Anders als auf der Anfrageseite gibt es keine Direktive, um auf den Antwortinhalt zu warten. Dieser Sample-Abruf ist im Kontext von Health Checks besonders nützlich und verwendbar.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
res.body_size: integer Gibt die angekündigte Länge des Inhalts der HTTP-Antwort in Bytes zurück. Dies entspricht dem angekündigten Content-Length-Header oder, bei Chunked-Kodierung, der Größe der verfügbaren Daten. Anders als auf der Anfrageseite gibt es keine Direktive, um auf den Antwortinhalt zu warten. Dieser Sample-Abruf ist im Kontext von Health Checks besonders nützlich und verwendbar.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
res.cache_hit: boolean Gibt den booleschen Wert “true” zurück, wenn die Antwort aus einem HTTP-Cache-Eintrag erstellt wurde, andernfalls den booleschen Wert “false”.
res.cache_name: string Gibt eine Zeichenfolge mit dem Namen des HTTP-Caches zurück, aus dem die HTTP-Antwort erstellt wurde, wenn res.cache_hit true ist; andernfalls eine leere Zeichenfolge.
res.comp: boolean Gibt den booleschen Wert “true” zurück, wenn HAProxy die Antwort komprimiert hat, andernfalls den booleschen Wert “false”. Damit können zusätzliche Informationen in die Protokolleinträge aufgenommen werden.
res.comp_algo: string Gibt eine Zeichenfolge mit dem Namen des verwendeten Algorithmus zurück, wenn HAProxy die Antwort komprimiert hat, beispielsweise “deflate”. Damit können zusätzliche Informationen in die Protokolleinträge aufgenommen werden.
res.cook([<name>]): string
Extrahiert das letzte Vorkommen des Cookie-Namens <name> aus einer “Set-Cookie”-Headerzeile der
Antwort und gibt dessen Wert als Zeichenfolge zurück. Ohne Namensangabe wird der Wert des ersten
Cookies zurückgegeben.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
ACL-Varianten:
res.cook_cnt([<name>]): integer
Gibt eine Ganzzahl zurück, die der Anzahl der Vorkommen des Cookies <name> in der Antwort
entspricht, oder aller Cookies, wenn <name> nicht angegeben ist. Dies ist vor allem zusammen
mit ACLs nützlich, um verdächtige Antworten zu erkennen.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
res.cook_names([<delim>]): string
Bildet eine Zeichenfolge durch Verkettung aller Cookie-Namen, wie sie beim Auswerten der Regel
in der Antwort in den Set-Cookie-Headern erscheinen. Das Standardtrennzeichen ist das Komma (’,’);
es kann jedoch über das optionale Argument <delim> überschrieben werden. Dabei wird nur das
erste Zeichen von <delim> berücksichtigt.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
res.cook_val([<name>]): integer
Extrahiert das letzte Vorkommen des Cookie-Namens <name> aus einer “Set-Cookie”-Headerzeile der
Antwort, wandelt dessen Wert in eine Ganzzahl um und gibt sie zurück. Ohne Namensangabe wird der
Wert des ersten Cookies zurückgegeben.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
res.fhdr([<name>[,<occ>]]): string
Diese Abrufmethode funktioniert wie req.fhdr(), arbeitet jedoch mit den Headern einer HTTP-Antwort.
Wie req.fhdr() gibt die Abrufmethode res.fhdr() vollständige Werte zurück. Wenn der Header als Liste definiert ist, sollten Sie res.hdr() verwenden.
Diese Abrufmethode ist mitunter für Header wie Date oder Expires nützlich.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
res.fhdr_cnt([<name>]): integer
Diese Abrufmethode funktioniert wie req.fhdr_cnt(), arbeitet jedoch mit den Headern einer HTTP-Antwort.
Wie req.fhdr_cnt() arbeitet die Abrufmethode res.fhdr_cnt() mit vollständigen Werten. Wenn der Header als Liste definiert ist, sollten Sie res.hdr_cnt() verwenden.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
res.hdr([<name>[,<occ>]]): string
Diese Abrufmethode funktioniert wie req.hdr(), arbeitet jedoch mit den Headern einer HTTP-Antwort.
Wie req.hdr() betrachtet die Abrufmethode res.hdr() das Komma als Trennzeichen. Ist dies nicht gewünscht, sollte res.fhdr() verwendet werden.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
ACL-Varianten:
Hinweis: Auf ACL-Varianten darf kein Konverter folgen; sie dürfen auch nicht in ACLs mit einer Mustervergleichsmethode “-m” verwendet werden.
res.hdr_cnt([<name>]): integer
Diese Abrufmethode funktioniert wie req.hdr_cnt(), arbeitet jedoch mit den Headern einer HTTP-Antwort.
Wie req.hdr_cnt() betrachtet die Abrufmethode res.hdr_cnt() das Komma als Trennzeichen. Ist dies nicht gewünscht, sollte res.fhdr_cnt() verwendet werden.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
res.hdr_ip([<name>[,<occ>]]): ip
Diese Abrufmethode funktioniert wie req.hdr_ip(), arbeitet jedoch mit den Headern einer HTTP-Antwort.
Dies kann nützlich sein, um Daten in eine Stick Table zu übernehmen.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
res.hdr_names([<delim>]): string
Bildet eine Zeichenfolge durch Verkettung aller Headernamen, wie sie beim Auswerten der Regel in
der Antwort erscheinen. Das Standardtrennzeichen ist das Komma (’,’); es kann jedoch über das
optionale Argument <delim> überschrieben werden. Dabei wird nur das erste Zeichen von <delim>
berücksichtigt.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
res.hdr_val([<name>[,<occ>]]): integer
Diese Abrufmethode funktioniert wie req.hdr_val(), arbeitet jedoch mit den Headern einer HTTP-Antwort.
Dies kann nützlich sein, um Daten in eine Stick Table zu übernehmen.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
res.hdrs: string Gibt die aktuellen Antwortheader als Zeichenfolge zurück, einschließlich der abschließenden Leerzeile, die die Header vom Anfrageinhalt trennt. Anhand dieser Leerzeile lässt sich ein abgeschnittener Headerblock erkennen. Dieser Sample-Abruf ist für bestimmte SPOE-Headeranalysatoren und für erweiterte Protokollierung nützlich.
Dies kann auch in expect-Regeln auf Basis von tcp-check verwendet werden.
res.hdrs_bin: binary Gibt die aktuellen Antwortheader in voranalysierter Binärform zurück. Damit lässt sich ein Teil der Verarbeitung über SPOE auslagern. Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden. Jede Zeichenfolge wird durch eine Längenangabe gefolgt von der darin angegebenen Anzahl Bytes beschrieben. Die Länge wird mit der in der SPOE-Dokumentation beschriebenen variablen Ganzzahlkodierung dargestellt. Das Ende der Liste wird durch ein Paar aus leerem Headernamen und leerem Wert markiert, beide mit der Länge 0.
*(<str:header-name>``<str:header-value>)<empty string>``<empty string>
int: Zur Kodierung siehe die SPOE-Dokumentation. str: <int:length>``<bytes>
res.timer.hdr: integer Zeit vom Aufbau der TCP-Verbindung zum Server bis zum Senden seiner vollständigen Antwortheader. Sie wird in Millisekunden angegeben und entspricht %Tr in log-format. Einzelheiten finden Sie in Abschnitt 8.4 „Zeitereignisse“.
res.ver: string resp_ver: string (veraltet) Gibt die Versionszeichenfolge aus der HTTP-Antwort im
Format “<major>.<minor>” zurück. Dies kann für Protokolleinträge nützlich sein, ist aber
hauptsächlich für ACL vorgesehen. Ist die Version der Antwort ungültig, schlägt dieser
Sample-Abruf fehl.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
ACL-Varianten:
server_status: integer Gibt eine Ganzzahl mit dem vom Server empfangenen HTTP-Statuscode zurück. Wenn keine Antwort vom Server empfangen wurde, schlägt der Sample-Abruf fehl.
set-cookie([<name>]): string (deprecated)
Extrahiert das letzte Vorkommen des Cookie-Namens <name> aus einer “Set-Cookie”-Headerzeile der
Antwort und verwendet den zugehörigen Wert für den Vergleich. Dies ist mit der früheren Funktion
von “appsession” mit Standardoptionen vergleichbar, unterstützt aber die Synchronisierung zwischen
mehreren Peers und die Erhaltung des Zustands über Neustarts hinweg.
Diese Abruffunktion ist veraltet und wurde durch die Abrufmethode “res.cook” ersetzt. Dieses Schlüsselwort wird in Kürze entfernt.
status: integer Gibt eine Ganzzahl mit dem HTTP-Statuscode der HTTP-Antwort zurück, beispielsweise 302. Dies wird hauptsächlich in ACLs und mit Ganzzahlbereichen verwendet, etwa um jeglichen Location-Header zu entfernen, wenn die Antwort kein 3xx-Status ist. Dies ist der vom Client empfangene Statuscode, sofern er nicht geändert wird, beispielsweise durch eine Aktion ‘set-status’.
Dies kann in expect-Regeln auf Basis von tcp-check verwendet werden.
txn.status: integer Gibt eine Ganzzahl mit dem HTTP-Statuscode der Transaktion zurück, wie er im Protokoll angegeben wird.
txn.timer.total: integer Gesamte aktive Zeit für die HTTP-Anfrage vom Empfang des ersten Bytes des Anfrageheaders durch den Proxy bis zum Senden des letzten Bytes des Antwortinhalts. Dies entspricht %Ta in log-format und wird in Millisekunden (ms) angegeben. Weitere Informationen finden Sie in Abschnitt 8.4 „Zeitereignisse“.
unique-id: string Gibt die der Anfrage zugeordnete unique-id zurück. Die Direktive “unique-id-format” muss gesetzt sein; andernfalls schlägt der Sample-Abruf unique-id fehl. Die unique-id wird zwar üblicherweise mit HTTP-Anfragen verwendet, diese Abrufmethode kann jedoch auch mit anderen Protokollen verwendet werden. Bei anderen Protokollen als HTTP darf die Direktive unique-id-format selbstverständlich keine HTTP-Bestandteile enthalten. Siehe: unique-id-format und unique-id-header.
url: string Extrahiert die URL der Anfrage in der darin vorliegenden Form. Typische Anwendungen sind Caches mit Vorabrufunterstützung sowie Portale, die mehrere Informationen aus Datenbanken zusammenführen und in Caches vorhalten müssen. In ACLs ist “path” gegenüber “url” vorzuziehen, da Clients eine vollständige URL senden können, wie dies bei Proxys üblich ist. Der einzig wirkliche Anwendungsfall ist der Vergleich mit “*”, das in “path” nicht passt und für das bereits eine vordefinierte ACL existiert. Siehe auch “path” und “base”. Beachten Sie, dass der HTTP-Standard jeglichen Fragmentverweis in der URI (’#’ nach dem Pfad) strikt verbietet und dieser daher abgewiesen wird. Hat das Frontend, das die Anfrage empfängt, jedoch “option accept-unsafe-violations-in-http-request” gesetzt, wird dieser Fragmentteil akzeptiert und erscheint auch in der URL.
ACL-Varianten:
Hinweis: Auf ACL-Varianten darf kein Konverter folgen; sie dürfen auch nicht in ACLs mit einer Mustervergleichsmethode “-m” verwendet werden.
url32: integer Gibt einen 32-Bit-Hash des Werts zurück, der durch Verkettung des ersten Host-Headers mit der gesamten URL einschließlich der Parameter entsteht, also nicht nur mit dem Pfadteil der Anfrage wie beim oben beschriebenen Abruf “base32”. Dies ist nützlich, um die Aktivität je URL zu verfolgen. Gespeichert wird ein kürzerer Hash, was viel Speicher spart. Der Ausgabetyp ist eine vorzeichenlose Ganzzahl.
url32+src: binary Gibt die Verkettung der Abrufmethoden “url32” und “src” zurück. Das Ergebnis ist vom Typ binary und je nach Adressfamilie der Quelladresse 8 oder 20 Bytes groß. Damit lassen sich Zähler je IP und je URL führen.
url_ip: ip Extrahiert die IP-Adresse aus der URL der Anfrage, wenn der Hostteil als IP-Adresse angegeben ist. Ist der Hostteil ein Name, schlägt der Abruf fehl, da keine Namensauflösung erfolgt. Die Verwendung ist sehr eingeschränkt. Beispielsweise kann ein Überwachungssystem dieses Feld anstelle der Quell-IP verwenden, um zu testen, welchen Pfad eine bestimmte Quelladresse nehmen würde, oder um einen Eintrag in einer Tabelle für eine bestimmte Quelladresse zu erzwingen. Es kann zusammen mit ‘http-request set-dst’ verwendet werden, um das frühere ‘option http_proxy’ nachzubilden.
url_port: integer Extrahiert den Portteil aus der URL der Anfrage. Wenn in der Anfrage kein Port angegeben ist, wird Port 80 angenommen. Wie bei “url_ip” funktioniert dies nur, wenn der Authority-Teil der URL als Adresse angegeben ist. Bei einem Hostnamen schlägt der Abruf fehl, da hier keine Namensauflösung erfolgt.
urlp([<name>[,<delim>[,i]]]): string
Extrahiert das erste Vorkommen des Parameters <name> aus der Abfragezeichenfolge, die nach ‘?’
oder <delim> beginnt und vor ‘&’, ‘;’ oder <delim> endet. Beim Parameternamen wird zwischen
Groß- und Kleinschreibung unterschieden, sofern nicht “i” als drittes Argument angegeben ist.
Ohne Namensangabe passt jeder Parameter, und der erste wird zurückgegeben. Das Ergebnis ist eine
Zeichenfolge mit dem Wert des Parameters <name> in seiner Darstellung in der Anfrage; eine
URL-Dekodierung erfolgt nicht. Dies kann zur Sitzungsbindung anhand einer Client-ID, zum
Extrahieren eines als URL-Parameter übergebenen Anwendungscookies oder für Prüfungen in ACLs
verwendet werden. Beachten Sie, dass die ACL-Variante dieser Abrufmethode mehrere Parameter
durchläuft und ohne Namensangabe nacheinander alle Parameterwerte liefert.
ACL-Varianten:
Hinweis: Auf ACL-Varianten darf kein Konverter folgen; sie dürfen auch nicht in ACLs mit einer Mustervergleichsmethode “-m” verwendet werden.
Beispiel:
urlp_val([<name>[,<delim>[,i]]]): integer
Siehe “urlp” oben. Diese Variante extrahiert den URL-Parameter <name> aus der Anfrage und wandelt
ihn in eine Ganzzahl um. Dies kann beispielsweise zur Sitzungsbindung anhand einer Benutzer-ID
oder in ACLs zum Vergleich einer Seitennummer oder eines Preises verwendet werden.
7.3.7. Sample-Abruf für Entwickler
Diese Methoden zum Sample-Abruf sind Entwicklern vorbehalten und dürfen niemals in einer Produktionsumgebung verwendet werden, außer auf Anforderung eines Entwicklers zur Fehlersuche. Außerdem wird keine besondere Rücksicht auf Abwärtskompatibilität genommen. Es gibt keine Garantie, dass die folgenden Abrufmethoden nicht geändert, umbenannt oder einfach entfernt werden. Seien Sie daher besonders vorsichtig, falls Sie eine davon verwenden müssen. Um Mehrdeutigkeiten zu vermeiden, liegen diese Methoden im eigenen Namensbereich “internal”, beispielsweise “internal.strm.is_htx”.
Übersicht der Methoden zum Sample-Abruf in diesem Abschnitt und ihrer jeweiligen Typen:
Ausführliche Liste:
internal.htx.data: integer Gibt die Größe in Bytes zurück, die die Daten in der einem Kanal zugeordneten HTX-Nachricht belegen. Der Kanal wird anhand der Sample-Richtung ausgewählt.
internal.htx.free: integer Gibt den freien Platz (size - used) in Bytes in der einem Kanal zugeordneten HTX-Nachricht zurück. Der Kanal wird anhand der Sample-Richtung ausgewählt.
internal.htx.free_data: integer Gibt den freien Platz für Daten in Bytes in der einem Kanal zugeordneten HTX-Nachricht zurück. Der Kanal wird anhand der Sample-Richtung ausgewählt.
internal.htx.has_eom: boolean Gibt true zurück, wenn die einem Kanal zugeordnete HTX-Nachricht das Flag für das Nachrichtenende (EOM) enthält, andernfalls false. Der Kanal wird anhand der Sample-Richtung ausgewählt.
internal.htx.nbblks: integer Gibt die Anzahl der Blöcke in der einem Kanal zugeordneten HTX-Nachricht zurück. Der Kanal wird anhand der Sample-Richtung ausgewählt.
internal.htx.size: integer Gibt die Gesamtgröße in Bytes der einem Kanal zugeordneten HTX-Nachricht zurück. Der Kanal wird anhand der Sample-Richtung ausgewählt.
internal.htx.used: integer Gibt die insgesamt belegte Größe in Bytes (Daten + Metadaten) in der einem Kanal zugeordneten HTX-Nachricht zurück. Der Kanal wird anhand der Sample-Richtung ausgewählt.
internal.htx_blk.size(<idx>): integer
Gibt die Größe des Blocks an Position <idx> in der einem Kanal zugeordneten HTX-Nachricht zurück,
oder 0, wenn er nicht existiert. Der Kanal wird anhand der Sample-Richtung ausgewählt. <idx> kann
eine beliebige positive Ganzzahl oder einer der folgenden Sonderwerte sein: * head : Der älteste
eingefügte Block * tail : Der zuletzt eingefügte Block * first: Der erste Block, bei dem die Analyse
(neu) beginnen soll.
internal.htx_blk.type(<idx>): string
Gibt den Typ des Blocks an Position <idx> in der einem Kanal zugeordneten HTX-Nachricht zurück,
oder “HTX_BLK_UNUSED”, wenn er nicht existiert. Der Kanal wird anhand der Sample-Richtung
ausgewählt. <idx> kann eine beliebige positive Ganzzahl oder einer der folgenden Sonderwerte sein:
* head : Der älteste eingefügte Block * tail : Der zuletzt eingefügte Block * first: Der erste Block,
bei dem die Analyse (neu) beginnen soll.
internal.htx_blk.data(<idx>): binary
Gibt den Wert des DATA-Blocks an Position <idx> in der einem Kanal zugeordneten HTX-Nachricht
zurück, oder eine leere Zeichenfolge, wenn er nicht existiert oder kein DATA-Block ist. Der Kanal
wird anhand der Sample-Richtung ausgewählt. <idx> kann eine beliebige positive Ganzzahl oder
einer der folgenden Sonderwerte sein:
* head : Der älteste eingefügte Block
* tail : Der zuletzt eingefügte Block
* first: Der erste Block, bei dem die Analyse (neu) beginnen soll
internal.htx_blk.hdrname(<idx>): string
Gibt den Headernamen des HEADER-Blocks an Position <idx> in der einem Kanal zugeordneten
HTX-Nachricht zurück, oder eine leere Zeichenfolge, wenn er nicht existiert oder kein HEADER-Block
ist. Der Kanal wird anhand der Sample-Richtung ausgewählt. <idx> kann eine beliebige positive
Ganzzahl oder einer der folgenden Sonderwerte sein:
* head : Der älteste eingefügte Block
* tail : Der zuletzt eingefügte Block
* first: Der erste Block, bei dem die Analyse (neu) beginnen soll
internal.htx_blk.hdrval(<idx>): string
Gibt den Headerwert des HEADER-Blocks an Position <idx> in der einem Kanal zugeordneten
HTX-Nachricht zurück, oder eine leere Zeichenfolge, wenn er nicht existiert oder kein HEADER-Block
ist. Der Kanal wird anhand der Sample-Richtung ausgewählt. <idx> kann eine beliebige positive
Ganzzahl oder einer der folgenden Sonderwerte sein:
* head : Der älteste eingefügte Block
* tail : Der zuletzt eingefügte Block
* first: Der erste Block, bei dem die Analyse (neu) beginnen soll
internal.htx_blk.start_line(<idx>): string
Gibt den Wert des REQ_SL- oder RES_SL-Blocks an Position <idx> in der einem Kanal zugeordneten
HTX-Nachricht zurück, oder eine leere Zeichenfolge, wenn er nicht existiert oder kein SL-Block
ist. Der Kanal wird anhand der Sample-Richtung ausgewählt. <idx> kann eine beliebige positive
Ganzzahl oder einer der folgenden Sonderwerte sein:
* head : Der älteste eingefügte Block
* tail : Der zuletzt eingefügte Block
* first: Der erste Block, bei dem die Analyse (neu) beginnen soll
internal.strm.is_htx: boolean Gibt true zurück, wenn der aktuelle Datenstrom ein HTX-Datenstrom ist. Das bedeutet, dass die Daten in den Kanalpuffern in der internen HTX-Darstellung gespeichert sind. Andernfalls wird false zurückgegeben.
7.4. Vordefinierte ACLs
Einige vordefinierte ACLs sind fest einprogrammiert, damit sie nicht in jedem Frontend deklariert werden müssen, das sie benötigt. Zur Vermeidung von Verwechslungen sind ihre Namen durchgehend großgeschrieben. Die entsprechenden Ausdrücke sind nachfolgend aufgeführt.
17 - 8. Protokollierung
Eine der Stärken von HAProxy sind seine präzisen Protokolle. Sie bieten vermutlich die detailliertesten Informationen, die bei einem solchen Produkt verfügbar sind. Das ist bei der Fehlerbehebung in komplexen Umgebungen sehr wichtig. Zu den standardmäßig protokollierten Angaben gehören Client-Ports, Zeitmessungen der TCP/HTTP-Zustände, der genaue Stream-Zustand und die genaue Ursache bei der Beendigung, Angaben zu Entscheidungen über die Weiterleitung an einen Server und natürlich die Möglichkeit, beliebige Header zu erfassen.
Damit Administratoren schneller reagieren können, macht HAProxy interne wie externe Probleme deutlich sichtbar. Protokolle können gleichzeitig mit unterschiedlichen Stufenfiltern an verschiedene Ziele gesendet werden:
- globale Protokolle auf Prozessebene (Systemfehler, Start/Stopp usw.)
- Systemfehler und interne Fehler je Instanz (Ressourcenmangel, Programmfehler usw.)
- externe Probleme je Instanz (Server verfügbar/ausgefallen, maximale Verbindungszahl)
- Aktivitäten je Instanz (Clientverbindungen), entweder beim Aufbau oder bei der Beendigung.
- Steuerung der Protokollstufe je Anfrage, etwa http-request set-log-level silent if sensitive_request
Durch die Verteilung unterschiedlicher Protokollstufen auf verschiedene Protokollserver können mehrere Betriebsteams zusammenarbeiten und ihre Probleme möglichst schnell beheben. Beispielsweise kann das Systemteam systemweite Fehler überwachen, während das Anwendungsteam den Verfügbarkeitszustand seiner Server in Echtzeit beobachtet und das Sicherheitsteam Aktivitätsprotokolle mit einer Stunde Verzögerung auswertet.
8.1. Protokollstufen
TCP- und HTTP-Verbindungen können mit Datum, Uhrzeit, Quell-IP-Adresse, Zieladresse, Verbindungsdauer, Antwortzeiten, HTTP-Anfrage, HTTP-Statuscode, Anzahl übertragener Bytes, Umständen der Stream-Beendigung und sogar ausgetauschten Cookie-Werten protokolliert werden. Damit lassen sich beispielsweise Probleme eines bestimmten Nutzers verfolgen. Alle Meldungen können an bis zu zwei syslog-Server gesendet werden. Weitere Informationen zu Protokoll-Facilities stehen beim Schlüsselwort “log” in Abschnitt 4.2 .
8.2. Protokollformate
HAProxy unterstützt 5 Protokollformate. Mehrere Felder kommen in allen Formaten vor und werden in den folgenden Abschnitten erläutert. Einige können je nach Konfiguration leicht abweichen, da bestimmte Optionen eigene Kennzeichen verwenden. Folgende Formate werden unterstützt:
-
Das Standardformat ist sehr einfach und wird äußerst selten verwendet. Es liefert nur grundlegende Angaben zur eingehenden Verbindung zum Zeitpunkt ihrer Annahme: Quell-IP:Port, Ziel-IP:Port und Frontend-Name. Dieser Modus wird irgendwann entfallen und daher nur kurz beschrieben.
-
Das TCP-Format ist umfangreicher. Es wird durch “option tcplog” im Frontend aktiviert. HAProxy wartet dann gewöhnlich bis zum Verbindungsende, bevor es protokolliert. Das Format enthält wesentlich mehr Informationen, etwa Zeitmessungen, Verbindungszahlen und Warteschlangengröße. Für reine TCP-Proxys wird dieses Format empfohlen.
-
Das HTTP-Format ist für HTTP-Proxys am umfangreichsten. Es wird durch “option httplog” im Frontend aktiviert. Es enthält dieselben Angaben wie das TCP-Format, ergänzt um HTTP-spezifische Felder wie Anfrage, Statuscode sowie erfasste Header und Cookies. Für HTTP-Proxys wird dieses Format empfohlen.
-
Das CLF-HTTP-Format entspricht dem HTTP-Format, ordnet die Felder aber wie im CLF-Format an. In diesem Modus stehen alle Zeitmessungen, erfassten Werte, Flags usw. jeweils in einem eigenen Feld hinter den gemeinsamen Feldern, in derselben Reihenfolge wie im Standard-HTTP-Format.
-
Mit dem benutzerdefinierten Protokollformat lassen sich eigene Protokollzeilen gestalten.
Die folgenden Abschnitte beschreiben diese Formate im Einzelnen. Die Formatbeschreibung erfolgt feldweise. Sofern nicht anders angegeben, ist ein Feld ein Textabschnitt, der durch eine beliebige Anzahl von Leerzeichen abgegrenzt wird. Da syslog-Server am Zeilenanfang Felder einfügen können, wird stets angenommen, dass das erste Feld den Prozessnamen und die Prozesskennung enthält.
Hinweis: Da Protokollzeilen recht lang sein können, sind die Beispiele in den folgenden Abschnitten möglicherweise auf mehrere Zeilen aufgeteilt. Beispielzeilen beginnen mit 3 schließenden spitzen Klammern (’>>>’). Bei einer mehrzeiligen Darstellung endet jede nicht abschließende Zeile mit einem Backslash (’\’), und die nächste Zeile ist um zwei Zeichen eingerückt.
8.2.1. Standard-Protokollformat
Dieses Format wird verwendet, wenn keine besondere Option gesetzt ist. Die Meldung wird sofort bei Annahme der Verbindung ausgegeben. Derzeit ist dies das einzige Format, das die Ziel-IP-Adresse und die Zielports der Anfrage protokolliert.
Beispiel:
Feld Format Auszug aus dem obigen Beispiel
Ausführliche Feldbeschreibung:
- “source_ip” ist die IP-Adresse des Clients, der die Verbindung aufgebaut hat.
- “source_port” ist der TCP-Port des Clients, der die Verbindung aufgebaut hat.
- “destination_ip” ist die IP-Adresse, mit der sich der Client verbunden hat.
- “destination_port” ist der TCP-Port, mit dem sich der Client verbunden hat.
- “frontend_name” ist der Name des Frontends (oder Listeners), das die Verbindung angenommen und verarbeitet hat.
- “mode” ist der Betriebsmodus des Frontends (TCP oder HTTP).
Bei einem UNIX-Socket sind Quell- und Zieladresse als “unix:” gekennzeichnet. Die Ports geben die interne ID des Sockets an, der die Verbindung angenommen hat; dieselbe ID erscheint auch in den Statistiken.
Für neue Installationen wird von diesem veralteten Format abgeraten, da es irgendwann entfallen wird.
8.2.2. TCP-Protokollformat
Das TCP-Format wird durch “option tcplog” im Frontend verwendet und für reine TCP-Proxys empfohlen. Es liefert viele wertvolle Informationen zur Fehlerbehebung. Da es Zeitmessungen und Bytezähler enthält, wird die Meldung normalerweise am Sitzungsende ausgegeben. Mit “option logasap” kann sie früher ausgegeben werden, was in den meisten Umgebungen mit langen Sitzungen wie entfernten Terminals sinnvoll ist. Sitzungen, die den “monitor”-Regeln entsprechen, werden niemals protokolliert. Mit “option dontlognull” im Frontend können außerdem Meldungen für Sitzungen unterdrückt werden, in denen Client und Server keine Daten ausgetauscht haben. Bei “option dontlog-normal” im Frontend werden erfolgreiche Verbindungen nicht protokolliert.
Intern ist das TCP-Protokollformat als benutzerdefiniertes Format mit genau der folgenden Zeichenkette deklariert. Sie kann bei Bedarf auch als Grundlage für Erweiterungen dienen. Alternativ lässt sich die Variable HAPROXY_TCP_LOG_FMT verwenden. Die Verwendung beschreibt Abschnitt 8.2.6 „Benutzerdefiniertes Protokollformat“:
Das CLF-Protokollformat ist intern als benutzerdefiniertes Format mit genau dieser Zeichenkette deklariert:
Einige Felder können je nach Konfigurationsoption leicht abweichen. Sie sind unten mit einem Sternchen (’*’) hinter dem Feldnamen gekennzeichnet.
Beispiel:
Feld Format Auszug aus dem obigen Beispiel
Ausführliche Feldbeschreibung:
-
“client_ip” ist die IP-Adresse des Clients, der die TCP-Verbindung zu HAProxy aufgebaut hat. Wurde die Verbindung stattdessen über einen UNIX-Socket angenommen, ersetzt das Wort “unix” die IP-Adresse. Bei einem Socket mit “accept-proxy” und korrekt verwendetem PROXY-Protokoll oder mit “accept-netscaler-cip” und korrekt verwendetem NetScaler Client IP Insertion-Protokoll geben die Protokolle die Informationen der weitergeleiteten Verbindung wieder.
-
“client_port” ist der TCP-Port des Clients, der die Verbindung aufgebaut hat. Wurde sie über einen UNIX-Socket angenommen, steht hier stattdessen die ID des annehmenden Sockets, die auch in der Statistikschnittstelle erscheint.
-
“accept_date” ist der genaue Zeitpunkt, zu dem HAProxy die Verbindung empfangen hat. Er kann geringfügig vom im Netzwerk beobachteten Zeitpunkt abweichen, wenn die Verbindung im System-Backlog warten musste. Gewöhnlich entspricht er dem Zeitpunkt in den Protokollen vorgeschalteter Firewalls. Im HTTP-Modus wird accept_date auf den frühesten Zeitpunkt zurückgesetzt, zu dem die Verbindung eine neue Anfrage empfangen kann: bei HTTP/1 auf das Ende der vorherigen Antwort, bei HTTP/2 unmittelbar nach der vorherigen Anfrage.
-
“frontend_name” ist der Name des Frontends (oder Listeners), das die Verbindung angenommen und verarbeitet hat.
-
“backend_name” ist der Name des Backends (oder Listeners), das zur Verwaltung der Verbindung zum Server gewählt wurde. Wenn keine Umschaltregel angewendet wurde, entspricht es dem Frontend, was bei TCP-Anwendungen häufig der Fall ist.
-
“server_name” ist der Name des letzten Servers, an den die Verbindung gesendet wurde. Nach Verbindungsfehlern und einer Umverteilung kann er vom zuerst gewählten Server abweichen. Dieser Server gehört zum Backend, das die Anfrage verarbeitet hat. Wurde die Verbindung vor Erreichen eines Servers abgebrochen, steht statt des Servernamens “
<NOSRV>”. -
“Tw” ist die gesamte Wartezeit in den verschiedenen Warteschlangen in Millisekunden. Der Wert kann “-1” sein, wenn die Verbindung vor Erreichen der Warteschlange abgebrochen wurde. Weitere Einzelheiten stehen unten unter „Zeitmessungen“.
-
“Tc” ist die gesamte Wartezeit bis zum Verbindungsaufbau zum endgültigen Server in Millisekunden, einschließlich Wiederholungsversuchen. Der Wert kann “-1” sein, wenn die Verbindung abgebrochen wurde, bevor eine Verbindung zum Server hergestellt werden konnte. Weitere Einzelheiten stehen unten unter „Zeitmessungen“.
-
“Tt” ist die gesamte Zeit zwischen Annahme und letztem Schließen in Millisekunden. Sie umfasst alle Verarbeitungsschritte. Eine Ausnahme besteht bei “option logasap”: Dann endet die Zeitmessung mit der Protokollausgabe. Ein vorangestelltes ‘+’ zeigt in diesem Fall an, dass der endgültige Wert größer sein wird. Weitere Einzelheiten stehen unten unter „Zeitmessungen“.
-
“bytes_read” ist die Gesamtzahl der zum Zeitpunkt der Protokollausgabe vom Server an den Client übertragenen Bytes. Bei “option logasap” erhält der Wert ein vorangestelltes ‘+’, das auf einen möglicherweise größeren Endwert hinweist. Es handelt sich um einen 64-Bit-Zähler; Werkzeuge zur Protokollauswertung müssen ihn daher ohne Überlauf verarbeiten können.
-
“termination_state” beschreibt den Zustand der Sitzung bei ihrer Beendigung. Das Feld zeigt den Sitzungszustand, die Seite, die die Sitzung beendet hat, und den Grund dafür (Zeitüberschreitung, Fehler usw.). Normalerweise sollten die Flags “–” lauten. Dies bedeutet, dass eine der Seiten die Sitzung beendet hat und keine Daten mehr in den Puffern lagen. Weitere Einzelheiten stehen unten unter „Stream-Zustand bei der Trennung“.
-
“actconn” ist die Gesamtzahl gleichzeitiger Verbindungen im Prozess zum Zeitpunkt der Protokollierung der Sitzung. Sie hilft zu erkennen, wann systemseitige Grenzen je Prozess erreicht wurden. Liegt actconn etwa nahe bei 512, während mehrere Verbindungsfehler auftreten, begrenzt das System den Prozess wahrscheinlich auf 1024 Dateideskriptoren, die alle belegt sind. Zur Systemanpassung siehe Abschnitt 3 „Globaler Abschnitt“.
-
“feconn” ist die Gesamtzahl gleichzeitiger Verbindungen im Frontend zum Zeitpunkt der Protokollierung der Sitzung. Damit lassen sich der Ressourcenbedarf bei hoher Last abschätzen und das Erreichen von “maxconn” des Frontends erkennen. Große sprunghafte Anstiege deuten meistens auf einen Engpass bei den Backend-Servern hin, manchmal aber auch auf einen Denial-of-Service-Angriff.
-
“beconn” ist die Gesamtzahl gleichzeitiger Verbindungen, die das Backend zum Zeitpunkt der Protokollierung der Sitzung verwaltet. Dazu gehören alle gleichzeitig auf Servern aktiven sowie die in Warteschlangen wartenden Verbindungen. Damit lässt sich abschätzen, wie viele zusätzliche Server eine Anwendung bei hoher Last benötigt. Große sprunghafte Anstiege deuten meistens auf einen Engpass bei den Backend-Servern hin, manchmal aber auch auf einen Denial-of-Service-Angriff.
-
“srv_conn” ist die Gesamtzahl der zum Zeitpunkt der Protokollierung der Sitzung noch auf dem Server aktiven Verbindungen. Sie kann den konfigurierten Parameter “maxconn” des Servers niemals überschreiten. Liegt sie sehr häufig nahe bei oder genau auf “maxconn”, greift die Verkehrsregelung häufig ein. Dann ist entweder maxconn des Servers zu niedrig, oder es gibt zu wenige Server, um die Last mit optimaler Antwortzeit zu verarbeiten. Ist “srv_conn” nur bei einem Server hoch, hat dieser meist ein Problem, durch das die Verarbeitung von Verbindungen länger dauert als bei den anderen Servern.
-
“retries” ist die Zahl der Wiederholungsversuche beim Verbindungsaufbau zum Server in dieser Sitzung. Sie muss normalerweise null sein, außer wenn ein Server genau zum Zeitpunkt des Verbindungsversuchs gestoppt wird. Häufige Wiederholungsversuche deuten meist auf ein Netzwerkproblem zwischen HAProxy und dem Server oder einen falsch konfigurierten System-Backlog des Servers hin, der keine neuen Verbindungen aufnehmen kann. Ein optional vorangestelltes ‘+’ zeigt an, dass die Sitzung nach Erreichen der maximalen Anzahl von Wiederholungsversuchen beim ursprünglichen Server umverteilt wurde. Der protokollierte Servername bezeichnet dann den Server, an den die Verbindung umverteilt wurde, und nicht den ersten. Beide können beispielsweise bei Hashing dennoch identisch sein. Als Faustregel gilt daher: Steht vor der Anzahl der Wiederholungsversuche ein ‘+’, sollte sie nicht dem protokollierten Server zugerechnet werden.
-
“srv_queue” ist die Gesamtzahl der Anfragen, die vor dieser Anfrage in der Serverwarteschlange verarbeitet wurden. War die Anfrage nicht in der Serverwarteschlange, ist der Wert null. Die ungefähre Antwortzeit des Servers lässt sich abschätzen, indem die Wartezeit durch die Anzahl der Anfragen in der Warteschlange geteilt wird. Durchläuft eine Sitzung nach einer Umverteilung zwei Serverwarteschlangen, werden ihre Positionen addiert. Eine Anfrage sollte nur nach einer Umverteilung sowohl die Server- als auch die Backend-Warteschlange durchlaufen.
-
“backend_queue” ist die Gesamtzahl der Anfragen, die vor dieser Anfrage in der globalen Warteschlange des Backends verarbeitet wurden. War die Anfrage nicht in der globalen Warteschlange, ist der Wert null. Damit lässt sich die durchschnittliche Warteschlangenlänge abschätzen. Geteilt durch den Parameter “maxconn” eines Servers ergibt sie leicht die Anzahl fehlender Server. Nach einer Umverteilung kann eine Sitzung die Backend-Warteschlange zweimal durchlaufen; dann werden beide Positionen addiert. Eine Anfrage sollte nur nach einer Umverteilung sowohl die Server- als auch die Backend-Warteschlange durchlaufen.
8.2.3. HTTP-Protokollformat
Das HTTP-Format ist das vollständigste und für HTTP-Proxys am besten geeignete Format. Es wird durch “option httplog” im Frontend aktiviert. Es liefert dieselben Informationen wie das TCP-Format und zusätzlich HTTP-spezifische Angaben. Wie beim TCP-Format wird die Meldung gewöhnlich am Stream-Ende ausgegeben, außer wenn “option logasap” angegeben ist. Dies ist meist nur für Download-Websites sinnvoll. Ein Stream, der den “monitor”-Regeln entspricht, wird niemals protokolliert. Mit “option dontlognull” im Frontend können außerdem Streams von der Protokollierung ausgenommen werden, bei denen der Client keine Daten gesendet hat. Bei “option dontlog-normal” im Frontend werden erfolgreiche Verbindungen nicht protokolliert.
Intern ist das HTTP-Protokollformat als benutzerdefiniertes Format mit genau der folgenden Zeichenkette deklariert. Sie kann bei Bedarf auch als Grundlage für Erweiterungen dienen. Alternativ lässt sich die Variable HAPROXY_HTTP_LOG_FMT verwenden. Die Verwendung beschreibt Abschnitt 8.2.6 „Benutzerdefiniertes Protokollformat“:
Das CLF-Protokollformat ist intern als benutzerdefiniertes Format mit genau dieser Zeichenkette deklariert:
Die meisten Felder entsprechen denen des TCP-Protokolls, einige unterscheiden sich. Manche Felder können je nach Konfigurationsoption leicht abweichen. Sie sind unten mit einem Sternchen (’*’) hinter dem Feldnamen gekennzeichnet.
Beispiel:
Feld Format Auszug aus dem obigen Beispiel
Ausführliche Feldbeschreibung:
-
“client_ip” ist die IP-Adresse des Clients, der die TCP-Verbindung zu HAProxy aufgebaut hat. Wurde die Verbindung stattdessen über einen UNIX-Socket angenommen, ersetzt das Wort “unix” die IP-Adresse. Bei einem Socket mit “accept-proxy” und korrekt verwendetem PROXY-Protokoll oder mit “accept-netscaler-cip” und korrekt verwendetem NetScaler Client IP Insertion-Protokoll geben die Protokolle die Informationen der weitergeleiteten Verbindung wieder.
-
“client_port” ist der TCP-Port des Clients, der die Verbindung aufgebaut hat. Wurde sie über einen UNIX-Socket angenommen, steht hier stattdessen die ID des annehmenden Sockets, die auch in der Statistikschnittstelle erscheint.
-
“request_date” ist der genaue Zeitpunkt, zu dem HAProxy das erste Byte der HTTP-Anfrage empfangen hat (Protokollfeld %tr).
-
“frontend_name” ist der Name des Frontends (oder Listeners), das die Verbindung angenommen und verarbeitet hat.
-
“backend_name” ist der Name des Backends (oder Listeners), das zur Verwaltung der Verbindung zum Server gewählt wurde. Wenn keine Umschaltregel angewendet wurde, entspricht es dem Frontend.
-
“server_name” ist der Name des letzten Servers, an den die Verbindung gesendet wurde. Nach Verbindungsfehlern und einer Umverteilung kann er vom zuerst gewählten Server abweichen. Dieser Server gehört zum Backend, das die Anfrage verarbeitet hat. Wurde die Anfrage vor Erreichen eines Servers abgebrochen, steht statt des Servernamens “
<NOSRV>”. Hat das Statistiksubsystem die Anfrage abgefangen, steht dort stattdessen “<STATS>”. -
“TR” ist die gesamte Wartezeit in Millisekunden vom Empfang des ersten Bytes bis zur vollständigen HTTP-Anfrage des Clients, ohne Nachrichtenkörper. Der Wert kann “-1” sein, wenn die Verbindung vor Empfang der vollständigen Anfrage abgebrochen oder eine ungültige Anfrage empfangen wurde. Er sollte immer sehr klein sein, da eine Anfrage gewöhnlich in ein einziges Paket passt. Hohe Werte deuten meist auf Netzwerkprobleme zwischen Client und HAProxy oder auf von Hand eingegebene Anfragen hin. Weitere Einzelheiten stehen in Abschnitt 8.4 „Zeitmessungen“.
-
“Tw” ist die gesamte Wartezeit in den verschiedenen Warteschlangen in Millisekunden. Der Wert kann “-1” sein, wenn die Verbindung vor Erreichen der Warteschlange abgebrochen wurde. Weitere Einzelheiten stehen in Abschnitt 8.4 „Zeitmessungen“.
-
“Tc” ist die gesamte Wartezeit bis zum Verbindungsaufbau zum endgültigen Server in Millisekunden, einschließlich Wiederholungsversuchen. Der Wert kann “-1” sein, wenn die Anfrage abgebrochen wurde, bevor eine Verbindung hergestellt werden konnte. Weitere Einzelheiten stehen in Abschnitt 8.4 „Zeitmessungen“.
-
“Tr” ist die gesamte Wartezeit in Millisekunden, bis der Server eine vollständige HTTP-Antwort ohne Daten gesendet hat. Der Wert kann “-1” sein, wenn die Anfrage vor Empfang einer vollständigen Antwort abgebrochen wurde. Er entspricht gewöhnlich der Bearbeitungszeit des Servers für die Anfrage, kann aber durch die vom Client an den Server gesendete Datenmenge beeinflusst werden. Hohe Werte bei “GET”-Anfragen deuten meist auf einen überlasteten Server hin. Weitere Einzelheiten stehen in Abschnitt 8.4 „Zeitmessungen“.
-
“Ta” ist die Zeit, in der die Anfrage in HAProxy aktiv war: die gesamte Zeit in Millisekunden zwischen dem Empfang des ersten Anfragebytes und dem Senden des letzten Antwortbytes. Sie umfasst alle Verarbeitungsschritte außer Handshake (siehe Th) und Leerlaufzeit (siehe Ti). Eine Ausnahme besteht bei “option logasap”: Dann endet die Zeitmessung mit der Protokollausgabe. Ein vorangestelltes ‘+’ zeigt in diesem Fall an, dass der endgültige Wert größer sein wird. Weitere Einzelheiten stehen in Abschnitt 8.4 „Zeitmessungen“.
-
“status_code” ist der an den Client zurückgegebene HTTP-Statuscode. Er wird gewöhnlich vom Server gesetzt, kann aber auch von HAProxy stammen, wenn der Server nicht erreichbar ist oder HAProxy seine Antwort blockiert.
-
“bytes_read” ist die Gesamtzahl der zum Zeitpunkt der Protokollausgabe an den Client übertragenen Bytes, einschließlich HTTP-Headern. Bei “option logasap” erhält der Wert ein vorangestelltes ‘+’, das auf einen möglicherweise größeren Endwert hinweist. Es handelt sich um einen 64-Bit-Zähler; Werkzeuge zur Protokollauswertung müssen ihn daher ohne Überlauf verarbeiten können.
-
“captured_request_cookie” ist ein optionaler Eintrag im Format “name=value”, der anzeigt, dass der Client dieses Cookie in der Anfrage mitgesendet hat. Cookie-Name und maximale Länge werden mit “capture cookie” in der Frontend-Konfiguration festgelegt. Ist die Option nicht gesetzt, enthält das Feld einen einzelnen Bindestrich (’-’). Es kann nur ein Cookie erfasst werden. Damit wird gewöhnlich der Austausch von Sitzungs-IDs zwischen Client und Server verfolgt, um durch Anwendungsfehler verursachte Sitzungsverwechslungen zwischen Clients zu erkennen. Weitere Einzelheiten stehen unten unter „HTTP-Header und Cookies erfassen“.
-
“captured_response_cookie” ist ein optionaler Eintrag im Format “name=value”, der anzeigt, dass der Server mit seiner Antwort ein Cookie zurückgegeben hat. Cookie-Name und maximale Länge werden mit “capture cookie” in der Frontend-Konfiguration festgelegt. Ist die Option nicht gesetzt, enthält das Feld einen einzelnen Bindestrich (’-’). Es kann nur ein Cookie erfasst werden. Damit wird gewöhnlich der Austausch von Sitzungs-IDs zwischen Client und Server verfolgt, um durch Anwendungsfehler verursachte Sitzungsverwechslungen zwischen Clients zu erkennen. Weitere Einzelheiten stehen unten unter „HTTP-Header und Cookies erfassen“.
-
“termination_state” beschreibt den Zustand des Streams bei seiner Beendigung. Wie bei TCP-Protokollen zeigt das Feld den Stream-Zustand, die Seite, die den Stream beendet hat, und den Grund dafür (Zeitüberschreitung, Fehler usw.). Die letzten beiden Zeichen enthalten außerdem Angaben zu Persistenzaktionen an Cookies. Normalerweise sollten die Flags mit “–” beginnen. Dies bedeutet, dass eine der Seiten den Stream beendet hat und keine Daten mehr in den Puffern lagen. Weitere Einzelheiten stehen unten unter „Stream-Zustand bei der Trennung“.
-
“actconn” ist die Gesamtzahl gleichzeitiger Verbindungen im Prozess zum Zeitpunkt der Protokollierung des Streams. Sie hilft zu erkennen, wann systemseitige Grenzen je Prozess erreicht wurden. Liegt actconn etwa nahe bei 512 oder 1024, während mehrere Verbindungsfehler auftreten, begrenzt das System den Prozess wahrscheinlich auf 1024 Dateideskriptoren, die alle belegt sind. Zur Systemanpassung siehe Abschnitt 3 „Globaler Abschnitt“.
-
“feconn” ist die Gesamtzahl gleichzeitiger Verbindungen im Frontend zum Zeitpunkt der Protokollierung des Streams. Damit lassen sich der Ressourcenbedarf bei hoher Last abschätzen und das Erreichen von “maxconn” des Frontends erkennen. Große sprunghafte Anstiege deuten meistens auf einen Engpass bei den Backend-Servern hin, manchmal aber auch auf einen Denial-of-Service-Angriff.
-
“beconn” ist die Gesamtzahl gleichzeitiger Verbindungen, die das Backend zum Zeitpunkt der Protokollierung des Streams verwaltet. Dazu gehören alle gleichzeitig auf Servern aktiven sowie die in Warteschlangen wartenden Verbindungen. Damit lässt sich abschätzen, wie viele zusätzliche Server eine Anwendung bei hoher Last benötigt. Große sprunghafte Anstiege deuten meistens auf einen Engpass bei den Backend-Servern hin, manchmal aber auch auf einen Denial-of-Service-Angriff.
-
“srv_conn” ist die Gesamtzahl der zum Zeitpunkt der Protokollierung des Streams noch auf dem Server aktiven Verbindungen. Sie kann den konfigurierten Parameter “maxconn” des Servers niemals überschreiten. Liegt sie sehr häufig nahe bei oder genau auf “maxconn”, greift die Verkehrsregelung häufig ein. Dann ist entweder maxconn des Servers zu niedrig, oder es gibt zu wenige Server, um die Last mit optimaler Antwortzeit zu verarbeiten. Ist “srv_conn” nur bei einem Server hoch, hat dieser meist ein Problem, durch das die Verarbeitung von Anfragen länger dauert als bei den anderen Servern.
-
“retries” ist die Zahl der Wiederholungsversuche beim Verbindungsaufbau zum Server in diesem Stream. Sie muss normalerweise null sein, außer wenn ein Server genau zum Zeitpunkt des Verbindungsversuchs gestoppt wird. Häufige Wiederholungsversuche deuten meist auf ein Netzwerkproblem zwischen HAProxy und dem Server oder einen falsch konfigurierten System-Backlog des Servers hin, der keine neuen Verbindungen aufnehmen kann. Ein optional vorangestelltes ‘+’ zeigt an, dass der Stream nach Erreichen der maximalen Anzahl von Wiederholungsversuchen beim ursprünglichen Server umverteilt wurde. Der protokollierte Servername bezeichnet dann den Server, an den die Verbindung umverteilt wurde, und nicht den ersten. Beide können beispielsweise bei Hashing dennoch identisch sein. Als Faustregel gilt daher: Steht vor der Anzahl der Wiederholungsversuche ein ‘+’, sollte sie nicht dem protokollierten Server zugerechnet werden.
-
“srv_queue” ist die Gesamtzahl der Anfragen, die vor dieser Anfrage in der Serverwarteschlange verarbeitet wurden. War die Anfrage nicht in der Serverwarteschlange, ist der Wert null. Die ungefähre Antwortzeit des Servers lässt sich abschätzen, indem die Wartezeit durch die Anzahl der Anfragen in der Warteschlange geteilt wird. Durchläuft eine Sitzung nach einer Umverteilung zwei Serverwarteschlangen, werden ihre Positionen addiert. Eine Anfrage sollte nur nach einer Umverteilung sowohl die Server- als auch die Backend-Warteschlange durchlaufen.
-
“backend_queue” ist die Gesamtzahl der Anfragen, die vor dieser Anfrage in der globalen Warteschlange des Backends verarbeitet wurden. War die Anfrage nicht in der globalen Warteschlange, ist der Wert null. Damit lässt sich die durchschnittliche Warteschlangenlänge abschätzen. Geteilt durch den Parameter “maxconn” eines Servers ergibt sie leicht die Anzahl fehlender Server. Nach einer Umverteilung kann ein Stream die Backend-Warteschlange zweimal durchlaufen; dann werden beide Positionen addiert. Eine Anfrage sollte nur nach einer Umverteilung sowohl die Server- als auch die Backend-Warteschlange durchlaufen.
-
“captured_request_headers” ist die Liste der Anfrage-Header, die durch “capture request header” im Frontend erfasst wurden. Mehrere Header können erfasst werden; sie sind durch einen senkrechten Strich (’|’) getrennt. Ist keine Erfassung aktiviert, entfallen die geschweiften Klammern, wodurch sich die übrigen Felder verschieben. Dieses Feld kann Leerzeichen enthalten. Seine Verwendung erfordert daher einen ausgefeilteren Protokollparser als ohne das Feld. Weitere Einzelheiten stehen unten unter „HTTP-Header und Cookies erfassen“.
-
“captured_response_headers” ist die Liste der Antwort-Header, die durch “capture response header” im Frontend erfasst wurden. Mehrere Header können erfasst werden; sie sind durch einen senkrechten Strich (’|’) getrennt. Ist keine Erfassung aktiviert, entfallen die geschweiften Klammern, wodurch sich die übrigen Felder verschieben. Dieses Feld kann Leerzeichen enthalten. Seine Verwendung erfordert daher einen ausgefeilteren Protokollparser als ohne das Feld. Weitere Einzelheiten stehen unten unter „HTTP-Header und Cookies erfassen“.
-
“http_request” ist die vollständige HTTP-Anfragezeile mit Methode, Anfrage und HTTP-Versionszeichenkette. Nicht druckbare Zeichen werden kodiert (siehe unten „Nicht druckbare Zeichen“). Dies ist immer das letzte Feld. Es ist stets von Anführungszeichen umschlossen und das einzige Feld, das selbst Anführungszeichen enthalten kann. Neue Felder werden vor diesem Feld in das Protokollformat eingefügt. Ist die Anfrage sehr groß und passt nicht in den standardmäßigen syslog-Puffer (1024 Zeichen), kann das Feld abgeschnitten werden. Deshalb muss es immer das letzte Feld bleiben.
8.2.4. HTTPS-Protokollformat
Das HTTPS-Format eignet sich am besten für HTTP-Verbindungen über SSL. Es erweitert das HTTP-Format (siehe Abschnitt 8.2.3 ) um SSL-bezogene Informationen und wird durch “option httpslog” im Frontend aktiviert. Wie bei TCP und HTTP wird die Meldung gewöhnlich am Stream-Ende ausgegeben, außer wenn “option logasap” angegeben ist. Ein Stream, der den “monitor”-Regeln entspricht, wird niemals protokolliert. Mit “option dontlognull” im Frontend können außerdem Streams von der Protokollierung ausgenommen werden, bei denen der Client keine Daten gesendet hat. Bei “option dontlog-normal” im Frontend werden erfolgreiche Verbindungen nicht protokolliert.
Intern ist das HTTPS-Protokollformat als benutzerdefiniertes Format mit genau der folgenden Zeichenkette deklariert. Sie kann bei Bedarf auch als Grundlage für Erweiterungen dienen. Alternativ lässt sich die Variable HAPROXY_HTTPS_LOG_FMT verwenden. Die Verwendung beschreibt Abschnitt 8.2.6 „Benutzerdefiniertes Protokollformat“:
Dieses Format entspricht im Wesentlichen dem HTTP-Format (siehe Abschnitt 8.2.3 ), an das neue Felder angehängt werden. Diese neuen Felder (Zeilen 17 und 18) werden hier erläutert. Für die HTTP-Felder siehe den HTTP-Abschnitt.
Beispiel:
Feld Format Auszug aus dem obigen Beispiel
Ausführliche Feldbeschreibung:
-
“fc_err” ist der Verbindungsstatus auf der Frontend-Seite und entspricht dem Sample-Abruf “fc_err”. Weitere Informationen liefern die Beschreibungen der Sample-Abruffunktionen “fc_err” und “fc_err_str”.
-
“ssl_fc_err” ist der letzte Fehler des ersten SSL-Fehlerstapels, der aus Sicht des Frontends auf der Verbindung aufgetreten ist. Damit lassen sich beispielsweise Fehler beim SSL-Handshake erkennen. Wenn alles erfolgreich war, ist der Wert 0. Weitere Informationen stehen in der Beschreibung des Sample-Abrufs “ssl_fc_err”.
-
“ssl_c_err” ist der Status der Prüfung des Clientzertifikats. Der Handshake kann auch bei einem Prüfungsfehlercode ungleich null erfolgreich sein, wenn der Fehler ignoriert wird. Siehe den Sample-Abruf “ssl_c_err” und die Option “crt-ignore-err”.
-
“ssl_c_ca_err” ist der Status der Prüfung der Clientzertifikatskette. Der Handshake kann auch bei einem Prüfungsfehlercode ungleich null erfolgreich sein, wenn der Fehler ignoriert wird. Siehe den Sample-Abruf “ssl_c_ca_err” und die Option “ca-ignore-err”.
-
“ssl_fc_is_resumed” ist wahr, wenn die eingehende TLS-Sitzung über den zustandsbehafteten Cache oder ein zustandsloses Ticket wiederaufgenommen wurde. Eine TLS-Sitzung kann von mehreren Anfragen gemeinsam genutzt werden.
-
“ssl_fc_sni” ist die vom Client zur Zertifikatsauswahl übermittelte SNI (Server Name Indication). Sie entspricht gewöhnlich dem Hostnamen der ersten Anfrage einer Verbindung. Fehlt das Feld, hat der Client möglicherweise keine SNI gesendet. haproxy verwendet dann das Standardzertifikat oder weist bei strict-sni die Verbindung ab.
-
“ssl_version” ist die SSL-Version des Frontends.
-
“ssl_ciphers” ist der für die Verbindung verwendete SSL-Cipher.
8.2.5. Fehlerprotokollformat
Schlägt eine eingehende Verbindung wegen eines SSL-Handshakes oder eines ungültigen PROXY-Protokoll-Headers fehl, protokolliert HAProxy das Ereignis in einem kürzeren, festen Zeilenformat. Dies gilt nicht, wenn mit “error-log-format” ein eigenes Fehlerprotokollformat definiert wurde. Standardmäßig werden Meldungen mit der Stufe LOG_INFO ausgegeben. Ist im Backend “log-separate-errors” gesetzt, wird stattdessen LOG_ERR verwendet. Verbindungen ohne Datenaustausch, etwa Prüfanfragen, werden bei gesetzter Option “dontlognull” nicht protokolliert.
Das Standardformat sieht so aus:
Diese Felder liefern nur die grundlegenden Informationen zur Untersuchung fehlgeschlagener Verbindungen.
Mit der Direktive “error-log-format” wird das oben beschriebene ältere Format nicht mehr verwendet; alle Fehlerprotokollzeilen folgen dann dem definierten Format.
Es folgt ein Beispiel für ein recht vollständiges error-log-format. Es gibt Quelladresse und -port, den Zeitpunkt von accept() für die Verbindung, den Frontend-Namen, die Anzahl aktiver Verbindungen im Prozess und im betreffenden Frontend, die interne Fehlerkennung von haproxy für die Frontend-Verbindung, die hexadezimale OpenSSL-Fehlernummer (die zur vollständigen Dekodierung an “openssl errstr” übergeben werden kann), den Status der Extraktion des Clientzertifikats (0 bedeutet kein Fehler), den Status der Prüfung des Clientzertifikats anhand der CA (0 bedeutet kein Fehler), einen booleschen Wert für eine neue oder wiederaufgenommene Verbindung, die optionale Server Name Indication (SNI) des Clients sowie gegebenenfalls den SSL-Versionsnamen und die auf der Verbindung verwendeten SSL-Cipher aus. Fehler bei Backend-Verbindungen werden hier niemals gemeldet: Damit eine Backend-Verbindung fehlschlagen kann, muss sie bereits einen erfolgreich angelegten Stream durchlaufen haben. Sie erscheint deshalb im regulären Verkehrsprotokoll (siehe option httplog oder option httpslog).
8.2.6. Benutzerdefiniertes Protokollformat
Ursprünglich dienten benutzerdefinierte Protokollformate ausschließlich der Protokollierung. Weil sich damit aber bequem mehrere komplexe Ausdrücke zu einer Zeichenkette zusammensetzen lassen, wurden sie von vielen Direktiven übernommen, die zuvor nur eine Zeichenkette als Argument akzeptierten. Diese können nun auch eine solche Formatdefinition annehmen. Derartige Argumente heißen in diesem Dokument meist “<fmt>” und werden genau wie das hier beschriebene Argument der Direktive “log-format” definiert.
Reichen die Standardformate für die Protokollierung nicht aus, lassen sich neue Formate sehr genau festlegen. Ein Protokollformat von Grund auf zu erstellen ist nicht immer einfach. Deshalb wird dringend empfohlen, zunächst die vorhandenen Formate (“option tcplog”, “option httplog”, “option httpslog”) anzusehen, das am besten passende auszuwählen, seine entsprechende “log-format”-Zeichenkette zu kopieren und anzupassen.
Eine benutzerdefinierte Protokollformatdefinition ist aus Sicht der Konfiguration ein einziges Argument. Sie darf deshalb keine Leerzeichen oder Tabulatoren enthalten, außer wenn diese mit einem Backslash (’\’) maskiert werden oder die gesamte Definition in Anführungszeichen steht. Letzteres wird empfohlen. Formatzeichenketten ohne Anführungszeichen werden nicht mehr empfohlen: Die Erfahrung zeigt, dass sie sehr fehleranfällig sind, weil bereits ein fehlender Backslash das Format unbemerkt abschneiden kann. Solche Konfigurationen sind weiterhin häufig anzutreffen, weil Protokollformate nach Version 1.5-dev9 breit übernommen wurden, 3 Jahre bevor Anführungszeichen verwendbar waren. Es wird jedoch empfohlen, sie jetzt in Zeichenketten mit Anführungszeichen umzuwandeln und die Backslashes zu entfernen.
Eine Protokollformatdefinition besteht aus beliebig vielen Formatelementen, getrennt durch Text und Leerzeichen. Ein Formatelement beginnt mit ‘%’. Um ein wörtliches ‘%’ auszugeben, muss ihm ein weiteres ‘%’ vorangestellt werden, sodass ‘%%’ entsteht.
Formatelemente können Aliase oder Sample-Ausdrücke sein:
Steht ein Element in eckigen Klammern (’[’ .. ‘]’), wird es als Regel mit einem Sample-Ausdruck verwendet (siehe Abschnitt 7.3 ). Damit lassen sich seltenere Angaben ergänzen, etwa der DN des SSL-Clientzertifikats oder der Schlüssel, mit dem ein Eintrag in einer Stick Table gespeichert würde. Dies wird auch häufig bei Aktionen außerhalb der Protokollierung verwendet, etwa zur Header-Bearbeitung oder für Variablen.
Hat das Element dagegen einen alphanumerischen Namen, ist es ein Alias. Die verfügbaren Aliase stehen in der folgenden Tabelle.
Elemente können Argumente in geschweiften Klammern (’{}’) annehmen. Mehrere Argumente werden darin durch Kommas getrennt. Flags lassen sich mit einem vorangestellten ‘+’ oder ‘-’ hinzufügen oder entfernen. Die verfügbaren Flags werden weiter unten aufgeführt.
Der besondere Alias “%o” überträgt seine Flags auf alle anderen Formatelemente derselben Formatzeichenkette. Dies ist besonders bei Zeichenketten mit Anführungszeichen (“Q”) und maskierten Zeichen (“E”) praktisch.
Der besondere Alias “%OG” liefert den Ursprung einer Protokollmeldung, also wann und wo sie erzeugt wurde, in lesbarer Form. Das ist besonders bei “option logasap” nützlich: Einige Protokollvariablen oder Sample-Abrufe können unvollständige Werte liefern oder sich unterschiedlich verhalten, je nachdem, wann und wo der Formatausdruck ausgewertet wurde. Mögliche Werte sind:
- “sess_error”: Die Meldung wurde bei der Behandlung eines Sitzungsfehlers erzeugt.
- “sess_killed”: Die Meldung wurde beim Abbruch einer Sitzung erzeugt (beendete embryonale Sitzung).
- “txn_accept”: Die Meldung wurde unmittelbar nach Annahme der Frontend-Verbindung erzeugt.
- “txn_request”: Die Meldung wurde nach Empfang der Clientanfrage erzeugt.
- “txn_connect”: Die Meldung wurde nach Aufbau der Backend-Verbindung erzeugt.
- “txn_response”: Die Meldung wurde bei der Verarbeitung der Serverantwort erzeugt.
- “txn_close”: Die Meldung wurde im letzten Transaktionsschritt vor dem Schließen erzeugt.
- “unspec”: Unbekannt oder nicht angegeben. “%OG” ist nur bei der Protokollierung relevant.
Elemente können optional mit (’()’) benannt werden. Der Name muss unmittelbar nach ‘%’ vor den Argumenten stehen. Bei gesetztem Kodierungsflag wie “json” oder “cbor” wird er automatisch als Schlüsselname verwendet. Ohne Kodierungsflag, also standardmäßig, wird der Name ignoriert. Der Ausgabetyp eines Elements lässt sich durch ‘:type’ hinter dem Namen erzwingen: %(itemname:itemtype)aliasname oder %(itemname:itemtype)[expr], wobei itemtype ‘str’, ‘sint’ oder ‘bool’ sein kann. Die Typangabe ist nur bei Verwendung einer Kodierungsmethode relevant. Auch ein leerer Name ist möglich, um den Ausgabetyp eines anonymen Elements zu erzwingen: %(:itemtype), etwa wenn die Kodierung nicht global gesetzt ist. Weitere Informationen stehen unten bei den Flag-Definitionen.
Da benutzerdefinierte Protokollformate ursprünglich nur für die Protokollierung gedacht waren, werden nicht druckbare und unsichere Zeichen (außerhalb der ASCII-Codes 32 bis 126 sowie einige weitere) je nach Einsatzort gesondert behandelt. Abschnitt 8.6 beschreibt das genaue Vorgehen für Protokolle. Es verhindert die Ausgabe unsicherer Codes, die die Lesbarkeit im Terminal beeinträchtigen. Bei Header-Feldern, Health Checks oder Antwortnutzdaten sind die Regeln weniger streng: Nur in HTTP-Header-Feldern verbotene Zeichen werden durch ihre hexadezimale Kodierung mit vorangestelltem ‘%’ ersetzt. Normalerweise ist dies unproblematisch. Es kann aber die Ausgabe verändern, wenn ein Zeichen unverändert erwartet wird, etwa beim Erstellen einer Fehlerseite oder vollständiger Antwortnutzdaten, in denen Zeilenumbrüche als “%0A” erscheinen könnten.
Hinweis: Bei den Konfigurationsdirektiven “log-format”, “log-format-sd” und “unique-id-format” gelten Leerzeichen als Trennzeichen und werden zusammengefasst.
Hinweis: Beim syslog-Nachrichtenformat RFC5424 sollten die Zeichen ‘"’, ‘\’ und ‘]’ innerhalb von PARAM-VALUE durch ein vorangestelltes ‘\’ maskiert werden (Einzelheiten unter https://tools.ietf.org/html/rfc5424#section-6.3.3 ). In solchen Fällen sollte das Flag “E” in Betracht gezogen werden.
Folgende Element-Flags werden unterstützt und lassen sich über die Argumente des Elements aktivieren oder deaktivieren:
- Q: Eine Zeichenkette in Anführungszeichen setzen.
- X: Hexadezimale Darstellung (IPs, Ports, %Ts, %rt, %pid).
- E: Die Zeichen ‘"’, ‘\’ und ‘]’ in einer Zeichenkette durch ein vorangestelltes ‘\’ maskieren (vorgesehen für Protokollformate mit strukturierten Daten nach RFC5424).
- bin: Versuchen, Binärdaten zu erhalten. Dies kann bei Sample-Ausdrücken mit binärer Ausgabe nützlich sein, um die Originaldaten zu bewahren. Dabei können jedoch nicht druckbare Zeichen einschließlich NULL-Bytes entstehen, die die meisten syslog-Endpunkte nicht erwarten. Das Flag ist daher hauptsächlich für set-var-fmt, Ringpuffer und binärfähige Protokollendpunkte vorgesehen. Es kann nur global mit %o gesetzt werden; als Option eines einzelnen Elements wird es ignoriert.
- json: Den Wert automatisch im JSON-Format kodieren. Bei globaler Aktivierung werden nur benannte Formatelemente berücksichtigt. Unvollständige Zahlenwerte, etwa ‘%B’ bei logasap, die ohne Kodierung normalerweise ein vorangestelltes ‘+’ erhalten, werden unverändert kodiert. Die Option ‘+E’ wird außerdem ignoriert. Wie in Abschnitt 8.6 beschrieben, werden Zeichen außerhalb des Bereichs 32..126 Byte für Byte mit JSON-Escape-Sequenzen maskiert, sodass die Ausgabe unabhängig von der Eingabe aus druckbarem ASCII besteht. Dies gilt auch für gültige UTF-8-Sequenzen: Nach dem Dekodieren erscheint Nicht-ASCII-Text als seine einzelnen Bytes. Beispielsweise wird U+00E9, kodiert als 0xC3 0xA9, als “\u00C3\u00A9” protokolliert. Mit “utf8” unten lässt sich solcher Text erhalten.
- utf8: Zusammen mit “json” werden gültige UTF-8-Sequenzen aus mehreren Bytes unmaskiert ausgegeben. C1-Steuerzeichen (U+0080 bis U+009F) werden weiterhin maskiert und durch ihren Codepunkt dargestellt. Ungültige Sequenzen werden Byte für Byte maskiert, damit die Ausgabe immer gültiges UTF-8 bleibt. Da gültiges UTF-8 unverändert ausgegeben wird, kann ein Client mit bestimmten Sonderzeichen die Darstellung einer Protokollzeile im Terminal oder in einem Protokollbetrachter verändern, etwa mit Richtungswechseln, Zeichen ohne Breite oder Zeilen- und Absatztrennern. Deshalb sollte dieses Flag nur für Inhalte aus vertrauenswürdigen Quellen verwendet werden oder wenn die Protokolle nicht in einem Terminal angezeigt werden sollen. Ohne “json” hat es keine Wirkung.
- cbor: Den Wert automatisch im CBOR-Format kodieren. Bei globaler Aktivierung werden nur benannte Formatelemente berücksichtigt. Standardmäßig werden cbor-kodierte Daten in HEX-Form dargestellt, damit sie auf stdout druckbar bleiben und mit gewöhnlichen syslog-Endpunkten verwendet werden können. Wie bei json werden unvollständige Zahlenwerte unverändert kodiert und ‘+E’ ignoriert. Zusammen mit ‘+bin’ werden direkt rohe binäre CBOR-Nutzdaten erzeugt. Dabei entstehen nicht druckbare Zeichen; dies ist daher hauptsächlich für set-var-fmt, Ringpuffer und binärfähige Protokollendpunkte vorgesehen.
Beispiel:
Die derzeit definierten Aliase stehen in der folgenden Tabelle:
R = Einschränkungen: H = nur mode http; S = nur SSL; L = nur Protokollierung
8.3. Erweiterte Protokollierungsoptionen
Einige erweiterte Protokollierungsoptionen werden häufig gesucht, sind aber beim bloßen Durchsehen der Optionen schwer zu finden. Dieser Abschnitt bietet einen Einstieg in einige Optionen für eine bessere Protokollierung. Einzelheiten zur Verwendung stehen in der Schlüsselwortreferenz.
8.3.1. Protokollierung externer Tests deaktivieren
Überwachungswerkzeuge führen häufig Health Checks an HAProxy aus. Dies kann ein Load-Balancer auf Schicht 3 wie LVS oder ein kommerzieller Load-Balancer sein, aber auch ein umfassenderes Überwachungssystem wie Nagios. Bei sehr häufigen Tests stellt sich oft die Frage, wie sich deren Protokollierung deaktivieren lässt. Dafür gibt es drei Möglichkeiten:
-
Kommen die Verbindungen aus beliebigen Quellen und sind sie reine TCP-Prüfanfragen, soll oft einfach die Protokollierung von Verbindungen ohne Datenaustausch deaktiviert werden. Dazu dient “option dontlognull” im Frontend. Dies unterdrückt auch die Protokollierung von Portscans, was erwünscht sein kann oder auch nicht.
-
Die Aktion “http-request set-log-level silent” kann mit unterschiedlichen Bedingungen verwendet werden, etwa Quellnetzen, Pfaden oder User-Agents.
-
Wird eine bekannte URI für die Tests verwendet, diese mit “monitor-uri” für die Überwachung reservieren. Jeder Host, der diese Anfrage sendet, erhält dann nur das Ergebnis eines Health Checks; die Anfrage wird nicht protokolliert.
8.3.2. Vor dem Ende des Streams protokollieren
Bei einer Protokollierung erst am Verbindungsende bleibt der Ablauf während sehr langer Streams, etwa entfernter Terminalsitzungen oder großer Downloads, unsichtbar. “option logasap” im Frontend umgeht dieses Problem: HAProxy protokolliert dann möglichst früh, unmittelbar vor Beginn der Datenübertragung. Bei TCP wird weiterhin der Verbindungsstatus zum Server erfasst; bei HTTP erfolgt die Ausgabe direkt nach Verarbeitung der Server-Header. Die angegebene Bytezahl ist dann die Anzahl der an den Client gesendeten Header-Bytes. Zur Unterscheidung von gewöhnlichen Protokollen erhalten Gesamtzeit und Bytezahl ein vorangestelltes ‘+’, das auf sicher größere tatsächliche Werte hinweist.
8.3.3. Protokollstufe bei Fehlern erhöhen
Manchmal ist es praktischer, Protokolle des normalen Datenverkehrs von Fehlerprotokollen zu trennen, etwa um Fehler in Protokolldateien leichter zu überwachen. Mit “log-separate-errors” steigt die syslog-Stufe für Verbindungen mit Fehlern, Zeitüberschreitungen, Wiederholungsversuchen, Umverteilungen oder HTTP-Statuscodes 5xx von “info” auf “err”. Dadurch kann ein syslog-Daemon die Meldungen in einer eigenen Datei ablegen. Die Fehler sollten unbedingt auch in der Datei für den normalen Datenverkehr verbleiben, damit die Reihenfolge der Meldungen erhalten bleibt. Vorsicht ist auch geboten, wenn der syslog-Daemon bereits alle Meldungen oberhalb von “notice” in einer “admin”-Datei speichert, da “err” höher als “notice” liegt.
8.3.4. Protokollierung erfolgreicher Verbindungen deaktivieren
Es mag zunächst ungewöhnlich klingen, doch manche großen Websites müssen mehrere Tausend Meldungen pro Sekunde verarbeiten. Es fällt ihnen schwer, diese lange vollständig aufzubewahren oder Fehler darin zu erkennen. Ist im Frontend “dontlog-normal” gesetzt, werden normale Verbindungen nicht protokolliert. Als normal gilt dabei eine Verbindung ohne Fehler, Zeitüberschreitung, Wiederholungsversuch oder Umverteilung. Bei HTTP wird zusätzlich der Statuscode geprüft; Antworten mit Status 5xx gelten ebenfalls nicht als normal und werden protokolliert. Von dieser Einstellung wird jedoch ausdrücklich abgeraten, weil dadurch die meisten nützlichen Informationen aus den Protokollen verschwinden. Nur verwenden, wenn keine Alternative besteht.
8.3.5. Protokollprofile
Direktiven wie “log-format”, “log-format-sd”, “error-log-format” oder “log-tag” konfigurieren die Protokollformatierung global oder auf Proxy-Ebene. Es kann jedoch sinnvoll sein, diese Einstellungen möglichst nahe am Protokollziel festzulegen, also je “log”-Direktive.
Dazu dient der Abschnitt “log-profile”, der an beliebiger Stelle der Konfiguration definiert werden kann. Seine Schlüsselwörter beschreiben, wie die für eine bestimmte log-Direktive ausgegebenen Meldungen aufgebaut werden sollen.
Eine “log”-Direktive kann ein bestimmtes log-profile anhand seines Namens auswählen. Mehrere “log”-Direktiven können dasselbe Profil verwenden.
log-profile <name> Erstellt ein neues Protokollprofil mit der Kennung <name>.
log-tag <string> Überschreibt das syslog-Tag, das mit “log-tag” global oder je Proxy gesetzt wurde.
on <step> [drop] [format <fmt>] [sd <sd_fmt>] Überschreibt die Formatzeichenkette, mit der die Protokollzeile normalerweise beim Schritt <step> erzeugt wird. <fmt> überschreibt je nach <step> die Zeichenkette “log-format” oder “error-log-format”, während <sd_fmt> die Zeichenkette “log-format-sd” überschreibt. Beides kann kombiniert werden.
Mit dem besonderen Schlüsselwort “drop” wird für den angegebenen <step> keine Meldung ausgegeben. Es hat Vorrang vor zuvor definierten Angaben für “format” und “sd”.
Mögliche Werte für <step> sind:
- “accept”: log-format überschreiben, wenn die Meldung unmittelbar nach Annahme der Frontend-Verbindung entsteht.
- “request”: log-format überschreiben, wenn die Meldung nach Empfang der Clientanfrage entsteht.
- “connect”: log-format überschreiben, wenn die Meldung nach Aufbau der Backend-Verbindung entsteht.
- “response”: log-format überschreiben, wenn die Meldung während der Verarbeitung der Serverantwort entsteht.
- “close”: log-format überschreiben, wenn die Meldung im letzten Transaktionsschritt (txn) entsteht.
- “error”: error-log-format überschreiben, wenn die Meldung aufgrund eines Transaktionsfehlers entsteht.
- “any”: log-format und error-log-format für alle Protokollierungsschritte überschreiben, sofern keine genauere Festlegung für einen einzelnen Schritt vorliegt.
Weitere relevante Werte für <step> stehen bei der Aktion “do-log”.
Diese Einstellung ist nur für “log”-Direktiven in Kontexten relevant, in denen “log-format” sinnvoll ist, etwa bei http- und tcp-Proxys. Andernfalls wird sie ignoriert.
Beispiel:
8.4. Zeitmessungen
Zeitmessungen helfen sehr bei der Untersuchung von Netzwerkproblemen. Alle Werte werden in Millisekunden (ms) angegeben und sollten zusammen mit den Flags zur Stream-Beendigung ausgewertet werden. Im TCP-Modus mit “option tcplog” im Frontend werden 3 Messpunkte als “Tw/Tc/Tt” ausgegeben, im HTTP-Modus 5 als “TR/Tw/Tc/Tr/Ta”. Hinzu kommen drei weitere Messwerte: “Th”, “Ti” und “Tq”.
Zeitmessungen im HTTP-Modus:
Zeitmessungen im TCP-Modus:
-
Th: Gesamtdauer für die Annahme der TCP-Verbindung und die Handshakes der Protokolle niedrigerer Schichten, derzeit proxy-protocol und SSL. Dies kann während der gesamten Verbindungsdauer nur einmal geschehen. Ein hoher Wert kann bedeuten, dass der Client nur vorab eine Verbindung aufgebaut, aber noch nichts gesendet hat, dass Netzwerkprobleme wie MTU-Probleme den rechtzeitigen Abschluss des Handshakes verhindern oder dass die Berechnung des SSL-Handshakes sehr aufwendig war. Diese Zeit wird nur vor der ersten Anfrage angegeben. Sie kann daher über alle Anfragen gemittelt werden, um den anteiligen Aufwand zu ermitteln. Bei der zweiten und allen folgenden Anfragen wird hier stets null ausgegeben.
Dieser Messwert heißt als log-format-Alias %Th und als Sample-Abruf fc.timer.handshake.
-
Ti: Leerlaufzeit vor der HTTP-Anfrage, nur im HTTP-Modus. Gemessen wird zwischen dem Ende der Handshakes und dem ersten Byte der HTTP-Anfrage. Bei einer zweiten Anfrage im Keep-Alive-Modus beginnt die Messung nach dem Ende der Übertragung der vorherigen Antwort. Bei einem Multiplex-Protokoll wie HTTP/2 beginnt sie unmittelbar nach der vorherigen Anfrage. Manche Browser bauen Verbindungen vorab auf, um die Latenz einer späteren Anfrage zu verringern, und halten sie bis zur Verwendung offen. Diese Verzögerung erscheint als Leerlaufzeit. Ein Wert von -1 bedeutet, dass auf der Verbindung nichts empfangen wurde.
Dieser Messwert heißt als log-format-Alias %Ti und als Sample-Abruf req.timer.idle.
-
TR: Gesamtdauer für den Empfang der Clientanfrage, nur im HTTP-Modus. Dies ist die Zeit vom Empfang der ersten Bytes bis zur Leerzeile, die das Ende der HTTP-Header markiert. “-1” bedeutet, dass das Header-Ende nie empfangen wurde. Dies geschieht bei vorzeitigem Schließen durch den Client oder einer Zeitüberschreitung. Die Dauer ist gewöhnlich sehr kurz, da die meisten Anfragen in ein einziges Paket passen. Ein hoher Wert kann auf eine bei einem Test von Hand eingegebene Anfrage hinweisen.
Dieser Messwert heißt als log-format-Alias %TR und als Sample-Abruf req.timer.hdr.
-
Tq: Gesamtdauer für den Empfang der Clientanfrage ab Verbindungsannahme oder ab dem Senden des letzten Bytes der vorherigen Antwort, nur im HTTP-Modus. Sie entspricht genau Th + Ti + TR, außer wenn einer dieser Werte -1 ist; dann ist auch Tq gleich -1. Vor HTTP Keep-Alive und dem vorzeitigen Verbindungsaufbau durch Browser war dieser Wert sehr nützlich. Heute wird empfohlen, stattdessen TR zu verwenden, da die Leerlaufzeit die Berichte stark mit Schwankungen belastet.
Dieser Messwert heißt als log-format-Alias %Tq und als Sample-Abruf req.timer.tq.
-
Tw: Gesamte Wartezeit in den Warteschlangen auf einen freien Verbindungsplatz. Sie berücksichtigt die Backend- und Serverwarteschlangen und hängt von deren Größe sowie davon ab, wie lange der Server für vorherige Anfragen benötigt. “-1” bedeutet, dass die Anfrage vor Erreichen der Warteschlange beendet wurde, was meist bei ungültigen oder abgewiesenen Anfragen geschieht.
Dieser Messwert heißt als log-format-Alias %Tw und als Sample-Abruf req.timer.queue.
-
Tc: Gesamtdauer für den Aufbau der TCP-Verbindung zum Server. Dies ist die Zeit zwischen dem Senden der Verbindungsanfrage durch den Proxy und ihrer Bestätigung durch den Server, also zwischen TCP-SYN-Paket und zugehörigem SYN/ACK-Antwortpaket. “-1” bedeutet, dass keine Verbindung zustande kam.
Dieser Messwert heißt als log-format-Alias %Tc und als Sample-Abruf bc.timer.connect.
-
Tr: Antwortzeit des Servers, nur im HTTP-Modus. Dies ist die Zeit zwischen dem Aufbau der TCP-Verbindung zum Server und dem Senden seiner vollständigen Antwort-Header. Sie gibt ausschließlich die Bearbeitungszeit der Anfrage ohne den Netzwerkaufwand für die Datenübertragung an. Muss der Client Daten an den Server senden, etwa bei einer POST-Anfrage, läuft die Messung jedoch bereits, was die scheinbare Antwortzeit verfälschen kann. Bei POST-Anfragen von Clients hinter einem nicht vertrauenswürdigen Netzwerk sollte diesem Feld daher gewöhnlich nur eingeschränkt vertraut werden. “-1” bedeutet, dass der letzte Antwort-Header, die Leerzeile, nie empfangen wurde. Meist ist dann die Serverzeitgrenze vor Verarbeitung der Anfrage abgelaufen oder der Server hat eine ungültige Antwort geliefert.
Dieser Messwert heißt als log-format-Alias %Tr und als Sample-Abruf res.timer.hdr.
-
Td: Gesamtdauer der Übertragung der Antwortnutzdaten bis zum letzten an den Client gesendeten Byte. Bei HTTP beginnt sie nach dem letzten Antwort-Header, also nach Tr.
Es ist nicht garantiert, dass die gesendeten Daten beim Client ankommen; sie können im Kernel oder im Netzwerk festhängen.
Dieser Messwert heißt als log-format-Alias %Td und als Sample-Abruf res.timer.data.
-
Ta: Gesamte aktive Zeit der HTTP-Anfrage vom Empfang des ersten Bytes ihres Headers durch den Proxy bis zum Senden des letzten Bytes des Antwortkörpers. Eine Ausnahme besteht bei der Option “logasap”: Dann entspricht sie nur (TR+Tw+Tc+Tr) und erhält ein vorangestelltes ‘+’. Daraus lässt sich die Datenübertragungszeit “Td” durch Abziehen der übrigen gültigen Messwerte berechnen:
Messwerte mit dem Wert "-1" müssen aus dieser Gleichung ausgeschlossen werden.
"Ta" kann niemals negativ sein.
Dieser Messwert heißt als log-format-Alias %Ta und als Sample-Abruf txn.timer.total.
- Tt: Gesamtdauer des Streams von der Annahme durch den Proxy bis zum Schließen beider Seiten. Eine Ausnahme besteht bei der Option “logasap”: Dann entspricht sie nur (Th+Ti+TR+Tw+Tc+Tr) und erhält ein vorangestelltes ‘+’. Daraus lässt sich die Datenübertragungszeit “Td” durch Abziehen der übrigen gültigen Messwerte berechnen:
Messwerte mit dem Wert "-1" müssen aus dieser Gleichung ausgeschlossen werden.
Im TCP-Modus müssen außerdem "Ti", "Tq" und "Tr" ausgeschlossen werden.
"Tt" kann niemals negativ sein; bei HTTP entspricht Tt einfach (Th+Ti+Ta).
Dieser Messwert heißt als log-format-Alias %Tt und als Sample-Abruf fc.timer.total.
-
Tu: Geschätzte Gesamtdauer aus Sicht des Clients von der Annahme durch den Proxy bis zum Schließen beider Seiten, ohne Leerlaufzeit. Damit lässt sich die vom Nutzer wahrgenommene Gesamtdauer grob messen, ohne den Einfluss der Keep-Alive-Leerlaufzeit zwischen Anfragen. Es ist nur eine Schätzung, da sie gleiche Netzwerklatenzen in beiden Richtungen voraussetzt. Eine Ausnahme besteht bei der Option “logasap”: Dann entspricht sie nur (Th+TR+Tw+Tc+Tr) und erhält ein vorangestelltes ‘+’.
Dieser Messwert heißt als log-format-Alias %Tu und als Sample-Abruf txn.timer.user.
Diese Zeitmessungen liefern wertvolle Hinweise auf Fehlerursachen. Da TCP Wiederholungsintervalle von 3, 6, 12… Sekunden vorgibt, hängen Werte nahe Vielfachen von 3s fast immer mit Paketverlusten durch Netzwerkprobleme zusammen, etwa Kabel, Aushandlung oder Überlastung. Liegt “Ta” oder “Tt” nahe einer konfigurierten Zeitgrenze, wurde ein Stream häufig wegen einer Zeitüberschreitung abgebrochen.
Die häufigsten Fälle:
-
Liegt “Th” oder “Ti” nahe bei 3000, ging wahrscheinlich ein Paket zwischen Client und Proxy verloren. In lokalen Netzen ist dies sehr selten, kann aber bei weit entfernten Clients mit großen Anfragen auftreten. Höhere Werte können auch ohne Netzwerkproblem entstehen. Während eines Angriffs oder unmittelbar nach dem Ende eines Ressourcenengpasses nimmt HAProxy manchmal Tausende Verbindungen innerhalb weniger Millisekunden an. Die dafür benötigte Zeit verzögert zwangsläufig die Verarbeitung anderer Verbindungen etwas. Werden einige Tausend Verbindungen gleichzeitig angenommen, können daher Anfragezeiten von einigen zehn Millisekunden entstehen. In einem Keep-Alive-Modus können längere Leerlaufzeiten erscheinen, da “Ti” die Wartezeit auf weitere Anfragen misst.
-
Liegt “Tc” nahe bei 3000, ging beim Verbindungsaufbau wahrscheinlich ein Paket zwischen Server und Proxy verloren. Dieser Wert sollte stets sehr niedrig sein, etwa 1 ms in lokalen Netzen und weniger als einige zehn ms in entfernten Netzen.
-
Liegt “Tr” fast immer unter 3000, mit wenigen Ausnahmen, die ungefähr dem Durchschnitt zuzüglich 3000 entsprechen, gehen wahrscheinlich Pakete zwischen Proxy und Server verloren.
-
Ist “Ta” selbst bei kleinen Bytezahlen groß, schließen häufig weder Client noch Server die Verbindung, während HAProxy im Tunnelmodus arbeitet und beide einen Keep-Alive-Modus vereinbart haben. Zur Behebung muss eine HTTP-Option verwendet werden, die Keep-Alive oder das Schließen im Frontend oder Backend beeinflusst. Bei Verbindungsregelung mit “maxconn” auf den Servern sind möglichst kleine Werte für ‘Ta’ oder ‘Tt’ wichtig: Erst wenn eine Verbindung freigegeben wird, erhält der Server eine neue.
Weitere auffällige Fälle im HTTP-Protokoll (‘xx’ steht für einen beliebigen, zu ignorierenden Wert):
8.5. Stream-Zustand bei der Trennung
TCP- und HTTP-Protokolle enthalten unmittelbar vor der Anzahl aktiver Verbindungen im Feld “termination_state” ein Kennzeichen zur Stream-Beendigung. Im TCP-Modus ist es 2 Zeichen lang, im HTTP-Modus 4. Jedes Zeichen hat eine eigene Bedeutung:
- Das erste Zeichen bezeichnet das erste Ereignis, das zur Beendigung des Streams führte:
- Das zweite Zeichen bezeichnet den Zustand des TCP- oder HTTP-Streams beim Schließen:
- Das dritte Zeichen gibt an, ob der Client das Persistenz-Cookie mitgesendet hat, nur im HTTP-Modus:
- Das letzte Zeichen beschreibt die Aktionen am vom Server zurückgegebenen Persistenz-Cookie, nur im HTTP-Modus:
Die Kombination der ersten beiden Flags zeigt ausführlich, was beim Ende des Streams oder der Sitzung geschah und warum er beziehungsweise sie beendet wurde. Sie hilft etwa, überlastete Server, Netzwerkprobleme, lokale Ressourcenengpässe und Angriffe zu erkennen.
Die häufigsten Kombinationen von Beendigungsflags stehen unten in alphabetischer Reihenfolge. Zur leichteren Orientierung folgt die Variante mit Kleinbuchstaben jeweils direkt auf die mit Großbuchstaben.
Flags Grund
-- Normale Beendigung.
CC Der Client brach ab, bevor die Verbindung zum Server aufgebaut war.
Dies kann geschehen, wenn HAProxy einen kürzlich ausgefallenen oder
ungeprüften Server zu erreichen versucht und der Client abbricht,
während HAProxy auf dessen Antwort oder auf "timeout connect" wartet.
CD Der Client brach während der Datenübertragung unerwartet ab. Mögliche
Ursachen sind ein Browserabsturz, ein zwischengeschaltetes Gerät,
das die Verbindung zwischen Client und HAProxy aktiv trennt,
Routingprobleme auf diesem Weg oder ein Keep-Alive-Stream zwischen
Server und Client, den zuerst der Client beendet.
cD Der Client hat während der gesamten Dauer von "timeout client"
weder Daten gesendet noch bestätigt. Häufig sind Netzwerkfehler
auf der Clientseite oder ein unsauberes Verlassen des Netzwerks
durch den Client die Ursache.
CH Der Client brach ab, während er auf den Beginn der Serverantwort
wartete. Möglicherweise antwortete der Server zu langsam, oder
der Client klickte zu früh auf 'Stop'.
cH "timeout client" lief beim Warten auf Clientdaten während einer
POST-Anfrage ab. Eine Ursache können zu große TCP-MSS-Werte für
PPPoE-Netze sein, die keine Pakete voller Größe übertragen können.
Dies kann auch auftreten, wenn die Clientzeitgrenze kleiner als
die Serverzeitgrenze ist und der Server zu lange zum Antworten braucht.
CQ Der Client brach ab, während sein Stream auf einen Server mit
genügend freien Verbindungsplätzen wartete. Möglicherweise waren
alle Server ausgelastet oder der zugewiesene Server antwortete zu langsam.
CR Der Client brach ab, bevor er eine vollständige HTTP-Anfrage gesendet
hatte. Wahrscheinlich wurde die Anfrage von Hand mit einem telnet-Client
eingegeben und zu früh abgebrochen. Der HTTP-Statuscode ist hier
vermutlich 400. Gelegentlich kann auch ein IDS die Verbindung zwischen
HAProxy und Client beenden. Mit "option http-ignore-probes" lassen
sich Verbindungen ohne Datenaustausch ignorieren.
cR "timeout http-request" lief ab, bevor der Client eine vollständige
HTTP-Anfrage gesendet hatte. Mögliche Ursachen sind zu große TCP-MSS-
Werte auf der Clientseite für PPPoE-Netze, die keine Pakete voller
Größe übertragen können, zu langsam von Hand eingegebene Anfragen
oder eine vergessene Leerzeile am Anfrageende. Der HTTP-Statuscode
ist hier vermutlich 408. Hinweis: Einige Browser haben seit Kurzem
eine "pre-connect"-Funktion. Sie verbinden sich vorsorglich mit kürzlich
besuchten Websites, falls der Nutzer sie erneut aufrufen möchte.
Dadurch entstehen viele Verbindungen, die bei zuerst ablaufender
Zeitgrenze mit 408 Request Timeout oder bei vorherigem Schließen
durch den Browser mit 400 Bad Request enden. Sie füllen die Protokolle
und erhöhen Fehlerzähler. Manche Versionen einiger Browser sollen
sogar den Fehlercode anzeigen. Mit "option http-ignore-probes" im
Frontend lassen sich diese unerwünschten Auswirkungen umgehen:
Verbindungen ohne Datenübertragung werden vollständig ignoriert.
Dadurch werden allerdings auch Fehler von Nutzern mit
Verbindungsproblemen verborgen.
CT Der Client brach ab, während sein Stream mit tarpit verzögert wurde.
Es ist wichtig zu prüfen, ob dies bei gültigen Anfragen geschieht,
um fehlerhafte tarpit-Regeln auszuschließen. Bei vielen solchen
Fällen kann es sinnvoll sein, "timeout tarpit" näher an den
durchschnittlichen Messwert "Tw" zu senken, damit nicht wenige
Angreifer unnötig Ressourcen binden.
LC HAProxy fing die Anfrage ab und verarbeitete sie lokal. Sie wurde
nicht an den Server gesendet. Dies tritt nur bei einer Weiterleitung
durch einen Parameter "redir" in der Serverzeile auf.
LR HAProxy fing die Anfrage ab und verarbeitete sie lokal. Sie wurde
nicht an den Server gesendet. Gewöhnlich wurde eine Weiterleitung
zurückgegeben, eine HTTP-return-Anweisung verarbeitet oder die
Anfrage von einem Applet bearbeitet, etwa stats, cache,
Prometheus-Exporter oder Lua-Applet.
LH HAProxy fing die Antwort ab und verarbeitete sie lokal. Gewöhnlich
wurde eine Weiterleitung zurückgegeben oder eine HTTP-return-Anweisung
verarbeitet.
SC Der Server oder ein Gerät zwischen ihm und HAProxy wies die
TCP-Verbindung ausdrücklich zurück; der Proxy empfing ein TCP-RST
oder eine ICMP-Nachricht. Unter bestimmten Umständen meldet auch
der Netzwerk-Stack, dass der Server nicht erreichbar ist, etwa
wegen einer fehlenden Route oder ARP-Antwort im lokalen Netz.
Im HTTP-Modus ist der Statuscode dann vermutlich 502 oder 503.
sC "timeout connect" lief ab, bevor die Verbindung zum Server
vollständig aufgebaut war. Im HTTP-Modus ist der Statuscode
dann vermutlich 503 oder 504.
SD Die Serververbindung endete während der Datenübertragung mit einem
Fehler. Gewöhnlich hat HAProxy beim Datenaustausch ein RST vom
Server oder eine ICMP-Nachricht eines zwischengeschalteten Geräts
empfangen. Ursache kann ein Serverabsturz oder ein Netzwerkproblem
an einem zwischengeschalteten Gerät sein.
sD Der Server hat während der Datenphase für die gesamte Dauer von
"timeout server" weder Daten gesendet noch bestätigt. Häufige
Ursachen sind zu kurze Zeitgrenzen auf vorgeschalteten L4-Geräten
wie Firewalls oder Load-Balancern sowie Keep-Alive-Sitzungen zwischen
Client und Server, deren Zeitgrenze zuerst in HAProxy abläuft.
SH Der Server brach vor dem Senden seiner vollständigen HTTP-Antwort-
Header ab oder stürzte bei der Anfrageverarbeitung ab. Ein Abbruch
zu diesem Zeitpunkt ist sehr selten. Daher sollten seine Protokolle
darauf geprüft werden, ob und warum er abgestürzt ist. Die
protokollierte Anfrage kann auf eine kleine Gruppe fehlerhafter
Anfragen hinweisen, die Programmfehler in der Anwendung auslösen.
Gelegentlich kann auch ein IDS die Verbindung zwischen HAProxy
und dem Server beenden.
sH "timeout server" lief ab, bevor der Server seine Antwort-Header
zurückgeben konnte. Dies ist die häufigste Auffälligkeit und deutet
auf zu lange Transaktionen hin, vermutlich wegen überlasteter Server
oder Datenbanken. Kurzfristig hilft ein höherer Wert für "timeout server".
Die langen Antwortzeiten beeinträchtigen aber die Nutzererfahrung.
Die einzige dauerhafte Lösung besteht darin, die Anwendung zu korrigieren.
sQ Der Stream wartete zu lange in der Warteschlange und lief ab.
Tritt dies zu oft auf, die Einstellungen "timeout queue" und
"timeout connect" prüfen. Viele solche Fälle in kurzen Zeiträumen
können auf allgemeine Serverprobleme durch I/O- oder Datenbankengpässe
oder auf Überlastung durch externe Angriffe hindeuten.
PC Der Proxy verweigerte den Verbindungsaufbau zum Server, weil beim
Versuch die Socket-Grenze des Prozesses erreicht wurde. Der globale
Parameter "maxconn" kann erhöht werden, um dies zu verhindern.
Dieser Zustand ist sehr selten und kann auftreten, wenn der globale
Parameter "ulimit-n" von Hand erzwungen wird.
PD Nach dem Senden der Server-Header blockierte der Proxy eine fehlerhaft
formatierte Nachricht mit Chunked-Kodierung in einer Anfrage oder
Antwort. Meist handelt es sich um eine ungültige Nachricht vom Server
an den Client. HAProxy unterstützt Chunk-Größen bis 2GB - 1
(2147483647 Bytes). Größere Werte gelten als Fehler.
PH Der Proxy blockierte die Serverantwort, weil sie ungültig,
unvollständig, gefährlich hinsichtlich der Cache-Steuerung war oder
einem Sicherheitsfilter entsprach. Dabei erhält der Client einen
HTTP-Fehler 502. Eine mögliche Ursache ist ein HTTP-Headername mit
unzulässigen Zeichen. Selten kann der Proxy auch vor der Serverantwort
eine syntaktisch ungültige Clientanfrage mit Chunked-Kodierung
blockieren. Dann erhält der Client einen HTTP-Fehler 400, der auch
protokolliert wird. Schließlich kann ein Fehler beim Umschreiben
eines Antwort-Headers die Ursache sein. Dann wird ein HTTP-Fehler
500 gesendet; siehe "tune.maxrewrite" und "http-response strict-mode".
PR Der Proxy blockierte die HTTP-Anfrage des Clients: Bei ungültiger
HTTP-Syntax antwortete er mit einem HTTP-Fehler 400, bei einem
passenden deny-Filter mit einem HTTP-Fehler 403. Auch ein Fehler
beim Umschreiben eines Anfrage-Headers ist möglich. Dann wird
ein HTTP-Fehler 500 gesendet; siehe "tune.maxrewrite" und
"http-request strict-mode".
PT Der Proxy blockierte die Clientanfrage und verzögerte die Verbindung
mit tarpit, bevor er einen Serverfehler 500 zurückgab. An den Server
wurde nichts gesendet. Die Verbindung blieb so lange offen,
wie der Messwert "Tw" angibt.
RC Eine lokale Ressource war erschöpft, etwa Speicher, Sockets oder
Quellports, sodass die Serververbindung nicht aufgebaut werden konnte.
Die Fehlerprotokolle nennen genau die fehlende Ressource. Dies ist
sehr selten und lässt sich nur durch geeignete Systemanpassungen beheben.
Die Kombination der letzten beiden Flags zeigt ausführlich, wie Client, Server und HAProxy die Persistenz behandelt haben. Das ist bei Verbindungsabbrüchen sehr wichtig, wenn Nutzer über wiederholte Authentifizierung klagen. Häufig treten folgende Flags auf:
8.6. Nicht druckbare Zeichen
Damit Protokollauswertungswerkzeuge und Terminals beim Lesen der Protokolle keine Probleme bekommen, werden nicht druckbare Zeichen nicht unverändert ausgegeben. Stattdessen erscheint ihr zweistelliger hexadezimaler ASCII-Code mit vorangestelltem ‘#’. Nur Zeichen zwischen 32 und 126 einschließlich können unmaskiert protokolliert werden. Das Maskierungszeichen ‘#’ selbst wird zur Vermeidung von Mehrdeutigkeiten ebenfalls kodiert, als “#23”. Dasselbe gilt für ‘"’, das zu “#22” wird, sowie beim Protokollieren von Headern für ‘{’, ‘|’ und ‘}’.
Dies gilt nicht für die cbor-Kodierung, die bereits sichere Hexadezimalziffern oder korrekt abgegrenzte Binärblöcke verwendet. Diese werden nicht an ein Terminal gesendet, sondern von einem CBOR-Parser verarbeitet.
Die json-Kodierung verwendet stattdessen JSON-Escape-Sequenzen. Mit der Option +utf8 werden außerdem gültige UTF-8-Sequenzen aus mehreren Bytes unverändert ausgegeben (siehe das Flag “utf8” in Abschnitt 8.2.6 ).
Das Leerzeichen (’ ‘) wird in Headern nicht kodiert. Dies kann Werkzeuge beeinträchtigen, die Felder anhand der Anzahl von Leerzeichen bestimmen. Ein typischer Header mit Leerzeichen ist “User-Agent”.
Einige syslog-Daemons wie syslog-ng maskieren das Anführungszeichen (’"’) mit einem Backslash (’\’). Dies kann gefahrlos rückgängig gemacht werden, da Anführungszeichen sonst nirgendwo in den Protokollen vorkommen dürfen.
8.7. HTTP-Cookies erfassen
Das Erfassen von Cookies erleichtert es, eine vollständige Nutzersitzung zu verfolgen. Dazu dient “capture cookie” im Frontend; Einzelheiten stehen in Abschnitt 4.2 . Es kann nur ein Cookie erfasst werden. Dasselbe Cookie wird gleichzeitig in der Anfrage (Header “Cookie:”) und in der Antwort (Header “Set-Cookie:”) geprüft. Die jeweiligen Werte erscheinen im HTTP-Protokoll in “captured_request_cookie” und “captured_response_cookie” (siehe Abschnitt 8.2.3 zum HTTP-Protokollformat). Fehlt eines der Cookies, steht statt seines Werts ein Bindestrich (’-’). Dadurch lässt sich etwa der Wechsel eines Nutzers in eine neue Sitzung leicht erkennen, da ihm der Server ein neues Cookie zuweist. Auch ein unerwartet falsch gesetztes Cookie, das Sitzungen zwischen Clients verwechselt, lässt sich so erkennen.
Beispiele:
Für weitergehende Erfassungen können “http-request”- und “http-response”-Regeln Cookies Variablen des Geltungsbereichs “txn” zuweisen. Die Werte lassen sich mit den Sample-Abruffunktionen “req.cook” und “res.cook” aus Anfrage oder Antwort auslesen (siehe Abschnitt 7.3.6 ) und mit “set-var” oder “set-var-fmt” einer Variablen zuweisen (siehe Abschnitt 4.3 ). Ein benutzerdefiniertes log-format kann diese Variablen dann an beliebiger Stelle ausgeben (siehe Abschnitt 8.2.6 ).
8.8. HTTP-Header erfassen (älteres Verfahren)
Das Erfassen von Headern hilft, eindeutige Anfragekennungen eines vorgeschalteten Proxys, virtuelle Hostnamen, User-Agents, content-length bei POST-Anfragen, Referrer und Ähnliches zu verfolgen. In Antworten lassen sich etwa Angaben zur Antwortlänge, zu den Vorgaben des Servers für den Cache oder zum Zielort eines Objekts bei einer Weiterleitung ermitteln.
Es gibt zwei Verfahren zur Header-Erfassung. Beim modernen Verfahren werden Variablen aus den gewünschten Headern oder aus zusammengesetzten Samples von “req.hdr_names”, “req.hdrs”, “res.hdr_names” und “res.hdrs” gesetzt; alle Möglichkeiten stehen in Abschnitt 7.3.6 . Mit den Aktionen “set-var” und “set-var-fmt” der Regelsätze “http-request” und “http-response” lassen sie sich Variablen des Geltungsbereichs “txn” zuweisen (siehe Abschnitt 4.3 ). Diese können dann in benutzerdefinierten Protokollformaten referenziert werden (siehe Abschnitt 8.2.6 ). Dies ist das empfohlene Verfahren zur Erfassung von HTTP-Headern.
Daneben gibt es das ältere Verfahren aus der Zeit vor http-request-Regeln und Variablen. Es erfordert keine Anpassung des Protokollformats und wird seit Langem sowohl zur Protokollierung als auch als Behelf verwendet, um Anfrageinformationen über die gesamte HTTP-Transaktion hinweg weiterzugeben. Es verwendet die älteren “capture”-Regelsätze und wird in diesem Abschnitt beschrieben.
Beim älteren Verfahren werden Header mit “capture request header” und “capture response header” im Frontend erfasst. Einzelheiten stehen in den Definitionen in Abschnitt 4.2 .
Anfrage- und Antwort-Header können gleichzeitig erfasst werden. Fehlende Header werden als leere Zeichenketten protokolliert. Kommt ein Header mehrfach vor, wird nur das letzte Vorkommen erfasst. Anfrage-Header werden in der Reihenfolge ihrer Deklaration innerhalb geschweifter Klammern ‘{’ und ‘}’ zusammengefasst und durch ‘|’ ohne Leerzeichen getrennt. Antwort-Header haben dieselbe Darstellung und folgen nach einem Leerzeichen auf den Block der Anfrage-Header. Beide Blöcke stehen im Protokoll unmittelbar vor der HTTP-Anfrage.
Als Sonderfall kann die Erfassung eines HTTP-Headers in einem TCP-Frontend definiert werden. Damit lassen sich Header protokollieren, die in einem HTTP-Backend ausgewertet werden, wenn die Anfrage anschließend an dieses Backend übergeben wird.
Beispiel:
8.9. Protokollbeispiele
Die folgenden Protokollbeispiele mit Erläuterungen stammen aus der Praxis; einige wurden von Hand erstellt. Zur besseren Lesbarkeit wurde der syslog-Teil entfernt. Sie sollen ausschließlich erklären, wie die Meldungen zu lesen sind.
>>> haproxy[674]: 127.0.0.1:33318 [15/Oct/2003:08:31:57.130] px-http \
px-http/srv1 6559/0/7/147/6723 200 243 - - ---- 5/3/3/1/0 0/0 \
"HEAD / HTTP/1.0"
=> Eine lange Anfrage (6.5s) wurde von Hand über 'telnet' eingegeben.
Der Server antwortete in 147 ms; die Sitzung endete normal ('----').
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57.149] px-http \
px-http/srv1 6559/1230/7/147/6870 200 243 - - ---- 324/239/239/99/0 \
0/9 "HEAD / HTTP/1.0"
=> Wie zuvor, aber die Anfrage stand hinter 9 anderen Anfragen in
der globalen Warteschlange und wartete dort 1230 ms.
=> Anfrage für eine lange Datenübertragung. Da "logasap" gesetzt war,
wurde die Meldung unmittelbar vor der Datenübertragung ausgegeben.
Der Server antwortete in 14 ms, 243 Header-Bytes wurden an den Client
gesendet, und von der Annahme bis zum ersten Datenbyte vergingen 30 ms.
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.925] px-http \
px-http/srv1 9/0/7/14/30 502 243 - - PH-- 3/2/2/0/0 0/0 \
"GET /cgi-bin/bug.cgi? HTTP/1.0"
=> Der Proxy blockierte eine Serverantwort: entweder aufgrund einer
"http-response deny"-Regel, wegen eines fehlerhaften, nicht HTTP-konformen
Formats oder weil sensible Informationen hätten zwischengespeichert
werden können. Die Antwort wird dann durch "502 bad gateway" ersetzt.
Die Flags ("PH--") zeigen, dass HAProxy die 502 zurückgab, nicht der Server.
>>> haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55.798] px-http \
px-http/`<NOSRV>` -1/-1/-1/-1/8490 -1 0 - - CR-- 2/2/2/0/0 0/0 ""
=> Der Client vervollständigte seine Anfrage nie und brach nach 8.5s
selbst ab ("C---"), während der Proxy auf die Anfrage-Header wartete
("-R--"). An keinen Server wurde etwas gesendet.
>>> haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06.103] px-http \
px-http/`<NOSRV>` -1/-1/-1/-1/50001 408 0 - - cR-- 2/2/2/0/0 0/0 ""
=> Der Client vervollständigte seine Anfrage nie. Nach 50s wurde sie
durch die Zeitüberschreitung abgebrochen ("c---"), während der Proxy
auf die Anfrage-Header wartete ("-R--"). An keinen Server wurde etwas
gesendet; der Proxy konnte dem Client jedoch den Statuscode 408 senden.
>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28.312] px-tcp \
px-tcp/srv1 0/0/5007 0 cD 0/0/0/0/0 0/0
=> Diese Meldung wurde mit "option tcplog" erzeugt. Die Clientzeitgrenze
lief nach 5 Sekunden ab ("c----").
>>> haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31.462] px-http \
px-http/srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 205/202/202/115/3 \
0/0 "HEAD / HTTP/1.0"
=> Die Anfrage benötigte 3s bis zur Vollständigkeit, vermutlich wegen
eines Netzwerkproblems. Die Serververbindung schlug nach 4 Versuchen
von je 2 Sekunden fehl ('SC--'); konfiguriert war 'retries 3'. Es gab
keine Umverteilung, sonst wäre "/+3" zu sehen. Der Client erhielt
Statuscode 503. Auf diesem Server bestanden 115 Verbindungen, auf
diesem Proxy 202 und im gesamten Prozess 205. Möglicherweise wies
der Server die Verbindung wegen zu vieler bestehender Verbindungen ab.
18 - 9. Unterstützte Filter
Im Folgenden sind die offiziell unterstützten Filter und ihre Parameter aufgeführt. Je nach Build-Optionen sind manche Filter möglicherweise nicht verfügbar. haproxy -vv zeigt die verfügbaren Filter an.
Siehe auch “filter”.
9.1. Trace
filter trace [name <name>] [random-forwarding] [max-fwd <max>] [hexdump]
Argumente:
Dieser Filter kann als Grundlage für die Entwicklung neuer Filter dienen. Er definiert alle Rückruffunktionen und gibt für jede eine Meldung mit nützlichen Informationen auf der Standardfehlerausgabe (stderr) aus. Damit lässt sich die Aktivität anderer Filter oder von HAProxy selbst untersuchen.
Mit <random-parsing> und/oder <random-forwarding> lässt sich das Verhalten eines Filters testen, der die zwischen Client und Server übertragenen Daten analysiert. Die Parameter fügen der Verarbeitung Verzögerungen hinzu.
9.2. HTTP-Komprimierung
filter comp-req
Aktiviert einen Filter, der ausdrücklich versucht, HTTP-Anfragen gemäß “compression” zu komprimieren. Setzt implizit “compression direction request”.
filter comp-res
Aktiviert einen Filter, der ausdrücklich versucht, HTTP-Antworten gemäß “compression” zu komprimieren. Setzt implizit “compression direction response”.
filter compression (veraltet)
Alias zur Abwärtskompatibilität, der funktional der Aktivierung beider Filter “comp-req” und “comp-res” entspricht. Das gewünschte Verhalten muss mit “compression” konfiguriert werden:
Seit HAProxy 1.7 ist die HTTP-Komprimierung als Filter umgesetzt. Zum Aktivieren und Konfigurieren muss weiterhin “compression” verwendet werden. Solange keine anderen Filter eingesetzt werden, genügt dies. Das gilt auch zusammen mit aktiviertem Cache oder fcgi-app. In diesem Fall wird die Antwort immer erst nach dem Speichern im Cache komprimiert. Sobald für denselben Listener, dasselbe Frontend oder Backend jedoch mindestens ein anderer Filter als Cache oder fcgi-app verwendet wird, muss die HTTP-Komprimierung ausdrücklich durch eine filter-Zeile aktiviert werden. Dadurch ist die Auswertungsreihenfolge der Filter festgelegt.
Siehe auch “compression”, Abschnitt 9.4 zum Cache-Filter und Abschnitt 9.5 zum fcgi-app-Filter.
9.3. Stream Processing Offload Engine (SPOE)
filter spoe [engine <name>] config <file>
Argumente:
Die Stream Processing Offload Engine (SPOE) ist ein Filter, der mit externen Komponenten kommuniziert. Er ermöglicht, bestimmte Verarbeitungsschritte für Streams in mehrschichtigen Anwendungen auszulagern. Die externen Komponenten und die mit ihnen ausgetauschten Informationen werden größtenteils in eigenen Dateien konfiguriert. Zusätzlich sind eigene Backends in der HAProxy-Konfiguration erforderlich.
SPOE kommuniziert mit externen Komponenten über ein eigenes Binärprotokoll, das Stream Processing Offload Protocol (SPOP).
Wird SPOE auf einen Stream angewendet, entsteht ein eigener Stream für die Kommunikation mit der externen Komponente. Der Hauptstream ist der übergeordnete Stream dieses “SPOE”-Streams. Daher lassen sich aus dem “SPOE”-Stream Variablen des Hauptstreams abrufen. Einzelheiten zu Variablen stehen in Abschnitt 2.8 .
Alle Angaben zur SPOE-Konfiguration und zur SPOP-Spezifikation stehen in “doc/SPOE.txt”.
9.4. Cache
filter cache <name>
Argumente:
Der Cache verwendet einen Filter zum Speichern cachefähiger Antworten. Mit den HTTP-Regeln “cache-store” und “cache-use” muss festgelegt werden, wie und wann der Cache verwendet wird. Der zugehörige Filter ist standardmäßig implizit definiert. Werden außer fcgi-app oder compression keine weiteren Filter verwendet, genügt das. In diesem Fall wird der Komprimierungsfilter immer nach dem Cache-Filter ausgewertet. Sobald für denselben Listener, dasselbe Frontend oder Backend mindestens ein anderer Filter als compression oder fcgi-app verwendet wird, muss der Cache jedoch ausdrücklich durch eine filter-Zeile eingebunden werden. Dadurch ist die Auswertungsreihenfolge der Filter festgelegt.
Siehe auch Abschnitt 9.2 zum Komprimierungsfilter, Abschnitt 9.5 zum fcgi-app-Filter und Abschnitt 6 zum Cache.
9.5. Fcgi-app
filter fcgi-app <name>
Argumente:
Die FastCGI-Anwendung verwendet einen Filter, um bei Anfragen alle benutzerdefinierten Parameter auszuwerten und bei Antworten die Header zu verarbeiten. <name> muss auf einen vorhandenen fcgi-app-Abschnitt verweisen. Die zu verwendende Anwendung sollte mit “use-fcgi-app” festgelegt werden. Der zugehörige Filter ist standardmäßig implizit definiert. Werden außer cache oder compression keine weiteren Filter verwendet, genügt das. Sobald für dasselbe Backend mindestens ein anderer Filter als compression oder cache verwendet wird, muss fcgi-app jedoch ausdrücklich durch eine filter-Zeile eingebunden werden. Dadurch ist die Auswertungsreihenfolge der Filter festgelegt.
Siehe auch “use-fcgi-app”, Abschnitt 9.2 zum Komprimierungsfilter, Abschnitt 9.4 zum Cache-Filter und Abschnitt 10 zu FastCGI-Anwendungen.
9.6. OpenTracing
Der OpenTracing-Filter unterstützt verteiltes Tracing direkt in HAProxy. Dazu sendet er eine OpenTracing-konforme Anfrage an einen unterstützten Tracer, etwa Datadog, Jaeger, Lightstep oder Zipkin. Die Tracer sind alphabetisch und nicht nach einer Rangfolge aufgeführt.
Die Funktion ist nur verfügbar, wenn HAProxy mit USE_OT=1 gebaut wurde.
Der OpenTracing-Filter muss ausdrücklich in der HAProxy-Konfiguration aktiviert werden. Andernfalls beteiligt er sich in keiner Weise an der Verarbeitung von HAProxy.
filter opentracing [id <id>] config <file>
Argumente:
Ausführliche Dokumentation zu Betrieb, Konfiguration und Verwendung des Filters steht im Verzeichnis addons/ot.
Hinweis: Der OpenTracing-Filter sollte für neue Entwürfe nicht verwendet werden, da die Autoren OpenTracing nicht mehr pflegen oder unterstützen. OpenTracing wird daher in 3.3 als veraltet markiert und in 3.5 entfernt. Seit 3.4 ist ein Ersatzfilter auf Basis von OpenTelemetry verfügbar. Vollständige Build-Anweisungen stehen derzeit unter:
9.7. Bandbreitenbegrenzung
Argumente:
Filter zur Bandbreitenbegrenzung sollten eingesetzt werden, um die Weiterleitungsgeschwindigkeit auf Stream-Ebene zu beschränken. Damit begrenzen sie die Netzwerkbandbreite, die eine Ressource belegt. Mehrere solche Filter lassen sich kombinieren. Beispielsweise kann eine Grenze pro Quelladresse verhindern, dass ein Client die gesamte Bandbreite beansprucht und andere Clients benachteiligt. Eine weitere Grenze pro Stream ermöglicht, mehrere Verbindungen desselben Clients gerecht zu behandeln.
Die Definitionsreihenfolge ist wichtig. Sind mehrere Bandbreitenfilter auf einem Stream aktiviert, werden sie in dieser Reihenfolge angewendet. Auch die Position anderer Filter spielt eine Rolle. Je nachdem, ob der HTTP-Komprimierungsfilter vor oder nach dem Bandbreitenfilter definiert ist, gilt die Grenze für die komprimierten oder die unkomprimierten Nutzdaten. Dasselbe gilt für den Cache-Filter.
Es gibt zwei Arten von Bandbreitenfiltern. Die erste setzt eine Standardgrenze je Stream durch. Die zweite verwendet eine Zuordnungstabelle, um eine Grenze gleichmäßig auf alle Streams aufzuteilen, die denselben Tabelleneintrag verwenden.
Je nach Filter-Schlüsselwort gilt die Begrenzung für eingehende Daten vom Client zum Server oder für ausgehende Daten vom Server zum Client. Für eingehende Daten muss “bwlim-in”, für ausgehende “bwlim-out” verwendet werden. In beiden Fällen greift die Bandbreitenbegrenzung bei der Datenweiterleitung auf Stream-Ebene.
Die Begrenzung gilt für Streams, nicht für Verbindungen. Bei Multiplex-Protokollen wie H2, H3 und FastCGI können Streams derselben Verbindung unterschiedliche Grenzen haben.
Für einen Bandbreitenfilter je Stream müssen Standardzeitraum und Standardgrenze definiert werden. Sie legen die standardmäßige Bandbreitenrate eines Streams fest. Nur bei dieser Filterart lassen sich die Werte mit Sample-Ausdrücken überschreiben, wenn der Filter durch eine TCP/HTTP-Aktion “set-bandwidth-limit” aktiviert wird.
Bei einem gemeinsam genutzten Bandbreitenfilter muss die Zuordnungstabelle die zur Richtung passende Byte-Rate speichern. Für eingehende Daten ist der Zähler “bytes_in_rate(<period>)” erforderlich, für ausgehende “bytes_out_rate(<period>)”.
Außerdem lässt sich die Mindestanzahl von Bytes festlegen, die ein Bandbreitenfilter für einen Stream auf einmal weiterleitet. Sie sollte verhindern, dass zu kleine Datenmengen übertragen werden, und so die CPU-Last verringern. Der Wert muss sorgfältig gewählt werden: Ist er zu klein, kann die CPU-Last steigen; ist er zu groß, kann die Latenz zunehmen. Er hängt auch eng mit der Bandbreitengrenze zusammen. Liegt er zu nahe an dieser Grenze, können Pausen nötig werden, um sie nicht zu überschreiten, weil auf einmal zu viele Bytes verbraucht werden. Der passende Wert hängt stark von der Filterkonfiguration ab. Ein sinnvoller Ausgangspunkt sind etwa 2 TCP MSS, normalerweise 2896 Bytes. Anschließend lässt sich der Wert anhand von Versuchen optimieren.
Beispiel:
Siehe auch “tcp-request content set-bandwidth-limit”, “tcp-response content set-bandwidth-limit”, “http-request set-bandwidth-limit” und “http-response set-bandwidth-limit”.
19 - 10. FastCGI-Anwendungen
HAProxy kann HTTP-Anfragen an FastCGI-Anwendungen mit der Rolle Responder senden. Diese Funktion wurde in HAProxy 2.1 eingeführt. Dazu müssen die Server für das FastCGI-Protokoll konfiguriert sein, mit dem Schlüsselwort “proto fcgi” in der Serverzeile. Außerdem muss eine FastCGI-Anwendung konfiguriert und von dem Backend verwendet werden, das diese Server verwaltet, mit dem Schlüsselwort “use-fcgi-app” im Proxy-Abschnitt. Es können mehrere FastCGI-Anwendungen definiert werden, aber ein Backend kann jeweils nur eine davon verwenden.
HAProxy implementiert alle Funktionen der FastCGI-Spezifikation für Responder-Anwendungen. Insbesondere können mehrere Anfragen über eine einzelne Verbindung gemultiplext werden.
10.1. Einrichtung
10.1.1. Abschnitt fcgi-app
fcgi-app <name>
Deklariert eine FastCGI-Anwendung namens <name>. Damit sie gültig ist, muss mindestens das
Dokumentwurzelverzeichnis definiert sein.
acl <aclname> <criterion> [flags] [operator] <value> ...
Deklariert oder ergänzt eine Zugriffsliste.
Einzelheiten zur Verwendung von ACL finden Sie beim Schlüsselwort “acl” in Abschnitt 4.2 und in Abschnitt 7 . Für eine FastCGI-Anwendung definierte ACLs sind privat. Sie können weder von anderen Anwendungen noch von Proxys verwendet werden. Ebenso kann eine FastCGI-Anwendung keine ACLs verwenden, die in einem anderen Abschnitt definiert wurden. Vordefinierte ACLs stehen jedoch zur Verfügung.
docroot <path>
Definiert das Dokumentwurzelverzeichnis auf dem entfernten Host. <path> wird verwendet, um den
Standardwert der FastCGI-Parameter SCRIPT_FILENAME und PATH_TRANSLATED zu bilden. Diese
Einstellung ist erforderlich.
index <script-name>
Definiert den Skriptnamen, der an eine mit einem Schrägstrich ("/") endende URI angehängt wird, um den Standardwert des FastCGI-Parameters SCRIPT_NAME zu setzen. Diese Einstellung ist optional.
Beispiel:
log-stderr global
Aktiviert die Protokollierung von STDERR-Meldungen der FastCGI-Anwendung.
Einzelheiten finden Sie beim Schlüsselwort “log” in Abschnitt 4.2 . Diese Einstellung ist optional. Standardmäßig werden STDERR-Meldungen ignoriert.
pass-header <name> [ { if | unless } <condition> ]
Gibt den Namen eines Anfrageheaders an, der an die FastCGI-Anwendung übergeben werden soll. Optional kann eine ACL-basierte Bedingung folgen; in diesem Fall wird die Direktive nur ausgewertet, wenn die Bedingung wahr ist.
Die meisten Anfrageheader stehen der FastCGI-Anwendung bereits mit dem Präfix “HTTP_” zur Verfügung. Diese Direktive ist daher nur nötig, um bewusst ausgelassene Header zu übergeben. Derzeit werden die Header “Authorization”, “Proxy-Authorization” sowie Hop-by-Hop-Header ausgelassen.
Die Header “Content-type” und “Content-length” werden niemals an die FastCGI-Anwendung übergeben, da sie bereits in Parameter umgewandelt werden.
path-info <regex>
Definiert einen regulären Ausdruck, um den Skriptnamen und die Pfadinformation aus dem
URL-dekodierten Pfad zu extrahieren. <regex> kann dazu zwei Erfassungsgruppen enthalten:
die erste für den Skriptnamen, die zweite für die Pfadinformation. Die erste ist erforderlich,
die zweite optional. So lässt sich der Skriptname aus dem Pfad extrahieren und die Pfadinformation
ignorieren. Diese Einstellung ist optional. Ist sie nicht definiert, wird kein Mustervergleich
auf dem Pfad ausgeführt, und die FastCGI-Parameter PATH_INFO und PATH_TRANSLATED werden nicht
gefüllt.
Wenn dieser reguläre Ausdruck definiert ist, sind Zeilenumbruch- und Nullzeichen im URL-dekodierten Pfad aus Sicherheitsgründen verboten. Andernfalls würde der Mustervergleich aufgrund einer Einschränkung bei der Ausführung regulärer Ausdrücke in HAProxy immer fehlschlagen. Wird eines dieser beiden Zeichen im URL-dekodierten Pfad gefunden, wird deshalb ein Fehler an den Client zurückgegeben. Hier gilt das Prinzip der geringsten Überraschung.
Beispiel:
option get-values
Aktiviert oder deaktiviert den Abruf von Variablen zur Verbindungsverwaltung.
HAProxy kann beim Verbindungsaufbau den Datensatz FCGI_GET_VALUES senden, um die Werte der folgenden Variablen abzurufen:
* FCGI_MAX_REQS Die maximale Anzahl gleichzeitiger Anfragen, die diese
Anwendung akzeptiert.
* FCGI_MPXS_CONNS "0", wenn diese Anwendung kein Verbindungsmultiplexing
unterstützt, andernfalls "1".
Einige FastCGI-Anwendungen unterstützen diese Funktion nicht. Andere schließen die Verbindung unmittelbar nach dem Senden ihrer Antwort. Daher ist diese Option standardmäßig deaktiviert.
Die maximale Anzahl gleichzeitiger Anfragen, die eine FastCGI-Anwendung akzeptiert, ist eine verbindungsbezogene Variable. Sie begrenzt nur die Anzahl der Datenströme pro Verbindung. Soll die Gesamtlast der Anwendung begrenzt werden, müssen die Serverparameter “maxconn” und “pool-max-conn” gesetzt werden. Unterstützt eine Anwendung kein Verbindungsmultiplexing, wird die maximale Anzahl gleichzeitiger Anfragen außerdem automatisch auf 1 gesetzt.
option keep-conn
Weist die FastCGI-Anwendung an, die Verbindung nach dem Senden einer Antwort offen zu halten oder zu schließen.
Ist diese Option deaktiviert, schließt die FastCGI-Anwendung die Verbindung nach der Antwort auf diese Anfrage. Standardmäßig ist die Option aktiviert.
option max-reqs <reqs>
Definiert die maximale Anzahl gleichzeitiger Anfragen, die diese Anwendung akzeptiert.
Diese Option kann überschrieben werden, wenn die Variable FCGI_MAX_REQS beim Verbindungsaufbau abgerufen wird. Unterstützt die Anwendung kein Verbindungsmultiplexing, wird die Option zudem ignoriert. Der Standardwert ist 1.
option mpxs-conns
Aktiviert oder deaktiviert die Unterstützung für Verbindungsmultiplexing.
Diese Option kann überschrieben werden, wenn die Variable FCGI_MPXS_CONNS beim Verbindungsaufbau abgerufen wird. Sie ist standardmäßig deaktiviert.
set-param <name> <fmt> [ { if | unless } <condition> ]
Setzt einen FastCGI-Parameter, der an diese Anwendung übergeben werden soll. Sein durch <fmt>
definierter Wert muss den Regeln für benutzerdefinierte Protokollformate entsprechen; siehe
Abschnitt 8.2.6
„Benutzerdefiniertes Protokollformat“. Optional kann eine
ACL-basierte Bedingung folgen; in diesem Fall wird die Direktive nur ausgewertet, wenn die
Bedingung wahr ist.
Mit dieser Direktive lassen sich die Werte der standardmäßigen FastCGI-Parameter überschreiben. Ergibt die Auswertung des Werts eine leere Zeichenfolge, wird die Regel ignoriert. Diese Direktiven werden in der Reihenfolge ihrer Deklaration ausgewertet.
Beispiel:
10.1.2. Proxy-Abschnitt
use-fcgi-app <name> Definiert die vom Backend zu verwendende FastCGI-Anwendung.
Argumente:
Dieses Schlüsselwort steht nur für HTTP-Proxys mit Backend-Funktion und mindestens einem FastCGI-Server zur Verfügung. FastCGI-Server können zwar mit HTTP-Servern kombiniert werden, dies wird jedoch ohne triftigen Grund nicht empfohlen; Einzelheiten zu den Einschränkungen finden Sie in Abschnitt 10.3 . Pro Backend kann jeweils nur eine Anwendung definiert werden.
Sobald für ein Backend eine FastCGI-Anwendung referenziert wird, kann je nach Konfiguration bestimmte Verarbeitung stattfinden, auch wenn die Anfrage nicht an einen FastCGI-Server gesendet wird. Regeln zum Setzen von Parametern oder zum Übergeben von Headern an eine Anwendung werden ausgewertet.
10.1.3. Beispiel
10.2. Standardparameter
Eine FastCGI-Anwendung mit der Rolle Responder erfüllt denselben Zweck wie ein CGI/1.1-Programm. Laut CGI/1.1-Spezifikation (RFC3875) müssen mehrere Variablen an das Skript übergeben werden. HAProxy setzt daher diese sowie einige weitere Variablen, die FastCGI-Anwendungen üblicherweise verwenden. Alle diese Variablen können überschrieben werden, allerdings mit Vorsicht.
10.3. Einschränkungen
Die aktuelle Implementierung hat einige Einschränkungen. Die erste betrifft die Art, wie bestimmte Anfrageheader vor FastCGI-Anwendungen verborgen werden. Dies geschieht bei der Headeranalyse auf der Backend-Seite vor dem Verbindungsaufbau. Zu diesem Zeitpunkt weiß HAProxy, dass das Backend eine FastCGI-Anwendung verwendet, aber noch nicht, ob die Anfrage an einen FastCGI-Server weitergeleitet wird. Um die Anfrageheader zu verbergen, entfernt HAProxy sie einfach aus der HTX-Nachricht. Wird die Anfrage schließlich an einen HTTP-Server weitergeleitet, bekommt dieser diese Header daher niemals zu sehen. Aus diesem Grund wird nicht empfohlen, FastCGI-Server und HTTP-Server im selben Backend zu kombinieren.
Ebenso werden die Regeln “set-param” und “pass-header” während der Analyse der Anfrageheader ausgewertet. Die Auswertung findet daher immer statt, auch wenn die Anfrage schließlich an einen HTTP-Server weitergeleitet wird.
Wird eine Regel “set-param” angewendet, wird der HTX-Nachricht ein Pseudoheader hinzugefügt. Wie das Umschreiben von HTTP-Headern kann dies bei vollem Puffer fehlschlagen. Die Regeln “set-param” konkurrieren dabei mit den Regeln “http-request”.
Schließlich werden alle FastCGI-Parameter und HTTP-Header in einem einzigen Datensatz FCGI_PARAM gesendet. Dieser Datensatz muss in einem Durchgang kodiert werden; andernfalls wird ein Verarbeitungsfehler zurückgegeben. Der kodierte Datensatz FCGI_PARAM darf daher nicht größer als ein Puffer sein. Eine Reserve muss hierbei jedoch nicht eingehalten werden.
20 - 11. Stick Tables und Peers
Stick Tables verknüpfen in HAProxy Informationen und Metriken mit einem Schlüssel eines bestimmten Typs. Diese Zuordnung bleibt nach der letzten Aktualisierung für eine bestimmte Dauer bestehen. Man kann sich darunter eine Tabellenzeile mit mehreren Spalten vorstellen: Der Schlüsselwert bestimmt die Zeilennummer, und jede Spalte steht für ein eigenes Kriterium.
Ursprünglich dienten Stick Tables dazu, die Zuordnung von Clients zu Servern zu speichern und damit persistente Sitzungen zwischen ihnen zu erhalten. Ein Client stellte eine Verbindung her oder sendete eine Anfrage und wurde anhand eines Merkmals wie Quelladresse, Cookie oder URL-Parameter identifiziert. Der ausgewählte Server wurde zusammen mit diesem Merkmal für eine konfigurierbare Dauer in einer Stick Table gespeichert. Spätere Zugriffe desselben Clients konnten so automatisch zu dem Server gelangen, auf dem seine Anwendungssitzung bestand.
Heute können Stick Tables mehr als nur eine Servernummer speichern. Dazu gehören Aktivitätsmetriken eines bestimmten Clients, etwa Anzahl und Rate von Anfragen, Verbindungen oder Bytes, sowie beliebige Ereigniszähler (“gpc”, allgemeine Zähler) und Markierungen zur Kennzeichnung bestimmter Client-Eigenschaften (“gpt”, allgemeine Markierung).
Auf Stick Tables können die “stick”-Direktiven zur Zuordnung von Clients zu Servern zugreifen. Die “track-sc”-Regeln legen fest, welcher Schlüssel in welcher Tabelle zur Erfassung von Metriken verfolgt wird. Außerdem können zahlreiche Sample-Abruffunktionen und Konverter einen Schlüssel unmittelbar nachschlagen, um bestimmte Metriken oder Daten abzurufen. Grundsätzlich frischen Tabellenaktualisierungen (gpt/gpc/metrics) und Abfragen der Serverzuordnung den betroffenen Eintrag auf und verschieben seinen Ablaufzeitpunkt. Reine Abfragen durch Sample-Abruffunktionen und Konverter lesen dagegen nur die Daten aus, ohne den Ablaufzeitpunkt zu verschieben.
Damit der Mechanismus skaliert und das Neuladen von HAProxy sowie Failover übersteht, können Aktualisierungen von Stick Tables über den in Abschnitt 11.2 beschriebenen “Peers”-Mechanismus mit anderen Knoten, den “peers”, ausgetauscht werden. Zur Feinabstimmung dieser Kommunikation lässt sich auch festlegen, dass bestimmte Tabellen nur Informationen von Peers empfangen oder dass Aktualisierungen von Peers an eine andere Tabelle weitergeleitet werden.
Stick Tables lassen sich in Proxy-Abschnitten (Frontends und Backends) mit “stick-table” deklarieren. Pro Abschnitt ist nur eine Tabelle möglich; sie erhält den Namen des Abschnitts. In Peers-Abschnitten dient dazu “table”, gefolgt vom Tabellennamen. Damit können mehrere Stick Tables im selben “peers”-Abschnitt deklariert werden. Werden mehrere Tabellen benötigt, empfiehlt sich in der Regel die Deklaration in einem Peers-Abschnitt, wenn sie gemeinsam genutzt werden sollen. Andernfalls können zusätzliche Backend-Abschnitte angelegt werden, die jeweils nur die “stick-table”-Definition enthalten.
11.1. stick-table deklarieren
Die Deklaration einer Stick Table in einem Proxy-Abschnitt (“frontend”, “backend”, “listen”) ähnelt der in einem “peers”-Abschnitt. Der Unterschied: Im Peers-Abschnitt ist ein Name erforderlich, und die Option “peers” entfällt.
In einem “frontend”-, “backend”- oder “listen”-Abschnitt:
stick-table type <type> size <size> [expire <expire>] [nopurge] [recv-only] [write-to
<wtable>] [srvkey <srvkey>] [store <data_type>]* [brates-factor <factor>] [peers
<peersect>]
In einem “peers”-Abschnitt:
table <name> type <type> size <size> [expire <expire>] [nopurge] [recv-only]
[write-to <wtable>] [srvkey <srvkey>] [store <data_type>]* [brates-factor <factor>]
Argumente, zunächst die Pflichtargumente, danach alphabetisch sortiert:
-
type
<type>Dieses Pflichtargument legt den Schlüsseltyp auf<type>fest. Er besteht meist aus einem einzelnen Wort, kann aber auch eigene Argumente haben:-
ip Dieser Typ sollte zugunsten eines eindeutigen Typs wie “ipv4” oder “ipv6” vermieden werden. Vor Version 3.2 war er die einzige Möglichkeit, IPv4 zu konfigurieren. In 3.2 ist “ip” ein Alias für “ipv4”; “ipv4” wird bevorzugt. In einer künftigen Version wird “ip” stattdessen “ipv6” entsprechen. Der Typ soll lediglich den Übergang von Versionen vor 3.2 zu Versionen nach 3.2 erleichtern.
-
ipv4 Eine so deklarierte Tabelle speichert ausschließlich IPv4-Adressen. Diese Form benötigt wenig Speicher, etwa 50 Bytes pro Eintrag, und ermöglicht sehr schnelle Such- und Speichervorgänge mit fast keinem Zusatzaufwand. Sie wird hauptsächlich zum Speichern der Quell-IP-Adressen von Clients verwendet.
-
ipv6 Eine mit “type ipv6” deklarierte Tabelle speichert ausschließlich IPv6-Adressen. Diese Form benötigt wenig Speicher, etwa 60 Bytes pro Eintrag, und ermöglicht sehr schnelle Such- und Speichervorgänge mit fast keinem Zusatzaufwand. Sie wird hauptsächlich zum Speichern der Quell-IP-Adressen von Clients verwendet.
-
integer Eine mit “type integer” deklarierte Tabelle speichert 32bit-Ganzzahlen, die beispielsweise eine Client-Kennung aus einer Anfrage darstellen können.
-
string [len
<len>] Eine mit “type string” deklarierte Tabelle speichert Teilzeichenketten mit bis zu<len>Zeichen. Liefert die Musterextraktion eine längere Zeichenkette als<len>, wird sie vor dem Speichern gekürzt. Beim Abgleich werden höchstens<len>Zeichen der gespeicherten Zeichenkette mit dem extrahierten Muster verglichen. Ohne Angabe gilt eine Grenze von 32 Zeichen. Eine größere Länge kann den Speicherbedarf erheblich erhöhen. -
binary [len
<len>] Eine mit “type binary” deklarierte Tabelle speichert Binärblöcke mit<len>Bytes. Liefert die Musterextraktion einen längeren Block als<len>, wird er vor dem Speichern gekürzt. Liefert der Sample-Ausdruck einen kürzeren Block als<len>, wird er mit 0 aufgefüllt. Ohne Angabe gilt eine Grenze von 32 Bytes. Eine größere Länge kann den Speicherbedarf erheblich erhöhen.
-
-
size
<size>Dieses Pflichtargument legt die maximale Anzahl der Tabelleneinträge auf<size>fest und beeinflusst den Speicherbedarf unmittelbar. Pro Eintrag sind etwa 50 Bytes zusätzlich zur oben angegebenen Schlüsselgröße, den optional gespeicherten Metriken und gegebenenfalls der Zeichenkette einzuplanen. Die Suffixe “k”, “m”, “g” stehen für die Faktoren 2^10, 2^20 und 2^30. -
expire
<delay>Legt die maximale Lebensdauer eines Eintrags seit seiner letzten Erstellung, Auffrischung durch ’track-sc’ oder einem Treffer durch ‘stick match’ oder ‘stick on’ fest. Die Ablaufdauer<delay>verwendet wie die verschiedenen Zeitüberschreitungen das Standardzeitformat, standardmäßig Millisekunden. Die Höchstdauer liegt knapp über 24 Tagen. Einzelheiten stehen in Abschnitt 2.5 . Ohne Angabe laufen Sitzungen nicht automatisch ab. Ist die Tabelle voll, werden beim Anlegen neuer Einträge jedoch die ältesten entfernt. Ohne Ablaufdauer darf “nopurge” daher nicht verwendet werden. Hinweis: ’table_*’-Konverter schlagen Einträge nach, verschieben aber deren Ablaufzeitpunkt nicht, da sie kein ’track-sc’ benötigen. -
brates-factor
<factor>Legt einen Faktor für die Rate eingehender und ausgehender Bytes fest. Statt einzelner Bytes werden Byte-Blöcke gezählt. Intern verwenden Raten 32-Bit-Zähler und sind daher auf etwa 4 Milliarden pro Zeitraum begrenzt. Mit diesem Parameter können Raten die Grenze von 4G innerhalb des festgelegten Zeitraums überschreiten. Der Faktor muss größer als 0 und kleiner oder gleich 1024 sein. -
nopurge verhindert, dass bei voller Tabelle ältere Einträge gelöscht werden. Ohne diese Option entfernt HAProxy beim Speichern in einer vollen Tabelle einige der ältesten Einträge, um Platz für neue zu schaffen. Das ist meist das gewünschte Verhalten. In bestimmten Fällen ist es jedoch sinnvoll, neue Einträge abzulehnen und die alten zu behalten. Das kann etwa zutreffen, wenn die Datenmenge die Hardware-Kapazität weit übersteigt und neuen Clients lieber der Zugriff verweigert werden soll als bereits verbundenen. Bei Verwendung dieses Parameters muss “expire” richtig eingestellt werden; siehe oben.
-
recv-only gibt an, dass die Tabelle ausschließlich zum Abrufen der gewünschten Daten von einem entfernten Peer und nicht für eigene Aktualisierungen verwendet werden soll. Das Schlüsselwort ermöglicht den Abruf rein lokaler Werte wie “conn_cur”. Diese werden standardmäßig nicht übernommen, da sie mit den Änderungen des lokalen Peers an der Tabelle kollidieren würden. Die Option ist nur für Tabellen sinnvoll, die weder in Tracking-Regeln noch in Verfahren zur Tabellenaktualisierung verwendet werden; einfacher gesagt: für entfernte Tabellen, aus denen nur Informationen abgerufen werden.
-
peers
<peersect>Neu angelegte, aktualisierte oder aufgefrischte Einträge werden zur Synchronisierung an die Peers im Abschnitt<peersect>gesendet. Von diesen Peers übernommene Schlüssel werden ebenfalls in der Tabelle eingefügt oder aktualisiert. Beim Start kann außerdem versucht werden, Einträge von einer älteren Prozessinstanz zu übernehmen, die über diesen Abschnitt als lokaler Peer bezeichnet wird. -
srvkey
<srvkey>Legt fest, wie die einzelnen Server für die Stick Table identifiziert werden. Gültig sind “name” und “addr”. Bei “name” wird das Serverargument<name>verwendet, das auch aus einer Vorlage stammen kann. Bei “addr” dient die aktuelle Netzwerkadresse einschließlich Port als Kennung. “addr” ist besonders nützlich, wenn die Serveradressen für über Peers abgeglichene Stick Tables durch Diensterkennung erzeugt werden und ein Zuordnungstoken bei allen Peers zuverlässig denselben Host bezeichnen soll. -
store
<data_type>Speichert zusätzliche Informationen in der Stick Table. ACLs können damit verschiedene Kriterien zur Aktivität des Clients prüfen, der dem Eintrag in der Stick Table entspricht. Jeder hier angegebene Datentyp vergrößert die Einträge um den Platz für die zusätzlichen Daten. Ein Eintrag kann mehrere Datentypen speichern. Dazu können nach “store” mehrere Typen als kommagetrennte Liste stehen. Alternativ lässt sich “store” mit jeweils einem oder mehreren Datentypen wiederholen. Alle zu speichernden Datentypen müssen ausdrücklich deklariert werden; nur “server_id” wird automatisch erkannt und aktiviert. Verweist eine ACL auf einen nicht gespeicherten Datentyp, trifft sie nicht zu. Einige Typen benötigen ein Argument, das unmittelbar nach dem Typ in runden Klammern stehen muss. Die unterstützten Typen und ihre Argumente sind unten aufgeführt. -
write-to
<wtable>Gibt eine weitere Stick Table an, in die Aktualisierungen von Peers zusätzlich zur Quelltabelle geschrieben werden.<wtable>muss denselben Typ und dieselbe Schlüssellänge wie die deklarierte Tabelle haben. Die Quelltabelle kann nicht selbst als Ziel dienen. Bei jeder über einen Peer empfangenen Aktualisierung versucht HAProxy, den zugehörigen Eintrag in<wtable>aufzufrischen. Fehlt er, wird er angelegt; andernfalls werden seine Werte und sein Timer aktualisiert. In<wtable>werden nur Typen wie server_id, server_key und gpt geschrieben, die nicht an arithmetischen Operationen beteiligt sind. So beeinflussen bereits verarbeitete Werte einer entfernten Tabelle nicht die Rechenoperationen in der lokalen Zieltabelle; etwa ein gemeinsam genutzter kumulativer Zähler würde sonst endlos anwachsen. Ein häufiger Einsatz ist die Verwendung von Zuordnungsregeln für Server-Persistenz in einem Peers-Cluster, da passende Schlüssel aus entfernten Tabellen übernommen werden.
Die folgenden Datentypen können über “store” mit einem Eintrag verknüpft werden. Werden viele Typen gespeichert, kann der Speicherbedarf erheblich steigen. Alle unten genannten Werte zusammen können Hunderte von Bytes je Eintrag benötigen, bei 1 Million Einträgen also Hunderte von MB. Deshalb steht der ungefähre Speicherbedarf jedes Typs in eckigen Klammern hinter dem Argument.
Argumente:
-
bytes_in_cnt [8 bytes] Zählt die Bytes vom Client zum Server. Diese positive 64-Bit-Ganzzahl enthält die Gesamtzahl der Bytes, die von Clients empfangen wurden, die diesem Eintrag entsprechen. Header zählen mit. Damit lässt sich der Missbrauch von Upload-Funktionen auf Foto- oder Videoservern begrenzen. Gemessen wird beim Eingang der Daten in HAProxy; die Komprimierung beeinflusst den Zähler daher nicht.
-
bytes_in_rate(
<period>) [12 bytes] Misst die Byte-Rate vom Client zum Server. Der ganzzahlige Parameter<period>gibt in Millisekunden an, über welchen Zeitraum der Mittelwert berechnet wird. Gemeldet wird die durchschnittliche Eingangsrate in Bytes pro Zeitraum. Damit lassen sich Benutzer erkennen, die zu viel und zu schnell hochladen. Warnung: Bei großen Uploads kann die gesamte Datenmenge erst bei deren Abschluss gezählt werden. Dadurch entstehen Spitzen in der mittleren Übertragungsgeschwindigkeit statt eines gleichmäßigen Verlaufs. “option contstats” kann dies teilweise glätten, allerdings nicht vollständig. Für eine gerechtere Bewertung wird byte_in_cnt empfohlen. -
bytes_out_cnt [8 bytes] Zählt die Bytes vom Server zum Client. Diese positive 64-Bit-Ganzzahl enthält die Gesamtzahl der Bytes, die an Clients gesendet wurden, die diesem Eintrag entsprechen. Header zählen mit. Damit lässt sich Missbrauch durch Bots begrenzen, die die gesamte Website herunterladen. Gemessen wird beim Eingang der Daten in HAProxy; die Komprimierung beeinflusst den Zähler daher nicht.
-
bytes_out_rate(
<period>) [12 bytes] Misst die Byte-Rate vom Server zum Client. Der ganzzahlige Parameter<period>gibt in Millisekunden an, über welchen Zeitraum der Mittelwert berechnet wird. Gemeldet wird die durchschnittliche Ausgangsrate in Bytes pro Zeitraum. Damit lassen sich Benutzer erkennen, die zu viel und zu schnell herunterladen. Warnung: Bei großen Übertragungen kann die gesamte Datenmenge erst bei deren Abschluss gezählt werden. Dadurch entstehen Spitzen in der mittleren Übertragungsgeschwindigkeit statt eines gleichmäßigen Verlaufs. “option contstats” kann dies teilweise glätten, allerdings noch nicht vollständig. Für eine gerechtere Bewertung wird byte_out_cnt empfohlen. -
conn_cnt [4 bytes] Zählt die Verbindungen. Diese positive 32-Bit-Ganzzahl enthält die absolute Anzahl der Verbindungen, die von Clients eingegangen sind, die diesem Eintrag entsprechen. Sie müssen nicht angenommen worden sein; gezählt wird bereits ihr Eingang.
-
conn_cur [4 bytes] Zählt die aktuellen Verbindungen. Diese positive 32-Bit-Ganzzahl enthält die Anzahl gleichzeitig bestehender Verbindungen für den Eintrag. Sobald eine eingehende Verbindung dem Eintrag entspricht, wird der Zähler erhöht; beim Ende der Verbindung wird er verringert. So lässt sich jederzeit die genaue Anzahl gleichzeitiger Verbindungen für einen Eintrag ermitteln. Der Wert wird standardmäßig nicht von anderen Peers übernommen: Er wäre nicht aussagekräftig, da er den lokalen Zähler ignorieren würde. Zusammen mit recv-only lässt sich damit jedoch die Anzahl gleichzeitiger Verbindungen anderer Peers übernehmen.
-
conn_rate(
<period>) [12 bytes] Misst die Verbindungshäufigkeit. Der ganzzahlige Parameter<period>gibt in Millisekunden an, über welchen Zeitraum der Mittelwert berechnet wird. Gemeldet wird die durchschnittliche Rate eingehender Verbindungen in Verbindungen pro Zeitraum. Das Ergebnis ist eine Ganzzahl, die sich mit ACLs prüfen lässt. Ob Verbindungen angenommen oder abgelehnt werden, beeinflusst die Messung nicht. -
glitch_cnt [4 bytes] Zählt Protokollauffälligkeiten auf Frontend-Verbindungen. Diese positive 32-Bit-Ganzzahl enthält die Gesamtzahl der auf einer Frontend-Verbindung gemeldeten Auffälligkeiten. Dabei handelt es sich um ungewöhnliche oder aus Protokollsicht unerwartete Client-Aktionen. Sie können auf einen stark fehlerhaften Client oder einen Angreifer hinweisen. Der Zähler kann helfen, in solchen Fällen über den Umgang mit dem Client zu entscheiden.
-
glitch_rate(
<period>) [12 bytes] Misst die Häufigkeit von Protokollauffälligkeiten. Der ganzzahlige Parameter<period>gibt in Millisekunden an, über welchen Zeitraum der Mittelwert berechnet wird. Gemeldet wird die durchschnittliche Rate von Auffälligkeiten auf Frontend-Verbindungen in diesem Zeitraum. Damit lassen sich fehlerhafte Clients oder mögliche Angreifer erkennen, die aus Protokollsicht ungewöhnliche oder unerwartete Aktionen ausführen, sofern HAProxy diese entsprechend gekennzeichnet hat. -
gpc(
<nb>) [4 *<nb>bytes] Ist ein Array aus<nb>allgemeinen Zählern. Die positiven 32-Bit-Ganzzahlen können beliebige Werte zählen. Meist werden sie als fortlaufende Zähler für bestimmte Einträge verwendet, etwa um das Erreichen einer Grenze festzuhalten und Aktionen auszulösen. Das Array ist auf 100 Elemente begrenzt, gpc0 bis gpc99, damit eine erzeugte Peer-Aktualisierungsnachricht in den Puffer passt. Es sollte berücksichtigt werden, dass viele Zähler die Datenmenge und die Last des Peers-Protokolls erhöhen: Jede Änderung eines Werts überträgt sämtliche Daten und Zähler. Dieser data_type schließt die älteren data_types ‘gpc0’ und ‘gpc1’ in derselben Tabelle aus. Beim Array-data_type ‘gpc’ wirken alle auf ‘gpc0’ und ‘gpc1’ bezogenen Sample-Abruffunktionen und Aktionen auf die ersten beiden Array-Elemente. -
gpc_rate(
<nb>,<period>) [12 *<nb>bytes] Ist ein Array mit den Erhöhungsraten allgemeiner Zähler über einen Zeitraum. Die Elemente sind positive 32-Bit-Ganzzahlen zur freien Verwendung. Wie<gpc>zählen sie Ereignisse; statt einer Summe speichern sie jedoch die Rate, mit der der Zähler erhöht wird. Meist dient dies zur Messung der Häufigkeit bestimmter Ereignisse, etwa Anfragen an eine bestimmte URL. Das Array ist auf 100 Elemente begrenzt: gpc_rate(100,<period>) ermöglicht das Speichern von gpc0_rate bis gpc99_rate. So passt eine erzeugte Peer-Aktualisierungsnachricht in den Puffer. Das Array kann nicht weniger als 1 Element enthalten; zum Speichern nur der Rate gpc0_rate dient gpc_rate(1,<period>). Es sollte berücksichtigt werden, dass viele Zähler die Datenmenge und die Last des Peers-Protokolls erhöhen: Jede Änderung eines Werts überträgt sämtliche Daten und Zähler. Dieser data_type schließt die älteren data_types ‘gpc0_rate’ und ‘gpc1_rate’ in derselben Tabelle aus. Beim Array-data_type ‘gpc_rate’ wirken alle auf ‘gpc0’ und ‘gpc1’ bezogenen Abruffunktionen und Aktionen auf die ersten beiden Array-Elemente. -
gpc0 [4 bytes] Ist der erste allgemeine Zähler, eine positive 32-Bit-Ganzzahl zur freien Verwendung. Meist dient er dazu, bestimmte Einträge zu markieren, etwa wenn ein Verhalten erkannt wurde, das bei späteren Abgleichen bekannt sein muss.
-
gpc0_rate(
<period>) [12 bytes] Ist die Erhöhungsrate des ersten allgemeinen Zählers über einen Zeitraum, eine positive 32-Bit-Ganzzahl zur freien Verwendung. Wie<gpc0>zählt sie Ereignisse, speichert jedoch statt einer Summe die Rate der Zählererhöhung. Meist dient dies zur Messung der Häufigkeit bestimmter Ereignisse, etwa Anfragen an eine bestimmte URL. -
gpc1 [4 bytes] Ist der zweite allgemeine Zähler, eine positive 32-Bit-Ganzzahl zur freien Verwendung. Meist dient er dazu, bestimmte Einträge zu markieren, etwa wenn ein Verhalten erkannt wurde, das bei späteren Abgleichen bekannt sein muss.
-
gpc1_rate(
<period>) [12 bytes] Ist die Erhöhungsrate des zweiten allgemeinen Zählers über einen Zeitraum, eine positive 32-Bit-Ganzzahl zur freien Verwendung. Wie<gpc1>zählt sie Ereignisse, speichert jedoch statt einer Summe die Rate der Zählererhöhung. Meist dient dies zur Messung der Häufigkeit bestimmter Ereignisse, etwa Anfragen an eine bestimmte URL. -
gpt(
<nb>) [4 *<nb>bytes] Ist ein Array aus<nb>allgemeinen Markierungen, jeweils positiven 32-Bit-Ganzzahlen zur freien Verwendung. Meist werden damit bestimmte Einträge markiert, etwa wenn ein Verhalten erkannt wurde, das bei späteren Abgleichen bekannt sein muss. Das Array ist auf 100 Elemente begrenzt: gpt(100) ermöglicht das Speichern von gpt0 bis gpt99. So passt eine erzeugte Peer-Aktualisierungsnachricht in den Puffer. Das Array kann nicht weniger als 1 Element enthalten; zum Speichern nur der Markierung gpt0 dient gpt(1). Es sollte berücksichtigt werden, dass viele Zähler die Datenmenge und die Last des Peers-Protokolls erhöhen: Jede Änderung eines Werts überträgt sämtliche Daten und Zähler. Dieser data_type schließt den älteren data_type ‘gpt0’ in derselben Tabelle aus. Beim Array-data_type ‘gpt’ wirken alle auf ‘gpt0’ bezogenen Abruffunktionen und Aktionen auf das erste Array-Element. -
gpt0 [4 bytes] Ist die erste allgemeine Markierung, eine positive 32-Bit-Ganzzahl zur freien Verwendung. Meist dient sie dazu, bestimmte Einträge zu markieren, etwa wenn ein Verhalten erkannt wurde, das bei späteren Abgleichen bekannt sein muss.
-
http_req_cnt [4 bytes] Zählt HTTP-Anfragen. Diese positive 32-Bit-Ganzzahl enthält die absolute Anzahl der HTTP-Anfragen von Clients, die diesem Eintrag entsprechen. Dabei spielt es keine Rolle, ob die Anfragen gültig sind. Bei clientseitigem Keep-Alive unterscheidet sich dieser Wert von der Anzahl der Sitzungen.
-
http_req_rate(
<period>) [12 bytes] Misst die Anfragehäufigkeit. Der ganzzahlige Parameter<period>gibt in Millisekunden an, über welchen Zeitraum der Mittelwert berechnet wird. Gemeldet wird die durchschnittliche HTTP-Anfragerate in Anfragen pro Zeitraum. Das Ergebnis ist eine Ganzzahl, die sich mit ACLs prüfen lässt. Dabei spielt es keine Rolle, ob die Anfragen gültig sind. Bei clientseitigem Keep-Alive unterscheidet sich dieser Wert von Sitzungen. -
http_err_cnt [4 bytes] Zählt Fehler bei HTTP-Anfragen. Diese positive 32-Bit-Ganzzahl enthält die absolute Anzahl der HTTP-Anfragefehler, die von Clients verursacht wurden, die diesem Eintrag entsprechen. Als Fehler zählen ungültige oder abgeschnittene Anfragen, abgelehnte oder durch Tarpitting verzögerte Anfragen und fehlgeschlagene Authentifizierungen. Antwortet der Server mit 4xx, gilt die Anfrage ebenfalls als Fehler, da der Client ihn ausgelöst hat, etwa bei der Suche nach Schwachstellen.
-
http_err_rate(
<period>) [12 bytes] Misst die Häufigkeit von HTTP-Anfragen. Der ganzzahlige Parameter<period>gibt in Millisekunden an, über welchen Zeitraum der Mittelwert berechnet wird. Gemeldet wird die durchschnittliche Fehlerrate bei HTTP-Anfragen in Anfragen pro Zeitraum. Was als Fehler gilt, beschreibt http_err_cnt oben. Das Ergebnis ist eine Ganzzahl, die sich mit ACLs prüfen lässt. -
http_fail_cnt [4 bytes] Zählt fehlerhafte HTTP-Antworten. Diese positive 32-Bit-Ganzzahl enthält die absolute Anzahl der von Servern verursachten HTTP-Antwortfehler, die diesem Eintrag entsprechen. Als Fehler zählen ungültige oder abgeschnittene Antworten sowie alle 5xx-Antworten außer 501 und 505. Der Zähler ist zur Erkennung von Dienstausfällen zusammen mit Pfad oder URI gedacht.
-
http_fail_rate(
<period>) [12 bytes] Misst die Häufigkeit fehlerhafter HTTP-Antworten. Der ganzzahlige Parameter<period>gibt in Millisekunden an, über welchen Zeitraum der Mittelwert berechnet wird. Gemeldet wird die durchschnittliche Fehlerrate bei HTTP-Antworten in Anfragen pro Zeitraum. Was als Fehler gilt, beschreibt http_fail_cnt oben. Das Ergebnis ist eine Ganzzahl, die sich mit ACLs prüfen lässt. -
server_id [4 bytes] Speichert als Ganzzahl die numerische ID des Servers, dem eine Anfrage zugewiesen wurde. Die Regeln “stick match”, “stick store” und “stick on” verwenden diesen Wert; beim Verweis darauf wird er automatisch aktiviert. Die Serverzuordnung anhand gelernter Informationen unterliegt Einschränkungen: Insbesondere gehen alle gelernten Zuordnungen bei einem Neustart verloren, sofern Peers nicht richtig zur Übertragung dieser Informationen beim Neustart konfiguriert sind, was empfohlen wird. Als Ergänzung anderer Zuordnungsverfahren kann dieses Verfahren sinnvoll sein, als alleiniger Mechanismus jedoch nicht immer.
-
sess_cnt [4 bytes] Zählt Sitzungen. Diese positive 32-Bit-Ganzzahl enthält die absolute Anzahl eingehender Sitzungen von Clients, die diesem Eintrag entsprechen. Eine Sitzung ist eine Verbindung, die von den Regeln auf Schicht 4 (“tcp-request connection”) angenommen wurde.
-
sess_rate(
<period>) [12 bytes] Misst die Sitzungshäufigkeit. Der ganzzahlige Parameter<period>gibt in Millisekunden an, über welchen Zeitraum der Mittelwert berechnet wird. Gemeldet wird die durchschnittliche Rate eingehender Sitzungen in Sitzungen pro Zeitraum. Das Ergebnis ist eine Ganzzahl, die sich mit ACLs prüfen lässt.
Beispiel:
Siehe auch “stick match”, “stick on”, “stick store-request”, “track-sc”, Abschnitt 2.5 zum Zeitformat, Abschnitt 11.2 zu Peers, Abschnitt 9.7 zur Bandbreitenbegrenzung und Abschnitt 7 zu ACLs.
11.2. Peers deklarieren
Stick-Table-Einträge beliebiger Datentypen können über TCP-Verbindungen zwischen mehreren HAProxy-Instanzen nach dem Multi-Master-Prinzip verteilt werden. Jede Instanz sendet ihre lokalen Änderungen und neuen Einträge an entfernte Peers. Die übertragenen Werte überschreiben die entfernten Werte ohne Zusammenfassung.
Eine Ausnahme ist “conn_cur”: Dieser Datentyp wird standardmäßig nie von Peers übernommen, da er lokale Werte abbilden soll. Frühere Versionen synchronisierten ihn standardmäßig. In Aktiv-Aktiv-Konfigurationen konnte das zu negativen Werten führen. Beim Neuladen oder beim Wechsel zwischen aktiver und passiver Rolle wuchsen die Werte immer weiter, weil der lokale Wert mehr Verbindungen auswies, als vor Ort bestanden. In manchen Konfigurationen kann die Übernahme von Peers dennoch sinnvoll sein, etwa bei einer passiven entfernten Tabelle, aus der ausschließlich Daten übernommen oder überwacht werden, ohne sie für Schreibvorgänge oder Aktualisierungen zu verwenden. Dazu lässt sich “recv-only” zur Tabellendeklaration hinzufügen. Die Informationen zu “conn_cur” werden in jedem Fall immer gesendet, damit Überwachungssysteme sie beobachten können.
Unterbrochener Datenaustausch wird automatisch erkannt und am letzten bekannten Stand fortgesetzt. Bei einem unterbrechungsfreien Neustart verbindet sich der alte Prozess außerdem über eine solche TCP-Verbindung mit dem neuen und überträgt alle Einträge, bevor der neue Prozess versucht, andere Peers zu erreichen. Dies ermöglicht eine sehr schnelle Replikation beim Neuladen: Selbst große Tabellen benötigen normalerweise nur einen Sekundenbruchteil.
Server werden auf entfernten Instanzen über ihre IDs identifiziert. Deshalb ist es wichtig, dass die Konfigurationen ähnlich aufgebaut sind oder zumindest für jeden Server bei allen Teilnehmern dieselbe ID fest vorgegeben wird.
peers <peersect>
Erstellt eine neue Peer-Liste namens <peersect>. Sie bildet einen eigenständigen Abschnitt, auf den eine oder mehrere Stick Tables verweisen.
bind [<address>]:port [param*]
Legt die Bindungsparameter des lokalen Peers dieses “peers”-Abschnitts fest. Solche Zeilen werden nicht zusammen mit einer “peer”-Zeile im selben “peers”-Abschnitt unterstützt.
disabled
Deaktiviert einen Peers-Abschnitt. Sowohl das Lauschen auf Verbindungen als auch jede Synchronisierung dieses Abschnitts werden abgeschaltet. Damit lässt sich die Synchronisierung von Stick Tables deaktivieren, ohne sämtliche “peers”-Verweise auszukommentieren.
default-bind [param*]
Legt die Bindungsparameter des lokalen Peers mit Ausnahme seiner Adresse fest.
default-server [param*]
Ändert die Standardoptionen für einen Server in einem “peers”-Abschnitt.
Argumente:
Siehe auch “server” und Abschnitt 5 zu Serveroptionen.
enabled
Aktiviert einen zuvor mit “disabled” deaktivierten Peers-Abschnitt erneut.
log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>]
“peers”-Abschnitte unterstützen dasselbe “log”-Schlüsselwort wie Proxys, um Informationen zum “peers”-Listener zu protokollieren. Einzelheiten stehen bei der Proxy-Option “log”.
peer <peername> [<address>]:port [param*]
Definiert einen Peer innerhalb eines Peers-Abschnitts. Entspricht <peername> dem lokalen Peer-Namen, lauscht HAProxy an der angegebenen Adresse auf Verbindungen entfernter Peers. Der lokale Name ist standardmäßig der Hostname; er lässt sich mit der Befehlszeilenoption “-L” oder der globalen Einstellung “localpeer” festlegen. Andernfalls gibt die Adresse das Ziel für die Verbindung zum entfernten Peer an. <peername> dient dann auf Protokollebene dazu, den entfernten Peer auf der Serverseite zu identifizieren und zu überprüfen.
Bei einem unterbrechungsfreien Neustart verwendet die alte Instanz die lokale Peer-Adresse, um sich mit der neuen zu verbinden und eine vollständige Replikation einzuleiten, den sogenannten Lernvorgang.
Es wird dringend empfohlen, auf allen Peers genau dieselbe Peers-Deklaration zu verwenden und den lokalen Peer-Namen ausschließlich über das Befehlszeilenargument “-L” oder die globale Einstellung “localpeer” festzulegen. So lassen sich konsistente Konfigurationsdateien für alle Peers leichter pflegen.
Im Adressparameter können Umgebungsvariablen verwendet werden; siehe Abschnitt 2.3 .
Hinweis: “peer” lässt sich ohne weitere Änderungen durch “server” ersetzen; siehe die Erklärung zu “server” unten.
server <peername> [<address>:<port>] [param*]
Wie bereits erwähnt, kann “server” anstelle von “peer” verwendet werden. Dabei werden alle transportbezogenen “server”-Parameter aus Abschnitt 5.2 unterstützt. Ist der betreffende Peer lokal, darf kein Adressparameter angegeben werden. Die Adresse muss stattdessen in einer “bind”-Zeile stehen; siehe “bind” in diesem “peers”-Abschnitt.
Einige “server”-Parameter sind für “peers”-Abschnitte nicht relevant. Peers unterstützen weder dynamische Hostnamenauflösung noch Health Checks. Parameter wie “init_addr”, “resolvers”, “check”, “agent-check” oder “track” werden daher nicht unterstützt. Ebenso gibt es weder Lastverteilung noch feste Serverzuordnung; “weight” und “cookie” haben deshalb keine Wirkung.
Beispiel:
shards <shards>
In manchen Konfigurationen soll der Inhalt von Stick Tables auf einige Peers verteilt werden, statt den gesamten Inhalt an jeden Peer im “peers”-Abschnitt zu senden. “shards” gibt in diesem Fall die Anzahl der an der Verteilung beteiligten Peers an. Siehe auch den Serverparameter “shard”.
table <tablename> type {ip | integer | string [len <length>] | binary [len <length>]}
size `<size>` [expire `<expire>`] [write-to `<wtable>`] [nopurge] [store `<data_type>`]*
[recv-only]
Konfiguriert eine Zuordnungstabelle für den aktuellen Abschnitt. Die Zeile wird genauso wie “stick-table” in anderen Abschnitten verarbeitet. Allerdings entfällt hier das Argument “peers”, und ein zusätzliches erstes Pflichtargument benennt die Stick Table. Anders als in anderen Abschnitten sind in “peers” mehrere “table”-Zeilen möglich. Die vollständige Definition von “table” und “stick-table” steht oben in Abschnitt 11.1 .
“peers”-Abschnitte haben eigene Namensräume für Stick Tables, damit gleiche Tabellennamen in verschiedenen “peers”-Abschnitten nicht kollidieren. Intern wird dem Tabellennamen der Name des “peers”-Abschnitts, gefolgt von ‘/’, vorangestellt. Wird an anderer Stelle der Konfiguration auf eine in “peers” deklarierte Stick Table verwiesen, muss dieser Name mit Präfix verwendet werden:
Auch beim Zugriff auf Stick Tables über die CLI muss dieser Name mit Präfix verwendet werden.
Im “peers”-Protokoll ist diese Unterscheidung nicht erforderlich, da nur “peers” desselben Abschnitts miteinander kommunizieren können. Mehrere “peers”-Abschnitte können Stick Tables gleichen Namens deklarieren. Über das Netzwerk wird der kürzere Tabellenname gesendet, lediglich mit einem vorangestellten ‘/’. Das verhindert Kollisionen zwischen Tabellen aus Backends und solchen aus “peers”-Abschnitten, wie in folgender ungewöhnlichen, aber unterstützten Konfiguration:
Die Tabelle “t1” im Abschnitt “mypeers” hat hier den globalen Namen “mypeers/t1”. Die im Backend deklarierte Tabelle “t1” heißt global “t1”. Im Peers-Protokoll heißt die erste Tabelle dagegen “/t1” und die zweite wiederum “t1”.
21 - 12. Weitere Abschnitte
Die nachfolgend beschriebenen Abschnitte werden weniger häufig verwendet und unterstützen in der Regel nur wenige Parameter. Zwischen ihnen besteht keine implizite Beziehung. Alle werden mit einem einzigen Schlüsselwort gestartet. Keiner von ihnen ist vor einem “global”-Abschnitt erlaubt. Die Unterstützung einiger von ihnen kann von Build-Optionen abhängen (z. B. alles SSL-bezogene).
12.1. Ablaufverfolgung
Zur Fehlersuche ist es möglich, Trace-Ausgaben in einem HAProxy-Subsystem zu aktivieren. Dies führt zu Debug-Nachrichten über ein bestimmtes Subsystem. Es handelt sich um ein sehr leistungsfähiges Werkzeug zur Diagnose von Problemen. Trace-Ausgaben können dynamisch über die CLI konfiguriert werden. Es ist auch möglich, einige Einstellungen in der Konfigurationsdatei vorzugeben, in speziellen “traces”-Abschnitten. Weitere Informationen zu Trace-Ausgaben finden sich im Management-Leitfaden. Es bleibt ein Entwicklerwerkzeug, das während komplexer Fehlersuch-Sitzungen verwendet wird. Es erzeugt umfangreiche Ausgaben und beansprucht Ressourcen; deshalb ist bei seiner Verwendung Vorsicht geboten. Da es ein Entwicklerwerkzeug ist, gibt es keine Garantie für die Rückwärtskompatibilität dieses Abschnitts.
traces
Startet einen neuen traces-Abschnitt. Es können ein oder mehrere “traces”-Abschnitte verwendet werden. Alle Direktiven werden in der Deklarationsreihenfolge ausgewertet, wobei die letzten Einstellungen die vorherigen überschreiben.
trace <source> <args...>
Konfiguriert ein “trace”-Subsystem. Jedes davon ist im Management-Handbuch zu finden und folgt exakt der gleichen Syntax. Alle Ausgaben, die der “trace”-Befehl erzeugen würde, werden während des Einlesens des Abschnitts ausgegeben. Meistens handelt es sich dabei um Fehler und Warnungen, aber bestimmte unvollständige Befehle können zulässige Auswahlmöglichkeiten auflisten. Dieser Befehl ist nicht für den regulären Einsatz gedacht und wird in der Regel nur von Entwicklern während komplexer Fehlersuch-Sitzungen empfohlen. Es ist wichtig, sich vor Augen zu führen, dass die Aktivierung von Trace-Ausgaben je nach Trace-Stufe und -Details die globale Leistung erheblich beeinträchtigen kann. Weitere Informationen zur Befehlssyntax finden Sie im Management-Handbuch.
Beispiel:
12.2. Benutzerlisten
Es ist möglich, den Zugriff auf frontend/backend/listen-Abschnitte oder auf HTTP-Statistiken zu steuern, indem nur authentifizierte und autorisierte Benutzer zugelassen werden. Dazu ist es erforderlich, mindestens eine Benutzerliste zu erstellen und Benutzer zu definieren.
userlist <listname>
Erstellt eine neue Benutzerliste mit dem Namen <listname>. Mehrere unabhängige Benutzerlisten können verwendet werden, um Authentifizierungs- und Autorisierungsdaten für unabhängige Kunden zu speichern.
group <groupname> [users <user>,<user>,(...)]
Fügt die Gruppe <groupname> zur aktuellen Benutzerliste hinzu. Es ist auch möglich, Benutzer dieser Gruppe durch eine durch Komma getrennte Liste von Namen hinzuzufügen, die durch das Schlüsselwort “users” eingeleitet wird.
user <username> [password|insecure-password <password>]
Fügt den Benutzer <username> zur aktuellen Benutzerliste hinzu. Es können sowohl sichere (verschlüsselte) als auch unsichere (unverschlüsselte) Passwörter verwendet werden. Verschlüsselte Passwörter werden mithilfe der Funktion crypt(3) ausgewertet, wobei je nach Systemfunktionen verschiedene Algorithmen unterstützt werden. Beispielsweise unterstützen moderne glibc-basierte Linux-Systeme MD5, SHA-256, SHA-512 und natürlich die klassische DES-basierte Methode zur Passwortverschlüsselung.
Achtung: Beachten Sie, dass die Verwendung von verschlüsselten Passwörtern je nach Anzahl der Anfragen und verwendetem Algorithmus erheblich erhöhten CPU-Verbrauch verursachen kann. Bei allen Hash-Varianten muss das Passwort für jede Anfrage durch den gewählten Algorithmus verarbeitet werden, bevor es mit dem in der Konfigurationsdatei angegebenen Wert verglichen werden kann. Die meisten aktuellen Algorithmen sind absichtlich so ausgelegt, dass sie rechenintensiv sind, um Brute-Force-Angriffe zu erschweren. Sie berechnen den Hash des Klartextpassworts mit Salt nicht nur einmal, sondern tausendfach. Dies kann schnell zu einem bedeutenden Faktor im gesamten CPU-Verbrauch von HAProxy werden und sogar zu Anwendungsabstürzen führen!
Um den hohen CPU-Verbrauch von Hash-Funktionen zu reduzieren, kann man die Anzahl der Runden der Hash-Funktion (Algorithmen der SHA-Familie) verringern oder die Kosten der Funktion verringern, falls der Algorithmus dies unterstützt.
Als Randbemerkung: musl-Implementierungen (z. B. Alpine Linux) sind bekannt dafür, Hash-Berechnungen langsamer durchzuführen als ihre glibc-Gegenstücke, daher kann auch dieser Aspekt berücksichtigt werden.
Alle Passwörter werden als normale Argumente behandelt und unterliegen daher den üblichen Regeln für Anführungszeichen und Maskierung aus Abschnitt 2.2 . Es wird deshalb empfohlen, Passwörter in einfache Anführungszeichen zu setzen.
Beispiel:
Bitte beachten Sie, dass beide Listen funktional identisch sind.
12.3. Mailer
Es ist möglich, E-Mail-Benachrichtigungen zu senden, wenn sich der Zustand von Servern ändert. Wenn konfigurierte E-Mail-Benachrichtigungen aktiviert sind, werden diese an jeden Mailer gesendet, der in einem Mailer-Abschnitt konfiguriert ist. E-Mails werden über Lua gesendet (siehe examples/lua/mailers.lua).
mailers <mailersect>
Erstellt eine neue Mailer-Liste mit dem Namen <mailersect>. Es handelt sich um einen unabhängigen Abschnitt, der von einem oder mehreren Proxys referenziert wird.
mailer <mailername> <ip>:<port>
Definiert einen Mailer innerhalb eines Mailer-Abschnitts.
Beispiel:
timeout mail <time>
Legt fest, wie viel Zeit verfügbar ist, um eine Mail/Verbindung herzustellen und an den Mail-Server zu senden. Ohne Angabe gilt der Standardwert 10 Sekunden. Damit während des anfänglichen TCP-Handshakes mindestens zwei SYN-ACK-Pakete gesendet werden können, wird ein Wert von mehr als 4 Sekunden empfohlen.
Beispiel:
12.4. HTTP-Fehler
Mehrere Gruppen von HTTP-Fehlern können global deklariert und anschließend in beliebige Proxy-Abschnitte importiert werden. Dieselbe Gruppe kann an mehreren Stellen referenziert und vollständig oder teilweise importiert werden.
http-errors <name>
Erstellt eine neue http-errors-Gruppe mit dem Namen <name>. Dies ist ein eigenständiger Abschnitt, der von einem oder mehreren Proxies über seinen Namen referenziert werden kann.
errorfile <code> <file>
Ordnet den Inhalt einer Datei einem HTTP-Fehlercode zu.
Argumente:
Weitere Einzelheiten enthält das Schlüsselwort “errorfile” in Abschnitt 4 .
Beispiel:
12.5. Ringpuffer
Ringpuffer können global deklariert und als Ziel für Log-Server oder Traces verwendet werden.
ring <ringname>
Erstellt einen neuen Ringpuffer mit dem Namen <ringname>.
backing-file <path>
Ersetzt die reguläre Speicherzuweisung durch eine in den RAM eingeblendete Datei zur Speicherung des Ringpuffers. Dies kann nützlich sein, um Traces oder Logs für die nachträgliche Analyse zu sammeln, ohne einen langsamen Client an die CLI anzuschließen. Neuere Inhalte ersetzen automatisch ältere, sodass stets die neuesten Inhalte verfügbar sind. Die in den Ringpuffer geschriebenen Inhalte sind in dieser Datei sichtbar, sobald der Prozess beendet ist (meist sind sie sogar sehr bald sichtbar, dies ist jedoch nicht garantiert, da die Schreibvorgänge nicht synchron sind).
Wenn diese Option verwendet wird, verringert sich der gesamte Speicherbereich um die Größe der Struktur “struct ring”, die am Anfang des Bereichs liegt und zur Wiederherstellung seines Inhalts erforderlich ist. Die Datei wird mit dem Benutzer, der den Prozess startet, als Eigentümer, dem Modus 0600 und der mit der Anweisung “size” konfigurierten Größe erstellt. Beim Einlesen der Anweisung (also auch während einer Konfigurationsprüfung) wird jede vorhandene nicht leere Datei zunächst durch Anhängen von “.bak” umbenannt. Eine zuvor vorhandene Datei mit dem Suffix “.bak” wird entfernt. So löscht ein sofortiges Neuladen oder ein Neustart des Prozesses keine wertvollen Debugging-Informationen. Ein Administrator hat Zeit, die neue “.bak”-Datei zu entdecken und bei Bedarf zu archivieren. Nach einem Absturz enthält die durch <path> bezeichnete Datei die aktuellsten Informationen; nach einem Neustart des Dienstes stehen diese stattdessen in der Datei “<path>.bak”. Der insgesamt benötigte Speicherplatz ist daher doppelt so groß wie der Ringpuffer. Fehler bei der Dateirotation werden stillschweigend ignoriert. Wenn keine Sicherungsdatei gewünscht ist, genügt es daher, die Datei in einem Verzeichnis ohne Schreibberechtigung abzulegen.
WARNUNG: Die Verwendung dieser Funktion hat Auswirkungen auf Stabilität und Sicherheit. Erstens kann die Speicherung des Ringpuffers auf einem langsamen Gerät (z. B. einer physischen Festplatte) spürbare Verzögerungen bei Zugriffen und möglicherweise sogar Panics verursachen, wenn zu viele Threads um den Zugriff konkurrieren. Zweitens könnte ein externer Prozess, der den Bereich verändert, den haproxy-Prozess zum Absturz bringen oder dazu führen, dass er Teile seines eigenen Speichers mit Traces überschreibt. Drittens können Schreibvorgänge in den Ringpuffer den Prozess zum Absturz bringen, wenn das Dateisystem voll wird, bevor der Ringpuffer gefüllt ist.
Die Informationen in diesem Ringpuffer sind strukturiert und können NICHT direkt mit einem Texteditor gelesen werden (auch wenn vieles davon gerade noch lesbar aussieht). Die Ausgabe dieser Datei ist ausschließlich für Entwickler bestimmt.
description <text>
Die Beschreibung ist ein optionaler Beschreibungstext für den Ringpuffer. Sie erscheint in der CLI. Standardmäßig wird dieses Feld mit <name> gefüllt.
format <format>
Format zur Speicherung von Ereignissen im Ringpuffer.
Argumente:
maxlen <length>
Die maximale Länge einer im Ringpuffer gespeicherten Ereignismeldung einschließlich des formatierten Headers. Ist eine Ereignismeldung länger als <length>, wird sie auf diese Länge gekürzt.
server <name> <address> [param*]
Konfiguriert einen TCP-Syslog-Server, an den Meldungen aus dem Ringpuffer weitergeleitet werden. Alle in Abschnitt 5.2 aufgeführten “server”-Parameter werden unterstützt. Einige dieser Parameter sind für “ring”-Abschnitte nicht relevant. Wichtig: Es gibt kaum einen Grund, einem Ringpuffer mehr als einen Server hinzuzufügen, da alle Server exakt dieselbe Kopie seines Inhalts erhalten. Daher schreitet der Ringpuffer nur mit der Geschwindigkeit des langsamsten Servers voran. Wenn ein Server nicht antwortet, verhindert er das Entfernen alter Meldungen und kann das Einfügen neuer Meldungen in den Ringpuffer blockieren. Die richtige Vorgehensweise zum Senden von Meldungen an mehrere Server besteht darin, für jeden Log-Server einen eigenen Ringpuffer zu verwenden, anstatt mehrere Server an denselben Ringpuffer anzuschließen. Die spezielle Server-Anweisung “log-proto” legt das Protokoll zum Senden der Meldungen fest.
size <size>
Die optionale Größe des Ringpuffers in Byte. Der Standardwert ist BUFSIZE.
timeout connect <timeout>
Legt die maximale Wartezeit fest, innerhalb derer ein Verbindungsversuch zu einem Server erfolgreich sein muss.
Argumente:
timeout server <timeout>
Legt fest, wie lange ausstehende Daten höchstens im Ausgabepuffer verbleiben dürfen.
Argumente:
Beispiel:
12.6. Log-Weiterleitung
Es können ein oder mehrere Abschnitte zur Log-Weiterleitung deklariert werden. HAProxy leitet alle empfangenen Log-Meldungen an eine Liste von Log-Servern weiter.
log-forward <name>
Erstellt einen neuen Proxy zur Log-Weiterleitung mit der Kennung <name>.
backlog <conns>
Gibt dem System beim Annehmen von Verbindungen einen Hinweis auf die ungefähr gewünschte Größe des Listen-Backlogs.
bind <addr> [param*]
Konfiguriert einen Listener für Log-Datenströme, der die weiterzuleitenden Meldungen empfängt. Die in Abschnitt 5.1 aufgeführten “bind”-Parameter einschließlich der SSL-Parameter werden unterstützt. Einige Angaben wie “alpn” sind jedoch für das Syslog-Protokoll über TCP möglicherweise nicht relevant. Diese Listener unterstützen sowohl den Modus “Octet Counting” als auch “Non-Transparent-Framing” gemäß rfc-6587.
dgram-bind <addr> [param*]
Konfiguriert einen Listener für Log-Datagramme, der die weiterzuleitenden Meldungen empfängt. Adressen müssen im IPv4- oder IPv6-Format mit nachfolgendem Port angegeben werden. Einige der in Abschnitt 5.1 aufgeführten “bind”-Parameter werden unterstützt, darunter “interface”, “namespace” und “transparent”. Die übrigen werden stillschweigend ignoriert, da sie für UDP/Syslog nicht relevant sind.
log global
Konfiguriert die Ziel-Log-Server. Weitere Einzelheiten enthält die Proxy-Dokumentation. Wenn kein Format angegeben ist, versucht HAProxy, das Format der eingehenden Log-Meldung beizubehalten. Die konfigurierte Facility wird ignoriert, es sei denn, die eingehende Meldung enthält keine Facility, das Ausgabeformat verlangt jedoch eine. Wenn das Eingabeformat keinen Zeitstempel enthält, das Ausgabeformat aber ein entsprechendes Feld hat, verwendet HAProxy das lokale Datum.
Beispiel:
maxconn <conns>
Legt die maximale Anzahl gleichzeitiger Verbindungen auf einem Proxy zur Log-Weiterleitung fest. Der Standardwert ist 10.
timeout client <timeout>
Legt die maximale Inaktivitätszeit auf der Client-Seite fest.
option assume-rfc6587-ntf
Weist HAProxy an, eingehende TCP-Log-Datenströme immer als nicht transparent gerahmt zu behandeln. Diese Option vereinfacht die Logik der Nachrichtenrahmung und sorgt für eine einheitliche Behandlung der Meldungen. Sie ist besonders bei fehlerhaft gebildeten Anfangszeichen nützlich.
option dont-parse-log
Ermöglicht HAProxy, Syslog-Meldungen weiterzuleiten, ohne sie zu analysieren und neu zu strukturieren. Dies ist nützlich für Meldungen, die möglicherweise nicht den üblichen Formaten entsprechen. Diese Option sollte zusammen mit der Einstellung format raw für die Log-Ziele verwendet werden, damit der ursprüngliche Meldungsinhalt erhalten bleibt.
option host { replace | fill | keep | append }
Legt für den Abschnitt log-forward die Strategie zum Umgang mit dem Syslog-Hostname-Feld in ausgehenden rfc3164- oder rfc5424-Meldungen fest.
replace Enthält die eingehende Meldung bereits einen Wert im
Hostname-Feld, wird dieser durch die Quell-IP-Adresse des
Absenders ersetzt. Enthält die eingehende Meldung keinen Wert
im Hostname-Feld (d. h. '-' in einer eingehenden rfc5424-Meldung
oder eine nicht konforme rfc3164- oder rfc5424-Meldung), wird
die Quell-IP-Adresse des Absenders als Hostname verwendet.
fill Enthält die eingehende Meldung bereits einen Wert im
Hostname-Feld, wird dieser beibehalten. Enthält die eingehende
Meldung keinen Wert im Hostname-Feld (d. h. '-' in einer
eingehenden rfc5424-Meldung oder eine nicht konforme rfc3164-
oder rfc5424-Meldung), wird die Quell-IP-Adresse des Absenders
als Hostname verwendet.
(Dies ist die Standardeinstellung)
keep Enthält die eingehende Meldung bereits einen Wert im
Hostname-Feld, wird dieser beibehalten. Enthält die eingehende
Meldung keinen Wert im Hostname-Feld, wird es auf 'localhost'
(rfc3164) bzw. '-' (rfc5424) gesetzt.
append Enthält die eingehende Meldung bereits einen Wert im
Hostname-Feld, werden ein Komma und die IP-Adresse des
Absenders angehängt. Enthält die eingehende Meldung keinen
Wert im Hostname-Feld, wird die Quell-IP-Adresse des
Absenders verwendet.
Für alle obigen Optionen gilt: Wenn die Quell-IP-Adresse des Absenders nicht verfügbar ist (z. B. bei einem UNIX/ABNS-Socket), wird die Strategie “keep” verwendet.
Diese Option ist nur für das Log-Ausgabeformat rfc3164 oder rfc5424 relevant. Bei anderen Formaten hat sie keine sichtbare Wirkung.
12.7. Zertifikatsspeicher
HAProxy verwendet einen internen Speichermechanismus zum Laden und Speichern der in der Konfiguration verwendeten Zertifikate. Dieser Speicher kann über einen “crt-store”-Abschnitt konfiguriert werden. Darin lassen sich Zertifikatsdefinitionen und die zu ladenden Dateien festlegen. Eine Zertifikatsdefinition muss vor ihrer Verwendung an anderer Stelle in der Konfiguration stehen.
crt-store [<name>]
“crt-store” akzeptiert als optionales Argument einen Namen. Wenn ein Name angegeben ist, muss jedes Zertifikat dieses Speichers mit “@<name>/<crt>” oder “@<name>/<alias>” referenziert werden.
Dateien im Zertifikatsspeicher können auch dynamisch über die CLI aktualisiert werden. Siehe “set ssl cert” in Abschnitt 9.3 des Verwaltungshandbuchs.
Im Abschnitt “crt-store” werden die folgenden Schlüsselwörter unterstützt:
- crt-base
- key-base
- load
crt-base <dir>
Legt das Standardverzeichnis fest, aus dem SSL-Zertifikate geladen werden, wenn “crt”-Anweisungen einen relativen Pfad verwenden. Angegebene absolute Pfade haben Vorrang und ignorieren “crt-base”. Bei Verwendung in einem crt-store wird crt-base aus dem globalen Abschnitt ignoriert.
key-base <dir>
Legt das Standardverzeichnis fest, aus dem private SSL-Schlüssel geladen werden, wenn “key”-Anweisungen einen relativen Pfad verwenden. Angegebene absolute Pfade haben Vorrang und ignorieren “key-base”. Bei Verwendung in einem crt-store wird key-base aus dem globalen Abschnitt ignoriert.
load [crt <filename>] [param*]
Lädt SSL-Dateien in den Zertifikatsspeicher. Die Parameterliste steht in Abschnitt „12.7.1. Ladeoptionen“.
Beispiel:
12.7.1. Ladeoptionen
Lädt SSL-Dateien in den Zertifikatsspeicher. Das Schlüsselwort load akzeptiert mehrere Parameter, die nachfolgend aufgeführt sind. Diese Schlüsselwörter können auch in einer crt-list verwendet werden.
crt <filename>
Dieses Argument ist erforderlich. Es lädt eine PEM-Datei, die das öffentliche Zertifikat enthalten muss, aber auch Zwischenzertifikate und den privaten Schlüssel enthalten kann. Wenn diese Datei keinen privaten Schlüssel enthält, kann ein Schlüssel mit dem Schlüsselwort “key” angegeben werden.
acme <string>
Diese Option ermöglicht die Konfiguration des ACME-Protokolls für ein bestimmtes Zertifikat. Die Funktion ist experimentell und erfordert das Schlüsselwort “expose-experimental-directives” im globalen Abschnitt.
Bei Verwendung des Schlüsselworts “acme” in einem crt-store ist ein Start ohne vorhandenes Zertifikat auf dem Datenträger möglich. Stattdessen wird ein temporäres Schlüsselpaar verwendet, bis das ACME-Zertifikat erzeugt ist. Dieses Verhalten ist auf crt-stores beschränkt: Weder eine crt-list-Zeile noch eine ssl-f-use-Zeile ermöglicht dies, ohne zuvor einen crt-store zu deklarieren.
Siehe auch Abschnitt 12.8 (“ACME”) und “domains” in diesem Abschnitt.
alias <string>
Optionales Argument. Gibt dem Zertifikat einen Alias, über den es in der Konfiguration referenziert werden kann. Bei Verwendung an anderer Stelle in der Konfiguration muss dem Alias ‘@/’ vorangestellt werden.
domains <string>
Konfiguriert die Liste der Domains, die für ACME-Zertifikate verwendet werden. Die erste Domain in der Liste wird als CN verwendet. Die Domains werden in der Liste durch Kommas getrennt.
Siehe auch Abschnitt 12.8 (“ACME”) und “acme” in diesem Abschnitt.
Beispiel:
ips <string>
Konfiguriert die Liste der IP-Adressen, die als IP-SANs in das ACME-Zertifikat aufgenommen werden. Die IP-Adressen werden in der Liste durch Kommas getrennt.
Das Erzeugen eines Zertifikats mit IPs kann die Verwendung des Profils “shortlived” erfordern.
Siehe auch Abschnitt 12.8 (“ACME”), “acme” und “domains” in diesem Abschnitt.
Beispiel:
key <filename>
Dieses Argument ist optional. Es lädt einen privaten Schlüssel im PEM-Format. Wenn in “crt” bereits ein privater Schlüssel definiert wurde, wird dieser überschrieben.
ocsp <filename>
Dieses Argument ist optional. Es lädt eine OCSP-Antwort im DER-Format. Diese kann über die CLI aktualisiert werden.
issuer <filename>
Dieses Argument ist optional. Es lädt das OCSP-Ausstellerzertifikat im PEM-Format. Um festzustellen, für welches Zertifikat eine OCSP-Antwort gilt, wird das Zertifikat des Ausstellers benötigt. Wenn das Ausstellerzertifikat nicht in der “crt”-Datei enthalten ist, kann es mit diesem Argument aus einer Datei geladen werden.
sctl <filename>
Dieses Argument ist optional. Es aktiviert die Unterstützung für die TLS-Erweiterung Certificate Transparency (RFC6962). Die Datei muss eine gültige Signed Certificate Timestamp List gemäß RFC enthalten. Die grundlegende Syntax der Datei wird beim Einlesen geprüft, Signaturen werden jedoch nicht verifiziert.
ocsp-update [ off | on ]
Aktiviert bei ‘on’ die automatische Aktualisierung von OCSP-Antworten und deaktiviert sie andernfalls. Der Standardwert ist ‘off’. Um die automatische OCSP-Aktualisierung für eine bind-Zeile zu aktivieren, kann diese Option in einem crt-store oder die globale Option “tune.ocsp-update.mode” verwendet werden. Wird ein Zertifikat in mehreren crt-lists mit unterschiedlichen Werten für ‘ocsp-update’ verwendet, wird ein Fehler ausgelöst. Derselbe Fehler tritt auf, wenn ein Zertifikat in einer bind-Zeile die globale Option erbt und in einer crt-list eine damit unvereinbare explizite ‘ocsp-update’-Einstellung hat.
Beispiele:
Beispielkonfiguration zur Aktivierung mit einer crt-list:
haproxy.cfg:
haproxy.list:
Beispielkonfiguration zur Aktivierung mit einem crt-store:
haproxy.cfg:
Wenn die Option auf ‘on’ gesetzt ist, wird versucht, eine OCSP-Antwort abzurufen, sobald im Frontend-Zertifikat eine OCSP-URI gefunden wird. Die einzige Einschränkung dieses Modus besteht darin, dass der Zertifikatsaussteller bekannt sein muss, damit die OCSP-certid gebildet werden kann. Jede OCSP-Antwort wird mindestens einmal pro Stunde aktualisiert, bei einer Ablaufzeit vor dieser Stundengrenze auch häufiger. Es gilt weiterhin ein Mindestintervall von 5 Minuten, damit Antworten mit sehr kurzer Gültigkeitsdauer oder ganz ohne ‘Next Update’ nicht zu häufig aktualisiert werden. Wegen dieser festen Grenze wird bei aktivierter automatischer Aktualisierung (‘on’) eine während der Initialisierung geladene OCSP-Antwort frühestens nach 5 Minuten aktualisiert, selbst wenn sie vor now+5m abläuft. Dies sollte kaum Probleme verursachen, da eine OCSP-Antwort beim Laden während der Initialisierung gültig sein muss (ihre Ablaufzeit muss in der Zukunft liegen) und daher wahrscheinlich nicht so kurz nach der Initialisierung abläuft. Ist für ein Zertifikat hingegen eine OCSP-URI angegeben, aber keine OCSP-Antwort vorhanden, sorgt ‘on’ für dieses Zertifikat dafür, dass die OCSP-Antwort unmittelbar nach der Initialisierung automatisch abgerufen wird. Die Standardwerte für die minimale und maximale Verzögerung (5 Minuten bzw. 1 Stunde) können mit den globalen Optionen “ocsp-update.maxdelay” und “ocsp-update.mindelay” konfiguriert werden.
Wenn eine OCSP-Antwort durch die automatische Aktualisierungsaufgabe oder nach einem Aufruf des CLI-Befehls “update ssl
ocsp-response” aktualisiert wird, wird eine eigene Log-Zeile ausgegeben. Sie verwendet ein eigenes Format mit dem Header “<OCSP-UPDATE>”, gefolgt von OCSP-spezifischen Informationen: - dem Pfad des zugehörigen Frontend-Zertifikats - einem numerischen Aktualisierungsstatus - einem textuellen Aktualisierungsstatus - der Anzahl fehlgeschlagener Aktualisierungen dieser Antwort - der Anzahl erfolgreicher Aktualisierungen dieser Antwort. Eine vollständige Liste der Fehlercodes und Fehlermeldungen enthält der CLI-Befehl “show ssl ocsp-updates”. Diese Zeile wird unabhängig davon ausgegeben, ob die betreffende OCSP-Antwort erfolgreich aktualisiert wurde. Die OCSP-Anfrage und -Antwort werden über eine http_client-Instanz gesendet und empfangen, für die dontlog-normal gesetzt ist und die bei einem Fehler (etwa einem nicht erreichbaren OCSP-Responder) das reguläre HTTP-Log-Format verwendet. Tritt ein solcher Fehler auf, wird neben der „regulären“ OCSP-Zeile (die wahrscheinlich den Textstatus “HTTP error” enthält) eine weitere Log-Zeile mit HTTP-bezogenen Informationen ausgegeben. Bei einem reinen HTTP-Fehler (etwa einem nicht erreichbaren OCSP-Responder) wird jedoch eine zusätzliche Log-Zeile im regulären HTTP-Log-Format ausgegeben. Nachfolgend stehen zwei Beispiele für solche Log-Zeilen: zuerst eine erfolgreiche OCSP-Aktualisierung, danach ein HTTP-Fehler mit den beiden unterschiedlichen Zeilen (zur besseren Lesbarkeit wurden die Zeilen aufgeteilt und die URL gekürzt):
Fehlerbehebung: Ein häufiger Fehler bei Zertifikaten von Let’s Encrypt tritt auf, wenn die DNS-Auflösung eine IPv6-Adresse liefert, das System aber keine gültige ausgehende IPv6-Route hat. In diesem Fall kann entweder eine passende Route eingerichtet oder im globalen Abschnitt die Option “httpclient.resolvers.prefer ipv4” gesetzt werden. Beim Fehler “OCSP response check failure” kann es sinnvoll sein, die Gültigkeit des bereitgestellten Ausstellerzertifikats zu prüfen. Nach der allgemeinen Fehlermeldung kann in Klammern auch eine genauere Fehlermeldung erscheinen. Dies ist bei den Fehlern “OCSP response check failure” und “Error during insertion” möglich.
jwt [ off | on ]
Ermöglicht bei ‘on’ die Verwendung dieses Zertifikats für die JWT-Validierung oder -Entschlüsselung über die Konverter “jwt_verify_cert”, “jwt_decrypt_cert” oder “jwt_decrypt”. Der Standardwert ist ‘off’.
Wenn diese Option für ein Zertifikat auf ‘on’ gesetzt ist, funktioniert der CLI-Befehl “del ssl cert” nicht. Damit ein Zertifikat gelöscht werden kann, darf es weder für SSL-Handshakes noch für die JWT-Validierung verwendet werden.
Diese Option kann zur Laufzeit mit den CLI-Befehlen “add ssl jwt” und “del ssl jwt” geändert werden. Siehe auch den CLI-Befehl “show ssl jwt”.
generate-dummy [ off | on ]
Ermöglicht bei ‘on’ die Erzeugung eines privaten Schlüssels und des zugehörigen selbstsignierten Zertifikats beim Einlesen der Konfiguration. Dies kann beispielsweise während Tests nützlich sein, wenn kein Zertifikat verfügbar ist. In diesem Fall können “keytype”, “bits” und “curves” verwendet werden, um den privaten Schlüssel anzupassen. Ohne Angabe dieser Option gilt der Standardwert ‘off’. (Siehe auch “keytype”, “bits” und “curves”.)
keytype [ RSA | ECDSA ]
Ermöglicht die Auswahl des Typs des privaten Schlüssels, der beim Einlesen der Konfiguration zur Erzeugung eines selbstsignierten Zertifikats verwendet wird. Dies gilt, wenn “generate-dummy” für dieses Zertifikat auf ‘on’ gesetzt ist. Ohne Angabe dieser Option gilt der Standardwert ‘RSA’. (Siehe auch “generate-dummy”.)
bits <number>
Konfiguriert die Bitanzahl zur Erzeugung eines selbstsignierten RSA-Zertifikats, wenn “generate-dummy” für dieses Zertifikat auf ‘on’ und “keytype” auf ‘RSA’ gesetzt ist. Ohne Angabe dieser Option gilt der Standardwert 2048. (Siehe auch “generate-dummy”.)
curves <string>
Konfiguriert die Kurven, wenn “generate-dummy” für dieses selbstsignierte Zertifikat auf ‘on’ und “keytype” auf ‘ECDSA’ gesetzt ist. Der Standardwert ist ‘P-384’.
12.8. ACME
acme <name>
Das ACME-Protokoll kann über den Abschnitt “acme” konfiguriert werden. Der Abschnitt akzeptiert das Argument “<name>”, mit dem ein Zertifikat diesem Abschnitt zugeordnet wird.
Der ACME-Abschnitt ermöglicht die Konfiguration von HAProxy als ACMEv2-Client. Diese Funktion ist experimentell. Daher muss “expose-experimental-directives” im globalen Abschnitt stehen, damit sie verwendet werden kann.
Eine Anleitung steht im HAProxy-Wiki unter https://github.com/haproxy/wiki/wiki/ACME:--native-haproxy
- Die Funktion ist auf die Challenges http-01, dns-01 oder dns-persist-01 beschränkt
derzeit. http-01 wird vollständig von HAProxy abgewickelt. Für dns-01 und dns-persist-01 wird jedoch entweder die dataplaneAPI oder ein anderes Drittanbieterwerkzeug benötigt, um mit der API eines DNS-Anbieters zu kommunizieren. Bei dns-persist-01 muss der TXT-Eintrag nur einmal gesetzt werden; dies kann daher auch manuell ohne Werkzeug erfolgen.
- Der Start ist ohne vorhandenes Zertifikat auf dem Datenträger möglich. Dazu
muss das Zertifikat in einem crt-store konfiguriert sein. Bei Verwendung des Schlüsselworts “acme” in einem crt-store wird ein temporäres Schlüsselpaar verwendet, bis das ACME-Zertifikat erzeugt ist.
- Die aktuelle HAProxy-Architektur arbeitet nicht blockierend; der Zugriff auf den Datenträger
sollte nach dem Laden der Konfiguration nicht mehr erfolgen, da er die Ereignisschleife und damit den Datenverkehr auf demselben Thread blockieren könnte. Deshalb müssen die von HAProxy erzeugten Zertifikate und Schlüssel außerhalb von HAProxy über “dump ssl cert” am Statistik-Socket exportiert werden. Der Export der Zertifikate lässt sich mit der dataplaneAPI oder dem Skript haproxy-dump-certs im Verzeichnis admin/cli/ automatisieren.
Der ACME-Scheduler startet beim Start von HAProxy. Er durchläuft die Zertifikate und startet eine ACME-Erneuerungsaufgabe, wenn notAfter hinter curtime + (notAfter - notBefore) / 12 liegt; ist notBefore nicht definiert, werden 7 Tage verwendet. Der Scheduler schläft anschließend und wacht nach 12 Stunden wieder auf. Eine Erneuerungsaufgabe kann mit “acme renew” manuell gestartet werden. Siehe auch “acme status” im Verwaltungshandbuch.
Die folgenden Schlüsselwörter können im ACME-Abschnitt verwendet werden:
account-key <filename>
Konfiguriert den Pfad zum Kontoschlüssel. Der Schlüssel muss vor dem Start von HAProxy erzeugt werden. Wenn kein account-Schlüsselwort verwendet wird, versucht der acme-Abschnitt, eine Datei mit dem aus dem Abschnittsnamen gebildeten Namen “<name>.account.key” zu laden. Ist die Datei nicht vorhanden, erzeugt HAProxy sie mit den Parametern aus dem acme-Abschnitt.
Ein privater RSA-Schlüssel kann auch manuell mit openssl erzeugt werden:
Oder ein ECDSA-Schlüssel:
acme-vars <string>
Übergibt beliebige Variablen über die Senke “dpapi” an das externe Werkzeug zur DNS-Bereitstellung (z. B. die dataplaneAPI). Die Bedeutung hängt vom Werkzeug ab; siehe dessen Dokumentation.
Dieses Schlüsselwort ist nur für den Challenge-Typ “dns-01” oder “dns-persist-01” relevant.
Siehe auch: “challenge”, “provider-name”
bits <number>
Konfiguriert die Bitanzahl für die Erzeugung eines RSA-Zertifikats. Der Standardwert ist 2048. Ein zu hoher Wert kann eine Warnung auslösen, wenn der Rechner nicht leistungsfähig genug ist. Dies lässt sich mit “warn-blocked-traffic-after” konfigurieren; eine zu lange Blockierung des Datenverkehrs kann jedoch den Watchdog auslösen.
challenge <string>
Erwartet als Parameter einen Challenge-Typ. Dieser muss http-01, dns-01 oder dns-persist-01 sein. Ohne Angabe ist http-01 der Standard.
dns-persist-01 implementiert draft-ietf-acme-dns-persist. Anders als dns-01 verwendet es einen statischen TXT-Eintrag unter “_validation-persist.<domain>”, der einmal gesetzt wird und sich zwischen Erneuerungen nicht ändert. Der Eintrag muss die Konto-URI sowie gegebenenfalls eine optionale Richtlinie enthalten. Dieser Challenge-Typ erfordert keinen Schreibzugriff auf die API des DNS-Anbieters bei jeder Erneuerung.
challenge-ready <value>[,<value>]*
Konfiguriert die Bedingungen, die erfüllt sein müssen, bevor dem ACME-Server mitgeteilt wird, dass eine dns-01-Challenge zur Validierung bereit ist. Zulässige Werte sind:
Mehrere Werte können durch Kommas getrennt kombiniert werden. Sind mehrere Bedingungen angegeben, verarbeitet HAProxy sie in folgender Reihenfolge: zuerst auf die CLI-Bestätigung warten (“cli”), dann die anfängliche Wartezeit einhalten (“delay”), danach die DNS-Vorabprüfungen ausführen (“dns”).
Diese Option ist nur mit den Challenge-Typen dns-01 und dns-persist-01 kompatibel.
Ist “challenge” auf “dns-01” gesetzt und diese Option nicht konfiguriert, ist “cli” der Standard.
Ist “challenge” auf “dns-persist-01” gesetzt und diese Option nicht konfiguriert, ist “dns,delay” der Standard.
Ist “challenge” auf “dns-persist-01” gesetzt, wird vor der Auswertung der challenge-ready-Bedingungen immer zunächst eine opportunistische DNS-Prüfung ausgeführt. Da der TXT-Eintrag “_validation-persist.<domain>” einmal gesetzt wird und sich zwischen Erneuerungen nicht ändert, prüft HAProxy bei der Erneuerung, ob der Eintrag bereits vorhanden ist. Gelingt die Prüfung für alle Domains, wird die Challenge sofort übermittelt, ohne die challenge-ready-Schritte (cli, delay, dns) zu durchlaufen. Schlägt die Prüfung fehl, greift HAProxy auf den normalen challenge-ready-Ablauf zurück.
Beispiel:
contact <string>
Die Kontakt-E-Mail-Adresse, die bei der CA dem Kontoschlüssel zugeordnet wird.
curves <string>
Konfiguriert bei Verwendung des Schlüsseltyps ECDSA die Kurven. Der Standard ist P-384.
directory <string>
Dieses Schlüsselwort konfiguriert die Verzeichnis-URL der CA, die dieser acme-Abschnitt verwendet. Es ist zwingend erforderlich, da keine Standard-URL existiert.
Beispiel:
dns-delay <time>
Konfiguriert die Wartezeit für die “challenge-ready”-Bedingungen “delay” und “dns”. Der Wert ist eine Zeitangabe im HAProxy-Zeitformat, etwa “5m” oder “300s”. Der Standardwert ist 30 Sekunden.
Ihre Bedeutung hängt von den verwendeten “challenge-ready”-Bedingungen ab:
Die Auflösung erfolgt über den konfigurierten resolvers-Abschnitt “default”, nicht über die autoritativen Nameserver. DNS-Caching auf Resolver-Ebene kann die Ergebnisse daher weiterhin beeinflussen.
dns-timeout <time>
Wenn “challenge-ready” den Wert “dns” enthält, konfiguriert dies die maximale Zeit für eine erfolgreiche Auflösung des TXT-Eintrags, bevor die Challenge abgebrochen wird. Der Wert ist eine Zeitangabe im HAProxy-Zeitformat, etwa “10m” oder “600s”. Der Standardwert ist 600 Sekunden.
Die Zeitmessung beginnt, sobald der erste DNS-Auflösungsversuch ausgelöst wird, also nach der anfänglichen Wartezeit “dns-delay”. Würde der nächste Auflösungsversuch erst nach Ablauf der Zeitüberschreitung ausgelöst, wird die Challenge mit einem Fehler abgebrochen. Dies verhindert endlose Wiederholungsversuche, wenn die DNS-Verbreitung fehlschlägt.
Siehe auch: “dns-delay”
keytype <string>
Konfiguriert den Typ des zu erzeugenden Schlüssels. Mögliche Werte sind “RSA” und “ECDSA”. Für ECDSA können außerdem die “curves” und für RSA die Anzahl der “bits” konfiguriert werden. Standardmäßig werden EC384-Schlüssel erzeugt.
map <map>
Konfiguriert die Zuordnungstabelle zum Speichern von Token als Schlüssel und Fingerabdruck als Wert. Dies ist für die Beantwortung einer Challenge bei mehreren verwendeten Konten nützlich. Die acme-Aufgabe fügt vor der Validierung der Challenge Einträge hinzu und entfernt sie am Ende der Aufgabe.
profile <string>
Fordert ein bestimmtes Zertifikatsprofil von der CA an, indem der newOrder-Anfrage ein Feld “profile” hinzugefügt wird. Dies implementiert draft-ietf-acme-profiles.
Profilnamen sind CA-spezifische kurze Bezeichner, etwa “classic” oder “shortlived”. Ist ein Profilname gesetzt, wird er unverändert in den JSON-Nutzdaten von newOrder gesendet. Die CA kann die Anfrage ignorieren oder einen Fehler zurückgeben, wenn sie das Profil nicht unterstützt. Ohne Angabe wird kein Profilfeld eingefügt, und die CA verwendet ihre standardmäßige Ausstellungsrichtlinie.
Die Profile von Let’s Encrypt sind unter https://letsencrypt.org/docs/profiles/ beschrieben.
Beispiel:
provider-name <string>
Legt den Namen des DNS-Anbieters fest, der über das Ziel “dpapi” an das externe DNS-Bereitstellungswerkzeug, etwa die dataplaneAPI, übergeben wird. Die zulässigen Werte hängen vom Werkzeug ab; Einzelheiten stehen in dessen Dokumentation.
Dieses Schlüsselwort ist nur bei den Challenge-Typen “dns-01” oder “dns-persist-01” sinnvoll.
Siehe auch: “challenge”, “acme-vars”
reuse-key { on | off }
Bei “on” erzeugt HAProxy keinen neuen privaten Schlüssel, sondern behält den bisherigen bei. Ein regelmäßiger Wechsel privater Schlüssel wird empfohlen. Wird diese Option aktiviert, wird empfohlen, die Schlüssel regelmäßig manuell neu zu erzeugen.
Diese Option kann bei RSA-Schlüsseln größer als 2048 nützlich sein, deren Erzeugung Zeit beanspruchen und dabei einen Thread verlangsamen kann.
Bei Verwendung des Caches des ACME-Servers kann derselbe Schlüssel nützlich sein, um ein gültiges Zertifikat für den aktuellen Schlüssel abzurufen.
Die Standardeinstellung ist “off”.
Beispiel:
eab-key-id <filename>
Konfiguriert den Pfad zur Datei mit der EAB-Schlüssel-ID. Die Zugangsdaten werden von der CA bereitgestellt und müssen vor dem Start von HAProxy unter dem angegebenen Pfad abgelegt werden. Sie werden nur bei der Kontoerstellung verwendet.
Die Datei muss eine einfache ASCII-Zeichenfolge enthalten.
EAB-Zugangsdaten werden nur bei der erstmaligen Erstellung des ACME-Kontos benötigt. Danach können sie aus der Konfiguration entfernt oder die Dateien geleert werden. Eine leere Datei wird ohne Meldung ignoriert. Leerraum wird mit Ausnahme des abschließenden Zeilenumbruchs nicht ignoriert.
Siehe auch: “eab-mac-key”, “eab-mac-alg”
eab-mac-key <filename>
Konfiguriert den Pfad zur Datei mit dem EAB-MAC-Schlüssel. Die Zugangsdaten werden von der CA bereitgestellt und müssen vor dem Start von HAProxy unter dem angegebenen Pfad abgelegt werden. Sie werden nur bei der Kontoerstellung verwendet.
Die Datei muss einen base64url-kodierten MAC-Schlüssel enthalten.
EAB-Zugangsdaten werden nur bei der erstmaligen Erstellung des ACME-Kontos benötigt. Danach können sie aus der Konfiguration entfernt oder die Dateien geleert werden. Eine leere Datei wird ohne Meldung ignoriert. Leerraum wird mit Ausnahme des abschließenden Zeilenumbruchs nicht ignoriert.
Siehe auch: “eab-key-id”, “eab-mac-alg”
eab-mac-alg { HS256 | HS384 | HS512 }
Konfiguriert den MAC-Algorithmus für die EAB-Signatur. Der Standard ist HS256. Der EAB-MAC-Schlüssel muss groß genug für den angegebenen MAC-Algorithmus sein. Nicht alle CAs unterstützen andere Algorithmen als HS256.
Siehe auch: “eab-key-id”, “eab-mac-key”
12.9. Health Checks
Mehrere Health Checks können global deklariert und von Servern in der gesamten Konfiguration verwendet werden. Dabei überschreiben sie die lokale Proxy-Konfiguration.
healthcheck <name>
Erstellt einen neuen Health Check mit dem Namen <name>. Dieser Name muss eindeutig sein. Er sollte in der server-Zeile verwendet werden, um einen bestimmten health-check-Abschnitt zu referenzieren.
type <type>
Legt den Typ des Health Checks fest. Dieser Parameter ist zwingend erforderlich. Folgende Typen werden unterstützt:
* tcp-check
* httpchk
* ssl-hello-chk
* smtpchk
* pgsql-check
* redis-check
* mysql-check
* ldap-check
* spop-check
Jeder Typ verwendet, sofern vorhanden, dieselben Parameter wie die entsprechende Proxy-Option. Beispielsweise können für den Typ “httpchk” die Methode, die URI usw. angegeben werden:
Beispiele:
Siehe auch: “option tcp-check”, “option httpchk”, “option ssl-hello-chk”, “option smtpchk”, “option mysql-check”, “option pgsql-check”, “option redis-check”, “option ldap-check” und “option spop-check”
http-check comment <string>
Fügt einem Health Check vom Typ “httpchk” eine bestimmte http-check-Regel hinzu. Die Syntax entspricht den zugehörigen Proxy-Direktiven. Einzelheiten stehen in der entsprechenden Proxy-Dokumentation.
tcp-check comment <string>
Fügt einem Health Check vom Typ “tcp-check” eine bestimmte tcp-check-Regel hinzu. Die Syntax entspricht den zugehörigen Proxy-Direktiven. Einzelheiten stehen in der entsprechenden Proxy-Dokumentation.
22 - 1. Voraussetzungen
Dieses Dokument erläutert, wie Sie HAProxy starten, stoppen und verwalten sowie Störungen diagnostizieren. Darüber hinaus behandelt es einige bekannte Einschränkungen und Fallstricke. Die Konfiguration von HAProxy ist nicht Gegenstand dieses Dokuments (lesen Sie dazu configuration.txt
).
Das Dokument setzt voraus, dass Sie über ausreichende Kenntnisse in der Administration UNIX-ähnlicher Betriebssysteme verfügen, täglich mit der Shell arbeiten und mit Werkzeugen zur Fehlerdiagnose wie strace und tcpdump vertraut sind.
23 - 2. HAProxy-Architektur
HAProxy ist ein ereignisgesteuerter, nicht blockierender Daemon mit mehreren Threads. Er plant sämtliche Aktivitäten über Ereignis-Multiplexing, statt die Umschaltung zwischen mehreren Aktivitäten dem System zu überlassen. Meist läuft er als einzelner Prozess. “ps aux” zeigt daher nur einen “haproxy”-Prozess an, außer während eines unterbrechungsfreien Neuladens, wenn ein älterer Prozess seine Arbeit parallel zum neuen beendet. Seine Aktivitäten lassen sich somit jederzeit leicht mit strace verfolgen. Um die verfügbaren Prozessoren zu nutzen, startet haproxy standardmäßig für jeden Prozessor, auf dem er laufen darf, einen Worker-Thread. Sofern nicht ausdrücklich anders konfiguriert, wird der eingehende Datenverkehr auf alle diese Threads verteilt, die dieselbe Ereignisschleife ausführen. Abhängigkeiten zwischen Threads werden sorgfältig auf das notwendige Minimum begrenzt, um eine annähernd lineare Skalierung zu erreichen. Das bedeutet unter anderem, dass eine bestimmte Verbindung von einem einzigen Thread bedient wird. Um die gesamte verfügbare Rechenleistung auszunutzen, müssen daher mindestens so viele Verbindungen wie Threads vorhanden sein, was fast immer gegeben ist.
HAProxy ist so ausgelegt, dass er sich beim Start in einer chroot-Umgebung isoliert, in der keinerlei Dateisystemzugriffe möglich sind. Dies gilt auch für seine Bibliotheken, etwa libc und libssl. Eine unmittelbare Folge ist, dass ein laufender Prozess keine Konfigurationsdatei neu laden kann, um Änderungen anzuwenden. Stattdessen wird ein neuer Prozess mit der aktualisierten Konfigurationsdatei gestartet. Weniger offensichtlich ist etwa, dass Zeitzonen- oder Resolver-Dateien, auf die libc zur Laufzeit zugreifen könnte, nicht gefunden werden. Das sollte allerdings normalerweise nicht vorkommen, da sie nach dem Start nicht mehr benötigt werden. Eine nützliche Folge dieses Prinzips ist, dass der HAProxy-Prozess vollständig zustandslos ist und nach seinem Beenden keine Aufräumarbeiten nötig sind. Jede funktionierende Methode zum Beenden des Prozesses ist daher geeignet.
HAProxy schreibt keine Protokolldateien. Er verwendet das standardisierte syslog-Protokoll, um Protokollmeldungen an einen entfernten Server zu senden, der sich häufig auf demselben System befindet.
Für Zeitüberschreitungen verwendet HAProxy eine interne Uhr, die aus der Systemzeit abgeleitet wird und unerwartete Abweichungen korrigiert. Dazu begrenzt er die Wartezeit auf ein Ereignis in poll() und misst die tatsächlich verstrichene Zeit. In der Praxis wartet er nie länger als eine Sekunde. Deshalb zeigt strace bei einem vollständig untätigen Prozess regelmäßig Aufrufe von poll() oder einer seiner Varianten, jeweils zwischen zwei gettimeofday()-Aufrufen. Diese sind normal, völlig harmlos und so kostengünstig, dass ihre Last auf Systemebene nicht messbar ist. Es handelt sich also nicht um eine Auffälligkeit. Beispiel:
HAProxy ist ein TCP-Proxy, kein Router. Er verarbeitet bestehende, vom Kernel validierte Verbindungen, jedoch weder Pakete beliebiger Art noch Sockets in anderen Zuständen, etwa SYN_RECV oder TIME_WAIT. Deren Vorhandensein kann ihn allerdings daran hindern, sich an einen Port zu binden. Das Annehmen eingehender und das Herstellen ausgehender Verbindungen übernimmt das System. Deshalb gibt es keinen Zusammenhang zwischen den Paketen auf den beiden Seiten einer weitergeleiteten Verbindung: Größe, Anzahl und sogar Adressfamilie können unterschiedlich sein. Da eine Verbindung nur über einen Socket im Zustand LISTEN angenommen werden kann, sind alle Sockets, auf denen HAProxy lauscht, mit “netstat” zur Anzeige lauschender Sockets sichtbar. Beispiel:
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1629/sshd tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2847/haproxy tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 2847/haproxy
24 - 3. HAProxy starten
HAProxy wird durch Aufruf des Programms “haproxy” mit mehreren Befehlszeilenargumenten gestartet. Die Syntax lautet:
Dabei steht [<options>]* für eine beliebige Anzahl von Optionen. Eine Option beginnt immer mit ‘-’, gefolgt von einem oder mehreren Buchstaben und gegebenenfalls einem oder mehreren weiteren Argumenten. Ohne Optionen zeigt HAProxy die Hilfe mit einer Übersicht der unterstützten Optionen an. Die verfügbaren Optionen können je nach Betriebssystem leicht variieren. Viele davon entsprechen einer Einstellung im Abschnitt “global”. In diesem Fall hat die Befehlszeile immer Vorrang vor der Konfigurationsdatei. So lassen sich Einstellungen schnell erzwingen, ohne Konfigurationsdateien zu ändern. Folgende Optionen sind derzeit verfügbar:
-- <cfgfile>*
Alle Argumente nach “–” sind Pfade zu Konfigurationsdateien oder -verzeichnissen, die in der angegebenen Reihenfolge geladen und verarbeitet werden. Dies ist vor allem nützlich, wenn die Shell zahlreiche numerisch geordnete Dateien laden soll. Siehe auch “-f”. Der Unterschied zwischen “–” und “-f” besteht darin, dass “-f” vor jedem Dateinamen stehen muss, während ein einzelnes “–” vor allen Dateinamen genügt. Beide Optionen können gemeinsam verwendet werden; die Reihenfolge in der Befehlszeile gilt weiterhin. Werden mehrere Dateien angegeben, muss jede Datei an einer Abschnittsgrenze beginnen. Ihr erstes Schlüsselwort muss also etwa “global”, “defaults”, “peers”, “listen”, “frontend” oder “backend” sein. Eine Datei kann beispielsweise nicht nur eine Serverliste enthalten.
-f <cfgfile|cfgdir>
Fügt <cfgfile> zur Liste der zu ladenden Konfigurationsdateien hinzu. Ist <cfgdir> ein Verzeichnis, werden alle darin enthaltenen Dateien (und nur Dateien) in lexikalischer Reihenfolge mit LC_COLLATE=C hinzugefügt. Berücksichtigt werden ausschließlich nicht versteckte Dateien, deren Name also nicht mit “.” beginnt, mit der Endung “.cfg”. Konfigurationsdateien werden in der angegebenen Reihenfolge geladen und verarbeitet. Die Option kann mehrfach angegeben werden, um mehrere Dateien zu laden. Siehe auch “–”. Der Unterschied zwischen “–” und “-f” besteht darin, dass “-f” vor jedem Dateinamen stehen muss, während ein einzelnes “–” vor allen Dateinamen genügt. Beide Optionen können gemeinsam verwendet werden; die Reihenfolge in der Befehlszeile gilt weiterhin. Werden mehrere Dateien angegeben, muss jede Datei an einer Abschnittsgrenze beginnen. Ihr erstes Schlüsselwort muss also etwa “global”, “defaults”, “peers”, “listen”, “frontend” oder “backend” sein. Eine Datei kann beispielsweise nicht nur eine Serverliste enthalten.
-C <dir>
Wechselt vor dem Laden der Konfigurationsdateien in das Verzeichnis <dir>. Dies ist bei relativen Pfaden nützlich. Vorsicht bei Platzhaltern nach “–”: Diese werden bereits vor dem Start von haproxy durch die Shell ersetzt.
-D
Startet als Daemon. Nach dem Fork löst sich der Prozess vom aktuellen Terminal; Fehler werden dort dann nicht mehr ausgegeben. Die Option entspricht dem Schlüsselwort “daemon” im Abschnitt “global” der Konfiguration. Es wird empfohlen, sie in jedem Init-Skript grundsätzlich zu erzwingen, damit eine fehlerhafte Konfiguration den Systemstart nicht verhindert.
-L <name>
Ändert den lokalen Peer-Namen, der standardmäßig dem lokalen Hostnamen entspricht, in <name>. Dies wird nur für die Peer-Replikation verwendet. In der Konfigurationsdatei kann der Peer-Name mit der Variablen $HAPROXY_LOCALPEER referenziert werden.
-N <limit>
Setzt den Standardwert für maxconn je Proxy auf <limit> statt auf den eingebauten Standardwert (gewöhnlich 2000). Nur zur Fehleranalyse nützlich.
-V
Aktiviert den ausführlichen Ausgabemodus und deaktiviert damit den stillen Modus. Hebt die Wirkung von “-q” oder “quiet” auf.
-W
Master-Worker-Modus. Entspricht dem Schlüsselwort “master-worker” im Abschnitt “global” der Konfiguration. Dieser Modus startet einen Master, der die Worker überwacht. HAProxy lässt sich dann unmittelbar durch Senden von SIGUSR2 an den Master neu laden. Der Master-Worker-Modus ist sowohl mit dem Vordergrund- als auch mit dem Daemon-Modus kompatibel. Er wird für den Betrieb mit mehreren Prozessen und mit systemd empfohlen.
-Ws
Master-Worker-Modus mit Unterstützung für systemd-Dienste vom Typ notify.
-4
Zwingt DNS-Resolver, ausschließlich IPv4-Adressen (“A”-Records) abzufragen und zu akzeptieren. Dies kann bei Schwierigkeiten in Umgebungen ohne durchgängige Dual-Stack-Konnektivität helfen. Die Option überschreibt die globale Direktive “dns-accept-family” und erzwingt dafür “ipv4”.
-c
Prüft nur die Konfigurationsdateien und beendet sich, bevor versucht wird, Sockets zu binden. Der Exit-Status ist null, wenn alles OK ist, und ungleich null, wenn ein Fehler auftritt. Auf vorhandene Warnungen wird hingewiesen. Standardmäßig gibt diese Option keine Erfolgsmeldung aus. Zusammen mit “-V” wird bei Erfolg “Configuration file is valid” ausgegeben.
Skripte müssen den Exit-Status verwenden, um den Erfolg des Befehls festzustellen.
-cc
Wertet eine Bedingung aus, wie sie in einem bedingten Konfigurationsblock verwendet wird. Der Exit-Status ist null, wenn die Bedingung wahr ist, 1, wenn sie falsch ist, und 2, wenn ein Fehler auftritt.
-d
Aktiviert den Debug-Modus. Dieser deaktiviert den Daemon-Modus, hält den Prozess im Vordergrund und zeigt eingehende sowie ausgehende Ereignisse an. Er darf niemals in einem Init-Skript verwendet werden.
-dA[file]
Schreibt unmittelbar nach dem vollständigen Laden der Konfiguration alle beim Start erkannten Abhängigkeiten als tar-Archiv in die angegebene Datei. Dies entspricht “set-dumpable libs”, legt die Bibliotheken aber in einer Datei ab, statt sie im Speicher zu halten. Nach einem Core-Dump können damit alle nötigen Bibliotheken für Entwickler bereitgestellt werden, damit sie den Core-Dump auswerten können. Die Option ist möglicherweise nicht auf allen Betriebssystemen verfügbar. Es wird dringend empfohlen, sie mit den regulären Konfigurationsdateien zu verwenden. Bei manueller Verwendung kann zusätzlich “-c” angegeben werden, damit haproxy unmittelbar nach der Ausgabe beendet wird, ohne zu starten. Beispiel:
-dC[key]
Gibt die Konfigurationsdatei aus. Dies geschieht nach der Zerlegung der Zeilen in Tokens; Kommentare werden daher entfernt und die Einrückung vereinheitlicht. Wird ein Schlüssel ungleich null angegeben, werden Zeilen vor sensiblen oder vertraulichen Feldern abgeschnitten. Kennungen und Adressen werden mit diesem Schlüssel gehasht ausgegeben, nach demselben Algorithmus wie im anonymisierten Modus der CLI. Die Ausgabe kann somit sicher mit einem Entwickler geteilt werden, der sie zur Untersuchung eines mit demselben Schlüssel anonymisierten Dumps benötigt. Siehe auch den CLI-Befehl “set anon”.
-dD
Aktiviert den Diagnosemodus. Dieser gibt zusätzliche Warnungen zu verdächtigen Konfigurationsanweisungen aus. Einige Ausgaben verhindern im Modus “zero-warning” den Start.
Solche Diagnosen sollen Menschen auf mögliche verborgene Probleme aufmerksam machen, die durchaus beabsichtigt sein können. Sie können sich auch innerhalb eines stabilen Zweigs und zwischen Rechnern mit exakt gleicher Konfiguration ändern. Daher werden sie regelmäßig gültige Anweisungen als verdächtig melden und sollten nur zusammen mit “-c” für eine eingehendere Diagnose verwendet werden. Ihre Ergebnisse dürfen niemals dazu verwendet werden, den Start eines Dienstes zu verhindern; dies geschieht bei Kombination mit “zero-warning” oder “-dW”.
-dF
Deaktiviert die schnelle Datenweiterleitung. Dieser Mechanismus optimiert die Weiterleitung, indem Daten direkt von einer Seite zur anderen gelangen, ohne den Stream aufzuwecken. Mit dieser Option lässt sich die Optimierung abschalten. Dabei wird auch jegliches TCP-Splicing im Kernel deaktiviert. Der Befehl ist nicht für den regulären Betrieb vorgesehen; Entwickler empfehlen ihn gewöhnlich nur bei komplexen Fehleranalysen.
-dG
Deaktiviert getaddrinfo() zur Auflösung von Hostnamen in Adressen. Dies kann helfen, wenn getaddrinfo() vermutlich nicht wie erwartet arbeitet. Die Option wurde eingeführt, weil auf verschiedenen Systemen zahlreiche fehlerhafte getaddrinfo()-Implementierungen existieren, die schwer zu untersuchende Auffälligkeiten verursachen.
-dI
Aktiviert unsicheres Forken. Dies entspricht “insecure-fork-wanted” im globalen Abschnitt. Es kann nützlich sein, wenn alle Regressionstests mit ASAN ausgeführt werden, die addr2line per Fork starten müssen, um Adressen aufzulösen.
-dK<class[,class]*>
Gibt die Liste der registrierten Schlüsselwörter jeder Klasse aus. Die verfügbaren Klassen zeigt “-dKhelp”. Mit “-dKall” lassen sich alle Klassen ausgeben; alternativ kann eine durch Kommas getrennte Auswahl der in der Hilfe genannten Klassen angegeben werden. Das Ausgabeformat hängt von der Schlüsselwortklasse ab: “cfg” zeigt bekannte Konfigurationsschlüsselwörter in einem der Konfigurationsdatei ähnlichen Format, während “smp” Sample-Abruffunktionen mit einer vorangestellten Kompatibilitätsmatrix für die jeweiligen Regelsätze ausgibt. Für Menschen ist diese Ausgabe selten unmittelbar brauchbar. Externe Werkzeuge können damit jedoch neue Schlüsselwörter an bestimmten Stellen erkennen, um Dokumentation, Syntaxhervorhebungsdateien, Konfigurationsparser, APIs usw. automatisch zu aktualisieren. Das Ausgabeformat kann sich im Laufe der Zeit etwas ändern. Es wird daher ausdrücklich empfohlen, damit hauptsächlich Unterschiede zu früheren Archiven zu erkennen. Nicht alle Schlüsselwörter sind aufgeführt: Viele gab es schon vor den verschiedenen Systemen zur Schlüsselwortregistrierung und erscheinen dort nicht. Da neue Schlüsselwörter aber ausschließlich über die modernen Mechanismen hinzugefügt werden, kann recht zuverlässig davon ausgegangen werden, dass sich Erweiterungen der Sprache mit dieser Ausgabe gut erkennen lassen. Die Schlüsselwörter werden erst nach vollständiger Auswertung der Konfiguration ausgegeben, sodass auch dynamisch erzeugte Schlüsselwörter erscheinen können. Um die Ausgabe zu erzeugen und anschließend zu beenden, eignet sich eine stille Konfigurationsprüfung mit einer vorhandenen Konfiguration:
Ist keine Konfigurationsdatei verfügbar, lassen sich mit “-f /dev/null” ebenfalls alle Standardschlüsselwörter ausgeben. Da dann kein Listener vorhanden ist, ist der Rückgabestatus jedoch ungleich null und muss ignoriert werden.
-dL
Gibt die Liste der dynamisch eingebundenen Bibliotheken aus, die am Ende der Konfigurationsverarbeitung geladen sind. Sie enthält gewöhnlich auch indirekte Abhängigkeiten, etwa aus Lua-Code geladene Bibliotheken, sowie die ausführbare Datei selbst. Das Ausgabeformat lässt sich ausreichend einfach bereinigen, um daraus unmittelbar ein tar-Archiv aller Abhängigkeiten zu erstellen. Da die Option den Programmstart nicht beendet, wird empfohlen, sie nur zusammen mit “-c” und “-q” zu verwenden. Dann erscheint ausschließlich die Liste der geladenen Objekte, bei einem Fehler nichts. Wenn ein solches Paket zur Analyse einer Core-Datei bereitgestellt wird, ist außerdem zu beachten, dass die meisten Bibliotheken symbolische Links sind. Beim Erstellen des Archivs muss deren Zielinhalt aufgenommen werden:
Beim Start im ausführlichen Modus (-V) werden zusätzlich die Adressbereiche der dynamisch eingebundenen Bibliotheken aufgelistet, sofern nicht der stille Modus (-q) verwendet wird.
-dM[<byte>[,]][help|options,...]
Erzwingt das Füllen von Speicher mit einem Prüfmuster und/oder ändert weitere Optionen zur Speicherfehleranalyse. Dabei wird jeder mit malloc() oder pool_alloc() reservierte Speicherbereich mit <byte> gefüllt, bevor er an den Aufrufer zurückgegeben wird. Ohne Angabe von <byte> gilt der Standardwert 0x50 (‘P’). Dies verlangsamt den Betrieb etwas, hilft aber dabei, Fehler durch fehlende Initialisierung im Code zuverlässig auszulösen, die sonst zufällige Abstürze verursachen. -dM0 macht dabei aus jedem malloc() faktisch ein calloc(). Wenn ein Fehler mit dieser Option auftritt oder verschwindet, liegt in jedem Fall ein Fehler in haproxy vor; bitte melden Sie ihn. Weitere Optionen können allein oder nach einem Komma hinter dem Byte-Wert angegeben werden. Die besondere Option “help” listet die derzeit unterstützten Optionen und ihre aktuellen Werte auf. Jede Debug-Option kann ausdrücklich ein- oder ausgeschaltet werden. Die günstigsten Einstellungen werden gewöhnlich bereits beim Build abhängig vom Betriebssystem gewählt und brauchen nicht angepasst zu werden, sofern kein Entwickler dies empfiehlt. Unterstützt werden folgende Debug-Optionen (ein/aus):
- fail / no-fail:
- no-merge / merge:
- cold-first / hot-first:
- integrity / no-integrity:
- backup / no-backup:
- no-global / global:
- no-cache / cache:
- caller / no-caller:
- tag / no-tag:
- poison / no-poison:
-dR
Deaktiviert die Socket-Option SO_REUSEPORT für lauschende Ports. Dies entspricht dem Schlüsselwort “noreuseport” im Abschnitt “global”. Die Option kann beim Betrieb mit mehreren Threads eingesetzt werden, wenn sich Probleme mit der Lastverteilung zwischen den haproxy-Threads zeigen; diese lassen sich mit top beobachten.
-dS
Deaktiviert den Systemaufruf splice(). Dies entspricht dem Schlüsselwort “nosplice” im Abschnitt “global”. Die Option kann helfen, wenn splice() vermutlich fehlerhaft arbeitet oder Leistungsprobleme verursacht, oder wenn die weitergeleiteten Daten mit strace sichtbar gemacht werden sollen. Bei Verwendung von splice() erscheinen sie dort nicht.
-dT
Deaktiviert ktls. Dies entspricht dem Schlüsselwort “noktls” im Abschnitt “global”. Die Option ist hauptsächlich bei einem vermuteten Fehler im Zusammenhang mit ktls nützlich.
-dV
Deaktiviert die serverseitige SSL-Prüfung. Dies entspricht “ssl-server-verify none” im Abschnitt “global”. Die Option ist nützlich, um Probleme aus dem Produktivbetrieb außerhalb der Produktivumgebung nachzustellen. Niemals in einem Init-Skript verwenden, da sie die Sicherheit der SSL-Verbindungen zu den Servern verringert.
-dW
Mit dieser Option verweigert haproxy den Start, sobald bei der Verarbeitung der Konfiguration eine Warnung ausgegeben wurde. Dies hilft, subtile Fehler zu erkennen und die Konfiguration sauber und über Versionsgrenzen hinweg portabel zu halten. Bei manuell verwalteten Konfigurationen wird die Option in Dienstskripten empfohlen. Bei generierten Konfigurationen, die häufig mehr Warnungen erzeugen, wird dagegen von ihr abgeraten. Zusammen mit “-c” führen Warnungen bei der Konfigurationsprüfung zu einem Fehlschlag. Dies entspricht der globalen Option “zero-warning”.
-dZ
Deaktiviert die Datenweiterleitung im Modus “zero-copy”. Dies entspricht dem Schlüsselwort “tune.disable-zero-copy-forwarding” im Abschnitt “global”. Die Option kann bei Datenverlust oder Problemen mit der Datenintegrität helfen oder dann, wenn die weitergeleiteten Daten mit strace sichtbar gemacht werden sollen, da sie auch jegliches TCP-Splicing im Kernel deaktiviert.
-db
Deaktiviert den Hintergrund- und Mehrprozessmodus. Der Prozess bleibt im Vordergrund. Dies wird hauptsächlich bei der Entwicklung oder kleinen Tests verwendet, da Ctrl-C zum Beenden des Prozesses genügt. Niemals in einem Init-Skript verwenden.
-dc
Aktiviert die Fehleranalyse für die CPU-Affinität. Vor dem Start werden die ausgewählten und ausgeschlossenen CPUs sowie deren Topologie ausgegeben.
-de
Deaktiviert den Poller “epoll”. Dies entspricht dem Schlüsselwort “noepoll” im Abschnitt “global”. Die Option ist hauptsächlich bei einem vermuteten Fehler dieses Pollers nützlich. Auf Systemen mit epoll-Unterstützung wird gewöhnlich auf den Poller “poll” zurückgegriffen.
-dk
Deaktiviert den Poller “kqueue”. Dies entspricht dem Schlüsselwort “nokqueue” im Abschnitt “global”. Die Option ist hauptsächlich bei einem vermuteten Fehler dieses Pollers nützlich. Auf Systemen mit kqueue-Unterstützung wird gewöhnlich auf den Poller “poll” zurückgegriffen.
-dp
Deaktiviert den Poller “poll”. Dies entspricht dem Schlüsselwort “nopoll” im Abschnitt “global”. Die Option ist hauptsächlich bei einem vermuteten Fehler dieses Pollers nützlich. Auf Systemen mit poll-Unterstützung wird gewöhnlich auf den Poller “select” zurückgegriffen. Dieser lässt sich nicht deaktivieren und ist auf 1024 Dateideskriptoren begrenzt.
-dr
Ignoriert Fehler bei der Auflösung von Serveradressen. Beim Prüfen einer Konfiguration außerhalb der Produktivumgebung fehlen sehr häufig dieselben Resolver, sodass die Auflösung von Serveradressen fehlschlägt. Dies erschwert Konfigurationstests. Die Option hängt für alle Server die Methode “none” an die Liste der Adressauflösungsmethoden an. So wird der Start auch dann nicht unterbrochen, wenn libc eine Adresse nicht auflösen kann.
-dt [<trace_desc>,...]
Aktiviert Traces auf stderr. Ohne Argument werden alle Trace-Quellen auf der Stufe error aktiviert. Damit lassen sich insbesondere Protokollverstöße von Clients oder Servern erkennen. Ein optionales Argument kann eine durch ‘,’ getrennte Liste verschiedener Trace-Konfigurationen enthalten. Jedes Element aktiviert eine oder alle Trace-Quellen. Zusätzlich können je Element Stufe und Ausführlichkeit angegeben werden, getrennt vom Trace-Namen und voneinander durch ‘:’. Wird ein ungültiger Name für Ausführlichkeit oder Stufe eingegeben, erscheint die Liste der verfügbaren Schlüsselwörter. Beispielsweise kann für jedes Feld zunächst ‘help’ angegeben werden, um diese Liste einzusehen.
-dv
Deaktiviert den Poller “evports”. Dies entspricht dem Schlüsselwort “noevports” im Abschnitt “global”. Die Option ist hauptsächlich bei einem vermuteten Fehler dieses Pollers nützlich. Auf Systemen mit Event-Ports (von Solaris 10 und neuer abgeleitetes SunOS) wird gewöhnlich auf den Poller “poll” zurückgegriffen.
-m <limit>
Begrenzt den für Prozessdaten reservierbaren Speicher auf <limit> Megabyte. Je nach Speicherbedarf im Normalbetrieb können dadurch Verbindungen abgewiesen werden oder Verzögerungen entstehen. Die Option dient hauptsächlich dazu, den haproxy-Prozess unter begrenztem Ressourcenverbrauch zu betreiben. Der Speicher wird nicht zwischen haproxy-Prozessen geteilt. Ein mit fork() erzeugter Kindprozess erbt die Ressourcengrenzen seines Elternprozesses. Im Master-Worker-Modus gilt diese Speichergrenze daher jeweils getrennt für den Master und den von ihm geforkten Worker-Prozess.
-n <limit>
Setzt die Verbindungsgrenze je Prozess auf <limit>. Dies entspricht dem Schlüsselwort “maxconn” im globalen Abschnitt, hat aber Vorrang davor. Damit lässt sich schnell eine niedrigere Grenze erzwingen, um einen Dienstausfall auf Systemen mit zu niedrigen Ressourcengrenzen zu vermeiden.
-p <file>
Schreibt beim Start die PIDs aller Prozesse in <file>. Dies entspricht dem Schlüsselwort “pidfile” im Abschnitt “global”. Die Datei wird vor dem Eintritt in die chroot-Umgebung und nach dem durch “-C” ausgelösten chdir() geöffnet. Jede PID steht in einer eigenen Zeile.
-q
Aktiviert den Modus “quiet”, der die Ausgabe von Meldungen unterdrückt. Zusammen mit “-c” kann damit lediglich geprüft werden, ob eine Konfigurationsdatei gültig ist.
-S <bind>[,bind_options...]
Bindet im Master-Worker-Modus eine Master-CLI, über die auf alle Prozesse zugegriffen werden kann, sowohl auf laufende als auch auf auslaufende. Aus Sicherheitsgründen wird empfohlen, die Master-CLI an einen lokalen UNIX-Socket zu binden. Die Bind-Optionen entsprechen denen des Schlüsselworts “bind” in der Konfigurationsdatei; die Wörter werden dabei durch Kommas statt durch Leerzeichen getrennt.
Dieser Socket kann bei einem unterbrechungsfreien Neuladen nicht dazu verwendet werden, die lauschenden Sockets eines alten Prozesses zu übernehmen.
-sf <pid>*
Sendet nach abgeschlossenem Start das Signal “finish” (SIGUSR1) an ältere Prozesse, damit sie ihre laufenden Arbeiten abschließen und sich beenden. <pid> ist eine Liste der zu benachrichtigenden PIDs, eine je Argument. Die Liste endet mit jeder Option, die mit “-” beginnt. Eine leere PID-Liste ist zulässig. Sie kann daher während der Ausführung aus dem Ergebnis eines Befehls wie “pidof” oder “pgrep” erzeugt werden.
-st <pid>*
Sendet nach abgeschlossenem Start das Signal “terminate” (SIGTERM) an ältere Prozesse, um sie sofort zu beenden, ohne ihre laufenden Arbeiten abzuschließen. <pid> ist eine Liste der zu benachrichtigenden PIDs, eine je Argument. Die Liste endet mit jeder Option, die mit “-” beginnt. Eine leere PID-Liste ist zulässig. Sie kann daher während der Ausführung aus dem Ergebnis eines Befehls wie “pidof” oder “pgrep” erzeugt werden.
-v
Gibt Version und Build-Datum aus.
-vv
Zeigt Version, Build-Optionen, Bibliotheksversionen und verwendbare Poller an. Diese Ausgabe wird bei Fehlermeldungen grundsätzlich angefordert.
-x <unix_socket>
Verbindet sich mit dem angegebenen Socket und versucht, die lauschenden Sockets des alten Prozesses zu übernehmen und zu verwenden, statt neue zu binden. Unter Linux hilft dies, beim Neuladen der Konfiguration keine neue Verbindung zu verpassen.
Ohne Master-Worker-Modus muss diese Fähigkeit in der Konfiguration mit “expose-fd listeners” für den Statistik-Socket aktiviert werden.
Im Master-Worker-Modus ist “expose-fd listeners” nicht nötig. Beim Neuladen verwendet der Master diese Option automatisch mit der Syntax “sockpair@”. Damit verbindet er sich direkt mit einem Worker, ohne einen in der Konfiguration deklarierten Statistik-Socket zu nutzen. Zum Deaktivieren kann -x /dev/null übergeben werden.
Eine sichere Methode zum Starten von HAProxy aus einer Init-Datei besteht darin, den Daemon-Modus zu erzwingen, vorhandene PIDs in einer PID-Datei abzulegen und ältere Prozesse anhand dieser Datei zum Abschließen ihrer Arbeit und anschließenden Beenden aufzufordern:
Ist die Konfiguration auf wenige bestimmte Dateien aufgeteilt, etwa getrennt nach tcp und http, wird die Option “-f” empfohlen:
Ist die Zahl der Dateien unbekannt, etwa bei kundenspezifischen Dateien, wird empfohlen, ihre Namen mit einer Folgenummer fester Breite zu beginnen und sie mit “–” zu laden, gegebenenfalls nach dem Laden von Standardeinstellungen:
Gelegentlich schlägt der Start aus irgendeinem Grund fehl. Dann sollte geprüft werden, ob die aufgerufene HAProxy-Version der erwarteten entspricht und die benötigten Funktionen wie SSL, PCRE, Komprimierung oder Lua unterstützt. Dies lässt sich mit “haproxy -vv” prüfen. Die Ausgabe enthält wichtige Angaben wie bestimmte Build-Optionen, das Zielsystem und die Versionen der verwendeten Bibliotheken. Sie wird auch bei Fehlermeldungen grundsätzlich angefordert:
HAProxy version 1.6-dev7-a088d3-4 2015/10/08 Copyright 2000-2015 Willy Tarreau willy@haproxy.org
Build options:
Default settings:
Encrypted password support via crypt(3): yes Built with zlib version: 1.2.6 Compression algorithms supported: identity(“identity”), deflate(“deflate”), \ raw-deflate(“deflate”), gzip(“gzip”) Built with OpenSSL version: OpenSSL 1.0.1o 12 Jun 2015 Running on OpenSSL version: OpenSSL 1.0.1o 12 Jun 2015 OpenSSL library supports TLS extensions: yes OpenSSL library supports SNI: yes OpenSSL library supports prefer-server-ciphers: yes Built with PCRE version: 8.12 2011-01-15 PCRE library supports JIT: no (USE_PCRE_JIT not set) Built with Lua version: Lua 5.3.1 Built with transparent proxy support using: IP_TRANSPARENT IP_FREEBIND
Available polling systems:
Total: 3 (3 usable), will use epoll.
Auch ohne Entwicklerkenntnisse lassen sich hier folgende wichtige Angaben prüfen:
- die Version
1.6-dev7-a088d3-4 bedeutet im obigen Beispiel, dass der Code auf Commit-ID “a088d3” steht, dem 4. Commit nach der offiziellen Version “1.6-dev7”. Version 1.6-dev7 würde als “1.6-dev7-8c1ad7” erscheinen. Entscheidend ist hier “1.6-dev7”: die 7. Entwicklungsversion der späteren Version 1.6. Eine Entwicklungsversion eignet sich nicht für den Produktivbetrieb, außer wenn genau bekannt ist, was man tut. Eine stabile Version wird mit 3 Zahlen angezeigt, etwa “1.5.14-16f863”. Dies bezeichnet den 14. Korrekturstand zu Version 1.5 und ist eine für den Produktivbetrieb geeignete Version.
- das Veröffentlichungsdatum
2015/10/08. Das Datum folgt dem universellen Format Jahr/Monat/Tag. Hier bedeutet dies den 8. Oktober 2015. Stabile Versionen erscheinen alle paar Monate, anfangs alle 1-2 Monate und bei sehr ausgereiften Produkten mitunter erst nach 6 Monaten. Ein altes Datum deutet daher darauf hin, dass wahrscheinlich mehrere inzwischen behobene Fehler oder Sicherheitsprobleme vorliegen. Ein Blick auf die offizielle Website kann sich deshalb lohnen.
- Build-Optionen
Sie sind für Anwender relevant, die ihre Pakete selbst bauen, und können unerwartetes Verhalten erklären. Die obige Entwicklungsversion wurde beispielsweise für Linux 2.6.28 oder neuer und eine generische CPU ohne CPU-spezifische Optimierungen erstellt. Außerdem fehlt jede Codeoptimierung (-O0), sodass die Leistung schlecht ausfallen wird.
- Bibliotheksversionen
Die zlib-Version wird aus der Bibliothek selbst ermittelt. zlib gilt allgemein als sehr stabil und benötigt fast nie ein Upgrade. OpenSSL meldet zwei Versionen: die beim Build verwendete und die aktuell im System verwendete. Diese können sich im letzten Buchstaben, niemals aber in den Zahlen unterscheiden. Auch das Build-Datum wird ausgegeben, da die meisten OpenSSL-Fehler Sicherheitsprobleme darstellen und ernst genommen werden müssen. Diese Bibliothek muss daher unbedingt aktuell gehalten werden. Eine 4 Monate alte Version ist hier höchst verdächtig; offenbar wurde ein Update versäumt. PCRE bietet sehr schnelle reguläre Ausdrücke und wird dringend empfohlen. Manche Erweiterungen wie JIT sind nicht in allen Versionen vorhanden und noch jung, weshalb einige Anwender beim Build darauf verzichten. Deshalb wird auch dieser Build-Status ausgegeben. Bei der Skriptsprache Lua erwartet HAProxy Version 5.3, die noch sehr jung ist, da sie kurz vor HAProxy 1.6 veröffentlicht wurde. Es ist wichtig, auf der Lua-Website nach Korrekturen für diesen Zweig zu sehen.
- Die verfügbaren Abfragesysteme beeinflussen die Skalierbarkeit des Prozesses, wenn
mehr als etwa tausend gleichzeitige Verbindungen verarbeitet werden. Sie stehen nur bereit, wenn beim Build das richtige System in der Variablen TARGET angegeben wurde. Unter Linux wird der Mechanismus “epoll” dringend empfohlen, unter BSD kqueue. Fehlen diese, wird poll() oder sogar select() verwendet, was bei vielen Verbindungen zu hoher CPU-Auslastung führt.
25 - 4. HAProxy stoppen und neu starten
HAProxy unterstützt ein geordnetes und ein sofortiges Stoppen. Beim sofortigen Stoppen genügt das Signal SIGTERM an den haproxy-Prozess: Er beendet sich unmittelbar und schließt alle bestehenden Verbindungen. Das geordnete Stoppen wird durch SIGUSR1 ausgelöst. Dabei gibt HAProxy nur die lauschenden Ports frei und verarbeitet die bestehenden Verbindungen weiter, bis sie geschlossen werden. Sobald die letzte Verbindung geschlossen ist, beendet sich der Prozess.
Das Dienstverwaltungsskript verwendet das sofortige Stoppen für die Aktionen “stop” und “restart”. Das geordnete Stoppen wird bei “reload” eingesetzt, um eine neue Konfiguration möglichst ohne Unterbrechung in einem neuen Prozess zu laden.
Beide Signale kann der neue haproxy-Prozess beim Neuladen oder Neustarten selbst senden. So werden sie zum spätestmöglichen Zeitpunkt und nur dann gesendet, wenn es unbedingt erforderlich ist. Dafür dienen die Optionen “-st” für sofortiges und “-sf” für geordnetes Stoppen.
Im Master-Worker-Modus muss zum Neuladen der Konfiguration kein neuer haproxy-Prozess gestartet werden. Der Master-Prozess reagiert auf SIGUSR2, indem er sich selbst mit dem Parameter -sf und den nachfolgenden PIDs der Worker erneut ausführt. Anschließend liest der Master die Konfigurationsdatei ein und erzeugt durch Fork neue Worker.
Um die Verwendung dieser Signale zu verstehen, ist der gesamte Neustartablauf wichtig.
Zunächst läuft bereits ein haproxy-Prozess. Die Administration fordert mit einem systemspezifischen Befehl wie “/etc/init.d/haproxy reload” an, die neue Konfigurationsdatei zu übernehmen. Das Dienstskript, also /etc/init.d/haproxy oder dessen Entsprechung, prüft zuerst mit “haproxy -c”, ob die Datei korrekt eingelesen werden kann. Danach versucht es, haproxy mit dieser Konfiguration und “-st” oder “-sf” zu starten.
HAProxy versucht nun, sich an alle lauschenden Ports zu binden. Bei einem schwerwiegenden Fehler, etwa einer auf dem System nicht vorhandenen Adresse oder fehlenden Berechtigungen, beendet sich der Prozess mit einem Fehler. Scheitert eine Socket-Bindung, weil ein Port bereits belegt ist, sendet der Prozess zunächst SIGTTOU an alle in der PID-Liste von “-st” oder “-sf” angegebenen Prozesse. Dieses sogenannte Pausensignal weist alle bestehenden haproxy-Prozesse an, vorübergehend nicht mehr auf ihren Ports zu lauschen, damit der neue Prozess erneut versuchen kann, sich zu binden. Der alte Prozess verarbeitet währenddessen die bestehenden Verbindungen weiter. Scheitert die Bindung weiterhin, etwa weil ein anderer Daemon denselben Port verwendet, sendet der neue Prozess SIGTTIN an die alten Prozesse. Diese nehmen daraufhin ihren Betrieb wieder auf, als wäre nichts geschehen: Sie lauschen wieder auf den Ports und nehmen Verbindungen an. Dieses Verfahren ist systemabhängig und wird von manchen Betriebssystemen im Mehrprozessbetrieb möglicherweise nicht unterstützt.
Kann sich der neue Prozess erfolgreich an alle Ports binden, sendet er entweder SIGTERM für sofortiges Stoppen bei “-st” oder SIGUSR1 für geordnetes Stoppen bei “-sf” an alle alten Prozesse. Damit teilt er ihnen mit, dass er den Betrieb übernommen hat und sie sich entweder sofort oder nach Abschluss ihrer Arbeit beenden müssen.
Dabei gibt es zwei kurze Zeitfenster von jeweils wenigen Millisekunden, in denen unter hoher Last einzelne Verbindungsfehler auftreten können. Typischerweise wird pro Neuladen etwa 1 Fehler je 10000 neuer Verbindungen pro Sekunde beobachtet. Eine stark ausgelastete Website mit 30000 neuen Verbindungen pro Sekunde kann somit bei jedem Neuladen etwa 3 fehlgeschlagene Verbindungen aufweisen. Dies geschieht in folgenden zwei Situationen:
-
Kann sich der neue Prozess wegen des alten Prozesses nicht binden, muss er zunächst die Folge SIGTTOU+SIGTTIN durchlaufen. Bei einigen Dutzend Frontends dauert dies typischerweise etwa eine Millisekunde. Währenddessen sind manche Ports weder an den alten noch an den neuen Prozess gebunden. Auf Systemen mit der Socket-Option SO_REUSEPORT umgeht HAProxy dies: Der neue Prozess kann sich binden, ohne den alten zuvor zur Freigabe aufzufordern. Die meisten BSD-Systeme unterstützen dies seit sehr langer Zeit. Linux unterstützte es in Version 2.0 und entfernte es etwa mit 2.2 wieder; damals waren jedoch einige Patches verfügbar. Mit Kernel 3.9 wurde es erneut eingeführt. Bei einer höheren als der oben genannten Fehlerrate daher sicherstellen, dass der Kernel mindestens 3.9 verwendet oder die entsprechenden Patches rückportiert wurden, was weniger wahrscheinlich ist.
-
Wenn die alten Prozesse ihre lauschenden Ports schließen, verteilt der Kernel noch im Socket-Backlog wartende Verbindungen möglicherweise nicht neu. Unter hoher Last kann unmittelbar vor dem Schließen ein SYN-Paket eintreffen, woraufhin der Client ein RST-Paket erhält. In kritischen Umgebungen, die selbst einen einzigen Verbindungsabbruch nicht tolerieren, werden deshalb manchmal Firewall-Regeln eingesetzt, die SYN-Pakete während des Neuladens blockieren und den Client zur erneuten Übertragung zwingen. Das ist vollständig systemabhängig: Manche Systeme können andere Warteschlangen lauschender Sockets berücksichtigen und das RST vermeiden. Ein zweiter Fall betrifft ein ACK des Clients für einen lokalen Socket, der unmittelbar vor dem Schließen im Zustand SYN_RECV war. Dieses ACK führt zu einem RST-Paket, ohne dass der haproxy-Prozess bereits von der Verbindung weiß. Dieser Fall ist schwieriger zu vermeiden. Die genannten Firewall-Regeln helfen jedoch, wenn sie etwa eine Sekunde vor dem Neustart des Prozesses angewendet werden.
Bei der überwiegenden Mehrheit der Nutzer treten solche Verbindungsabbrüche nie auf, da ihre Last nicht ausreicht, um diese Race Conditions auszulösen. Auch bei den meisten Nutzern mit hohem Datenverkehr liegt die Fehlerrate noch deutlich innerhalb der üblichen Schwankungen, sofern ihre Systeme zumindest SO_REUSEPORT korrekt unterstützen.
26 - 5. Grenzen für Dateideskriptoren
Damit alle eingehenden Verbindungen erfolgreich bedient werden können, berechnet HAProxy beim Laden die Gesamtzahl der Dateideskriptoren, die der Prozess während seiner Laufzeit benötigt. Ein gewöhnlicher Unix-Prozess erhält standardmäßig meist 1024 Dateideskriptoren; ein privilegierter Prozess kann diese Grenze selbst erhöhen. Dies ist ein Grund, HAProxy als root zu starten und die Grenze von ihm anpassen zu lassen. Die Standardgrenze von 1024 Dateideskriptoren reicht ungefähr für 500 gleichzeitige Verbindungen. In die Berechnung gehen der globale Parameter maxconn, der die Gesamtzahl der Verbindungen pro Prozess begrenzt, die Anzahl der Listener, die Server mit aktiviertem Health Check, Agent-Checks, Peers, Protokollziele sowie gegebenenfalls weitere technische Anforderungen ein. Als grobe Schätzung lässt sich maxconn verdoppeln und um einige Dutzend ergänzen.
Ursprünglich konnte HAProxy diesen Wert nicht berechnen. Er musste über die Einstellung “ulimit-n” im Abschnitt global vorgegeben werden. Deshalb findet sich diese Einstellung auch heute noch in vielen Konfigurationen. Häufig war sie jedoch falsch berechnet. Beim Annähern an maxconn scheiterten dann Verbindungen, statt dass eingehende Verbindungen bis zur Verfügbarkeit der benötigten Ressourcen gedrosselt wurden. Deshalb ist es wichtig, alle aus sehr alten Versionen übernommenen “ulimit-n”-Einstellungen zu entfernen.
Schon für mäßige Last muss die Anzahl der Dateideskriptoren erhöht werden. Dabei sind einige Besonderheiten des Betriebssystems zu beachten. Das Polling-Verfahren select() ist auf 1024 Dateideskriptoren begrenzt. Unter Linux konnte es früher zwar mehr verarbeiten, doch einige Betriebssysteme liefern übermäßig restriktive SELinux-Richtlinien aus, die select() mit mehr als 1024 Dateideskriptoren verbieten. Um Laufzeitprobleme zu vermeiden, verweigert HAProxy in diesem Fall inzwischen den Start. Auf allen unterstützten Betriebssystemen steht poll() ohne diese Einschränkung zur Verfügung. Es wird automatisch gewählt; für eine funktionierende Konfiguration ist daher nichts zu tun. Mit zunehmender Anzahl von Dateideskriptoren wird poll() jedoch sehr langsam. HAProxy begrenzt die Auswirkungen durch Maßnahmen wie einen internen Dateideskriptor-Cache und stapelweise Verarbeitung so weit wie möglich. Als Faustregel gilt dennoch, dass poll() mit mehr als tausend gleichzeitigen Verbindungen viel CPU-Leistung beansprucht.
Auf Linux-Systemen mit Kernel 2.6 oder neuer wird der Systemaufruf epoll() verwendet. Dieses erheblich besser skalierende Verfahren nutzt Rückrufe im Kernel und gewährleistet eine konstante Aufweckzeit unabhängig von der Anzahl registrierter, überwachter Dateideskriptoren. Es wird bei Erkennung automatisch verwendet, sofern HAProxy für eine Linux-Variante gebaut wurde. Verfügbarkeit und Unterstützung lassen sich mit “haproxy -vv” prüfen.
Auf unterstützten BSD-Systemen steht kqueue() als Alternative zur Verfügung. Es ist wesentlich schneller als poll() und durch die gebündelte Verarbeitung von Änderungen sogar etwas schneller als epoll(). Mindestens FreeBSD und OpenBSD unterstützen es. Wie bei epoll() unter Linux zeigt “haproxy -vv” die Unterstützung und Verfügbarkeit an.
Ein geeignetes Polling-Verfahren allein genügt nicht; der Prozess muss die Grenzwerte auch erreichen können. Beim Start setzt HAProxy sofort die Dateideskriptorgrenzen des neuen Prozesses und prüft den Erfolg. Fehler meldet er vor dem Fork, damit die Administration sie sehen kann. Wird der Prozess als root gestartet, sollte diese Einstellung ohne Weiteres gelingen. Bei einem Start durch einen unprivilegierten Benutzer kann sie jedoch scheitern. Gibt es einen zwingenden Grund, haproxy nicht als root zu starten, etwa weil Endnutzer oder ein eigenes Anwendungskonto ihn starten, kann die Systemadministration die Dateideskriptorgrenze für diesen Benutzer erhöhen. Mit “ulimit -n” in dessen Befehlszeile lässt sich prüfen, ob die Änderung wirksam ist. Die Ausgabe sollte den neuen Grenzwert zeigen.
Warnung: Werden die Grenzwerte im Konto eines unprivilegierten Benutzers geändert, wirken sie häufig erst bei dessen Anmeldung. Manche beim Systemstart ausgeführten Skripte und crontabs berücksichtigen sie überhaupt nicht. Das hängt vollständig vom Betriebssystem ab. Bei dieser Betriebsweise daher vor dem Start von haproxy stets “ulimit -n” prüfen. Generell wird empfohlen, haproxy im Produktionsbetrieb niemals als unprivilegierter Benutzer zu starten. Ein weiterer wichtiger Grund ist, dass haproxy sonst einige Schutzmaßnahmen nicht aktivieren kann.
Auch wenn das System dem haproxy-Prozess die angeforderte Anzahl von Dateideskriptoren erlaubt, können zwei weitere systemspezifische Grenzen erreicht werden. Die erste ist die systemweite Dateideskriptorgrenze: Sie umfasst alle offenen Dateideskriptoren sämtlicher Prozesse. Wird sie erreicht, geben accept() oder socket() gewöhnlich ENFILE zurück. Die zweite ist die harte Dateideskriptorgrenze pro Prozess, über die setrlimit() nicht hinausgehen darf. Beide hängen stark vom Betriebssystem ab. Unter Linux wird die systemweite Grenze beim Start anhand der Speichermenge festgelegt und kann mit dem sysctl-Parameter “fs.file-max” geändert werden. Die harte Grenze pro Prozess beträgt standardmäßig 1048576 und lässt sich mit “fs.nr_open” ändern.
Zu niedrige Dateideskriptorgrenzen lassen sich auch an einem laufenden Prozess erkennen. strace zeigt bei accept() und socket() den Rückgabewert “-1 EMFILE”, wenn die Prozessgrenze erreicht ist. In diesem Fall genügt es, “ulimit-n” zu erhöhen oder die Einstellung zu entfernen. Geben die Systemaufrufe “-1 ENFILE” zurück, sind dagegen Kernel-Grenzen erreicht, und ein systemweiter Parameter muss angepasst werden. Diese Probleme müssen unbedingt behoben werden: Sie verursachen hohe CPU-Auslastung, wenn accept() scheitert, sowie Verbindungsfehler, die für Benutzer meist sichtbar sind. Eine weitere Lösung besteht darin, den globalen Wert maxconn zu senken, um eine sequenzielle Verarbeitung zu erzwingen, und gegebenenfalls HTTP-Keep-Alive zu deaktivieren, damit Verbindungen schneller freigegeben und wiederverwendet werden.
27 - 6. Speicherverwaltung
HAProxy verwendet eine einfache und schnelle Speicherverwaltung mit Pools. Da nur wenige verschiedene Objekttypen benötigt werden, ist es wesentlich effizienter, neue Objekte aus einem Pool mit Objekten passender Größe zu entnehmen, als für jede Größe malloc() aufzurufen. Die Pools sind als Stapel nach dem LIFO-Prinzip organisiert. Neu zugeteilte Objekte stammen daher aus den zuletzt zurückgegebenen Objekten, die noch in den CPU-Caches liegen. Pools ähnlicher Größe werden zusammengelegt, um die Speicherfragmentierung zu begrenzen.
Da die Leistung im Vordergrund steht, wird standardmäßig jedes zurückgegebene Objekt wieder in seinen ursprünglichen Pool gelegt. Der zugeteilte Speicher wird nie freigegeben, weil eine baldige Wiederverwendung erwartet wird.
Über die CLI lässt sich die Speichernutzung der Pools mit dem Befehl “show pools” prüfen:
Der Poolname dient nur als Hinweis: Er entspricht dem ersten Objekttyp, der diesen Pool verwendet. Die Größe in Klammern bezeichnet die Größe der Objekte im Pool. Objektgrößen werden immer auf das nächste Vielfache von 16 Bytes aufgerundet. Die Ausgabe zeigt die Anzahl der aktuell zugeteilten Objekte und die entsprechende Bytezahl, sodass sich der Pool mit dem höchsten Speicherverbrauch leicht ermitteln lässt. Das Feld “used” nennt zusätzlich die Anzahl der gerade verwendeten Objekte. Die Differenz zwischen “allocated” und “used” entspricht den zurückgegebenen Objekten, die sofort wieder verfügbar sind. Die Adresse am Zeilenende ist die Adresse des Pools. Die anschließende Zahl ist sein Index, sofern vorhanden; wurde kein Index zugewiesen, wird -1 ausgegeben.
Mit der Befehlszeilenoption “-m”, gefolgt von einer Anzahl Megabytes, lässt sich die Speicherzuteilung pro Prozess begrenzen. Die Grenze erfasst den gesamten adressierbaren Speicher des Prozesses, einschließlich des von Bibliotheken verwendeten Speichers und des Stacks. Sie stellt einen zuverlässigen Grenzwert für Systeme mit begrenzten Ressourcen dar. Die Wirkung entspricht “ulimit -v” auf Systemen, die dies unterstützen, beziehungsweise “ulimit -d” auf anderen Systemen.
Schlägt eine Speicherzuteilung fehl, weil der Grenzwert erreicht ist oder das System nicht genügend Speicher hat, gibt haproxy zunächst alle verfügbaren Objekte aus sämtlichen Pools frei und versucht anschließend erneut, Speicher zuzuteilen. Diese Freigabe ungenutzten Speichers lässt sich auch durch das Signal SIGQUIT an den haproxy-Prozess auslösen.
Beim Neuladen gibt auch der Prozess, der in den Zustand des geordneten Herunterfahrens versetzt wurde, nach jeder Freigabe einer Verbindung automatisch Pool-Speicher frei. So wird möglichst viel Speicher für den neuen Prozess verfügbar.
28 - 7. CPU-Auslastung
Versionshinweis: Dieses Kapitel enthält historische Hinweise zum Mehrprozessbetrieb. Seit HAProxy 2.5 werden nbproc und bind process nicht mehr unterstützt. Konfigurieren Sie für diese Ausgabe Threads mit nbthread, thread-groups und cpu-map in den globalen Einstellungen
.
HAProxy verbringt normalerweise den größten Teil seiner Zeit im System und einen kleineren Teil im Benutzerraum. Eine sorgfältig optimierte CPU mit 3.5 GHz kann auf einem einzelnen Kern bei 100% CPU-Auslastung etwa 80000 vollständige Verbindungsaufbauten und -abbauten pro Sekunde bewältigen. Bei vollständiger Auslastung eines Kerns sind folgende Anteile typisch:
- 95% System, 5% Benutzerraum bei langen TCP-Verbindungen oder großen HTTP-Objekten
- 85% System und 15% Benutzerraum bei kurzen TCP-Verbindungen oder kleinen HTTP-Objekten im Close-Modus
- 70% System und 30% Benutzerraum bei kleinen HTTP-Objekten im Keep-Alive-Modus
Viele Regeln und reguläre Ausdrücke erhöhen den Anteil im Benutzerraum. Firewall-Regeln, Verbindungsverfolgung und komplexe Routingtabellen erhöhen dagegen den Systemanteil.
Auf den meisten Systemen lässt sich die bei Netzwerkübertragungen beobachtete CPU-Zeit in 4 Teile gliedern:
-
Interrupt-Zeit: Sie umfasst die gesamte Verarbeitung beim Eingang von I/O-Ereignissen, noch bevor der Zielprozess bekannt ist. Rx-Pakete werden typischerweise hier erfasst. Auf Systemen wie Linux, die die Interrupt-Verarbeitung an einen eigenen Thread delegieren können, erscheint dieser Anteil möglicherweise als softirq; der Thread heißt ksoftirqd/0 für CPU 0. Welche CPU diese Arbeit übernimmt, bestimmen in der Regel die Hardwareeinstellungen. Bei softirq lässt sich die Verarbeitung jedoch häufig auf eine andere CPU verlagern. Dieser Anteil wird oft als störende Zusatzlast wahrgenommen, weil er keinem Prozess zugeordnet ist. Tatsächlich bereitet er die Arbeit für den Prozess vor.
-
Systemzeit: Sie umfasst die Verarbeitung durch Kernel-Code, der aus dem Benutzerraum aufgerufen wird. Beispielsweise zählen Systemaufrufe dazu. Alle synchron ausgelieferten Tx-Pakete werden als Systemzeit erfasst. Müssen Pakete wegen voller Warteschlangen zurückgestellt werden, können sie später im Interrupt-Kontext verarbeitet werden, etwa nach Eingang eines ACK, das ein TCP-Fenster öffnet.
-
Benutzerzeit: Hier wird ausschließlich Anwendungscode im Benutzerraum ausgeführt. HAProxy läuft ausschließlich in diesem Bereich, nutzt aber intensiv Systemaufrufe. Regelverarbeitung, reguläre Ausdrücke, Komprimierung und Verschlüsselung erhöhen diesen Anteil der CPU-Auslastung.
-
Leerlaufzeit: Sie fällt an, wenn die CPU nichts zu tun hat. Beispielsweise wartet HAProxy auf eine eingehende Verbindung oder darauf, dass Daten gesendet werden können, weil das System noch auf ein ACK des Clients wartet, um diese Daten zu übertragen.
Für die Tätigkeit von HAProxy ist in der Praxis meist die folgende, hinreichend brauchbare, aber keineswegs exakte Zuordnung möglich: Interrupt/softirq entsteht durch die Rx-Verarbeitung in Kernel-Treibern, Benutzerzeit durch die Verarbeitung auf Schicht 7 in HAProxy und Systemzeit durch die Netzwerkverarbeitung auf dem Tx-Pfad.
HAProxy arbeitet mit einer Ereignisschleife. Er wartet mit poll() oder einer Alternative auf neue Ereignisse, verarbeitet sie möglichst schnell und kehrt dann zu poll() zurück. Dabei misst er die Wartezeit in poll() im Verhältnis zur Zeit für die Ereignisverarbeitung. Der Anteil der Polling-Zeit an der Gesamtzeit heißt “idle” und bezeichnet die Zeit, in der auf ein Ereignis gewartet wird. Die Statistikseite zeigt ihn in der Zeile “idle”, die CLI unter “Idle_pct”. Ein Wert nahe 100% bedeutet sehr geringe Last; ein Wert nahe 0% bedeutet ständige Aktivität. Auf einem überlasteten System ist die Messung nicht besonders genau, weil andere Prozesse dem haproxy-Prozess die CPU entziehen können. Dennoch zeigt sie gut, wie HAProxy seine eigene Auslastung einschätzt: Sind sowohl die Systemlast als auch der Leerlaufanteil niedrig, hat HAProxy möglicherweise viel Arbeit zu erledigen, etwa durch sehr aufwendige Regeln. Meldet HAProxy dagegen nahezu 100% Leerlauf, obwohl die Verarbeitung langsam ist, kann er sie nicht beschleunigen, da er bereits auf eingehende Daten wartet. Im folgenden Beispiel ist haproxy vollständig im Leerlauf:
Wird der Leerlaufanteil sehr klein, ist es wichtig, das System zu optimieren und Prozesse sowie Interrupts passend zuzuordnen, damit für alle Aufgaben möglichst viel CPU-Leistung verfügbar bleibt. Ist eine Firewall vorhanden, kann es sinnvoll sein, sie testweise zu deaktivieren oder zu optimieren, um auszuschließen, dass sie einen erheblichen Teil der Leistungsbegrenzung verursacht. Das Entladen einer zustandsbehafteten Firewall senkt im Allgemeinen sowohl Interrupt/softirq- als auch Systemzeit, da sie auf dem Rx- und dem Tx-Pfad eingreift. Unter Linux zeigt das Entladen der Module nf_conntrack und ip_conntrack, ob sich dadurch etwas gewinnen lässt. Ist dies der Fall, läuft das Modul mit Standardeinstellungen und muss für bessere Leistung optimiert werden. Meist bedeutet das eine deutlich größere Hashtabelle. Unter FreeBSD deaktiviert “pfctl -d” die Firewall “pf” samt zustandsbehafteter Verarbeitung.
Wird viel Zeit in Interrupt/softirq verbracht, ist sicherzustellen, dass diese Verarbeitung und haproxy nicht auf derselben CPU laufen. Die meisten Systeme binden Aufgaben bevorzugt an die CPU, die den Netzwerkverkehr empfängt, weil dies bestimmte Arbeitslasten beschleunigt. Bei stark netzwerkabhängigen Arbeitslasten wirkt es umgekehrt: Der haproxy-Prozess konkurriert mit der zugehörigen Kernel-Verarbeitung. HAProxy an einen Kern und die Interrupts an einen anderen Kern mit demselben L3-Cache zu binden, verbessert die Netzwerkleistung meist spürbar. In der Praxis ist der Arbeitsumfang von HAProxy und Netzwerk-Stack ähnlich, sodass jeder nahezu eine ganze CPU auslasten kann. Unter Linux erfolgt die Zuordnung für haproxy mit taskset oder cpu-map in der haproxy-Konfiguration, für Interrupts unter /proc/irq. Viele Netzwerkschnittstellen unterstützen mehrere Warteschlangen und Interrupts. Meist hilft es, sie auf wenige CPU-Kerne mit gemeinsamem L3-Cache zu verteilen. irq_balance bitte immer stoppen; bei solchen Arbeitslasten trifft es stets die ungünstigste Entscheidung.
Bei CPU-intensiven Arbeitslasten mit viel SSL-Datenverkehr oder Komprimierung können mehrere auf bestimmte Aufgaben spezialisierte Prozesse sinnvoll sein. Eine allgemeingültige Regel gibt es jedoch nicht; dies muss experimentell ermittelt werden.
Zur Erhöhung der verfügbaren CPU-Leistung lässt sich HAProxy mit der Direktive “nbproc” im Abschnitt global in mehreren Prozessen ausführen. Dabei gelten einige Einschränkungen:
- Health Checks werden pro Prozess ausgeführt. Die Zielserver erhalten daher so viele Prüfungen, wie Prozesse laufen;
- maxconn-Werte und Warteschlangen gelten pro Prozess. Der Wert muss deshalb passend gewählt werden, damit die Server nicht überlastet werden;
- ausgehende Verbindungen sollten keine Portbereiche verwenden, um Konflikte zu vermeiden
- Stick Tables gelten pro Prozess und werden nicht zwischen Prozessen geteilt;
- jeder peers-Abschnitt kann jeweils nur in einem Prozess laufen;
- CLI-Operationen wirken jeweils nur auf einen einzelnen Prozess.
Unter diesen Voraussetzungen ist häufig eine erste Schicht aus mehreren Prozessen am einfachsten, die die aufwendige Verarbeitung übernimmt und den Datenverkehr an eine zweite Schicht mit einem einzelnen Prozess weitergibt. Dieses Verfahren eignet sich für die beiden CPU-intensiven Funktionen SSL und Komprimierung. Instanzen lassen sich leicht über UNIX-Sockets verketten, die weniger Aufwand als TCP-Sockets verursachen und keine Ports verbrauchen. Mit dem Proxy-Protokoll können Clientinformationen an die nächste Stufe weitergegeben werden. Dabei ist es meist sinnvoll, alle Aufgaben für den Einzelprozessbetrieb an Prozess Nummer 1 und zusätzliche Aufgaben an die nachfolgenden Prozesse zu binden. So lassen sich ähnliche Konfigurationen für unterschiedliche Rechner leichter erzeugen.
Unter Linux ab Version 3.9 ist der Mehrprozessbetrieb von HAProxy erheblich effizienter, wenn jeder Prozess einen eigenen lauschenden Socket an derselben Kombination IP:port verwendet. Der Kernel verteilt die Last dann gleichmäßig auf die Prozesse, statt alle aufzuwecken. Weitere Informationen enthält die Option “process” der “bind”-Schlüsselwörter im Konfigurationshandbuch.
29 - 8. Protokollierung
Für die Protokollierung verwendet HAProxy immer einen syslog-Server, da er nicht auf das Dateisystem zugreift. Üblicherweise sendet er Protokollmeldungen über UDP an den Protokollserver, standardmäßig auf Port 514. Sehr häufig ist dafür 127.0.0.1 eingestellt, wo der lokale syslog-Daemon läuft. Ebenso können Meldungen über das Netzwerk an einen zentralen Server gesendet werden. Dieser bietet besonders im Aktiv/Aktiv-Betrieb Vorteile, wenn die Meldungen in ihrer Eingangsreihenfolge zusammengeführt werden sollen. HAProxy kann Protokollmeldungen auch über einen UNIX-Socket an den lokalen syslog-Daemon senden. Davon wird jedoch ausdrücklich abgeraten: Wird der syslog-Server neu gestartet, während haproxy läuft, wird der Socket ersetzt und neue Protokollmeldungen gehen verloren. Da HAProxy in einer chroot-Umgebung isoliert ist, kann er keine Verbindung zum neuen Socket herstellen. Im praktischen Betrieb wurde zudem beobachtet, dass die Protokollpuffer bei UNIX-Sockets sehr klein sind und selbst unter sehr geringer Last Meldungen verloren gehen. Für Tests kann dieses Verfahren dennoch ausreichen.
Es wird empfohlen, die folgende Direktive in den Abschnitt “global” aufzunehmen, damit HAProxy mit der Facility “local0” an den lokalen Daemon protokolliert:
Anschließend die folgende Direktive in jeden Abschnitt “defaults” oder in jeden Frontend- und Backend-Abschnitt aufnehmen:
Damit nutzen alle Protokolle die globale Festlegung des Protokollservers.
Einige syslog-Daemons empfangen standardmäßig keinen UDP-Datenverkehr. Die Syntax zum Aktivieren hängt daher vom verwendeten Daemon ab:
-
Bei sysklogd muss das Argument “-r” in der Befehlszeile des Daemons angegeben werden, damit er auf einem UDP-Socket auf entfernte Protokollmeldungen lauscht. Dies lässt sich nicht auf die Adresse 127.0.0.1 beschränken; er empfängt daher auch Meldungen von entfernten Systemen.
-
Bei rsyslogd müssen die folgenden Zeilen zur Konfigurationsdatei hinzugefügt werden:
- Bei syslog-ng lässt sich wie folgt eine neue Quelle anlegen. Sie muss anschließend in einer der “log”-Direktiven als gültige Quelle eingetragen werden:
Weitere Informationen enthält das Handbuch des jeweiligen syslog-Daemons. Wenn in den Protokolldateien des Systems keine Meldungen erscheinen, helfen folgende Tests:
-
haproxy neu starten. Jedes Frontend und Backend protokolliert eine Zeile zu seinem Start. Werden diese Meldungen empfangen, funktioniert die Protokollierung.
-
“strace -tt -s100 -etrace=sendmsg -p <haproxy’s pid>” ausführen und eine Aktivität erzeugen, die voraussichtlich protokolliert wird. Die mit sendmsg() gesendeten Meldungen sollten sichtbar sein. Andernfalls haproxy unter strace neu starten. Sind weiterhin keine Meldungen zu sehen, liegt eindeutig ein Konfigurationsfehler vor.
-
Mit tcpdump den Datenverkehr auf Port 514 beobachten, etwa auf der Loopback-Schnittstelle, wenn die Meldungen lokal gesendet werden: “tcpdump -As0 -ni lo port 514”. Sind dort Pakete sichtbar, werden die Meldungen nachweislich gesendet; dann muss der syslogd-Daemon untersucht werden.
Während die Frontends, die eingehende Verbindungen annehmen, die Verkehrsprotokolle senden, müssen auch Backends protokollieren können, um Zustandsänderungen eines Servers nach einem Health Check zu melden. Alle verfügbaren Protokolleinstellungen sind im Konfigurationshandbuch von HAProxy beschrieben.
Zweckmäßig ist eine Facility, die kein anderer Daemon verwendet. HAProxy-Beispiele schlagen häufig “local0” für Verkehrsprotokolle und “local1” für Verwaltungsprotokolle vor, da diese im praktischen Betrieb sonst nicht vorkommen. Eine einzelne Facility würde ebenfalls ausreichen. Getrennte Protokolle erleichtern die Auswertung. Zu beachten ist aber auch, dass Protokolle vertrauliche Informationen enthalten können und deshalb nicht mit anderen Protokollen vermischt werden dürfen, die versehentlich an unbefugte Personen gelangen könnten.
Für die Fehlerbehebung im laufenden Betrieb bei möglichst geringer Beeinträchtigung der Serverkapazität wird das mit HAProxy gelieferte Werkzeug “halog” empfohlen. Es ähnelt grep und ist für die sehr schnelle Verarbeitung von HAProxy-Protokolldateien ausgelegt. Typische Durchsatzwerte liegen zwischen 1 und 2 GB Protokolldaten pro Sekunde. Es kann gezielt Meldungen auswählen, etwa nach HTTP-Statuscodeklassen, Verbindungsabschlussstatus, Antwortzeitbereichen oder ausschließlich nach Fehlern suchen, Zeilen zählen, die Ausgabe auf eine bestimmte Zeilenzahl begrenzen und weitergehende Statistiken erstellen. Dazu gehören das Sortieren von Servern nach Antwortzeit oder Fehleranzahl, von URLs nach Zeit oder Anzahl und von Clientadressen nach Zugriffszahl. Damit lassen sich Auffälligkeiten wie ein Bot, der die Website in einer Schleife aufruft, schnell erkennen und blockieren.
30 - 9. Statistiken und Überwachung
Der Status von HAProxy lässt sich abfragen. Am häufigsten wird dafür die HTTP-Statistikseite verwendet. Diese Seite bietet zusätzlich ein CSV-Ausgabeformat für Überwachungswerkzeuge. Dasselbe Format steht über den Unix-Socket zur Verfügung.
Die Statistiken sind in Kategorien zusammengefasst, die als Domänen bezeichnet werden und den verschiedenen Komponenten von HAProxy entsprechen. Zwei Domänen stehen zur Verfügung: proxy und resolvers. Ohne ausdrückliche Angabe wird die Domäne proxy ausgewählt. Beachten Sie, dass auf der HTTP-Seite nur die Proxy-Statistiken ausgegeben werden.
9.1. CSV-Format
Die Statistiken können entweder über den Unix-Socket oder über die HTTP-Seite abgefragt werden. Beide Wege liefern ein CSV-Format mit den nachfolgend beschriebenen Feldern. Die erste Zeile beginnt mit einem Rautezeichen (’#’) und enthält für jedes durch Komma getrennte Feld ein Wort als Spaltentitel. Alle weiteren Zeilen ab der zweiten verwenden ein klassisches CSV-Format mit Komma als Trennzeichen und dem doppelten Anführungszeichen (’"’) als optionalem Textbegrenzer. Dieser wird nur verwendet, wenn der eingeschlossene Text mehrdeutig ist, also ein Anführungszeichen oder ein Komma enthält. Doppelte Anführungszeichen (’"’) innerhalb des Textes werden verdoppelt (’""’); dieses Format erkennen die meisten Werkzeuge. Fügen Sie vor diesen Spalten keine weiteren ein, damit Werkzeuge mit fest kodierten Spaltenpositionen weiterhin funktionieren.
Bei den Proxy-Statistiken stehen hinter jedem Feldnamen in Klammern die Typen, für die dieses Feld einen Wert enthalten kann. Die Typen sind L (Listener), F (Frontends), B (Backends) und S (Server). Es gibt einen festen Satz statischer Felder, die stets in derselben Reihenfolge vorhanden sind. Eine Spalte mit dem Zeichen ‘-’ markiert das Ende der statischen Felder. Für die darauf folgenden Felder sind weder Vorhandensein noch Reihenfolge garantiert.
Die statischen Felder der Statistikdomäne proxy sind:
Für alle anderen Statistikdomänen sind weder das Vorhandensein noch die Reihenfolge der Felder garantiert. In diesem Fall sollte zum Auswerten der CSV-Daten immer die Kopfzeile verwendet werden.
9.2. Typisiertes Ausgabeformat
Sowohl “show info” als auch “show stat” unterstützen einen Modus, in dem jeder Ausgabewert zusammen mit seinem Typ und ausreichenden Informationen ausgegeben wird, um zu erkennen, wie der Wert über mehrere Prozesse hinweg aggregiert werden soll und wie er sich verändert.
In allen Fällen enthält die Ausgabe genau einen Wert pro Zeile. Sämtliche Informationen sind in Felder aufgeteilt, die durch Doppelpunkte (’:’) getrennt werden.
Die erste Spalte bezeichnet das ausgegebene Objekt oder die Metrik. Ihr Format hängt vom ausgebenden Befehl ab und wird in diesem Abschnitt nicht beschrieben. Üblicherweise besteht sie aus einer Folge von Kennungen und Feldnamen.
Die zweite Spalte enthält 4 Zeichen, die in dieser Reihenfolge Herkunft, Art, Gültigkeitsbereich und Persistenzstatus des gemeldeten Werts angeben. Das erste Zeichen (die Herkunft) gibt an, woher der Wert stammt. Mögliche Zeichen sind:
Das zweite Zeichen (die Art) beschreibt die Art der im Feld enthaltenen Information, damit ein Aggregator entscheiden kann, mit welcher Operation mehrere Werte zusammenzufassen sind. Mögliche Zeichen sind:
Das dritte Zeichen (der Gültigkeitsbereich) gibt an, auf welchen Bereich sich der Wert bezieht. Manche Angaben gelten pro Prozess, andere pro Konfiguration oder für das gesamte System. Diese Unterscheidung ist wichtig, um zu entscheiden, ob bei der Aggregation ein einzelner Wert beibehalten werden sollte oder mehrere Werte zusammengefasst werden müssen. Derzeit werden folgende Zeichen unterstützt:
Das vierte Zeichen (der Persistenzstatus) gibt an, ob der Wert (die Metrik) flüchtig ist oder über Neuladungen hinweg erhalten bleibt. Folgende Zeichen sind vorgesehen:
Für die Nutzer dieser Informationen reichen diese 4 Zeichen in der Regel aus, um zu bestimmen, wie aggregierte Informationen über mehrere Prozesse hinweg korrekt dargestellt werden können.
Die darauf folgende dritte Spalte gibt den Feldtyp an: “s32” (vorzeichenbehaftete 32-Bit-Ganzzahl), “s64” (vorzeichenbehaftete 64-Bit-Ganzzahl), “u32” (vorzeichenlose 32-Bit-Ganzzahl), “u64” (vorzeichenlose 64-Bit-Ganzzahl) oder “str” (Zeichenkette). Der Typ muss vor dem Parsen des Werts bekannt sein, damit dieser korrekt gelesen wird. Beispielsweise bleibt eine Zeichenkette, die nur Ziffern enthält, eine Zeichenkette und ist keine Ganzzahl, etwa ein bei einer Prüfung extrahierter Fehlercode.
Die vierte Spalte enthält anschließend den Wert selbst, entsprechend seinem Typ kodiert. Zeichenketten werden unverändert unmittelbar nach dem Doppelpunkt ohne führendes Leerzeichen ausgegeben. Enthält eine Zeichenkette einen Doppelpunkt, erscheint dieser ganz normal. Die Ausgabe sollte daher nicht ausschließlich an Doppelpunkten aufgeteilt werden, da sonst manche Prüfausgaben oder Serveradressen abgeschnitten werden könnten.
9.3. Unix-Socket-Befehle
Der Statistik-Socket ist standardmäßig nicht aktiviert. Zum Aktivieren muss im Abschnitt global der haproxy-Konfiguration eine Zeile hinzugefügt werden. Eine zweite Zeile wird empfohlen, um eine längere Wartezeit festzulegen, was bei der manuellen Befehlseingabe hilfreich ist:
Durch Wiederholen der Zeile lassen sich auch mehrere Statistik-Sockets hinzufügen und an einen TCP-Port statt an einen UNIX-Socket binden. Dies wird wegen der damit verbundenen Gefahr nie standardmäßig eingerichtet, kann aber in manchen Situationen praktisch sein:
Für den Zugriff auf den Socket wird ein externes Werkzeug wie “socat” benötigt. Socat ist ein vielseitiges Werkzeug zum Verbinden beliebiger Ein- und Ausgaben. Hier wird es verwendet, um Terminals oder für Skripte ein Paar stdin/stdout-Pipes mit dem Socket zu verbinden. Hauptsächlich werden die folgenden beiden Aufrufformen verwendet:
Die erste Form wird mit Skripten verwendet. Die Ausgabe eines Skripts kann an haproxy gesendet und die Ausgabe von haproxy an ein anderes Skript weitergereicht werden. Das ist beispielsweise zum Abrufen von Zählern oder Angriffsspuren nützlich.
Die zweite Form dient ausschließlich der manuellen Befehlseingabe. Dabei wird das Terminal von der readline-Bibliothek verwaltet, die Zeilenbearbeitung und einen Befehlsverlauf unterstützt. Das ist bei wiederholten Befehlen sehr praktisch, etwa zum Beobachten eines Zählers.
Der Socket unterstützt drei Betriebsarten:
- nicht interaktiv, ohne Eingabeaufforderung
- interaktiv, ohne Eingabeaufforderung
- interaktiv mit Eingabeaufforderung
Wenn socat eine Verbindung zum Socket herstellt, ist standardmäßig der nicht interaktive Modus aktiv. In diesem Modus kann eine einzelne Zeile gesendet werden. Sie wird als Ganzes verarbeitet, die Antworten werden zurückgesendet und nach dem Ende der Antwort wird die Verbindung geschlossen. Skripte und Überwachungswerkzeuge verwenden diesen Modus. Darin können mehrere Befehle gesendet werden, wenn sie durch ein Semikolon (’;’) getrennt sind. Beispiel:
Wenn ein Befehl ein Semikolon oder einen umgekehrten Schrägstrich benötigt, etwa innerhalb eines Werts, muss diesem Zeichen ein umgekehrter Schrägstrich (’\’) vorangestellt werden.
Im interaktiven Modus können neue Befehle gesendet werden, nachdem die Befehle der vorherigen Zeilen abgeschlossen sind. Es gibt zwei Varianten: eine ohne Eingabeaufforderung, die wie der nicht interaktive Modus funktioniert, aber auf einen neuen Befehl wartet, statt den Socket zu schließen; und eine, bei der am Zeilenanfang eine Eingabeaufforderung (’>’) erscheint. Der interaktive Modus eignet sich für anspruchsvollere Werkzeuge, der Modus mit Eingabeaufforderung für die manuelle Bedienung.
Der Modus lässt sich mit dem Befehl “prompt” ändern. Standardmäßig schaltet er zwischen dem interaktiven Modus und dem Modus mit Eingabeaufforderung um. Die Eingabe von “prompt” im interaktiven Modus aktiviert die Eingabeaufforderung. Optional akzeptiert der Befehl einen bestimmten Modus:
- “n”: nicht interaktiver Modus (ein einzelner Befehl, dann Ende)
- “i”: interaktiver Modus (mehrere Befehle, ohne Eingabeaufforderung)
- “p”: Modus mit Eingabeaufforderung (mehrere Befehle mit Eingabeaufforderung)
Da standardmäßig der nicht interaktive Modus aktiv ist, muss “prompt” als erster Befehl verwendet werden, um ihn zu ändern. Andernfalls bewirkt der vorherige Befehl das Schließen der Verbindung. Beim Wechsel in den nicht interaktiven Modus wird die Verbindung geschlossen, sobald alle Befehle derselben Zeile abgeschlossen sind.
Aus diesem Grund beginnt man bei der manuellen Fehlersuche häufig mit dem Befehl “prompt”:
show info …
Interaktive Werkzeuge können mit “prompt i” beginnen, um in den interaktiven Modus ohne Eingabeaufforderung zu wechseln.
Optional kann die Laufzeit des Prozesses in der Eingabeaufforderung angezeigt werden. Der Befehl “prompt timed” aktiviert die Eingabeaufforderung und schaltet die Zeitanzeige um. Die Laufzeit wird im Format “d:hh:mm:ss” angezeigt, wobei “d” die Anzahl der Tage und “hh”, “mm” und “ss” die Anzahl der Stunden, Minuten beziehungsweise Sekunden mit jeweils zwei Ziffern angeben:
[23:03:34:39]> show version 2.8-dev9-e5e622-18
[23:03:34:41]> quit
Wenn die Laufzeitanzeige an der Master-CLI aktiviert ist, zeigt die Eingabeaufforderung die Laufzeit des aktuell ausgewählten Prozesses an. Dies funktioniert also für den Master, den aktuellen Worker oder einen älteren Worker:
Da mehrere Befehle gleichzeitig eingegeben werden können, verwendet haproxy eine Leerzeile als Trennzeichen für das Ende der Ausgabe jedes Befehls. Dabei wird sichergestellt, dass kein Befehl selbst eine Leerzeile ausgeben kann. Ein Skript kann die Ausgabe dadurch auch dann leicht auswerten, wenn mehrere Befehle in einer einzigen Zeile übermittelt wurden.
Manche Befehle akzeptieren optionale Nutzdaten. Um einem Befehl Nutzdaten hinzuzufügen, muss die erste Zeile mit dem Muster “<<\n” enden. Die folgenden Zeilen werden als Nutzdaten behandelt; es können beliebig viele Zeilen sein. Zum Bestätigen eines Befehls mit Nutzdaten muss die Eingabe mit einer Leerzeile enden.
Das Nutzdatenmuster kann angepasst werden, um das Ende der Nutzdaten anders zu kennzeichnen. Sollen Nutzdaten mit etwas anderem als einer Leerzeile enden, kann zwischen ‘<<’ und ‘\n’ ein eigenes Muster festgelegt werden. Zusätzlich zu ‘<<’ sind bis zu 64 Zeichen zulässig; andernfalls wird die Eingabe nicht als Nutzdaten erkannt. Dies sollte für zufällige Nutzdatenmuster ausreichen. Beispiel für eine PEM-Datei mit Leerzeilen und Kommentaren:
Es gibt Einschränkungen: Das Muster “<<” darf nicht unmittelbar an das letzte Wort der Zeile angehängt werden. Die Länge einer Befehlszeile darf tune.bufsize nicht überschreiten. Dabei wird das Muster, das die Nutzdaten einleitet, mitgezählt, die Nutzdaten selbst jedoch nicht. Die Nutzdatengröße ist standardmäßig auf 128KB begrenzt. Dies kann mit dem globalen Parameter “tune.cli.max-payload-size” unter Beachtung einiger Vorsichtsmaßnahmen geändert werden. Beachten Sie, dass das Muster zum Beenden der Nutzdaten in diese Grenze einbezogen wird.
Während der Eingabe von Nutzdaten im interaktiven Modus wechselt die Eingabeaufforderung von “> " zu “+ “.
Beachten Sie, dass bei mehreren haproxy-Prozessen, die auf denselben Sockets gestartet wurden, jeder beliebige Prozess die Anfrage annehmen kann und seine eigenen Statistiken ausgibt.
Die derzeit auf dem Statistik-Socket unterstützten Befehle sind unten aufgeführt. Bei einem unbekannten Befehl zeigt haproxy eine Bedienungshilfe mit allen unterstützten Befehlen an. Einige Befehle haben eine komplexere Syntax; bei einem Fehler wird in der Regel erläutert, welcher Teil des Befehls ungültig ist.
Manche Befehle erfordern höhere Berechtigungen. Reichen Ihre Berechtigungen nicht aus, erhalten Sie den Fehler “Permission denied”. Weitere Informationen finden Sie bei der Option “level” der “bind”-Zeilen im Konfigurationshandbuch.
abort ssl ca-file <cafile>
Bricht eine temporäre Aktualisierungstransaktion für eine CA-Datei ab und verwirft sie.
Siehe auch “set ssl ca-file” und “commit ssl ca-file”.
abort ssl cert <filename>
Bricht eine temporäre Aktualisierungstransaktion für ein SSL-Zertifikat ab und verwirft sie.
Siehe auch “set ssl cert” und “commit ssl cert”.
abort ssl crl-file <crlfile>
Bricht eine temporäre Aktualisierungstransaktion für eine CRL-Datei ab und verwirft sie.
Siehe auch “set ssl crl-file” und “commit ssl crl-file”.
acme renew <certificate>
Startet eine ACME-Aufgabe zur Zertifikatserzeugung mit dem angegebenen Zertifikatsnamen. Das Zertifikat muss einem acme-Abschnitt zugeordnet sein; siehe Abschnitt 12.8 „ACME“ des Konfigurationshandbuchs. Siehe auch “acme status”.
acme status
Zeigt den Status aller Zertifikate an, die mit ACME konfiguriert wurden.
Dieser Befehl gibt folgende Werte, durch Tabulatoren getrennt, aus:
- Den Namen des in HAProxy konfigurierten Zertifikats
- Den in der Konfiguration verwendeten acme-Abschnitt
- Den Status der acme-Aufgabe: “Running”, “Scheduled” oder “Stopped”
- Das UTC-Ablaufdatum des Zertifikats im ISO8601-Format
- Die relative Zeit bis zum Ablauf (0d, falls abgelaufen)
- Den geplanten UTC-Termin des Zertifikats im ISO8601-Format
- Die relative Zeit bis zum geplanten Termin (0d bei Running)
Beispiel:
add acl [@<ver>] <acl> <pattern>
Fügt der ACL <acl> einen Eintrag hinzu. <acl> ist die von “show acl” zurückgegebene #<id> oder der zurückgegebene <name>. Dieser Befehl prüft nicht, ob der Eintrag bereits vorhanden ist. Einträge werden der aktuellen Version der ACL hinzugefügt, sofern nicht mit “@<ver>” eine bestimmte Version angegeben wird. Diese Versionsnummer muss zuvor mit “prepare acl” zugewiesen worden sein und liegt zwischen den Versionen, die in der Ausgabe von “show acl” als “curr_ver” und “next_ver” gemeldet werden. Einträge, die mit einer bestimmten Versionsnummer hinzugefügt wurden, ergeben erst nach einer “commit acl”-Operation einen Treffer. Sie können jedoch mit dem Befehl “show acl @<ver>” eingesehen und mit “clear acl @<ver>” gelöscht werden. Dieser Befehl kann nicht verwendet werden, wenn die Referenz <acl> ein Name ist, der auch für eine Map verwendet wird. In diesem Fall muss stattdessen der Befehl “add map” verwendet werden.
add backend <name> from <defproxy> [mode <mode>] [guid <guid>]
Erzeugt eine neue Backend-Proxy-Instanz mit dem Namen <name>.
Es können nur TCP- oder HTTP-Proxys erzeugt werden. Alle Einstellungen werden von der Standard-Proxy-Instanz <defproxy> geerbt. Standardmäßig muss der Backend-Modus über das gleichnamige Argument angegeben werden, sofern <defproxy> ihn nicht bereits ausdrücklich festlegt. Bei Bedarf kann auch ein optionales GUID-Argument verwendet werden.
Server können mit dem Befehl “add server” hinzugefügt werden. Das Backend wird im unveröffentlichten Zustand initialisiert. Sobald es für den Datenverkehr bereit ist, kann die neu erzeugte Instanz mit “publish backend” verfügbar gemacht werden.
Alle benannten Standard-Proxys können verwendet werden, sofern sie dieselben Vererbungsregeln erfüllen, die beim Einlesen der Konfiguration gelten. Es gibt jedoch Ausnahmen, etwa wenn der Modus weder TCP noch HTTP ist.
Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind.
add map [@<ver>] <map> <key> <value>
Fügt der Map <map> einen Eintrag hinzu, der dem Schlüssel <key> den Wert <value> zuordnet. Dieser Befehl prüft nicht, ob der Eintrag bereits vorhanden ist. Er dient hauptsächlich dazu, eine Map nach einer “clear”- oder “prepare”-Operation zu füllen. Einträge werden der aktuellen Version der ACL hinzugefügt, sofern nicht mit “@<ver>” eine bestimmte Version angegeben wird. Diese Versionsnummer muss zuvor mit “prepare acl” zugewiesen worden sein und liegt zwischen den Versionen, die in der Ausgabe von “show acl” als “curr_ver” und “next_ver” gemeldet werden. Einträge, die mit einer bestimmten Versionsnummer hinzugefügt wurden, ergeben erst nach einer “commit map”-Operation einen Treffer. Sie können jedoch mit dem Befehl “show map @<ver>” eingesehen und mit “clear acl @<ver>” gelöscht werden. Wird die bezeichnete Map auch als ACL verwendet, berücksichtigt die ACL nur den Teil <key> und ignoriert den Teil <value>. Mit der Nutzdatensyntax können mehrere Schlüssel-Wert-Paare hinzugefügt werden, indem jedes Paar in einer eigenen Zeile eingegeben wird. In jeder neuen Zeile ist das erste Wort der Schlüssel; der Rest der Zeile wird als Wert betrachtet und kann auch Leerzeichen enthalten.
Beispiel:
add server <backend>/<server> [args]*
Erzeugt eine neue Serverinstanz im Backend <backend>.
Der Name <server> darf im Backend noch nicht verwendet werden. Für das Backend gilt die besondere Einschränkung, dass es einen dynamischen Lastverteilungsalgorithmus verwenden muss. Eine Teilmenge der Schlüsselwörter der server-Anweisung in der Konfigurationsdatei kann zur Konfiguration des Serververhaltens verwendet werden (“add server help” listet sie auf). Einstellungen einer eventuell vorhandenen ‘default-server’-Anweisung im selben Backend werden nicht übernommen.
Derzeit wird ein dynamischer Server statisch mit der init-addr-Methode “none” initialisiert. Das bedeutet, dass keine Namensauflösung erfolgt, wenn als Adresse ein FQDN angegeben wird, auch wenn die Servererzeugung akzeptiert wird.
Damit Neuladevorgänge unterstützt werden, wird erwartet, dass der über die CLI erzeugte Server auch manuell in die entsprechende HAProxy-Konfigurationsdatei eingetragen wird. Ein dynamischer Server, der nicht in der Konfiguration vorhanden ist, wird nach einem Neuladevorgang nicht wiederhergestellt.
Ein dynamischer Server kann mit dem Schlüsselwort “track” den Prüfstatus eines anderen Servers aus der Konfiguration verfolgen. Es ist jedoch nicht möglich, einen anderen dynamischen Server zu verfolgen. Dadurch bleibt die Verfolgungskette auch dann konsistent, wenn dynamische Server gelöscht werden.
Mit dem Schlüsselwort “check” wird die Unterstützung für Health Checks aktiviert. Der Health Check ist standardmäßig deaktiviert und muss unabhängig vom Server mit dem Befehl “enable health” aktiviert werden. Für Agent-Prüfungen dienen das Schlüsselwort “agent-check” und der Befehl “enable agent”. In diesem Fall kann der Agent den Server je nach gemeldetem Status aktivieren, ohne dass ausdrücklich “enable server” ausgeführt wird. Daher ist beim Entfernen eines dynamischen Servers mit Agent-Prüfung besondere Vorsicht erforderlich. Der Agent sollte zuerst mit “disable agent” deaktiviert werden, damit der Server vor dem Entfernen in den erforderlichen Wartungsmodus versetzt werden kann.
Bei einer großen Anzahl dynamischer Server kann die fd-Grenze erreicht werden. Siehe in diesem Fall die Dokumentation des globalen Schlüsselworts “u-limit”.
add server help
Listet die Schlüsselwörter auf, die die aktuelle HAProxy-Version für dynamische Server unterstützt. Die Syntax der Schlüsselwörter ähnelt der server-Zeile der Konfigurationsdatei; Einzelheiten stehen in der jeweiligen Dokumentation.
add ssl ca-file <cafile> <payload>
Fügt einer ca-file ein neues Zertifikat hinzu. Dieser Befehl ist nützlich, wenn die Puffergrößengrenze der CLI erreicht wurde und mehrere Zertifikate hinzugefügt werden sollen. Statt mit “set” alle Zertifikate auf einmal zu setzen, kann jedes Zertifikat einzeln hinzugefügt werden. “set ssl ca-file” setzt die ca-file zurück.
Beispiel:
add ssl crt-list <crtlist> <certificate>
Fügt einer crt-list ein Zertifikat hinzu. Der Befehl kann auch für Verzeichnisse verwendet werden, da Verzeichnisse inzwischen auf dieselbe Weise wie crt-lists geladen werden. Mit diesem Befehl kann ein Zertifikatsname als Parameter angegeben werden. Für SSL-Optionen oder Filter muss stattdessen eine crt-list-Zeile als Nutzdaten gesendet werden. Die Nutzdaten unterstützen nur eine einzige crt-list-Zeile. Der Befehl lädt das Zertifikat für alle bind-Zeilen, die die crt-list verwenden. Um ein neues Zertifikat an HAProxy zu übertragen, müssen die Befehle “new ssl cert” und “set ssl cert” verwendet werden.
Beispiel:
add ssl ech <bind> <payload>
Fügt einer <bind>-Zeile einen ECH-Schlüssel hinzu. Die Nutzdaten müssen im PEM-for-ECH-Format vorliegen.
(https://datatracker.ietf.org/doc/html/draft-farrell-tls-pemesni
)
Das Format der bind-Zeile ist <frontend>/@<filename>:<linenum> (Beispiel: frontend1/@haproxy.conf
:19) oder <frontend>/<name>, wenn die bind-Zeile mit dem Schlüsselwort “name” benannt wurde.
Erfordert eine OpenSSL-Version mit ECH-Unterstützung. HAProxy muss mit USE_ECH=1 kompiliert sein. Dieser Befehl wird nur auf einer CLI-Verbindung im experimentellen Modus unterstützt (siehe “experimental-mode on”).
Siehe auch “show ssl ech” und “ech” in Abschnitt 5.1 des Konfigurationshandbuchs.
Beispiel:
add ssl jwt <filename>
Fügt ein bereits geladenes Zertifikat der Liste der Zertifikate hinzu, die für die JWT-Validierung verwendet werden können (siehe Konverter “jwt_verify_cert”). Dieser Befehl funktioniert nicht bei laufenden Transaktionen. Siehe auch die Befehle “del ssl jwt” und “show ssl jwt”. Weitere Informationen stehen bei der Zertifikatsoption “jwt”.
clear counters
Setzt die Höchstwerte der Statistikzähler in jedem Proxy (Frontend und Backend) und in jedem Server zurück. Die kumulierten Zähler bleiben unverändert. Die von “show activity” gemeldeten internen Aktivitätszähler werden ebenfalls zurückgesetzt. Damit lassen sich nach einem Vorfall die Zähler zurücksetzen, ohne neu starten oder die Verkehrszähler löschen zu müssen. Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufen “operator” oder “admin” konfiguriert sind.
clear counters all
Setzt alle Statistikzähler in jedem Proxy (Frontend und Backend) und in jedem Server zurück. Dies hat dieselbe Wirkung wie ein Neustart. Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind.
clear acl [@<ver>] <acl>
Entfernt alle Einträge aus der ACL <acl>. <acl> ist die von “show acl” zurückgegebene #<id> oder der zurückgegebene <name>. Wenn die Referenz <acl> ein Name ist, der auch für eine Map verwendet wird, wird diese Map ebenfalls geleert. Standardmäßig wird nur die aktuelle Version der ACL geleert (die Version, gegen die geprüft wird). Es kann jedoch eine andere Version angegeben werden, indem auf ‘@’ die Versionsnummer folgt.
clear map [@<ver>] <map>
Entfernt alle Einträge aus der Map <map>. <map> ist die von “show map” zurückgegebene #<id> oder der zurückgegebene <name>. Wenn die Referenz <map> ein Name ist, der auch für eine ACL verwendet wird, wird diese ACL ebenfalls geleert. Standardmäßig wird nur die aktuelle Version der Map geleert (die Version, gegen die geprüft wird). Es kann jedoch eine andere Version angegeben werden, indem auf ‘@’ die Versionsnummer folgt.
clear table <table> [ data.<type> <operator> <value> ] | [ key <key> ] |
Entfernt Einträge aus der Stick Table <table>.
Dies wird üblicherweise verwendet, um die Sperre für Benutzer aufzuheben, die sich über einen ungerechtfertigt verweigerten Zugriff auf einen Dienst beschweren. Es können aber auch Einträge zur Sitzungsbindung gelöscht werden, die einem zu ersetzenden Server zugeordnet sind (Einzelheiten siehe “show table” weiter unten). Manchmal wird das Entfernen eines Eintrags verweigert, weil er gerade von einer Sitzung verfolgt wird. Üblicherweise genügt es, einige Sekunden später nach dem Ende der Sitzung einen neuen Versuch zu unternehmen.
Werden keine Optionsargumente angegeben, werden alle Einträge entfernt.
Bei der Form “data.” werden Einträge entfernt, auf die ein Filter anhand der gespeicherten Daten zutrifft (siehe “stick-table” in Abschnitt 4.2). In <type> muss ein gespeicherter Datentyp angegeben werden. Dieser Datentyp muss in der Tabelle gespeichert sein, andernfalls wird ein Fehler gemeldet. Die Daten werden gemäß <operator> mit der 64-Bit-Ganzzahl <value> verglichen. Es gelten dieselben Operatoren wie bei ACLs:
- eq: erfasst Einträge, deren Daten diesem Wert entsprechen
- ne: erfasst Einträge, deren Daten diesem Wert nicht entsprechen
- le: erfasst Einträge, deren Daten kleiner oder gleich diesem Wert sind
- ge: erfasst Einträge, deren Daten größer oder gleich diesem Wert sind
- lt: erfasst Einträge, deren Daten kleiner als dieser Wert sind
- gt: erfasst Einträge, deren Daten größer als dieser Wert sind
Bei der key-Form wird der Eintrag <key> entfernt. Der Schlüssel muss denselben Typ wie die Tabelle haben; derzeit sind nur IPv4, IPv6, Ganzzahl und Zeichenfolge möglich.
Bei der ptr-Form wird der Eintrag <ptr> entfernt. <ptr> wird in der Form 0xffff geschrieben und muss der Adresse entsprechen, die ein zuvor ausgeführter “show table”-Befehl zurückgegeben hat. Das Identifizieren eines Eintrags über seinen Zeiger kann sinnvoll sein, wenn dies über den Schlüssel wegen eines leeren Schlüssels oder mit der CLI inkompatibler Zeichen nicht möglich ist.
Wenn data.<type> ein Array-Typ ist, kann mit “[]” auf einen bestimmten Index im Array zugegriffen werden, etwa so: data.gpt[1]
Beispiel:
commit acl @<ver> <acl>
Übernimmt alle Änderungen an Version <ver> der ACL <acl> und löscht alle früheren Versionen. <acl> ist die von “show acl” zurückgegebene #<id> oder der zurückgegebene <name>. Die Versionsnummer muss zwischen “curr_ver”+1 und “next_ver” liegen, wie von “show acl” gemeldet. Der zu übernehmende ACL-Inhalt kann bei Bedarf mit “show acl @<ver> <acl>” eingesehen werden. Die angegebene Versionsnummer wurde normalerweise mit dem Befehl “prepare acl” erzeugt. Die Ersetzung erfolgt atomar: Die aktuelle Version wird atomar auf die angegebene Version gesetzt. Dadurch werden alle Einträge anderer Versionen sofort unsichtbar und alle Einträge der neuen Version sichtbar. Mit diesem Befehl können auch sämtliche sichtbaren Einträge einer ACL atomar entfernt werden, indem zuerst “prepare acl” aufgerufen wird und anschließend die Version übernommen wird, ohne Einträge hinzuzufügen. Dieser Befehl kann nicht verwendet werden, wenn die Referenz <acl> ein Name ist, der auch für eine Map verwendet wird. In diesem Fall muss stattdessen der Befehl “commit map” verwendet werden.
commit map @<ver> <map>
Übernimmt alle Änderungen an Version <ver> der Map <map> und löscht alle früheren Versionen. <map> ist die von “show map” zurückgegebene #<id> oder der zurückgegebene <name>. Die Versionsnummer muss zwischen “curr_ver”+1 und “next_ver” liegen, wie von “show map” gemeldet. Der zu übernehmende Map-Inhalt kann bei Bedarf mit “show map @<ver> <map>” eingesehen werden. Die angegebene Versionsnummer wurde normalerweise mit dem Befehl “prepare map” erzeugt. Die Ersetzung erfolgt atomar: Die aktuelle Version wird atomar auf die angegebene Version gesetzt. Dadurch werden alle Einträge anderer Versionen sofort unsichtbar und alle Einträge der neuen Version sichtbar. Mit diesem Befehl können auch sämtliche sichtbaren Einträge einer Map atomar entfernt werden, indem zuerst “prepare map” aufgerufen wird und anschließend die Version übernommen wird, ohne Einträge hinzuzufügen.
commit ssl ca-file <cafile>
Übernimmt eine temporäre Transaktion zur Aktualisierung einer SSL-CA-Datei.
Bei einer bestehenden CA-Datei (Status “Used” in “show ssl ca-file”) wird der neue CA-Dateieintrag in den CA-Dateibaum eingefügt. Jede Instanz, die den CA-Dateieintrag verwendet hat, wird zusammen mit den benötigten SSL-Kontexten neu aufgebaut. Alle zuvor von den neu aufgebauten Instanzen verwendeten Kontexte werden entfernt. Bei Erfolg wird der bisherige CA-Dateieintrag aus dem Baum entfernt. Bei einem Fehlschlag wird nichts entfernt oder gelöscht; alle ursprünglichen SSL-Kontexte bleiben erhalten und werden weiterhin verwendet. Sobald die temporäre Transaktion übernommen wurde, wird sie zerstört.
Bei einer neuen CA-Datei (nach “new ssl ca-file”, Status “Unused” in “show ssl ca-file”) wird die CA-Datei in den CA-Dateibaum eingefügt, aber nirgendwo in HAProxy verwendet. Um sie zu verwenden und SSL-Kontexte zu erzeugen, die sie nutzen, muss sie mit “add ssl crt-list” einer crt-list hinzugefügt werden.
Siehe auch “new ssl ca-file”, “set ssl ca-file”, “add ssl ca-file”, “abort ssl ca-file” und “add ssl crt-list”.
commit ssl cert <filename>
Übernimmt eine temporäre Transaktion zur Aktualisierung eines SSL-Zertifikats.
Bei einem bestehenden Zertifikat (Status “Used” in “show ssl cert”) werden alle benötigten SSL-Kontexte und SNIs erzeugt und eingefügt; die bisherigen werden entfernt. Die bisherigen SSL-Zertifikate werden im Speicher überall dort ersetzt, wo <filename> in der Konfiguration verwendet wurde. Bei einem Fehlschlag wird nichts entfernt oder eingefügt. Sobald die temporäre Transaktion übernommen wurde, wird sie zerstört.
Bei einem neuen Zertifikat (nach “new ssl cert”, Status “Unused” in “show ssl cert”) wird das Zertifikat in einen Zertifikatsspeicher übernommen, aber nirgendwo in HAProxy verwendet. Um es zu verwenden und seine SNIs zu erzeugen, muss es mit “add ssl crt-list” einer crt-list oder einem Verzeichnis hinzugefügt werden.
Siehe auch “new ssl cert”, “set ssl cert”, “abort ssl cert” und “add ssl crt-list”.
commit ssl crl-file <crlfile>
Übernimmt eine temporäre Transaktion zur Aktualisierung einer SSL-CRL-Datei.
Bei einer bestehenden CRL-Datei (Status “Used” in “show ssl crl-file”) wird der neue CRL-Dateieintrag in den CA-Dateibaum eingefügt, der sowohl CA-Dateien als auch CRL-Dateien enthält. Jede Instanz, die den CRL-Dateieintrag verwendet hat, wird zusammen mit den benötigten SSL-Kontexten neu aufgebaut. Alle zuvor von den neu aufgebauten Instanzen verwendeten Kontexte werden entfernt. Bei Erfolg wird der bisherige CRL-Dateieintrag aus dem Baum entfernt. Bei einem Fehlschlag wird nichts entfernt oder gelöscht; alle ursprünglichen SSL-Kontexte bleiben erhalten und werden weiterhin verwendet. Sobald die temporäre Transaktion übernommen wurde, wird sie zerstört.
Bei einer neuen CRL-Datei (nach “new ssl crl-file”, Status “Unused” in “show ssl crl-file”) wird die CRL-Datei in den CRL-Dateibaum eingefügt, aber nirgendwo in HAProxy verwendet. Um sie zu verwenden und SSL-Kontexte zu erzeugen, die sie nutzen, muss sie mit “add ssl crt-list” einer crt-list hinzugefügt werden.
Siehe auch “new ssl crl-file”, “set ssl crl-file”, “abort ssl crl-file” und “add ssl crt-list”.
debug counters [reset|show|on|off|all|bug|chk|cnt|glt|?]*
Listet interne, im Code platzierte Zähler auf, die je nach Build-Optionen unterschiedlich sein können. Einige hängen von DEBUG_STRICT ab, andere von DEBUG_COUNTERS. Der Befehl akzeptiert eine Kombination mehrerer Argumente, von denen manche Aktionen und andere Filter festlegen: - bug aktiviert die Auflistung der Zähler für BUG_ON()-Anweisungen - cnt aktiviert die Auflistung der Zähler für COUNT_IF()-Anweisungen - chk aktiviert die Auflistung der Zähler für CHECK_IF()-Anweisungen - glt aktiviert die Auflistung der Zähler für COUNT_GLITCH()-Anweisungen - all zeigt auch Zähler an, die nie ausgelöst wurden (Wert 0) - Aktion off: deaktiviert die Aktualisierung der COUNT_IF()-Zähler - Aktion on: aktiviert die Aktualisierung der COUNT_IF()-Zähler - Aktion reset: setzt alle angegebenen Zähler zurück - Aktion show: zeigt alle angegebenen Zähler an
Standardmäßig gilt die Aktion “show”, um Zähler anzuzeigen; aufgelistet werden alle Zählertypen mit einem Wert ungleich null. Der Befehl “show” gilt implizit, wenn keine andere Aktion angegeben ist. Er ist nur vorhanden, um das Erzeugen von Befehlen aus Skripten zu erleichtern.
Die Ausgabe beginnt mit einem ganzzahligen Zähler, gefolgt vom Zählertyp in Großbuchstaben, seiner Position im Code (file:line), dem Funktionsnamen und optional “: " samt einer Beschreibung. Das Ausgabeformat kann sich zwischen Hauptversionen ändern. Neue Typen und Einträge können zur Verbesserung der Fehlerdiagnose in stabile Versionen zurückportiert werden. Eine Überwachung dieser Zähler sollte nur mit sehr großzügiger und toleranter Auswertung erfolgen, vorzugsweise überhaupt nicht.
Normalerweise verwenden Endbenutzer diesen Befehl nicht. Ein Entwickler, der die Ursache eines Problems ermittelt und nach CNT- oder GLT-Einträgen sucht, kann sie jedoch darum bitten. “CHK”-Einträge mit einem Wert ungleich null sollten nicht auftreten und sollten den Entwicklern gemeldet werden, da sie auf falsche Annahmen im Code hindeuten können.
debug dev <command> [args]*
Ruft einen entwicklerspezifischen Befehl auf. Dies wird nur auf einer CLI-Verbindung im Expertenmodus unterstützt (siehe “expert-mode on”). Solche Befehle sind äußerst gefährlich und verzeihen keine Fehler; jede Fehlanwendung kann den Prozess zum Absturz bringen. Sie sind ausschließlich für Experten vorgesehen und dürfen keinesfalls verwendet werden, sofern keine entsprechende Anweisung vorliegt. Einige sind nur verfügbar, wenn HAProxy mit definiertem DEBUG_DEV gebaut wurde, da sie Auswirkungen auf die Sicherheit haben können. Alle diese Befehle erfordern admin-Berechtigungen. Sie sind bewusst nicht dokumentiert, um ihre Verwendung durch Personen zu vermeiden, die mit dem Quellcode nicht vertraut sind.
del acl <acl> [<key>|#<ref>]
Löscht alle Einträge der ACL <acl>, die dem Schlüssel <key> entsprechen. <acl> ist die von “show acl” zurückgegebene #<id> oder der zurückgegebene <name>. Wenn <ref> verwendet wird, löscht dieser Befehl nur die angegebene Referenz. Die Referenz lässt sich durch Auflisten des ACL-Inhalts ermitteln. Wenn die Referenz <acl> ein Name ist, der auch für eine Map verwendet wird, wird der Eintrag auch aus der Map gelöscht.
del backend <name>
Entfernt den Backend-Proxy mit dem Namen <name>.
Diese Operation ist nur für TCP- oder HTTP-Proxys möglich. Damit sie gelingt, muss zuvor die Veröffentlichung der Backend-Instanz aufgehoben worden sein. Außerdem müssen zuerst alle ihre Server entfernt werden (über den CLI-Befehl “del server”). Schließlich darf kein Stream mehr mit der Backend-Instanz verbunden sein.
Weitere Einschränkungen verhindern das Entfernen eines Backends. Ein Backend kann nicht entfernt werden, wenn Konfigurationselemente ausdrücklich darauf verweisen, etwa eine use_backend-Regel oder Sample-Ausdrücke. Manche Proxy-Optionen sind ebenfalls mit dem Löschen zur Laufzeit inkompatibel. Derzeit gilt dies, wenn das veraltete dispatch oder option transparent verwendet wird. Ein Backend kann auch nicht entfernt werden, wenn darin eine stick-table deklariert ist. Schließlich ist es derzeit unmöglich, ein Backend zu entfernen, in dem QUIC-Server vorhanden waren.
Es kann sinnvoll sein, vor diesem Befehl “wait be-removable” zu verwenden, um die genannten Voraussetzungen zu prüfen. Damit lässt sich auch auf das endgültige Schließen der Streams warten, die mit dem Ziel-Backend verbunden sind.
Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind.
del map <map> [<key>|#<ref>]
Löscht alle Einträge der Map <map>, die dem Schlüssel <key> entsprechen. <map> ist die von “show map” zurückgegebene #<id> oder der zurückgegebene <name>. Wenn <ref> verwendet wird, löscht dieser Befehl nur die angegebene Referenz. Die Referenz lässt sich durch Auflisten des Map-Inhalts ermitteln. Wenn die Referenz <map> ein Name ist, der auch für eine ACL verwendet wird, wird der Eintrag auch aus der Map gelöscht.
del ssl ca-file <cafile>
Löscht einen CA-Dateibaumeintrag aus HAProxy. Die CA-Datei muss unbenutzt und aus allen crt-lists entfernt sein. “show ssl ca-file” zeigt den Status der CA-Dateien an. Das Löschen funktioniert nicht bei einem Zertifikat, auf das in der Konfiguration direkt mit den Direktiven “ca-file” oder “ca-verify-file” verwiesen wird.
del ssl cert <certfile>
Löscht einen Zertifikatsspeicher aus HAProxy. Das Zertifikat muss unbenutzt sein (auch für die JWT-Validierung) und aus allen crt-lists oder Verzeichnissen entfernt sein. “show ssl cert” zeigt den Status des Zertifikats an. Das Löschen funktioniert nicht bei einem Zertifikat, auf das in der Konfiguration direkt mit der Direktive “crt” verwiesen wird.
del ssl crl-file <crlfile>
Löscht einen CRL-Dateibaumeintrag aus HAProxy. Die CRL-Datei muss unbenutzt und aus allen crt-lists entfernt sein. “show ssl crl-file” zeigt den Status der CRL-Dateien an. Das Löschen funktioniert nicht bei einem Zertifikat, auf das in der Konfiguration direkt mit der Direktive “crl-file” verwiesen wird.
del ssl crt-list <filename> <certfile[:line]>
Löscht einen Eintrag aus einer crt-list. Dabei werden alle in den Frontends für diesen Eintrag verwendeten SNIs gelöscht. Wird ein Zertifikat mehrmals in einer crt-list verwendet, muss angegeben werden, welche Zeile gelöscht werden soll. Die Zeilennummern werden mit “show ssl crt-list -n <crtlist>” angezeigt.
del ssl ech <bind>
Löscht die ECH-Schlüssel einer bind-Zeile.
Das Format der bind-Zeile ist <frontend>/@<filename>:<linenum> (Beispiel: frontend1/@haproxy.conf
:19) oder <frontend>/<name>, wenn die bind-Zeile mit dem Schlüsselwort “name” benannt wurde.
Erfordert eine OpenSSL-Version mit ECH-Unterstützung. HAProxy muss mit USE_ECH=1 kompiliert sein. Dieser Befehl wird nur auf einer CLI-Verbindung im experimentellen Modus unterstützt (siehe “experimental-mode on”).
Siehe auch “show ssl ech”, “add ssl ech” und “ech” in Abschnitt 5.1 des Konfigurationshandbuchs.
Beispiel:
del ssl jwt <filename>
Entfernt ein bereits geladenes Zertifikat aus der Liste der Zertifikate, die für die JWT-Validierung verwendet werden können (siehe Konverter “jwt_verify_cert”). Dieser Befehl funktioniert nicht bei laufenden Transaktionen. Siehe auch die Befehle “add ssl jwt” und “show ssl jwt”. Weitere Informationen stehen bei der Zertifikatsoption “jwt”.
del server <backend>/<server>
Löscht einen entfernbaren Server aus dem Backend <backend>. Ein Server ist entfernbar, wenn er alle folgenden Bedingungen erfüllt:
- Andere Konfigurationselemente verweisen nicht auf ihn
- Er muss bereits im Wartungsmodus sein (siehe “disable server”)
- Er darf keine aktiven oder inaktiven Verbindungen haben
Ist eine dieser Bedingungen nicht erfüllt, schlägt der Befehl fehl.
Aktive Verbindungen haben mindestens eine laufende Anfrage. Ihr Beenden lässt sich mit “shutdown sessions server” beschleunigen. Es wird dringend empfohlen, vor “del server” den Befehl “wait srv-removable” zu verwenden, um sicherzustellen, dass alle aktiven oder inaktiven Verbindungen geschlossen sind und der Befehl gelingt.
disable agent <backend>/<server>
Kennzeichnet die zusätzliche Agent-Prüfung als vorübergehend angehalten.
Wird aufgrund des Parameters agent-check einer server-Direktive eine Agent-Prüfung als zusätzliche Prüfung ausgeführt, werden neue Prüfungen nur initialisiert, wenn der Agent aktiviert ist. Daher verhindert disable agent das Starten neuer Agent-Prüfungen, bis der Agent mit enable agent wieder aktiviert wird.
Wenn ein Agent deaktiviert wird, werden zusätzliche Agent-Prüfungen, die noch bei aktiviertem Agenten gestartet wurden, wie folgt verarbeitet: Alle Ergebnisse, die das Gewicht ändern würden, insbesondere “drain” oder ein vom Agenten zurückgegebenes Gewicht, werden ignoriert. Ansonsten bleibt die Verarbeitung der Agent-Prüfung unverändert.
Diese Funktion soll die gewichtsändernde Wirkung der Agent-Prüfungen anhalten, damit das Gewicht eines Servers mit set weight eingestellt werden kann, ohne vom Agenten überschrieben zu werden.
Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind.
disable dynamic-cookie backend <backend>
Deaktiviert die Erzeugung dynamischer Cookies für das Backend <backend>
disable frontend <frontend>
Kennzeichnet das Frontend als vorübergehend angehalten. Dies entspricht dem bei einem sanften Neustart verwendeten Modus: Das Frontend gibt den Port frei, kann bei Bedarf aber wieder aktiviert werden. Dies sollte mit Vorsicht verwendet werden, da einige Betriebssysteme außer Linux es nicht wieder aktivieren können. Diese Funktion ist für Umgebungen vorgesehen, in denen das Anhalten eines Proxys undenkbar ist, aber ein falsch konfigurierter Proxy korrigiert werden muss. So lässt sich der Port freigeben und von einem anderen Prozess binden, um den Betrieb wiederherzustellen. Das Frontend wird auf der Statistikseite mit dem Status “STOP” angezeigt.
Das Frontend kann entweder über seinen Namen oder über seine numerische ID mit vorangestelltem Rautezeichen (’#’) angegeben werden.
Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind.
disable health <backend>/<server>
Kennzeichnet den primären Health Check als vorübergehend angehalten. Dadurch werden keine Health Checks mehr gesendet, und das Ergebnis des letzten Health Checks wird ignoriert. Der Server befindet sich im ungeprüften Zustand und gilt als UP, sofern eine zusätzliche Agent-Prüfung ihn nicht auf DOWN setzt.
Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind.
disable server <backend>/<server>
Kennzeichnet den Server für Wartungsarbeiten als DOWN. In diesem Modus werden keine weiteren Prüfungen auf dem Server ausgeführt, bis er den Wartungsmodus verlässt. Wird der Server von anderen Servern verfolgt, werden auch diese während der Wartung auf DOWN gesetzt.
Auf der Statistikseite wird ein wegen Wartung auf DOWN gesetzter Server mit dem Status “MAINT” angezeigt; Server, die ihn verfolgen, erscheinen mit “MAINT(via)”.
Sowohl das Backend als auch der Server können entweder über ihren Namen oder über ihre numerische ID mit vorangestelltem Rautezeichen (’#’) angegeben werden.
Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind.
dump ssl cert <certfile>
Gibt ein in den HAProxy-Speicher geladenes Zertifikat aus. Die Ausgabe erfolgt im PEM-Format: zuerst der private Schlüssel, dann das Endzertifikat und schließlich die Zertifikatskette. Auch eine Transaktion kann ausgegeben werden, indem dem Dateinamen ein Sternchen vorangestellt wird. Dies ist nützlich, um Zertifikate im Dateisystem zu speichern, wenn sie über die CLI und nicht im Dateisystem aktualisiert wurden.
Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind.
Beispiele:
dump stats-file
Erzeugt eine Statistikdatei (stats-file), mit der die HAProxy-Zählerwerte beim Start vorgeladen werden können. Weitere Einzelheiten stehen im Abschnitt „Statistikdatei“.
echo <text>
Gibt Text über die CLI aus. Dies kann nützlich sein, um Kommentare zwischen Befehlen auszugeben, wenn die Ergebnisse mehrerer Befehle ausgegeben werden.
Beispiel:
enable agent <backend>/<server>
Setzt eine vorübergehend angehaltene zusätzliche Agent-Prüfung fort.
Einzelheiten zu den Auswirkungen des vorübergehenden Startens und Anhaltens eines zusätzlichen Agenten stehen unter “disable agent”.
Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind.
enable dynamic-cookie backend <backend>
Aktiviert die Erzeugung dynamischer Cookies für das Backend <backend>. Außerdem muss ein geheimer Schlüssel bereitgestellt werden.
enable frontend <frontend>
Setzt ein vorübergehend angehaltenes Frontend fort. Einige der lauschenden Ports können möglicherweise nicht mehr gebunden werden (etwa wenn ein anderer Prozess sie seit der Operation ‘disable frontend’ belegt hat). In diesem Fall wird ein Fehler angezeigt. Manche Betriebssysteme können ein deaktiviertes Frontend möglicherweise nicht wieder aktivieren.
Das Frontend kann entweder über seinen Namen oder über seine numerische ID mit vorangestelltem Rautezeichen (’#’) angegeben werden.
Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind.
enable health <backend>/<server>
Setzt einen vorübergehend angehaltenen primären Health Check fort. Dadurch werden wieder Health Checks gesendet. Einzelheiten stehen unter “disable health”.
Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind.
enable server <backend>/<server>
Wenn der Server zuvor für Wartungsarbeiten als DOWN gekennzeichnet wurde, wird er als UP gekennzeichnet und die Prüfungen werden wieder aktiviert.
Sowohl das Backend als auch der Server können entweder über ihren Namen oder über ihre numerische ID mit vorangestelltem Rautezeichen (’#’) angegeben werden.
Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind.
experimental-mode [on|off]
Ohne Optionen zeigt dieser Befehl an, ob der experimentelle Modus für die aktuelle Verbindung aktiviert oder deaktiviert ist. Mit “on” wird der experimentelle Modus nur für die aktuelle CLI-Verbindung aktiviert, mit “off” deaktiviert.
Der experimentelle Modus ermöglicht den Zugriff auf zusätzliche Funktionen, die sich noch in Entwicklung befinden. Diese Funktionen sind derzeit nicht stabil und sollten mit Vorsicht verwendet werden. Zwischen Versionen können inkompatible Änderungen auftreten.
Bei Verwendung über die Master-CLI sollte dieser Befehl kein Präfix erhalten, da er den Modus für jeden Worker setzt, wenn eine Verbindung zu dessen CLI hergestellt wird.
Beispiel:
expert-mode [on|off]
Dieser Befehl ähnelt experimental-mode, schaltet jedoch den Expertenmodus um.
Der Expertenmodus zeigt Expertenbefehle an, die für den Prozess äußerst gefährlich sein können und Entwicklern gelegentlich helfen, wichtige Informationen über komplexe Fehler zu sammeln. Eine Fehlanwendung dieser Funktionen führt wahrscheinlich zu einem Prozessabsturz. Diese Option darf nur nach entsprechender Aufforderung verwendet werden. Dieser Befehl wird bewusst nicht in der Hilfemeldung aufgelistet. Er ist nur auf der Berechtigungsstufe admin zugänglich. Ein Wechsel auf eine andere Stufe setzt den Expertenmodus automatisch zurück.
Bei Verwendung über die Master-CLI sollte dieser Befehl kein Präfix erhalten, da er den Modus für jeden Worker setzt, wenn eine Verbindung zu dessen CLI hergestellt wird.
Beispiel:
get map <map> <value>
Sucht den Wert <value> in der Map <map> oder in der ACL <acl>. <map> oder <acl> stehen für die von “show map” oder “show acl” zurückgegebene #<id> oder den zurückgegebenen <name>. Dieser Befehl gibt alle übereinstimmenden Muster zurück, die dieser Map zugeordnet sind. Dies ist bei der Fehlerdiagnose von Maps und ACLs nützlich. Das Ausgabeformat besteht aus einer Zeile pro Abgleichstyp. Jede Zeile besteht aus einer Folge von Wörtern, die durch Leerzeichen getrennt sind.
Die ersten beiden Wörter sind:
Die folgenden Wörter werden nur zurückgegeben, wenn das Muster auf einen Eintrag zutrifft.
`<index type>`: "tree" oder "list". Der interne Suchalgorithmus.
`<case>`: "case-insensitive" oder "case-sensitive". Die
Berücksichtigung der Groß-/Kleinschreibung.
`<entry matched>`: match="`<entry>`". Gibt das übereinstimmende Muster zurück.
Dies ist bei regulären Ausdrücken nützlich.
Die letzten beiden Wörter zeigen den zurückgegebenen Wert und seinen Typ an. Im Fall “acl” existiert das Muster nicht.
return=nothing: Keine Rückgabe, da es keine "map" gibt.
return="`<value>`": Der als Zeichenfolge zurückgegebene Wert.
return=cannot-display: Der Wert kann nicht in eine Zeichenfolge umgewandelt werden.
type="`<type>`": Der Typ des zurückgegebenen Samples.
get var <name>
Zeigt Existenz, Typ und Inhalt der prozessweiten Variablen ’name’ an. Nur prozessweite Variablen sind lesbar, daher muss der Name mit ‘proc.’ beginnen; andernfalls wird keine Variable gefunden. Dieser Befehl erfordert die Berechtigungsstufe “operator” oder “admin”.
get weight <backend>/<server>
Meldet das aktuelle und das anfängliche Gewicht des Servers <server> im Backend <backend>, oder einen Fehler, wenn eines von beiden nicht existiert. Das anfängliche Gewicht ist das in der Konfigurationsdatei angegebene. Beide sind normalerweise gleich, sofern das aktuelle Gewicht nicht geändert wurde. Sowohl das Backend als auch der Server können entweder über ihren Namen oder über ihre numerische ID mit vorangestelltem Rautezeichen (’#’) angegeben werden.
help [<command>]
Gibt die Liste bekannter Schlüsselwörter und ihrer grundlegenden Verwendung oder die zum angeforderten Befehl passenden Befehle aus. Dieselbe Hilfeanzeige erscheint auch bei unbekannten Befehlen.
httpclient [--htx] <method> <URI>
Startet eine HTTP-Client-Anfrage und gibt die Antwort über die CLI aus. Dies wird nur auf einer CLI-Verbindung im Expertenmodus unterstützt (siehe “expert-mode on”) und ist ausschließlich für die Fehlerdiagnose vorgesehen. Der httpclient kann einen Servernamen in der URL über den resolvers-Abschnitt “default” auflösen, der standardmäßig mit den DNS-Servern aus /etc/resolv.conf befüllt wird. Einen Host aus /etc/hosts kann er jedoch nicht auflösen, sofern kein lokaler dns-Daemon verwendet wird, der solche Namen auflösen kann.
Die Option –htx ermöglicht es, mit der Funktion htx_dump() die interne htx-Darstellung von HAProxy zu verwenden, die hauptsächlich der Fehlerdiagnose dient.
new ssl ca-file <cafile>
Erzeugt einen neuen leeren CA-Dateibaumeintrag, der mit einem Satz von CA-Zertifikaten befüllt und einer crt-list hinzugefügt werden soll. Dieser Befehl sollte in Kombination mit “set ssl ca-file”, “add ssl ca-file” und “add ssl crt-list” verwendet werden.
new ssl cert <filename>
Erzeugt einen neuen leeren SSL-Zertifikatsspeicher, der mit einem Zertifikat befüllt und einem Verzeichnis oder einer crt-list hinzugefügt werden soll. Dieser Befehl sollte in Kombination mit “set ssl cert” und “add ssl crt-list” verwendet werden.
new ssl crl-file <crlfile>
Erzeugt einen neuen leeren CRL-Dateibaumeintrag, der mit einem Satz von CRLs befüllt und einer crt-list hinzugefügt werden soll. Dieser Befehl sollte in Kombination mit “set ssl crl-file” und “add ssl crt-list” verwendet werden.
prepare acl <acl>
Weist in der ACL <acl> eine neue Versionsnummer für eine atomare Ersetzung zu. <acl> ist die von “show acl” zurückgegebene #<id> oder der zurückgegebene <name>. Die neue Versionsnummer wird in der Antwort nach “New version created:” angezeigt. Mit dieser Nummer lässt sich anschließend das Hinzufügen neuer ACL-Einträge vorbereiten, die nach ihrer Übernahme die aktuellen Einträge atomar ersetzen. Sie wird in “show acl” als “next_ver” gemeldet. Das Zuweisen neuer Versionen hat keine Auswirkungen, da ungenutzte Versionen automatisch entfernt werden, sobald eine neuere Version übernommen wird. Versionsnummern sind vorzeichenlose 32-Bit-Werte, die am Ende ihres Wertebereichs wieder am Anfang beginnen; beim Vergleich in einem externen Programm ist daher Vorsicht erforderlich. Dieser Befehl kann nicht verwendet werden, wenn die Referenz <acl> ein Name ist, der auch für eine Map verwendet wird. In diesem Fall muss stattdessen der Befehl “prepare map” verwendet werden.
prepare map <map>
Weist in der Map <map> eine neue Versionsnummer für eine atomare Ersetzung zu. <map> ist die von “show map” zurückgegebene #<id> oder der zurückgegebene <name>. Die neue Versionsnummer wird in der Antwort nach “New version created:” angezeigt. Mit dieser Nummer lässt sich anschließend das Hinzufügen neuer Map-Einträge vorbereiten, die nach ihrer Übernahme die aktuellen Einträge atomar ersetzen. Sie wird in “show map” als “next_ver” gemeldet. Das Zuweisen neuer Versionen hat keine Auswirkungen, da ungenutzte Versionen automatisch entfernt werden, sobald eine neuere Version übernommen wird. Versionsnummern sind vorzeichenlose 32-Bit-Werte, die am Ende ihres Wertebereichs wieder am Anfang beginnen; beim Vergleich in einem externen Programm ist daher Vorsicht erforderlich.
prompt [help | n | i | p | timed]*
Ändert das Verhalten des interaktiven Modus und die am Zeilenanfang angezeigte Eingabeaufforderung: - “help”: zeigt die Verwendung des Befehls an - “n”: wechselt in den nicht interaktiven Modus - “i”: wechselt in den interaktiven Modus - “p”: wechselt in den interaktiven Modus mit Eingabeaufforderung - “timed”: schaltet die Zeitanzeige in der Eingabeaufforderung um
Ohne Option wird zwischen dem Modus mit Eingabeaufforderung und dem nicht interaktiven Modus gewechselt. Im nicht interaktiven Modus wird die Verbindung geschlossen, sobald der letzte Befehl der aktuellen Zeile abgeschlossen ist. Im interaktiven Modus wird die Verbindung nach Abschluss eines Befehls nicht geschlossen, sodass ein weiterer eingegeben werden kann. Im Modus mit Eingabeaufforderung bleibt der interaktive Modus aktiv; am Zeilenanfang erscheint eine Eingabeaufforderung, die anzeigt, dass der Interpreter auf einen neuen Befehl wartet. Die Eingabeaufforderung besteht aus einer schließenden spitzen Klammer mit nachfolgendem Leerzeichen “> “.
Der Modus mit Eingabeaufforderung eignet sich eher für menschliche Benutzer, der interaktive Modus für fortgeschrittene Skripte und der nicht interaktive Modus (Standard) für einfache Skripte. Der nicht interaktive Modus ist für den Master-Socket nicht verfügbar.
publish backend <backend>
Aktiviert die Weiterleitung von Inhalten zu einer Backend-Instanz. Dies ist die Umkehrung des Befehls “unpublish backend”. Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufen “operator” oder “admin” konfiguriert sind.
quit
Schließt die Verbindung im interaktiven Modus.
set anon [on|off] [<key>]
Dieser Befehl aktiviert oder deaktiviert den „anonymisierten Modus“ für die aktuelle CLI-Sitzung. Dabei werden bestimmte als sensibel oder vertraulich eingestufte Felder in Befehlsausgaben durch Hashes ersetzt. Diese erhalten genügend Konsistenz zwischen den Elementen, damit Entwickler bei der Fehlersuche Beziehungen zwischen ihnen erkennen können. Zugleich ist ihre Bitzahl (24) niedrig genug, um sie wegen der großen Anzahl möglicher Treffer nicht umkehrbar zu machen. Wird der Modus ohne Angabe eines Schlüssels aktiviert, wird der globale Schlüssel verwendet (entweder in der Konfigurationsdatei mit “anonkey” angegeben oder über den CLI-Befehl “set anon global-key” gesetzt). Wurde kein solcher Schlüssel gesetzt, wird ein zufälliger erzeugt. Andernfalls kann der für die aktuelle Sitzung zu verwendende 32-Bit-Schlüssel angegeben werden, etwa um den Schlüssel einer früheren Ausgabe wiederzuverwenden und Ausgaben leichter zu vergleichen. Entwickler benötigen diesen Schlüssel nie. Es wird empfohlen, ihn niemals weiterzugeben, da er es ermöglichen könnte, Vermutungen darüber zu bestätigen oder zu widerlegen, was bestimmte Hashes verbergen.
set dynamic-cookie-key backend <backend> <value>
Ändert den geheimen Schlüssel, der zur Erzeugung dynamischer Cookies für die Sitzungsbindung verwendet wird. Dadurch werden bestehende Sitzungen unterbrochen.
set anon global-key <key>
Setzt den globalen Anonymisierungsschlüssel auf <key>. Dieser muss eine 32-Bit-Ganzzahl zwischen 0 und 4294967295 sein (0 deaktiviert den globalen Schlüssel). Dieser Befehl erfordert admin-Berechtigungen.
set map <map> [<key>|#<ref>] <value>
Ändert den Wert, der jedem Schlüssel <key> in einer Map <map> entspricht. <map> ist die von “show map” zurückgegebene #<id> oder der zurückgegebene <name>. Wird anstelle von <key> die Referenz <ref> verwendet, wird nur der Eintrag geändert, auf den <ref> verweist. Der neue Wert ist <value>.
set maxconn frontend <frontend> <value>
Ändert die maxconn-Einstellung des angegebenen Frontends dynamisch. Jeder positive Wert einschließlich null ist zulässig; Werte oberhalb des globalen maxconn sind jedoch wenig sinnvoll. Wird die Grenze erhöht und warten Verbindungen, werden sie sofort angenommen. Wird sie auf einen Wert unterhalb der aktuellen Verbindungszahl gesenkt, wird die Annahme neuer Verbindungen verzögert, bis der Schwellenwert erreicht ist. Das Frontend kann entweder über seinen Namen oder über seine numerische ID mit vorangestelltem Rautezeichen (’#’) angegeben werden.
set maxconn server <backend/server> <value>
Ändert die maxconn-Einstellung des angegebenen Servers dynamisch. Jeder positive Wert einschließlich null ist zulässig; Werte oberhalb des globalen maxconn sind jedoch wenig sinnvoll.
set maxconn global <maxconn>
Ändert die globale maxconn-Einstellung dynamisch innerhalb des Bereichs, den die anfängliche globale maxconn-Einstellung vorgibt. Wird sie erhöht und warten Verbindungen, werden sie sofort angenommen. Wird sie auf einen Wert unterhalb der aktuellen Verbindungszahl gesenkt, wird die Annahme neuer Verbindungen verzögert, bis der Schwellenwert erreicht ist. Der Wert null stellt die anfängliche Einstellung wieder her.
set profiling memory { on | off }
Aktiviert oder deaktiviert CPU- oder Speicher-Profiling für das angegebene Teilsystem. Dies entspricht dem Setzen oder Löschen der “profiling”-Einstellungen im Abschnitt “global” der Konfigurationsdatei. Siehe auch “show profiling”. Wird das Aufgaben-Profiling manuell auf “on” gesetzt, werden die Scheduler-Statistiken automatisch zurückgesetzt. So lässt sich die Aktivität über ein bestimmtes Zeitintervall prüfen. Das Speicher-Profiling ist auf bestimmte Betriebssysteme beschränkt (funktioniert bekanntermaßen auf dem Ziel linux-glibc) und erfordert, dass USE_MEMORY_PROFILING beim Kompilieren gesetzt ist.
Beim Aufgaben-Profiling lässt sich das Erfassen der Sperr- und Speicherzeiten pro Aufgabe zur Laufzeit aktivieren oder deaktivieren. Die Änderung wird jedoch erst berücksichtigt, wenn das Profiling das nächste Mal von off/auto auf on wechselt (automatisch oder manuell). Wird mit “no-lock” das Sperr-Profiling pro Aufgabe deaktiviert, um CPU-Zyklen zu sparen, wird daher empfohlen, das Aufgaben-Profiling aus- und wieder einzuschalten, um die Änderung zu übernehmen.
set rate-limit connections global <value>
Ändert die prozessweite Begrenzung der Verbindungsrate, die durch die globale Einstellung ‘maxconnrate’ festgelegt wird. Der Wert null deaktiviert die Begrenzung. Diese Grenze gilt für alle Frontends, und die Änderung wirkt sofort. Der Wert wird als Anzahl der Verbindungen pro Sekunde angegeben.
set rate-limit http-compression global <value>
Ändert die maximale Eingangsrate der Komprimierung, die durch die globale Einstellung ‘maxcomprate’ festgelegt wird. Der Wert null deaktiviert die Begrenzung. Der Wert wird in Kilobytes pro Sekunde angegeben. In “show info” ist er in der Zeile “CompressBpsRateLim” in Bytes verfügbar.
set rate-limit sessions global <value>
Ändert die prozessweite Begrenzung der Sitzungsrate, die durch die globale Einstellung ‘maxsessrate’ festgelegt wird. Der Wert null deaktiviert die Begrenzung. Diese Grenze gilt für alle Frontends, und die Änderung wirkt sofort. Der Wert wird als Anzahl der Sitzungen pro Sekunde angegeben.
set rate-limit ssl-sessions global <value>
Ändert die prozessweite Begrenzung der SSL-Sitzungsrate, die durch die globale Einstellung ‘maxsslrate’ festgelegt wird. Der Wert null deaktiviert die Begrenzung. Diese Grenze gilt für alle Frontends, und die Änderung wirkt sofort. Der Wert wird als Anzahl der pro Sekunde an den SSL-Stack übergebenen Sitzungen angegeben. Die Begrenzung greift vor dem Handshake, um den Stack vor Handshake-Missbrauch zu schützen.
set server <backend>/<server> addr <ip4 or ip6 address> [port <port>]
Ersetzt die aktuelle IP-Adresse eines Servers durch die angegebene. Optional kann mit dem Parameter ‘port’ auch der Port geändert werden. Eine Portänderung unterstützt auch den Wechsel zur oder von der Portzuordnung (Schreibweise mit +X oder -Y), allerdings nur, wenn für den Health Check ein Port konfiguriert ist.
set server <backend>/<server> agent [ up | down ]
Erzwingt einen neuen Status für den Agenten eines Servers. Dies kann beispielsweise nützlich sein, um den Serverstatus sofort unabhängig von langsamen Agent-Prüfungen zu ändern. Die Änderung wird gegebenenfalls an Server weitergegeben, die diesen Server verfolgen.
set server <backend>/<server> agent-addr <addr> [port <port>]
Ändert die Adresse für Agent-Prüfungen eines Servers. Dadurch können Agent-Prüfungen zur Laufzeit auf eine andere Adresse umgestellt werden. Es können sowohl eine IP-Adresse als auch ein Hostname angegeben werden; letzterer wird aufgelöst. Optional kann auch der Agent-Port geändert werden.
set server <backend>/<server> agent-port <port>
Ändert den für Agent-Prüfungen verwendeten Port.
set server <backend>/<server> agent-send <value>
Ändert die Zeichenfolge, die an das Ziel der Agent-Prüfung gesendet wird. Damit kann die Zeichenfolge zusammen mit der Serveradresse aktualisiert werden, sodass beide weiterhin zusammenpassen.
set server <backend>/<server> health [ up | stopping | down ]
Erzwingt einen neuen Gesundheitsstatus für einen Server. Dies kann beispielsweise nützlich sein, um den Serverstatus sofort unabhängig von langsamen Health Checks zu ändern. Die Änderung wird gegebenenfalls an Server weitergegeben, die diesen Server verfolgen.
set server <backend>/<server> check-addr <ip4 | ip6> [port <port>]
Ändert die IP-Adresse für die Health Checks des Servers. Optional kann auch der für diese Health Checks verwendete Port geändert werden.
set server <backend>/<server> check-port <port>
Ändert den für Health Checks verwendeten Port auf <port>
set server <backend>/<server> state [ ready | drain | maint ]
Erzwingt einen neuen administrativen Status für einen Server. Dies kann nützlich sein, um die Lastverteilung und/oder jeglichen Datenverkehr zu einem Server zu deaktivieren. Der Status “ready” versetzt den Server in den normalen Modus; dies entspricht dem Befehl “enable server”. Der Status “maint” deaktiviert jeglichen Datenverkehr zum Server und sämtliche Health Checks; dies entspricht dem Befehl “disable server”. Der Modus “drain” nimmt den Server nur aus der Lastverteilung heraus, erlaubt aber weiterhin Prüfungen und neue Verbindungen mit Sitzungsbindung. Änderungen werden gegebenenfalls an Server weitergegeben, die diesen Server verfolgen.
set server <backend>/<server> weight <weight>[%]
Ändert das Gewicht eines Servers auf den als Argument angegebenen Wert. Dies entspricht genau dem weiter unten beschriebenen Befehl “set weight”.
set server <backend>/<server> fqdn <FQDN>
Ändert den FQDN eines Servers auf den als Argument angegebenen Wert. Dafür muss der zur Laufzeit verwendete interne DNS-Resolver für diesen Server konfiguriert und aktiviert sein.
set server <backend>/<server> ssl [ on | off ] (deprecated)
Diese Option konfiguriert die SSL-Verschlüsselung ausgehender Verbindungen zum Server. Wird sie ausgeschaltet, wird der gesamte Datenverkehr als Klartext übertragen; der Pfad der Health Checks bleibt unverändert.
Dieser Befehl ist veraltet. Stattdessen mit dem Befehl “add server” dynamisch einen neuen Server mit oder ohne SSL erzeugen.
set severity-output [ none | number | string ]
Ändert für die Dauer der aktuellen Sitzung das Format der Schweregradangabe in der Ausgabe des verbundenen Statistik-Sockets.
set ssl ca-file <cafile> <payload>
Dieser Befehl ist Teil eines Transaktionssystems; die Befehle “commit ssl ca-file” und “abort ssl ca-file” können erforderlich sein. Wenn keine Transaktion läuft, wird ein CA-Dateibaumeintrag erzeugt, in dem die in den Nutzdaten enthaltenen Zertifikate gespeichert werden. Der CA-Dateieintrag wird nicht im CA-Dateibaum gespeichert, sondern nur in einer temporären Transaktion gehalten. Existiert bereits eine Transaktion mit demselben Dateinamen, wird der bisherige CA-Dateieintrag gelöscht und durch den neuen ersetzt. Sobald die Änderungen abgeschlossen sind, muss die Transaktion mit “commit ssl ca-file” übernommen werden. Um mehrere Zertifikate einzeln hinzuzufügen, kann der Befehl “add ssl ca-file” verwendet werden.
Beispiel:
set ssl cert <filename> <payload>
Dieser Befehl ist Teil eines Transaktionssystems; die Befehle “commit ssl cert” und “abort ssl cert” können erforderlich sein. Das gesamte Transaktionssystem funktioniert mit jedem Zertifikat, das vom Befehl “show ssl cert” angezeigt wird, also mit jedem Frontend- oder Backend-Zertifikat. Wenn keine Transaktion läuft, wird das Zertifikat <filename> im Speicher in eine temporäre Transaktion dupliziert. Diese Transaktion wird anschließend mit der PEM-Datei aus den Nutzdaten aktualisiert. Existiert eine Transaktion mit demselben Dateinamen, wird sie aktualisiert. Auch mit einem Zertifikat verknüpfte Dateien (.issuer, .sctl, .ocsp usw.) können aktualisiert werden. Sobald die Änderungen abgeschlossen sind, muss die Transaktion mit “commit ssl cert” übernommen werden.
Dateien müssen über die CLI mit Vorsicht eingespielt werden, da eine Leerzeile das Ende der Nutzdaten signalisiert. Es wird empfohlen, eine bereinigte PEM-Datei einzuspielen. Eine einfache Methode ist, alle Leerzeilen zu entfernen und nur den Inhalt der PEM-Abschnitte beizubehalten. Dies lässt sich mit einem sed-Befehl erreichen.
Beispiel:
set ssl crl-file <crlfile> <payload>
Dieser Befehl ist Teil eines Transaktionssystems; die Befehle “commit ssl crl-file” und “abort ssl crl-file” können erforderlich sein. Wenn keine Transaktion läuft, wird ein CRL-Dateibaumeintrag erzeugt, in dem die in den Nutzdaten enthaltenen Sperrlisten gespeichert werden. Der CRL-Dateieintrag wird nicht im CRL-Dateibaum gespeichert, sondern nur in einer temporären Transaktion gehalten. Existiert bereits eine Transaktion mit demselben Dateinamen, wird der bisherige CRL-Dateieintrag gelöscht und durch den neuen ersetzt. Sobald die Änderungen abgeschlossen sind, muss die Transaktion mit “commit ssl crl-file” übernommen werden.
Beispiel:
set ssl ech <bind> <payload>
Ersetzt die ECH-Schlüssel einer bind-Zeile durch diesen Schlüssel. Die Nutzdaten müssen im PEM-for-ECH-Format vorliegen. (https://datatracker.ietf.org/doc/html/draft-farrell-tls-pemesni )
Das Format der bind-Zeile ist <frontend>/@<filename>:<linenum> (Beispiel: frontend1/@haproxy.conf
:19) oder <frontend>/<name>, wenn die bind-Zeile mit dem Schlüsselwort “name” benannt wurde.
Erfordert eine OpenSSL-Version mit ECH-Unterstützung. HAProxy muss mit USE_ECH=1 kompiliert sein. Dieser Befehl wird nur auf einer CLI-Verbindung im experimentellen Modus unterstützt (siehe “experimental-mode on”).
Siehe auch “show ssl ech”, “add ssl ech” und “ech” in Abschnitt 5.1 des Konfigurationshandbuchs.
$ openssl ech -public_name foobar.com -out foobar3.com.ech
$ echo -e "experimental-mode on;
set ssl ech frontend1/@haproxy.conf:19 <<%EOF%\n$(cat foobar3.com.ech)\n%EOF%\n" | \
socat /tmp/haproxy.sock -
set new ECH configs for frontend1/@haproxy.conf:19
set ssl ocsp-response <response | payload>
Dieser Befehl aktualisiert eine OCSP-Antwort für ein Zertifikat (siehe “crt” in “bind”-Zeilen). Dabei werden dieselben Prüfungen durchgeführt wie beim erstmaligen Laden der Antwort. <response> muss als base64-kodierte Zeichenfolge der DER-kodierten Antwort des OCSP-Servers übergeben werden. Dieser Befehl wird mit BoringSSL nicht unterstützt.
Beispiel:
set ssl tls-key <id> <tlskey>
Setzt den nächsten TLS-Schlüssel für den Listener <id> auf <tlskey>. Dieser Schlüssel wird zum letzten Schlüssel, während der vorletzte zur Verschlüsselung verwendet wird (die anderen dienen nur der Entschlüsselung). Der älteste vorhandene TLS-Schlüssel wird überschrieben. <id> ist entweder eine numerische #<id> oder der von “show tls-keys” zurückgegebene <file>. <tlskey> ist ein base64-kodierter TLS-Ticket-Schlüssel mit 48 oder 80 Bytes (z. B. openssl rand 80 | openssl base64 -A).
set table <table> key <key> [data.<data_type> <value>]*
Erzeugt oder aktualisiert einen Stick-Table-Eintrag in der Tabelle. Ist der Schlüssel nicht vorhanden, wird ein Eintrag eingefügt. Alle möglichen Werte für <data_type> stehen unter stick-table in Abschnitt 4.2. Die wahrscheinlich häufigste Verwendung ist das dynamische Eintragen von Quell-IP-Adressen mit einem Flag in gpc0, um eine IP-Adresse dynamisch zu sperren oder ihre Dienstqualität zu beeinflussen. In einem einzigen Aufruf können mehrere data_types übergeben werden.
Für einen bestehenden Eintrag kann optional statt der Suche über den Schlüssel eine Suche über ptr verwendet werden: <ptr> wird in der Form 0xffff geschrieben und muss der Adresse entsprechen, die ein zuvor ausgeführter “show table”-Befehl zurückgegeben hat. Das Identifizieren eines Eintrags über seinen Zeiger kann sinnvoll sein, wenn dies über den Schlüssel wegen eines leeren Schlüssels oder mit der CLI inkompatibler Zeichen nicht möglich ist.
Wenn data.<data_type> ein Array-Typ ist, kann mit “[]” auf einen bestimmten Index im Array zugegriffen werden, etwa so: data.gpt[1]
set timeout cli <delay>
Ändert die Zeitüberschreitung der CLI-Schnittstelle für die aktuelle Verbindung. Dies kann bei langen Diagnosesitzungen nützlich sein, in denen fortlaufend bestimmte Indikatoren geprüft werden müssen, ohne dass die Verbindung getrennt wird. Die Dauer wird in Sekunden angegeben.
set var <name> <expression>
Ermöglicht es, die prozessweite Variable ’name’ mit dem Ergebnis des Ausdrucks <expression> oder der Formatzeichenfolge <format> zu setzen oder zu überschreiben. Nur prozessweite Variablen können verwendet werden, daher muss der Name mit ‘proc.’ beginnen; andernfalls wird keine Variable gesetzt. <expression> und <format> dürfen nur „interne“ Sample-Abruf-Schlüsselwörter und Konverter enthalten. Am ehesten nützlich sind dabei str(‘something’), int(), einfache Zeichenfolgen oder Verweise auf andere Variablen. Der Befehlszeilenparser berücksichtigt keine Anführungszeichen, daher muss jedem Leerzeichen im Ausdruck ein umgekehrter Schrägstrich vorangestellt werden. Dieser Befehl erfordert die Berechtigungsstufe “operator” oder “admin”. Er wird nur auf einer CLI-Verbindung im experimentellen Modus unterstützt (siehe “experimental-mode on”).
set weight <backend>/<server> <weight>[%]
Ändert das Gewicht eines Servers auf den als Argument angegebenen Wert. Endet der Wert mit dem Zeichen ‘%’, ist das neue Gewicht relativ zum ursprünglich konfigurierten Gewicht. Absolute Gewichte zwischen 0 und 256 sind zulässig. Relative Gewichte müssen positiv sein; das resultierende absolute Gewicht wird begrenzt auf 256. Für Server einer Servergruppe mit statischem Lastverteilungsalgorithmus gelten strengere Einschränkungen, da das einmal gesetzte Gewicht nicht mehr geändert werden kann. Für diese Server sind daher nur die Werte 0 und 100% zulässig (oder 0 und das anfängliche Gewicht). Änderungen wirken sofort, manche LB-Algorithmen benötigen jedoch eine bestimmte Anzahl von Anfragen, um die Änderungen zu berücksichtigen. Typischerweise wird mit diesem Befehl ein Server während einer Aktualisierung deaktiviert, indem sein Gewicht auf null gesetzt wird. Nach der Aktualisierung wird er wieder aktiviert, indem das Gewicht auf 100% zurückgesetzt wird. Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind. Sowohl das Backend als auch der Server können entweder über ihren Namen oder über ihre numerische ID mit vorangestelltem Rautezeichen (’#’) angegeben werden.
show acl [[@<ver>] <acl>]
Gibt Informationen über ACL-Konverter aus. Ohne Argument wird die Liste aller verfügbaren ACLs zurückgegeben. Wird eine <acl> angegeben, wird ihr Inhalt ausgegeben. <acl> ist die #<id> oder der <name>. Standardmäßig wird die aktuelle Version der ACL angezeigt (die Version, gegen die derzeit geprüft wird und die in der ACL-Liste als ‘curr_ver’ gemeldet wird). Andere Versionen können ausgegeben werden, indem ‘@<ver>’ vor den ACL-Bezeichner gesetzt wird. Die Version wirkt als Filter; nicht vorhandene Versionen liefern einfach kein Ergebnis. Das Ausgabeformat ist dasselbe wie bei Maps, auch für die Sample-Werte. Die zurückgegebenen Daten sind keine Liste verfügbarer ACLs, sondern eine Liste aller Muster, aus denen ACLs bestehen. Viele dieser Muster können auch von Maps verwendet werden. Der Wert ’entry_cnt’ zählt alle ACL-Einträge, nicht nur die aktiven. Er enthält daher auch Einträge, die gerade hinzugefügt werden.
show anon
Zeigt den aktuellen Zustand des anonymisierten Modus (aktiviert oder deaktiviert) und den Schlüssel der aktuellen Sitzung an.
show backend
Gibt die Liste der im laufenden Prozess verfügbaren Backends aus
show cli level
Zeigt die CLI-Berechtigungsstufe der aktuellen CLI-Sitzung an. Das Ergebnis kann ‘admin’, ‘operator’ oder ‘user’ sein. Siehe auch die Befehle ‘operator’ und ‘user’.
Beispiel:
operator
Senkt die CLI-Berechtigungsstufe der aktuellen CLI-Sitzung auf operator. Sie kann nicht erhöht werden. Außerdem werden Expertenmodus und experimenteller Modus deaktiviert. Siehe auch “show cli level”.
unpublish backend <backend>
Schließt das Backend von der Auswahl für künftigen Datenverkehr aus. Dadurch werden use_backend- / default_backend-Regeln, die darauf verweisen, ignoriert und die nächsten Regeln zur inhaltsabhängigen Weiterleitung ausgewertet. Anders als bei deaktivierten Backends bleiben die Health Checks der Server aktiv. Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufen “operator” oder “admin” konfiguriert sind.
user
Senkt die CLI-Berechtigungsstufe der aktuellen CLI-Sitzung auf user. Sie kann nicht erhöht werden. Außerdem werden Expertenmodus und experimenteller Modus deaktiviert. Siehe auch “show cli level”.
show activity [-1 | 0 | thread_num]
Meldet einige Zähler zu internen Ereignissen, die Entwicklern und allgemein Personen mit ausreichender HAProxy-Kenntnis helfen, die Ursachen gemeldeten ungewöhnlichen Verhaltens einzugrenzen. Ein typisches Beispiel wäre ein korrekt laufender Prozess, der nie schläft und 100% der CPU beansprucht. Die Ausgabe enthält eine Zeile pro Metrik mit den Zählern der einzelnen Threads in derselben Zeile. Diese Zähler haben 32 Bit und laufen während der Prozesslebensdauer über, was kein Problem ist, da dieser Befehl normalerweise zweimal aufgerufen wird. Die Felder sind bewusst nicht dokumentiert, damit ihre genaue Bedeutung im Code geprüft wird, der die Zähler aktualisiert. Diese Werte werden auch durch den Befehl “clear counters” zurückgesetzt. Bei Bereitstellungen mit mehreren Threads gibt die erste Spalte die Summe aller Threads an (oder je nach Art der Metrik den Durchschnitt). Die Werte aller Threads folgen in Thread-Reihenfolge in eckigen Klammern. Optional kann die Nummer des auszugebenden Threads als Argument angegeben werden. Der Sonderwert “0” meldet den aggregierten Wert (erste Spalte); “-1”, der Standardwert, zeigt alle Spalten an. Wie im Modus mit einem einzelnen Thread werden keine Klammern ausgegeben, wenn nur eine Spalte angefordert wird.
show cli sockets
Listet CLI-Sockets auf. Das Ausgabeformat besteht aus 3 durch Leerzeichen getrennten Feldern. Das erste Feld ist die Socket-Adresse: ein Unix-Socket, ein Paar aus ipv4-Adresse und Port oder ein entsprechendes ipv6-Paar. Sockets anderer Typen werden nicht ausgegeben. Das zweite Feld beschreibt die Berechtigungsstufe des Sockets: ‘admin’, ‘user’ oder ‘operator’. Das letzte Feld listet die Prozesse, an die der Socket gebunden ist, durch Kommas getrennt auf; es kann Nummern oder ‘all’ enthalten.
Beispiel:
show cache
Listet die konfigurierten Caches und die in jedem Cache-Baum gespeicherten Objekte auf.
$ echo ‘show cache’ | socat stdio /tmp/sock1 0x7f6ac6c5b03a: foobar (shctx:0x7f6ac6c5b000, available blocks:3918) 1 2 3 4
- Zeiger auf die Cache-Struktur
- Cache-Name
- Zeiger auf den mmap-Bereich (shctx)
- Anzahl der im shctx zur Wiederverwendung verfügbaren Blöcke
0x7f6ac6c5b4cc hash:286881868 vary:0x0011223344556677 size:39114 (39 blocks), refcount:9, expire:237 1 2 3 4 5 6 7
- Zeiger auf den Cache-Eintrag
- Die ersten 32 Bit des Hashes
- Sekundärer Hash des Eintrags bei vary
- Größe des Objekts in Bytes
- Anzahl der für das Objekt verwendeten Blöcke
- Anzahl der Transaktionen, die den Eintrag verwenden
- Ablaufzeit; kann negativ sein, wenn der Eintrag bereits abgelaufen ist
show dev
Dieser Befehl bündelt Informationen, die HAProxy-Entwickler benötigen könnten, um die Ursachen eines bestimmten Problems besser zu verstehen. Für den Benutzer sind sie im Allgemeinen nicht nützlich, ermöglichen Entwicklern aber das Ausschließen bestimmter Hypothesen. Das Format besteht ungefähr aus einer Reihe von Abschnitten mit eingerückten Zeilen und jeweils einem Element pro Zeile, etwa Betriebssystemtyp und -version, CPU-Typ oder FD-Grenzen beim Start. Manche Felder werden weggelassen, um Wiederholungen oder unnötige Ausgaben zu vermeiden, wenn sie keinen Mehrwert liefern (z. B. unbegrenzte Werte). Künftig können weitere Felder hinzukommen oder sich einige ändern. Diese Ausgabe ist nicht zur Auswertung durch Skripte gedacht und sollte nicht als besonders zuverlässig angesehen werden. Sie soll im Wesentlichen denen Zeit sparen, die sie lesen können.
Technisch werden diese Informationen unverändert aus einer internen Struktur entnommen, die sie beim Start zusammen speichert, damit sie auch nach einem Absturz in einer Core-Datei zu finden sind. Daher können Entwickler um eine frühzeitige Ausgabe eines normal arbeitenden Prozesses bitten, um sie mit einem Core-Dump oder zwischen mehreren Neuladevorgängen zu vergleichen (beispielsweise können sich manche Grenzwerte ändern). Ist die Anonymisierung aktiviert, werden auch alle möglicherweise sensiblen Werte anonymisiert (z. B. der Knotenname).
Beispielausgabe:
show env [<name>]
Gibt eine oder alle dem Prozess bekannten Umgebungsvariablen aus. Ohne Argument werden alle Variablen ausgegeben. Mit einem Argument wird nur die angegebene Variable ausgegeben, sofern sie existiert. Andernfalls erscheint “Variable not found”. Die Variablen werden in demselben Format ausgegeben, in dem sie gespeichert oder vom Dienstprogramm “env” zurückgegeben werden, also “<name>=<value>”. Dies kann bei der Fehlerdiagnose von Konfigurationsdateien mit vielen Umgebungsvariablen hilfreich sein, um sicherzustellen, dass diese die erwarteten Werte enthalten. Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufen “operator” oder “admin” konfiguriert sind.
show errors [<iid>|<proxy>] [request|response]
Gibt die zuletzt bekannten, von Frontends und Backends erfassten HTTP/1.x-Anfrage- und Antwortfehler aus. Wird <iid> angegeben, beschränkt sich die Ausgabe auf Fehler des Frontends oder Backends mit der ID <iid>. Die Proxy-ID “-1” bewirkt die Ausgabe aller Instanzen. Wird stattdessen ein Proxy-Name angegeben, wird dessen ID als Filter verwendet. Wird nach dem Proxy-Namen oder der ID “request” oder “response” hinzugefügt, werden nur Anfrage- oder Antwortfehler ausgegeben. Dieser Befehl ist eingeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufen “operator” oder “admin” konfiguriert sind.
Erfasst werden können die letzten Anfrage- und Antwortfehler durch Protokollverletzungen, häufig aufgrund ungültiger Zeichen in Header-Namen. Der Bericht gibt genau an, welches Zeichen das Protokoll verletzt hat. Weitere wichtige Informationen werden ebenfalls gemeldet: der genaue Zeitpunkt der Fehlererkennung, die Namen von Frontend und Backend, der Servername (falls bekannt), die interne Transaktions-ID und die Quelladresse, von der die Sitzung gestartet wurde.
Alle Zeichen werden zurückgegeben; nicht druckbare Zeichen werden kodiert. Die häufigsten (\t = 9, \n = 10, \r = 13 und \e = 27) werden als ein Buchstabe nach einem umgekehrten Schrägstrich kodiert. Der umgekehrte Schrägstrich selbst wird als ‘\\’ kodiert, um Verwechslungen zu vermeiden. Andere nicht druckbare Zeichen werden als ‘\xNN’ kodiert, wobei NN die zweistellige hexadezimale Darstellung des ASCII-Codes des Zeichens ist.
Den Zeilen wird die Position ihres ersten Zeichens vorangestellt, beginnend bei 0 für den Pufferanfang. Pro Ausgabezeile wird höchstens eine Eingabezeile ausgegeben. Lange Zeilen werden auf mehrere aufeinanderfolgende Ausgabezeilen verteilt, sodass die Ausgabe nie breiter als 79 Zeichen ist. Ein solcher Zeilenumbruch ist leicht zu erkennen: Die Zeile endet nicht mit ‘\n’, und auf den Offset der nächsten Zeile folgt ein ‘+’-Zeichen, das die Fortsetzung der vorherigen Zeile kennzeichnet.
Beispiel:
show events [<sink>] [-w] [-n] [-0] [-s]
Ohne Option werden alle bekannten Ereignissenken und ihre Typen aufgelistet. Mit einer Option werden alle verfügbaren Ereignisse der angegebenen Senke ausgegeben, sofern sie vom Typ buffer ist. Wird nach dem Namen der Senke die Option “-w” übergeben, wartet der Befehl nach Erreichen des Pufferendes auf neue Ereignisse und zeigt sie an. Die Operation kann durch eine beliebige Eingabe (die verworfen wird) oder durch Schließen der Sitzung beendet werden. Die Option “-n” springt direkt an das Pufferende. Dies ist oft in Kombination mit “-w” nützlich, um nur neue Ereignisse zu melden. Der Einfachheit halber können mit “-wn” oder “-nw” beide Optionen gleichzeitig aktiviert werden. Standardmäßig werden alle Ereignisse durch ein Zeilenvorschubzeichen (’\n’ oder 10 oder 0x0A) getrennt. Mit dem Argument “-0” kann stattdessen das NUL-Zeichen (’\0’ oder 0) verwendet werden. Die Option “-s” bereinigt die Ausgabe, damit Binärinhalte aus erfassten oder dekodierten Daten die Darstellung im Terminal nicht verändern. Leerraumzeichen (Leerzeichen und Tabulator) werden durch ein Leerzeichen ersetzt, sodass jeder Datensatz auf einer Zeile bleibt. Andere Steuerzeichen (0x00 bis 0x1F und 0x7F) sowie Nicht-ASCII-Zeichen (0x80 und darüber) werden durch ein ‘?’ ersetzt. Die Ausgabelänge bleibt erhalten. So können beim Ausgeben eines Rings weder ANSI-Escape-Sequenzen noch Codes für die Schreibrichtung in das Terminal des Operators eingeschleust werden. Dies ist nützlich beim Ausgeben in ein Terminal oder an ein Programm, dessen Eingabe nicht als Sonderzeichen interpretiert werden darf, etwa Überwachungsskripte, deren Ausgabe unverändert in Berichte übernommen wird.
show fd [-!plcfbsd]* [[<tgid>]/[<fd>] | <fd>]
Gibt entweder die Liste aller offenen Dateideskriptoren oder nur den Dateideskriptor mit der Nummer <fd> aus, wenn diese angegeben ist. Auch die Form “<tgid>/<fd>” ist zulässig. Dabei kann jede Seite als Platzhalter leer bleiben (”/<fd>” für fd <fd> über alle Thread-Gruppen hinweg, “<tgid>/” für alle fds von <tgid>). <tgid> wird derzeit eingelesen, aber ignoriert, bis künftig fd-Tabellen pro Thread-Gruppe unterstützt werden. Optional kann ein Satz von Flags übergeben werden, um die Ausgabe auf bestimmte FD-Typen zu beschränken oder bestimmte FD-Typen auszuschließen. Bei ‘-’ oder ‘!’ wird die Auswahl für die folgenden Zeichen desselben Arguments umgekehrt. Vor jedem durch Leerraum getrennten Argumentwort wird diese Umkehrung zurückgesetzt. Wählbare FD-Typen sind ‘p’ für Pipes, ’l’ für Listener, ‘c’ für Verbindungen (jeden Typs), ‘f’ für Frontend-Verbindungen, ‘b’ für Backend-Verbindungen (jeden Typs), ’s’ für Verbindungen zu Servern und ’d’ für Verbindungen zur “dispatch”-Adresse oder zur transparenten Adresse des Backends. Dabei ist ‘b’ eine Kurzform für ‘sd’ und ‘c’ für ‘fb’ oder ‘fsd’. ‘c!f’ entspricht ‘b’ (alle Verbindungen außer Frontend-Verbindungen sind tatsächlich Backend-Verbindungen). Dies richtet sich ausschließlich an Entwickler, die interne Zustände beobachten müssen, um komplexe Probleme wie ungewöhnliche CPU-Auslastung zu untersuchen. Pro Zeile wird ein fd gemeldet. Sein Zustand im Poller wird mit Großbuchstaben für aktivierte und Kleinbuchstaben für deaktivierte Flags ausgegeben: “P” für „abgefragt“, “R” für „bereit“ und “A” für „aktiv“. Der Ereignisstatus verwendet “H” für „Verbindungsende“, “E” für „Fehler“, “O” für „Ausgabe“, “P” für „Priorität“ und “I” für „Eingabe“. Weitere Flags sind etwa “N” für „neu“ (gerade dem fd-Cache hinzugefügt), “U” für „aktualisiert“ (eine Aktualisierung im fd-Cache erhalten), “L” für “linger_risk” und “C” für „geklont“. Anschließend folgen die Position des Cache-Eintrags, der Zeiger auf den internen Eigentümer sowie der Zeiger auf den I/O-Callback und dessen Name, falls bekannt. Ist der Eigentümer eine Verbindung, werden die Verbindungsflags und das Ziel gemeldet (Frontend, Proxy oder Server). Ist der Eigentümer ein Listener, werden dessen Zustand und Frontend gemeldet. Ohne gute Kenntnis der Interna ist die Verwendung dieses Befehls nicht sinnvoll. Das Ausgabeformat kann sich im Laufe der Zeit weiterentwickeln, daher darf diese Ausgabe nicht von Werkzeugen ausgewertet werden, die dauerhaft funktionieren sollen. Manche internen Strukturzustände können der auflistenden Funktion verdächtig erscheinen; in diesem Fall wird der Ausgabezeile ein Ausrufezeichen (’!’) angehängt. Dies kann bei der Diagnose eines Vorfalls einen Ausgangspunkt liefern.
show info [typed|json] [desc] [float]
Gibt Informationen über den HAProxy-Status im aktuellen Prozess aus. Wird “typed” als optionales Argument übergeben, werden auch Feldnummern, -namen und -typen ausgegeben. So können externe Überwachungsprodukte Informationen aus ihnen unbekannten Feldern leicht abrufen, gegebenenfalls aggregieren und anschließend melden. Jedes Feld wird in einer eigenen Zeile ausgegeben. Wird “json” als optionales Argument übergeben, werden die Informationen der “typed”-Ausgabe im JSON-Format als Liste von JSON-Objekten bereitgestellt. Standardmäßig enthält das Format nur zwei durch einen Doppelpunkt (’:’) getrennte Spalten: links den Feldnamen, rechts den Wert. Im typisierten Ausgabeformat ist die Ausgabe eines einzelnen Objekts zusammenhängend, sodass der Empfänger nicht alles auf einmal speichern muss. Dies ist besonders zu beachten. Wird “float” als optionales Argument übergeben, können einige normalerweise als Ganzzahlen ausgegebene Felder für höhere Genauigkeit als Gleitkommazahlen ausgegeben werden. Welche Felder betroffen sind, ist bewusst nicht festgelegt, da sich dies im Laufe der Zeit ändern kann. Die Verwendung dieser Option setzt voraus, dass der Empfänger Gleitkommazahlen verarbeiten kann. Das verwendete Ausgabeformat ist sprintf("%f”).
Beim typisierten Ausgabeformat besteht jede Zeile aus 4 durch Doppelpunkte (’:’) getrennten Spalten. Die erste Spalte enthält eine durch Punkte getrennte Folge von 3 Elementen. Das erste Element ist die numerische Position des Felds in der Liste (beginnend bei null). Diese Position darf sich im Laufe der Zeit nicht ändern. Je nach Build-Optionen oder wenn künftig Felder gelöscht werden, sind jedoch Lücken zu erwarten. Das zweite Element ist der Feldname, wie er in der Standardausgabe von “show info” erscheint. Das dritte Element ist die relative Prozessnummer, beginnend bei 1.
Der Rest der Zeile nach dem ersten Doppelpunkt folgt dem weiter oben beschriebenen „typisierten Ausgabeformat“. Die zweite Spalte (nach dem ersten ‘:’) gibt Herkunft, Art und Geltungsbereich der Variablen an. Die dritte Spalte enthält den Feldtyp, einen der Werte “s32”, “s64”, “u32”, “u64” und “str”. Die vierte Spalte enthält den Wert selbst, den der Empfänger anhand von Spalte 3 einlesen und anhand von Spalte 2 verarbeiten kann.
Damit lautet das gesamte Zeilenformat im typisierten Modus:
Wird “desc” an den Befehl angehängt, folgen ein weiterer Doppelpunkt und eine Zeichenfolge in Anführungszeichen mit einer Beschreibung der Metrik. Zum Zeitpunkt der Erstellung wird dies nur für das Ausgabeformat “typed” und das Standardformat unterstützt.
Beispiel:
Im typisierten Format erleichtert die Prozess-ID am Ende der ersten Spalte das visuelle Zusammenführen der Ausgaben mehrerer Prozesse. Beispiel:
Das Format der JSON-Ausgabe ist in einem Schema beschrieben, das mit “show schema json” ausgegeben werden kann.
Die JSON-Ausgabe enthält keinen zusätzlichen Leerraum, um den Umfang der Ausgabe zu verringern. Für die menschliche Lesbarkeit kann es hilfreich sein, die Ausgabe durch ein Formatierungsprogramm zu leiten. Beispiel:
$ echo “show info json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool
Die JSON-Ausgabe enthält keinen zusätzlichen Leerraum, um den Umfang der Ausgabe zu verringern. Für die menschliche Lesbarkeit kann es hilfreich sein, die Ausgabe durch ein Formatierungsprogramm zu leiten. Beispiel:
$ echo “show info json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool
show libs
Gibt auf Systemen, die dies unterstützen, die Liste geladener gemeinsam genutzter dynamischer Bibliotheken und Objektdateien aus. Soweit verfügbar, werden für jedes gemeinsam genutzte Objekt der Bereich virtueller Adressen, die Größe und der Pfad zum Objekt angegeben. So lässt sich beispielsweise abschätzen, welche Bibliothek eine in einer Ausgabe erscheinende Funktion bereitstellt. Auf vielen Systemen ändern sich die Adressen bei jedem Neustart (Adressraumrandomisierung). Diese Liste müsste daher beim Start abgerufen werden, wenn sie zur Analyse einer Core-Datei verwendet werden soll. Dieser Befehl kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufen “operator” oder “admin” konfiguriert sind. Das Ausgabeformat kann zwischen Betriebssystemen, Architekturen und sogar HAProxy-Versionen variieren; Skripte sollten sich nicht darauf verlassen.
show map [[@<ver>] <map>]
Gibt Informationen über Map-Konverter aus. Ohne Argument wird die Liste aller verfügbaren Maps zurückgegeben. Wird eine <map> angegeben, wird ihr Inhalt ausgegeben. <map> ist die #<id> oder der <name>. Standardmäßig wird die aktuelle Version der Map angezeigt (die Version, gegen die derzeit geprüft wird und die in der Map-Liste als ‘curr_ver’ gemeldet wird). Andere Versionen können ausgegeben werden, indem ‘@<ver>’ vor den Map-Bezeichner gesetzt wird. Die Version wirkt als Filter; nicht vorhandene Versionen liefern einfach kein Ergebnis. Der Wert ’entry_cnt’ zählt alle Map-Einträge, nicht nur die aktiven. Er enthält daher auch Einträge, die gerade hinzugefügt werden.
In der Ausgabe ist die erste Spalte eine eindeutige Eintragskennung, die als Referenz für die Operationen “del map” und “set map” verwendet werden kann. Die zweite Spalte ist das Muster, die dritte das Sample, sofern verfügbar. Die zurückgegebenen Daten sind keine unmittelbare Liste verfügbarer Maps, sondern eine Liste aller Muster, aus denen Maps bestehen. Viele dieser Muster können auch von ACLs verwendet werden.
show peers [dict|-] [<peers section>]
Gibt Informationen über die in “peers”-Abschnitten konfigurierten Peers aus. Ohne Argument werden die Peers aus allen “peers”-Abschnitten aufgelistet. Wird <peers section> angegeben, werden nur Informationen über die Peers dieses “peers”-Abschnitts ausgegeben. Wird vor dem Namen des peers-Abschnitts “dict” angegeben, werden auch die vollständigen Tx/Rx-Wörterbuch-Caches ausgegeben (sehr umfangreich). Um einen peers-Abschnitt namens “dict” auszugeben, muss möglicherweise “-” übergeben werden.
Hier folgen zwei Beispielausgaben, in denen die Peers hostA, hostB und hostC zu “sharedlb”-peers-Abschnitten gehören. Nur hostA und hostB sind verbunden. Nur hostA hat Daten an hostB gesendet.
$ echo “show peers” | socat - /tmp/hostA 0x55deb0224320: [15/Apr/2019:11:28:01] id=sharedlb
state=0 flags=0x3 \ resync_timeout=<PAST> task_calls=45122
0x55deb022b540: id=hostC(remote) addr=127.0.0.12:10002 status=CONN \
reconnect=4s confirm=0 flags=0x0 0x55deb022a440: id=hostA(local) addr=127.0.0.10:10000 status=NONE
\ reconnect=<NEVER> confirm=0 flags=0x0 0x55deb0227d70: id=hostB(remote)
addr=127.0.0.11:10001 status=ESTA reconnect=2s confirm=0 flags=0x20000200 appctx:0x55deb028fba0
st0=7 st1=0 task_calls=14456 \ state=EST xprt=RAW src=127.0.0.1:37257
addr=127.0.0.10:10000 remote_table:0x55deb0224a10 id=stkt local_id=1 remote_id=1
last_local_table:0x55deb0224a10 id=stkt local_id=1 remote_id=1 shared tables:
$ echo “show peers” | socat - /tmp/hostB 0x55871b5ab320: [15/Apr/2019:11:28:03] id=sharedlb
state=0 flags=0x3 \ resync_timeout=<PAST> task_calls=3 0x55871b5b2540:
id=hostC(remote) addr=127.0.0.12:10002 status=CONN \ reconnect=3s
confirm=0 flags=0x0 0x55871b5b1440: id=hostB(local) addr=127.0.0.11:10001 status=NONE
\ reconnect=<NEVER> confirm=0 flags=0x0 0x55871b5aed70: id=hostA(remote)
addr=127.0.0.10:10000 status=ESTA \ reconnect=2s confirm=0
flags=0x20000200 appctx:0x7fa46800ee00 st0=7 st1=0 task_calls=62356 \
state=EST remote_table:0x55871b5ab960 id=stkt local_id=1 remote_id=1 last_local_table:0x55871b5ab960
id=stkt local_id=1 remote_id=1 shared tables:
show pools [byname|bysize|byusage] [detailed] [match <pfx>] [<nb>]
Den Status der internen Speicherpools ausgeben. Dies ist beispielsweise hilfreich, um bei Verdacht auf ein Speicherleck die Speichernutzung zu verfolgen. Der Befehl bewirkt genau dasselbe wie SIGQUIT im Vordergrundbetrieb, leert jedoch die Pools nicht. Standardmäßig wird die Ausgabe nicht sortiert. Bei Angabe von “byname” wird nach Poolnamen sortiert; bei “bysize” nach der Größe der Elemente in absteigender Reihenfolge; bei “byusage” nach der Gesamtnutzung in absteigender Reihenfolge, wobei nur verwendete Einträge angezeigt werden. Die Ausgabe kann auch auf die ersten <nb> Einträge beschränkt werden (beispielsweise beim Sortieren nach Nutzung). Mit “detailed” lassen sich weitere interne Details ausgeben, einschließlich der Liste aller zusammengeführten Pools. Wird schließlich “match” mit einem nachfolgenden Präfix angegeben, werden nur Pools angezeigt, deren Name mit diesem Präfix beginnt. Die angegebene Gesamtsumme bezieht sich nur auf Pools, die den Filterkriterien entsprechen. Beispiel:
show profiling [{all | status | tasks | memory}] [byaddr|bytime|byctx|aggr|<max_lines>]*
Die aktuellen Profiling-Einstellungen zeilenweise sowie den zu ihrer Änderung erforderlichen Befehl ausgeben. Wenn das Task-Profiling aktiviert ist, werden auch einige vom Scheduler erfasste Statistiken je Funktion ausgegeben, zusammen mit einer Zusammenfassung der Anzahl der Aufrufe, der gesamten und durchschnittlichen CPU-Zeit sowie der gesamten und durchschnittlichen Latenz. Wenn das Speicher-Profiling aktiviert ist, werden beispielsweise die Anzahl der Speicherzuweisungen und -freigaben sowie ihre Größen gemeldet. Mit den entsprechenden Schlüsselwörtern kann die Ausgabe auf den Profiling-Status, die Tasks oder das Speicher-Profiling beschränkt werden; standardmäßig werden sämtliche Profiling-Informationen ausgegeben. Mit einem numerischen Grenzwert lässt sich auch die Anzahl der Ausgabezeilen je Kategorie beschränken. Die Ausgabe kann nach Adresse, gesamter Ausführungszeit oder Aufrufkontext statt nach Nutzung sortiert werden, etwa um aufeinanderfolgende Aufrufe leichter zu vergleichen oder Optimierungsbedarf zu ermitteln. Außerdem lässt sich die Task-Aktivität nach aufgerufener Funktion zusammenfassen, statt die Details anzuzeigen. Profiling richtet sich hauptsächlich an Entwickler, da es Hinweise darauf liefert, wo der Code CPU-Zyklen oder Speicher verschwendet. Für die Überwachung liefert diese Ausgabe keine nützlichen Informationen.
show resolvers [<resolvers section id>]
Statistiken für den angegebenen resolvers-Abschnitt ausgeben, oder für alle resolvers-Abschnitte, wenn kein Abschnitt angegeben wird.
Für jeden Nameserver werden die folgenden Zähler ausgegeben:
show quic [<format>] [<filter>]
Informationen zu allen aktiven QUIC-Frontend-Verbindungen ausgeben. Dieser Befehl ist zugriffsbeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufen “operator” oder “admin” konfiguriert sind.
Ein optionales Argument steuert den Detailgrad der Ausgabe. Sein Wert lässt sich auf verschiedene Weise interpretieren. Als erste Möglichkeit können vordefinierte Werte verwendet werden: “oneline” für das Standardformat, “stream” für die Auflistung aller aktiven Streams und “full” für die Anzeige sämtlicher Informationen. Alternativ kann eine kommagetrennte Liste von Feldern angegeben werden, um die Ausgabe zu beschränken. Derzeit werden die Werte “tp”, “sock”, “pktns”, “cc” und “mux” unterstützt. Schließlich zeigt “help” im Formatargument stattdessen eine ausführlichere Hilfe an.
Das letzte Argument beschränkt oder erweitert die Verbindungsliste. Standardmäßig werden nur aktive Frontend-Verbindungen angezeigt. Mit dem zusätzlichen Argument “clo” werden stattdessen Frontend-Verbindungen angezeigt, die gerade geschlossen werden, mit “be” Backend-Verbindungen und mit “all” alle Kategorien. Durch Angabe der hexadezimalen Adresse kann die Ausgabe auch auf eine einzelne Verbindung beschränkt werden.
show servers conn [<backend>]
Den Zustand der aktuellen und ungenutzten Verbindungen der Server ausgeben, die zum angegebenen Backend gehören (oder zu allen Backends, wenn keines angegeben wird). Es kann ein Backendname oder eine Kennung verwendet werden.
Die Ausgabe besteht aus einer Kopfzeile mit den Feldbezeichnungen und anschließend einer Zeile je Server mit Backendname und -ID, Servername und -ID, Adresse, Port sowie einer Reihe von Werten. Die Anzahl der Felder hängt von der Anzahl der Threads ab. Das genaue Ausgabeformat kann sich je nach Version und Threadanzahl geringfügig unterscheiden. Beim Extrahieren von Ausgabewerten muss die Kopfzeile beachtet werden, um die Spalten zuzuordnen. Auch die Threadanzahl ist zu berücksichtigen, da die letzten Spalten Werte je Thread enthalten:
HAProxy beendet alle <purge_delay> einen Teil von <idle_cur>, wenn die Summe aus <idle_cur> und <used_cur> den Schätzwert <need_est> überschreitet. Dieser Schätzwert ändert sich abhängig von der Verbindungsaktivität.
Da ungenutzte Verbindungen auf mehrere Threads verteilt sind, können sich einige Werte bereits nach dem Lesen ändern. Daher ist die Konsistenz innerhalb einer Zeile nicht gewährleistet. Diese Ausgabe dient hauptsächlich der Fehlersuche und eignet sich weder für die regelmäßige Überwachung noch für die grafische Darstellung.
show servers state [<backend>]
Den Zustand der Server ausgeben, die in der laufenden Konfiguration enthalten sind. Mit einem Backendnamen oder einer Kennung kann die Ausgabe auf dieses Backend beschränkt werden.
Die Ausgabe hat das folgende Format:
- Die erste Zeile enthält die Formatversion (1 in dieser Spezifikation);
- die zweite Zeile enthält die Spaltenüberschriften mit einem vorangestellten Rautezeichen (’#’);
- die dritte und alle weiteren Zeilen enthalten Daten;
- jede Zeile, die mit einem Rautezeichen (’#’) beginnt, gilt als Kommentar.
Da mehrere Ausgabeversionen nebeneinander existieren können, sind nachfolgend die Felder und ihre Reihenfolge je Dateiformatversion aufgeführt:
show sess [<options>*]
Alle bekannten aktiven Streams ausgeben (früher als „Sitzungen“ bezeichnet). Dies bei langsamen Verbindungen vermeiden, da die Ausgabe sehr groß sein kann. Dieser Befehl ist zugriffsbeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufen “operator” oder “admin” konfiguriert sind. Auf Rechnern, deren Verbindungen schnell erneuert werden, kann die Ausgabe weniger Einträge enthalten, als tatsächlich vorhanden sind: Ausgegeben werden alle bestehenden Streams bis zu dem letzten, der vor der Befehlseingabe angelegt wurde; Streams, die zwischenzeitlich beendet werden, erscheinen nicht. Die unterstützten Optionen sind weiter unten aufgeführt.
show sess [<id> | all | help] [<options>*]
Viele interne Informationen zu den passenden Streams anzeigen. Der Befehl kennt zwei Ausgabeformate: ein kurzes, das standardmäßig verwendet wird, wenn keine bestimmte Streamkennung angefordert wird, und ein erweitertes für die Auflistung bestimmter Streams. Das kurze Format, das “show sess” standardmäßig verwendet, gibt nur einen Stream je Zeile mit wenigen Informationen aus. Am Zeilenanfang steht die Streamkennung in hexadezimaler Form (sie entspricht dem Zeiger auf den Stream).
In der erweiterten Form, die “show sess <id>” oder “show sess all” verwendet, werden Streams mit sehr vielen Details zur Fehlersuche über mehrere Zeilen ausgegeben (jeweils etwa 20), weiterhin beginnend mit ihrer Kennung. Als Trennzeichen zwischen Streams dient hier die Kennung am Zeilenanfang; zusätzliche Zeilen desselben Streams beginnen mit einem oder mehreren Leerzeichen (die Streamausgabe ist eingerückt). Die Ausgabe vieler Streams kann sehr groß werden, viel Zeit beanspruchen und die CPU stark belasten. Daher ist es stets besser, nur das erforderliche Minimum auszugeben. Für die meisten Benutzer sind diese Informationen nutzlos, HAProxy-Entwickler können sie jedoch zur Untersuchung komplexer Fehler verwenden. Das genaue Ausgabeformat ist absichtlich nicht dokumentiert, damit es sich entsprechend den Anforderungen frei weiterentwickeln kann, auch in stabilen Entwicklungszweigen. Zur Interpretation dieser Ausgabe soll die Funktion strm_dump_to_buffer() in src/stream.c herangezogen werden, um die genaue Bedeutung bestimmter Felder zu ermitteln.
Das Argument “help” zeigt ausführliche Hinweise zur Verwendung des Befehls an, statt Streams auszugeben.
Mit Optionen lässt sich die Ausgabe anpassen oder filtern. Folgende Optionen werden unterstützt: - backend <b> zeigt nur Streams an, die diesem Backend zugeordnet sind - frontend <f> zeigt nur Streams an, die diesem Frontend zugeordnet sind - older <age> zeigt nur Streams an, die älter als <age> Sekunden sind - server <b/s> zeigt nur Streams an, die dieser Kombination aus Backend und Server zugeordnet sind - show-uri gibt die URI der Transaktion aus, wie sie während der Anfrageanalyse erfasst wurde. Sie wird nur angezeigt, wenn sie erfasst wurde. - susp zeigt nur Streams an, die Entwickler anhand von Kriterien als verdächtig einstufen, die sich im Laufe der Zeit oder zwischen Versionen ändern können.
show stat [domain <resolvers|proxy>] [{<iid>|<proxy>} <type> <sid>] \
Statistiken ausgeben. Die Domäne bestimmt, welche Statistiken ausgegeben werden; derzeit stehen resolvers und proxy zur Verfügung. Standardmäßig wird das CSV-Format verwendet. Das oben beschriebene erweiterte typisierte Ausgabeformat lässt sich aktivieren, indem “typed” nach den übrigen Argumenten angegeben wird; mit “json” nach den übrigen Argumenten erfolgt die Ausgabe in JSON. Durch Angabe von <id>, <type> und <sid> lassen sich nur ausgewählte Elemente ausgeben: - <iid> ist eine Proxy-ID; -1 gibt alles aus. Alternativ kann ein Proxyname <proxy> angegeben werden. In diesem Fall dient die ID dieses Proxys zur Auswahl. - <type> wählt den Typ der ausgebbaren Objekte: 1 für Frontends, 2 für Backends, 4 für Server, -1 für alles. Diese Werte können durch ein bitweises ODER verknüpft werden, beispielsweise:
- `<sid>` ist eine Server-ID; -1 gibt alles aus dem ausgewählten Proxy aus.
Beispiel:
In diesem Beispiel wurden zwei Befehle gleichzeitig ausgeführt. So lässt sich im Mehrprozessbetrieb leicht erkennen, auf welchen Prozess sich die Statistiken beziehen. Beim typisierten Ausgabeformat ist dies nicht erforderlich, da die Prozessnummer in jeder Zeile ausgegeben wird. Die Leerzeile nach der Informationsausgabe kennzeichnet das Ende des ersten Blocks. Eine ähnliche Leerzeile erscheint am Ende des zweiten Blocks (Statistiken), damit erkennbar ist, dass die Ausgabe nicht abgeschnitten wurde.
Mit “typed” eignet sich das Ausgabeformat besser für Überwachungswerkzeuge, da es numerische Positionen liefert und den Typ jedes Ausgabefelds angibt. Jeder Wert steht in einer eigenen Zeile mit Prozessnummer, Elementnummer, Art, Herkunft und Geltungsbereich. Dasselbe Format ist über die HTTP-Statistiken verfügbar, indem “;typed” an die URI angehängt wird. Besonders zu beachten ist, dass beim typisierten Ausgabeformat die Daten eines einzelnen Objekts zusammenhängend ausgegeben werden, sodass ein verarbeitendes Programm nicht alles gleichzeitig speichern muss.
Mit dem Modifikator “up” werden nur Server aufgelistet, die als verfügbar gemeldet oder nicht geprüft werden. Nicht verfügbare Server sowie solche mit nicht aufgelöster Adresse oder im Wartungsmodus werden nicht aufgelistet. Dies entspricht der Option “;up” der HTTP-Statistiken. Ebenso verhält sich der Modifikator “no-maint” wie der HTTP-Modifikator “;no-maint” und schließt deaktivierte Server aus der Liste aus. Der Unterschied besteht darin, dass aktivierte, aber nicht verfügbare Server weiterhin aufgeführt werden.
Beim typisierten Ausgabeformat besteht jede Zeile aus 4 durch Doppelpunkte (’:’) getrennten Spalten. Die erste Spalte ist eine durch Punkte getrennte Folge von 5 Elementen. Das erste Element ist ein Buchstabe, der den Typ des beschriebenen Objekts angibt. Derzeit sind folgende Objekttypen bekannt: ‘F’ für ein Frontend, ‘B’ für ein Backend, ‘L’ für einen Listener und ‘S’ für einen Server. Das zweite Element ist eine positive Ganzzahl, die die eindeutige Kennung des Proxys darstellt, zu dem das Objekt gehört. Es entspricht der Spalte “iid” der CSV-Ausgabe und stimmt mit dem Wert der optionalen Direktive “id” im Frontend- oder Backend-Abschnitt überein. Das dritte Element ist eine positive Ganzzahl mit der eindeutigen Objektkennung innerhalb des Proxys und entspricht der Spalte “sid” der CSV-Ausgabe. Bei der Ausgabe eines Frontends oder Backends wird die ID 0 gemeldet. Bei einem Listener oder Server entspricht sie dessen jeweiliger ID innerhalb des Proxys. Das vierte Element ist die numerische Position des Felds in der Liste (beginnend bei null). Diese Position darf sich im Laufe der Zeit nicht ändern; abhängig von den Build-Optionen oder bei einer künftigen Entfernung von Feldern sind jedoch Lücken zu erwarten. Das fünfte Element ist der Feldname, wie er in der CSV-Ausgabe erscheint. Das sechste Element ist eine positive Ganzzahl und gibt die relative Prozessnummer an, beginnend bei 1.
Der Rest der Zeile nach dem ersten Doppelpunkt folgt dem oben beschriebenen „typisierten Ausgabeformat“. Die zweite Spalte (nach dem ersten ‘:’) gibt Herkunft, Art, Geltungsbereich und Persistenzstatus der Variablen an. Die dritte Spalte gibt den Feldtyp an: “s32”, “s64”, “u32”, “u64”, “flt” oder “str”. Die vierte Spalte enthält den Wert selbst, den ein verarbeitendes Programm anhand von Spalte 3 parsen und anhand von Spalte 2 verarbeiten kann.
Wird “desc” an den Befehl angehängt, werden ein weiterer Doppelpunkt und eine Zeichenkette in Anführungszeichen mit einer Beschreibung der Metrik angefügt. Zum Zeitpunkt der Erstellung dieser Dokumentation wird dies nur für das Ausgabeformat “typed” unterstützt.
Das gesamte Zeilenformat im typisierten Modus lautet somit:
Ein Beispiel für das typisierte Ausgabeformat:
Im typisierten Format erleichtert die Prozess-ID am Ende der ersten Spalte das visuelle Zusammenführen der Ausgaben mehrerer Prozesse. Dies zeigt das folgende Beispiel, in dem jede Zeile für jeden Prozess erscheint:
Das Format der JSON-Ausgabe ist in einem Schema beschrieben, das mit “show schema json” ausgegeben werden kann.
Die JSON-Ausgabe enthält keine zusätzlichen Leerraumzeichen, um ihr Volumen zu verringern. Für das Lesen durch Menschen kann es hilfreich sein, die Ausgabe durch ein Werkzeug zur lesbaren Formatierung zu leiten. Beispiel:
$ echo “show stat json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool
Die JSON-Ausgabe enthält keine zusätzlichen Leerraumzeichen, um ihr Volumen zu verringern. Für das Lesen durch Menschen kann es hilfreich sein, die Ausgabe durch ein Werkzeug zur lesbaren Formatierung zu leiten. Beispiel:
$ echo “show stat json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool
show ssl ca-file [[*][\]<cafile>[:<index>]]
Die Liste der in den Prozess geladenen CA-Dateien und die jeweilige Anzahl ihrer Zertifikate anzeigen. Die Zertifikate werden von keinem Frontend oder Backend verwendet, solange ihr Status nicht “Used” lautet. In der Liste kann ein Eintrag “@system-ca” erscheinen, den der httpclient standardmäßig lädt. Er enthält die von OpenSSL zurückgegebene Liste der vertrauenswürdigen CAs des Systems. Ist einem Dateinamen ein Sternchen vorangestellt, handelt es sich um eine noch nicht festgeschriebene Transaktion. Wird eine <cafile> ohne <index> angegeben, werden der Status der CA-Datei (“Used”/“Unused”) und anschließend Details zu allen in der CA-Datei enthaltenen Zertifikaten angezeigt. Die angezeigten Details entsprechen für jedes Zertifikat denen des Befehls “show ssl cert”. Wird eine <cafile> mit einem nachfolgenden <index> angegeben, werden nur die Details des Zertifikats mit dem angegebenen Index angezeigt. Die Indizes beginnen bei 1. Ist der Index ungültig (beispielsweise zu groß), wird nichts angezeigt. Dieser Befehl kann helfen zu prüfen, ob eine CA-Datei korrekt aktualisiert wurde. Die Details einer laufenden Transaktion lassen sich ebenfalls anzeigen, indem dem Dateinamen ein ‘’ vorangestellt wird. Ist das erste Zeichen des Dateinamens ein ‘’, kann es mit ‘\*’ maskiert werden.
Beispiel:
show ssl cert [[*][\]<filename>]
Die Liste der in den Prozess geladenen Zertifikate anzeigen. Sie werden von keinem Frontend oder Backend verwendet, solange ihr Status nicht “Used” lautet. Ist einem Dateinamen ein Sternchen vorangestellt, handelt es sich um eine noch nicht festgeschriebene Transaktion. Wird ein Dateiname angegeben, werden Details zum Zertifikat angezeigt. Dieser Befehl kann helfen zu prüfen, ob ein Zertifikat korrekt aktualisiert wurde. Details zu einer Transaktion lassen sich ebenfalls anzeigen, indem dem Dateinamen ein ‘’ vorangestellt wird. Ist das erste Zeichen des Dateinamens ein ‘’, kann es mit ‘\*’ maskiert werden. Mit diesem Befehl lassen sich auch die Details der OCSP-Antwort eines Zertifikats anzeigen, indem die Erweiterung “.ocsp” an den Dateinamen angehängt wird. Dies funktioniert sowohl für bereits festgeschriebene als auch für laufende Transaktionen. Bei einem Zertifikat aus einer festgeschriebenen Transaktion entspricht dieser Befehl dem Aufruf von “show ssl ocsp-response” mit der zugehörigen OCSP-Antwort-ID des Zertifikats.
Beispiel:
show ssl crl-file [[*][\]<crlfile>[:<index>]]
Die Liste der in den Prozess geladenen CRL-Dateien anzeigen. Sie werden von keinem Frontend oder Backend verwendet, solange ihr Status nicht “Used” lautet. Ist einem Dateinamen ein Sternchen vorangestellt, handelt es sich um eine noch nicht festgeschriebene Transaktion. Wird eine <crlfile> ohne <index> angegeben, werden der Status der CRL-Datei (“Used”/“Unused”) und anschließend Details zu allen in der CRL-Datei enthaltenen Sperrlisten angezeigt. Die Details jeder Liste beruhen auf der Ausgabe von “openssl crl -text -noout -in <file>”. Wird eine <crlfile> mit einem nachfolgenden <index> angegeben, werden nur die Details der Liste mit dem angegebenen Index angezeigt. Die Indizes beginnen bei 1. Ist der Index ungültig (beispielsweise zu groß), wird nichts angezeigt. Dieser Befehl kann helfen zu prüfen, ob eine CRL-Datei korrekt aktualisiert wurde. Die Details einer laufenden Transaktion lassen sich ebenfalls anzeigen, indem dem Dateinamen ein ‘’ vorangestellt wird. Ist das erste Zeichen des Dateinamens ein ‘’, kann es mit ‘\*’ maskiert werden.
Beispiel:
show ssl crt-list [-n] [<filename>]
Die Liste der crt-list-Dateien und Verzeichnisse anzeigen, die in der HAProxy-Konfiguration verwendet werden. Wird ein Dateiname angegeben, wird der Inhalt einer crt-list-Datei oder eines Verzeichnisses ausgegeben. Die Ausgabe kann anschließend als crt-list-Datei verwendet werden. Mit der Option ‘-n’ lassen sich die Zeilennummern anzeigen. Dies ist zusammen mit der Option ‘del ssl crt-list’ hilfreich, wenn ein Eintrag mehrfach vorkommt. Die Ausgabe mit der Option ‘-n’ ist mit dem crt-list-Format nicht kompatibel und kann von haproxy nicht geladen werden.
Beispiel:
show ssl ech [<name>]
Die Liste der im HAProxy-Prozess geladenen ECH-Schlüssel anzeigen.
Wird <name> angegeben, werden die Schlüssel für eine bestimmte bind-Zeile angezeigt. Das Format der bind-Zeile lautet <frontend>/@<filename>:<linenum> (Beispiel: frontend1/@haproxy.conf
:19) oder <frontend>/<name>, wenn die bind-Zeile mit dem Schlüsselwort “name” benannt wurde.
Der Eintrag ‘age’ gibt die Zeit in Sekunden an, die seit dem Laden des Schlüssels in die bind-Zeile vergangen ist. Dieser Wert wird beim Starten, Neuladen oder Neustarten von HAProxy zurückgesetzt.
Eine OpenSSL-Version mit ECH-Unterstützung ist erforderlich, und HAProxy muss mit USE_ECH=1 kompiliert werden. Dieser Befehl wird nur auf einer CLI-Verbindung im experimentellen Modus unterstützt (siehe “experimental-mode on”).
Siehe auch “ech” in Abschnitt 5.1 des Konfigurationshandbuchs.
Beispiel:
show ssl jwt
Die Liste der Zertifikate anzeigen, die zur JWT-Validierung verwendet werden können. Siehe auch die Befehle “add ssl jwt” und “del ssl jwt”. Weitere Informationen enthält die Zertifikatsoption “jwt”.
Beispiel:
show ssl ocsp-response [[text|base64] <id|path>]
Die IDs der OCSP-Baumeinträge für alle in HAProxy verwendeten OCSP-Antworten anzeigen, zusammen mit dem Pfad des zugehörigen Frontend-Zertifikats, dem Namen und Schlüssel-Hash des Ausstellers sowie der Seriennummer des Zertifikats, für das die OCSP-Antwort erstellt wurde. Wird eine gültige <id> oder der <path> eines gültigen Frontend-Zertifikats angegeben, wird der Inhalt der zugehörigen OCSP-Antwort angezeigt. Bei Angabe einer <id> kann das Ausgabeformat der Daten festgelegt werden. Die Standardoption ’text’ zeigt detaillierte Informationen zur OCSP-Antwort wie bei einem Aufruf von “openssl ocsp -respin <ocsp-response> -text”. Das Format ‘base64’ gibt den Inhalt einer OCSP-Antwort in base64 aus.
Beispiel:
show ssl ocsp-updates
Informationen zu den Einträgen anzeigen, die der OCSP-Aktualisierungsmechanismus betrifft. Der Befehl gibt eine Zeile je OCSP-Antwort aus. Sie enthält den erwarteten Aktualisierungszeitpunkt der Antwort, den Zeitpunkt der letzten erfolgreichen Aktualisierung sowie Zähler für erfolgreiche und fehlgeschlagene Aktualisierungen. Auch der Status der letzten Aktualisierung (erfolgreich oder nicht) wird numerisch und als Text angegeben. Eine vollständige Liste der möglichen Fehler folgt weiter unten. Die Zeilen werden aufsteigend nach dem Zeitpunkt ‘Next Update’ sortiert. Sie enthalten außerdem den Pfad des ersten Frontend-Zertifikats, das die OCSP-Antwort verwendet. Weitere Informationen zur automatischen OCSP-Aktualisierung enthalten der Befehl “show ssl ocsp-response” und die Option “ocsp-update”.
Folgende Fehlercodes und Fehlermeldungen sind für die Aktualisierung möglich:
Beispiel:
show ssl providers
Die Namen der Provider anzeigen, die OpenSSL bei der Initialisierung geladen hat. Das Laden von Providern kann über die OpenSSL-Konfigurationsdatei konfiguriert werden. Mit dieser Option lässt sich prüfen, ob die richtigen Provider geladen wurden. Dieser Befehl ist nur mit OpenSSL v3 verfügbar.
Beispiel:
show ssl sni [-f <frontend>] [-A] [-t <offset>]
Alle für das angegebene Frontend konfigurierten SNIs ausgeben, oder für alle Frontends, wenn keines angegeben wird. So lässt sich erkennen, welche SNIs ein Frontend anbietet und ob eine SNI für dasselbe Frontend durch mehrere Zertifikate mehrfach definiert ist.
Die Option -A filtert die Liste so, dass nur Zertifikate angezeigt werden, deren notAfter-Datum überschritten ist, also nur abgelaufene Zertifikate.
Die Option -t akzeptiert einen Zeitversatz in Sekunden oder mit einer Zeiteinheit (s, m, h, d), der zur aktuellen Zeit addiert wird. Zusammen mit -A lässt sich damit prüfen, welche Zertifikate nach Anwendung des Zeitversatzes abgelaufen sind. Um beispielsweise zu prüfen, welche Zertifikate in 30d abgelaufen wären, genügt “show ssl sni -A -t 30d”.
Die Spalten sind durch ein einzelnes \t getrennt und lassen sich daher einfach parsen.
Die Spalte ‘Frontend/Bind’ zeigt den Frontendnamen, gefolgt von der Position der bind-Zeile in der Konfiguration (frontend/file:linenum).
Die Spalte ‘SNI’ zeigt die SNI; sie kann ein CN, ein SAN oder ein Filter aus einer crt-list sein. Für die Standardzertifikate einer bind-Zeile (entweder ausdrücklich mit ‘default-crt’ deklariert oder, wenn kein ‘strict-sni’ verwendet wird, implizit das erste Zertifikat der bind-Zeile) wird das Zeichen ‘*’ in der Spalte SNI angezeigt.
Die Spalte ‘Negative Filter’ enthält die Liste der negativen Filter, die einem Platzhaltermuster zugeordnet sind. Sie zeigt alle negativen Filter derselben crt-list-Zeile. Sind keine vorhanden, wird ein Bindestrich angezeigt.
Die Spalte ‘Type’ zeigt den Typ des Verschlüsselungsalgorithmus: “rsa”, “ecdsa” oder “dsa”.
Die Spalte ‘Filename’ kann entweder einen Dateinamen aus der Konfiguration oder einen in einem crt-store deklarierten Alias enthalten.
Die Spalten ‘NotAfter’ und ‘NotBefore’ werden direkt aus dem X509-Endzertifikat ausgelesen.
Beispiel:
show startup-logs
Alle beim Start des aktuellen haproxy-Prozesses ausgegebenen Meldungen ausgeben. Jeder startup-logs-Puffer gehört ausschließlich zu seinem jeweiligen haproxy-Worker.
Dieses Schlüsselwort ist auch auf der Master-CLI verfügbar und zeigt dort den letzten Start- oder Neuladeversuch an.
show table
Allgemeine Informationen zu allen bekannten Stick Tables ausgeben: ihren Namen (den Namen des Proxys, der sie enthält), ihren Typ (derzeit null, immer IP), ihre Größe als maximal mögliche Anzahl von Einträgen sowie die Anzahl der derzeit verwendeten Einträge.
Beispiel:
show table <name> [ data.<type> <operator> <value> [data.<type> ...]] |
Den Inhalt der Stick Table <name> ausgeben. In diesem Modus werden wie bei “show table” zunächst allgemeine Informationen zur Tabelle in einer Zeile ausgegeben, anschließend alle Einträge. Da dies sehr aufwendig sein kann, lässt sich mit einem Filter festlegen, welche Einträge angezeigt werden.
Bei Verwendung der Form “data.” wird der Filter auf die gespeicherten Daten angewendet (siehe “stick-table” in Abschnitt 4.2). In <type> muss ein gespeicherter Datentyp angegeben werden. Dieser Datentyp muss in der Tabelle gespeichert sein, sonst wird ein Fehler gemeldet. Die Daten werden gemäß <operator> mit der 64-Bit-Ganzzahl <value> verglichen. Es gelten dieselben Operatoren wie bei ACLs:
- eq: Einträge auswählen, deren Daten diesem Wert entsprechen
- ne: Einträge auswählen, deren Daten diesem Wert nicht entsprechen
- le: Einträge auswählen, deren Daten kleiner oder gleich diesem Wert sind
- ge: Einträge auswählen, deren Daten größer oder gleich diesem Wert sind
- lt: Einträge auswählen, deren Daten kleiner als dieser Wert sind
- gt: Einträge auswählen, deren Daten größer als dieser Wert sind
In dieser Form können mehrere Datenfilter angegeben werden, bis zu einer beim Kompilieren festgelegten Höchstzahl (standardmäßig 4).
Bei Verwendung der key-Form wird der Eintrag <key> angezeigt. Der Schlüssel muss denselben Typ wie die Tabelle haben; zulässig sind derzeit nur IPv4, IPv6, Ganzzahlen und Zeichenketten.
Bei Verwendung der ptr-Form wird der Eintrag <ptr> angezeigt. <ptr> wird in der Form 0xffff geschrieben und muss der Adresse entsprechen, die ein vorheriger Befehl “show table” zurückgegeben hat. Die Auswahl eines Eintrags über seinen Zeiger kann hilfreich sein, wenn der Eintrag wegen eines leeren Schlüssels oder mit der CLI inkompatibler Zeichen nicht über den Schlüssel ausgewählt werden kann.
Wenn data.<type> ein Arraytyp ist, kann “[]” verwendet werden, um auf einen bestimmten Index im Array zuzugreifen, beispielsweise so: data.gpt[1]
Beispiel:
Bezieht sich das Datenkriterium auf einen dynamischen, zeitabhängigen Wert wie eine Byterate, wird der Wert bei der Auswertung des Eintrags dynamisch berechnet, um zu entscheiden, ob er ausgegeben werden muss. Ein solcher Filter kann daher eine Zeit lang zutreffen und anschließend nicht mehr, da die durchschnittliche Ereignisrate mit der Zeit sinkt.
Damit lassen sich Listen von IP-Adressen extrahieren, die den Dienst missbräuchlich nutzen, um sie zu überwachen oder sogar in einer Firewall zu sperren. Beispiel:
Wenn die Stick Table mit einem peers-Abschnitt synchronisiert wird, der Sharding unterstützt, wird für jeden Schlüssel die Shardnummer angezeigt (andernfalls wird ‘0’ gemeldet). So lässt sich erkennen, welche Peers diesen Schlüssel erhalten. Beispiel:
show tasks
Die Anzahl der derzeit in der Ausführungswarteschlange befindlichen Tasks ausgeben, zusammen mit der Anzahl der Vorkommen je Funktion und ihrer durchschnittlichen Latenz, sofern bekannt (bei reinen Tasks mit aktiviertem Task-Profiling). Die Ausgabe ist eine Momentaufnahme zum Zeitpunkt ihrer Erstellung. Sie kann abhängig davon variieren, welche Tasks in diesem Moment noch in der Warteschlange stehen. Dies gilt besonders im Einzelthreadbetrieb, da E/A-Vorgänge die Warteschlange seltener wieder füllen können (außer wenn die Warteschlange voll ist). Dieser Befehl greift exklusiv auf den Prozess zu und kann bei einem stark ausgelasteten Prozess geringe, aber messbare Latenzen verursachen. Daher darf er von automatischen Überwachungswerkzeugen nicht übermäßig verwendet werden.
show threads
Einige interne Zustände und Strukturen je Thread ausgeben, die Entwicklern helfen können, ein Problem zu verstehen. Für eine lesbare Darstellung wird je Thread ein Block ausgegeben. Wenn haproxy mit USE_THREAD_DUMP=1 gebaut wurde, kommt ein erweiterter Ausgabemechanismus mit Threadsignalen zum Einsatz, damit jeder Thread nacheinander seinen eigenen Zustand ausgeben kann. Ohne diese Option zeigt der Thread, der den Befehl verarbeitet, alle eigenen Details an; die anderen Threads werden weniger detailliert dargestellt. Vor dem Thread, der den Befehl bearbeitet, steht ein Sternchen (’*’). Vor Threads, die seit dem letzten Aufruf dieses Befehls keinen Fortschritt gemacht haben, kann außerdem eine schließende Winkelklammer (’>’) erscheinen. Dies weist auf einen Fehler im Code hin, der unbedingt gemeldet werden muss. Tritt dies zwischen zwei Threads auf, weist es gewöhnlich auf einen Deadlock hin. Ist ein Thread allein betroffen, handelt es sich um einen anderen Fehler, etwa eine beschädigte Liste. In jedem Fall ist der Prozess nicht mehr vollständig funktionsfähig und muss neu gestartet werden.
Das Ausgabeformat ist absichtlich nicht dokumentiert, damit es sich bei neuem Bedarf leicht weiterentwickeln kann, ohne irgendeine Form von Abwärtskompatibilität gewährleisten zu müssen. Wie bei “show activity” sind die Werte ohne den zugehörigen Code nicht aussagekräftig.
show tls-keys [id|*]
Alle geladenen Referenzen auf TLS-Ticketschlüssel ausgeben. Angezeigt werden die Referenz-ID des TLS-Ticketschlüssels und die Datei, aus der die Schlüssel geladen wurden. Beide können verwendet werden, um die TLS-Schlüssel mit “set ssl tls-key” zu aktualisieren. Wird eine ID als Parameter angegeben, werden die Tickets ausgegeben; mit * werden alle Schlüssel aller Referenzen ausgegeben.
show schema json
Das Schema ausgeben, das für die Ausgabe von “show info json” und “show stat json” verwendet wird.
Die Ausgabe enthält keine zusätzlichen Leerraumzeichen, um ihr Volumen zu verringern. Für das Lesen durch Menschen kann es hilfreich sein, die Ausgabe durch ein Werkzeug zur lesbaren Formatierung zu leiten. Beispiel:
$ echo “show schema json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool
Das Schema folgt “JSON Schema” (json-schema.org). Entsprechende Prüfwerkzeuge können daher die Ausgabe von “show info json” und “show stat json” anhand des Schemas überprüfen.
show trace [<source>]
Den aktuellen Tracestatus anzeigen. Für jede Quelle wird eine Zeile mit einem Status aus einem einzelnen Zeichen ausgegeben, der angibt, ob der Trace gestoppt ist, wartet oder läuft. Angezeigt werden das vom Trace verwendete Ausgabeziel (oder “none”, wenn keines festgelegt wurde) und die Anzahl der dort verworfenen Ereignisse, gefolgt von einer kurzen Beschreibung der Quelle. Wird ein Quellenname angegeben, erscheint eine detaillierte Liste aller von dieser Quelle unterstützten Ereignisse sowie ihres Status für jede Aktion (report, start, pause, stop): “+” bedeutet aktiviert, “-” bedeutet deaktiviert. Alle diese Ereignisse sind unabhängig voneinander. Ein Ereignis kann daher einen Start auslösen, ohne gemeldet zu werden, und umgekehrt.
show version
Die Version des aktuellen HAProxy-Prozesses anzeigen. Dieser Befehl ist auf der Master- und der Worker-CLI verfügbar. Beispiel:
shutdown frontend <frontend>
Das angegebene Frontend vollständig löschen. Alle Ports, an die es gebunden war, werden freigegeben. Nach diesem Vorgang lässt sich das Frontend nicht mehr aktivieren. Dies ist für Umgebungen vorgesehen, in denen das Anhalten eines Proxys ausgeschlossen ist, eine fehlerhafte Proxykonfiguration aber korrigiert werden muss. Auf diese Weise kann der Port freigegeben und in einem anderen Prozess gebunden werden, um den Betrieb wiederherzustellen. Nach seiner Beendigung erscheint das Frontend überhaupt nicht mehr auf der Statistikseite.
Das Frontend kann entweder durch seinen Namen oder durch seine numerische ID mit vorangestelltem Rautezeichen (’#’) angegeben werden.
Dieser Befehl ist zugriffsbeschränkt und kann nur über Sockets ausgeführt werden, die für die Berechtigungsstufe “admin” konfiguriert sind.
shutdown session <id>
Den Stream mit der angegebenen Streamkennung sofort beenden. Diese Kennung steht als erstes Feld am Zeilenanfang der Ausgaben von “show sess” (sie entspricht dem Zeiger auf den Stream). Damit lässt sich ein lang laufender Stream beenden, ohne auf eine Zeitüberschreitung zu warten, oder eine endlose Übertragung abbrechen. Auf diese Weise beendete Streams werden in den Protokollen mit einem ‘K’-Flag gekennzeichnet.
shutdown sessions server <backend>/<server>
Alle dem angegebenen Server zugeordneten Streams sofort beenden. Damit lassen sich beispielsweise lang laufende Streams beenden, nachdem ein Server in den Wartungsmodus versetzt wurde. Auf diese Weise beendete Streams werden in den Protokollen mit einem ‘K’-Flag gekennzeichnet.
Backend-Verbindungen bleiben im Leerlauf, außer wenn sich der Server bereits im Wartungsmodus befindet. In diesem Fall werden sie sofort zur Löschung vorgemerkt.
trace
Der Befehl “trace” ohne weitere Argumente listet die Tracequellen, ihren aktuellen Status und ihre kurzen Beschreibungen auf. Er dient nur als Menü für den Einstieg in die nächsten Ebenen; siehe die weiteren “trace”-Befehle unten.
trace 0
Alle Traces sofort stoppen. Dies ist als schnelle Möglichkeit zum Beenden einer Sitzung zur Fehlersuche gedacht oder als Notfallmaßnahme, wenn komplexe Traces für mehrere Quellen aktiviert wurden und den Dienst beeinträchtigen.
trace <source> [<args...>]
Traces für die Quelle <source> konfigurieren. Ohne Argument werden alle von dieser Quelle unterstützten Unterbefehle aufgelistet. Mehrere Unterbefehle können verkettet werden. Folgende Unterbefehle werden unterstützt:
event [ [+|-|!]<name> ] Ohne Argument werden alle Ereignisse aufgelistet, die die angegebene Quelle unterstützt. Ihnen wird ein “-” vorangestellt, wenn sie deaktiviert sind, oder ein “+”, wenn sie aktiviert sind. Zu beachten ist, dass ein einzelner Trace mit mehreren Ereignissen gekennzeichnet sein kann. Sobald eines der aktivierten Ereignisse mit einem der Ereignisse am Trace übereinstimmt, wird das Ereignis an das Trace-Subsystem übergeben. Beispielsweise kann der Empfang eines HTTP/2-Frames vom Typ HEADERS ein Frameereignis und ein Streamereignis auslösen, da der Frame einen neuen Stream erzeugt. Ist entweder das Frameereignis oder das Streamereignis für diese Quelle aktiviert, wird der Frame an das Trace-Framework übergeben.
Mit einem Argument lässt sich der Zustand jedes Ereignisses umschalten,
um es einzeln zu aktivieren oder zu deaktivieren. Zwei spezielle Schlüsselwörter
werden unterstützt: "none" passt auf kein Ereignis und deaktiviert alle
Ereignisse gleichzeitig; "any" passt auf alle Ereignisse und aktiviert sie
gleichzeitig. Andere Ereignisse hängen von der Ereignisquelle ab. Ein Ereignis
lässt sich durch Angabe seines Namens aktivieren, optional mit einem
vorangestellten '+' zur besseren Lesbarkeit. Zur Deaktivierung wird sein
Name mit einem vorangestellten '-' oder '!' angegeben.
Eine Tracequelle lässt sich vollständig deaktivieren, indem "event none"
angegeben wird. Die Quelle wird dann sofort vollständig ignoriert.
follow <other_source> Damit kann die Quelle <source> auch dann Traces ausgeben, wenn die andere Quelle <other_source> auf ein Kriterium fixiert ist und dasselbe Kriterium auch auf die aktuelle Quelle zutrifft. Ist beispielsweise eine Quelle auf eine Sitzung fixiert, bewirkt das Folgen dieser Quelle von einer anderen Quelle aus, dass die andere Quelle Traces für alle Ereignisse dieser Sitzung ausgibt. Damit lassen sich in gewissem Umfang Backend-Anfragen zusammen mit den zugehörigen Frontend-Verbindungen verfolgen. Die Quelle “session” erleichtert dies mit den Ereignissen “new” und “end”, die zur Verarbeitung der Fixierung verwendet werden können. Die Traces der Quelle <source> müssen in diesem Fall nicht aktiviert sein; ihr Tracestatus wird ebenfalls nicht beeinflusst. Einige Ereignisse können jedoch fehlen, wenn sie keine Informationen enthalten, die eine Zuordnung zum verfolgten Element ermöglichen. Mit diesem Befehl kann auch die Metaquelle “all” verwendet werden: Dann folgen alle Quellen <other_source>.
Beispiel:
level [<level>] Ohne Argument werden alle Tracestufen dieser Quelle aufgelistet; die aktuelle Stufe wird durch ein vorangestelltes Sternchen (’*’) gekennzeichnet. Mit einem Argument wird die Tracestufe auf die angegebene Stufe geändert. Detailstufen sind eine Form von Filtern, die vor der Meldung der Ereignisse angewendet werden. Diese Filter schließen Ereignisse je nach ihrer Bedeutung gezielt ein oder aus. Ein Entwickler muss beispielsweise möglicherweise genau wissen, an welcher Stelle im Code ein HTTP-Header als ungültig angesehen wurde, während seine Gültigkeit für den Endbenutzer vielleicht überhaupt nicht relevant ist. Derzeit gibt es 5 verschiedene Tracestufen:
Es wird dringend empfohlen, stets nur die Stufe "user" zu verwenden und
nur auf Anweisung eines Entwicklers zu anderen Stufen zu wechseln. Außerdem
ist es sinnvoll, vor dem Wechsel zu höheren Stufen zunächst die Ereignisse
zu konfigurieren, um die Ausgabe vieler Zeilen ohne angewendeten Filter zu
vermeiden. Mit diesem Befehl kann auch die Metaquelle "all" verwendet werden:
Dann wird die Stufe gleichzeitig auf alle vorhandenen Quellen angewendet.
lock [criterion] Ohne Argument werden alle Kriterien aufgelistet, die diese Quelle für die Fixierung unterstützt. Die aktuelle Auswahl wird durch ein vorangestelltes Sternchen (’*’) angezeigt. Fixierung bedeutet, dass sich die Quelle auf das erste passende Ereignis konzentriert und nur an dem Kriterium festhält, das dieses Ereignis ausgelöst hat; alles andere wird ignoriert, bis der Trace stoppt. So lässt sich beispielsweise ein Trace für eine einzelne Verbindung oder einen einzelnen Stream erfassen. Einige Traces unterstützen die folgenden Kriterien, jedoch nicht unbedingt alle, da manche Kriterien der Quelle möglicherweise nicht zur Verfügung stehen:
Zusätzlich kann jede Quelle bis zu 4 spezifische Kriterien bereitstellen,
etwa interne Zustände oder Verbindungs-IDs. Bei HTTP/2 lässt sich beispielsweise
auf den H2-Stream fixieren und andere Streams ignorieren, sobald ein Trace startet.
Wird ein Kriterium als Argument übergeben, wird es anstelle der anderen
verwendet. Jede bestehende Verfolgung wird sofort beendet, damit sie mit dem
neuen Kriterium neu starten kann. Alle Quellen unterstützen das spezielle
Schlüsselwort "nothing", um die Verfolgung dauerhaft zu deaktivieren.
{ pause | start | stop } [ [+|-|!]event] Ohne Argument werden die Ereignisse aufgelistet, die für das automatische Pausieren, Starten oder Stoppen eines Traces dieser Quelle aktiviert sind. Diese Ereignisse hängen von der jeweiligen Tracequelle ab. Mit einem Argument wird das Ereignis entweder für die angegebene Aktion aktiviert (optional mit vorangestelltem ‘+’) oder deaktiviert (mit vorangestelltem ‘-’ oder ‘!’). Das spezielle Schlüsselwort “now” ist kein Ereignis, sondern fordert die sofortige Ausführung der Aktion an. Die Schlüsselwörter “none” und “any” werden wie bei “trace event” unterstützt.
Die 3 unterstützten Aktionen sind "pause", "start" und "stop". Die Aktion
"pause" zählt Ereignisse auf, die einen laufenden Trace anhalten und auf ein
neues Startereignis warten lassen, um ihn erneut zu starten. Die Aktion
"start" zählt Ereignisse auf, die den Trace in den Wartemodus versetzen, bis
eines der Startereignisse auftritt. Die Aktion "stop" zählt Ereignisse auf,
die den Trace endgültig stoppen, bis er wieder manuell aktiviert wird. In der
Praxis ist es sinnvoll, einen Trace mit "start now" manuell zu starten, ohne
sich um Ereignisse zu kümmern, und ihn mit "stop now" zu stoppen. Um subtilere
Ereignisfolgen zu erfassen, kann "start" auf ein gewöhnliches Ereignis gesetzt
werden (etwa den Empfang einer HTTP-Anfrage) und "stop" auf ein sehr seltenes
Ereignis wie die Ausgabe eines bestimmten Fehlers. Dadurch entsprechen die
zuletzt erfassten Ereignisse den gewünschten Kriterien. Das Pausenereignis
ist hilfreich, um das Ende einer Folge zu erkennen, die Fixierung aufzuheben
und auf eine weitere Gelegenheit zur Erfassung zu warten. In diesem Fall kann
es sinnvoll sein, die Fixierung zu aktivieren, um nur ein bestimmtes Kriterium
(etwa einen Stream) zu verfolgen. "start" wird auf alles gesetzt, was dieses
Kriterium beginnen lässt (etwa alle Ereignisse, die einen Stream erzeugen),
"stop" auf die erwartete Anomalie und "pause" auf alles, was dieses Kriterium
beendet (etwa jedes Ereignis zum Streamende). Das Traceprotokoll enthält dann
vollständige Folgen fehlerfreier Serien, die jeweils ein einzelnes Objekt
betreffen, bis zur letzten Folge mit allem vom Beginn bis zur Anomalie.
sink [<sink>] Ohne Argument werden alle für diese Quelle verfügbaren Ereignisausgabeziele aufgelistet; das aktuell konfigurierte wird durch ein vorangestelltes Sternchen (’*’) gekennzeichnet. Das Ausgabeziel “none” ist immer verfügbar und bedeutet, dass alle Ereignisse einfach verworfen werden. Ihre Verarbeitung wird jedoch nicht ignoriert (beispielsweise findet eine Fixierung statt). Andere Ausgabeziele stehen abhängig von Konfiguration und Build-Optionen zur Verfügung; typischerweise sind “stdout” und “stderr” im Debugmodus nutzbar, und Ringpuffer im Speicher sollten ebenfalls verfügbar sein. Wird ein Name angegeben, ändert sich das Ausgabeziel für die angegebene Quelle sofort. Ein Wechsel des Ausgabeziels ändert die Ereignisse nicht. Im schlimmsten Fall gehen einige verloren, wenn ein ungültiges Ausgabeziel (oder “none”) verwendet wird; die Vorgänge werden jedoch an einem anderen Ziel fortgesetzt. Mit diesem Befehl kann auch die Metaquelle “all” verwendet werden: Dann wird das Ausgabeziel gleichzeitig auf alle vorhandenen Quellen angewendet.
verbosity [<level>] Ohne Argument werden alle Stufen des Detailgrads dieser Quelle aufgelistet; die aktuelle wird durch ein vorangestelltes Sternchen (’*’) gekennzeichnet. Mit einem Argument wird der Detailgrad auf die angegebene Stufe geändert.
Die Stufen des Detailgrads geben an, wie weit der Tracedekoder gehen sollte,
um detaillierte Informationen bereitzustellen. Dies hängt von der Tracequelle
ab, da einige Quellen nicht einmal einen spezifischen Dekoder bereitstellen.
Die Stufe "quiet" ist immer verfügbar und deaktiviert jede Dekodierung. Sie
kann helfen, zunächst festzustellen, was geschieht, bevor die Details
untersucht werden, da sie Leistung und Tracegröße nur sehr wenig beeinflusst.
Deklariert eine Quelle keine Stufen des Detailgrads, steht die Stufe "default"
zur Verfügung. Sie bewirkt den Aufruf eines Dekoders, wenn dies in den Traces
angegeben ist. Dies ist eine opportunistische Dekodierung. Deklariert
eine Quelle Stufen des Detailgrads, werden diese mit einer Beschreibung ihrer
Bedeutung aufgelistet. In diesem Fall arbeitet der von der Quelle
bereitgestellte Tracedekoder anhand der am Tracepunkt verfügbaren Informationen
so genau wie möglich. Standardmäßig ist die erste Stufe oberhalb von "quiet"
eingestellt.
update ssl ocsp-response <certfile>
Eine OCSP-Anfrage für die angegebene <certfile> erstellen und an den OCSP-Responder senden, dessen URI im Abschnitt “Authority Information Access” des Zertifikats angegeben sein sollte. Nur die erste URI wird berücksichtigt. Die als Antwort erwartete OCSP-Antwort wird anschließend geprüft und in den lokalen OCSP-Antwortbaum eingefügt. Dieser Befehl funktioniert nur für Zertifikate, für die bereits eine OCSP-Antwort gespeichert war, entweder bei der Initialisierung bereitgestellt oder zuvor über die Befehle “set ssl cert” oder “set ssl ocsp-response” gesetzt. Ist die empfangene OCSP-Antwort gültig und wurde sie korrekt in den lokalen Baum eingefügt, wird ihr Inhalt auf der Standardausgabe angezeigt. Das Format entspricht dem unter “show ssl ocsp-response” beschriebenen.
wait { -h | <delay> } [<condition> [<args>...]]
In der einfachsten Form ohne Bedingung wartet der Befehl lediglich die angegebene Zeit, bevor er fortfährt. Damit lassen sich Metriken über ein bestimmtes Zeitintervall erfassen.
Mit einer Bedingung und optionalen Argumenten wartet der Befehl, bis die angegebene Bedingung erfüllt ist, endgültig fehlschlägt oder während der gesamten Dauer <delay> unerfüllt bleibt. Folgende Bedingungen werden unterstützt:
-
be-removable
<proxy>: Wartet, bis das angegebene Proxybackend mit dem Befehl “del backend” entfernt werden kann. Manche Zustände werden niemals akzeptiert (beispielsweise ein noch veröffentlichtes Backend oder eines mit Servern darin). Sie führen zu einer spezifischen Fehlermeldung, die angibt, welche Bedingung nicht erfüllt ist. Ist vor Ablauf der Wartezeit alles OK, wird Erfolg zurückgegeben und der Vorgang beendet. -
srv-removable
<proxy>/<server>: Wartet, bis der angegebene Server mit dem Befehl “del server” entfernt werden kann, also im Wartungsmodus ist und keine Verbindungen mehr hat (weder aktive noch ungenutzte). Manche Zustände werden niemals akzeptiert (beispielsweise ein Server außerhalb des Wartungsmodus). Sie führen zu einer spezifischen Fehlermeldung, die angibt, welche Bedingung nicht erfüllt ist. Der Server kann sogar parallel bereits entfernt worden sein und nicht mehr existieren. Ist vor Ablauf der Wartezeit alles OK, wird Erfolg zurückgegeben und der Vorgang beendet.
Standardmäßig wird die Wartezeit in Millisekunden angegeben. Andere Einheiten werden ebenfalls akzeptiert, wenn sie mit den üblichen Zeiteinheiten (us, ms, s, m, h, d) als Suffix angegeben werden. Bei Verwendung mit dem Werkzeug ‘socat’ muss dessen Zeitüberschreitung zum Schließen verlängert werden, damit sie die Wartezeit abdeckt. Mit “-h” als erstem oder zweitem Argument werden Hinweise zur Verwendung des Befehls angezeigt. Beispiel:
9.4. Master-CLI
Die Master-CLI ist ein Socket, der im Master-Worker-Modus an den Masterprozess gebunden ist. Diese CLI ermöglicht den Zugriff auf die Unix-Socket-Befehle aller laufenden oder sich beendenden Prozesse und eine grundlegende Überwachung dieser Prozesse.
Die Master-CLI lässt sich ausschließlich über die Programmargumente von haproxy mit der Option -S konfigurieren. Diese Option akzeptiert auch kommagetrennte bind-Optionen.
Beispiel:
9.4.1. Befehle der Master-CLI
@<[!]pid>
Die Master-CLI verwendet eine besondere Präfixnotation, um auf die verschiedenen Prozesse zuzugreifen. Diese Notation ist leicht erkennbar, da sie mit einem @ beginnt.
Auf ein @-Präfix kann eine relative Prozessnummer oder ein Ausrufezeichen mit einer PID folgen (beispielsweise @1 oder @!1271). Ein einzelnes @ kann den Master angeben. Sich beendende Prozesse sind nur über die PID erreichbar, da relative Prozessnummern nur für die aktuellen Prozesse verwendbar sind.
Dieses Präfix kann einem Befehl vorangestellt werden, um anzugeben, dass dieser und nur dieser Befehl an den bezeichneten Prozess gesendet wird. In diesem Fall endet der vollständige Befehl wie jeder reguläre Befehl am Zeilenende oder an einem Semikolon.
Fehler: Das Protokoll sockpair@ zur Kommunikation zwischen Master und Worker ist auf macOS bekanntermaßen unzuverlässig, da die macOS-Implementierung von sendmsg(2) fehlerhaft ist. Ein Befehl kann daher ohne Antwort bleiben.
Beispiele:
Das Präfix kann auch als eigenständiger Befehl verwendet werden, um den Standardausführungskontext auf den bezeichneten Prozess umzuschalten. Alle nachfolgenden Befehle werden dann in diesem Prozess ausgeführt, bis ein neuer ‘@’-Befehl den Ausführungskontext erneut ändert.
Beispiele:
Hinweis zu Einschränkungen: Einige wenige Befehle ändern den Zustand einer CLI-Sitzung (beispielsweise “set anon”, “set timeout”) und verhalten sich bei einem Aufruf über die Master-CLI möglicherweise nicht genau gleich, da die Befehle einzeln in jeweils einer eigenen CLI-Sitzung gesendet werden. Ebenso überwachen einige wenige Befehle (“show events”, “wait”) die CLI aktiv auf Eingaben oder das Schließen der Verbindung und werden sofort unterbrochen, wenn die CLI geschlossen wird. Diese Befehle funktionieren über die Master-CLI nicht wie erwartet, da die Befehlseingabe nach jedem Befehl geschlossen wird. Für solche seltenen Fälle kann die unten beschriebene Variante “@@” besser geeignet sein.
@@<[!]pid> [command...]
Dieses Präfix beziehungsweise dieser Befehl ähnelt dem oben dokumentierten Präfix “@”, wechselt jedoch in den Workerprozess, übergibt ihm die gesamte Befehlszeile unverändert und bleibt dort, bis der Befehl endet. Auch Semikolons werden übergeben, sodass eine vollständige verkettete Befehlsfolge in einem Workerprozess ausgeführt werden kann. Die Verbindung zum Worker bleibt offen, bis die Befehlsliste abgeschlossen ist. Alle nach den Befehlen gesendeten Daten werden an die CLI des Workerprozesses weitergeleitet. Sie können von den ausgeführten Befehlen verarbeitet werden und gehen für die CLI des Masterprozesses verloren. So entsteht eine tatsächlich bidirektionale Verbindung mit dem Workerprozess. Bei Verwendung solcher Befehle muss daher sehr sorgfältig auf deren Abschluss gewartet werden, bevor neue Befehle an die Master-CLI gesendet werden.
Statt einen einzelnen Befehl auszuführen, kann auch eine vollständig interaktive Sitzung auf dem Workerprozess geöffnet werden, indem kein Befehl angegeben wird (also “@@1” in einer eigenen Zeile). Diese Sitzung lässt sich entweder durch Schließen der Verbindung oder durch Verlassen der CLI des Workerprozesses (mit dem Befehl “quit”) beenden. In diesem Fall wird der Eingabeaufforderungsmodus des Mastersockets (interactive, prompt, timed) an den Workerprozess weitergegeben.
Fehler: Das Protokoll sockpair@ zur Kommunikation zwischen Master und Worker ist auf macOS bekanntermaßen unzuverlässig, da die macOS-Implementierung von sendmsg(2) fehlerhaft ist. Ein Befehl kann daher ohne Antwort bleiben.
Beispiele:
expert-mode [on|off]
Dieser Befehl aktiviert “expert-mode” für jeden Worker, auf den über die Master-CLI zugegriffen wird. Zusammen mit “mcli-debug-mode” aktiviert er den Befehl auch auf dem Master. Er zeigt das Flag “e” in der Eingabeaufforderung der Master-CLI an.
Siehe auch “expert-mode” in Abschnitt 9.3 und “mcli-debug-mode” in 9.4.1.
experimental-mode [on|off]
Dieser Befehl aktiviert “experimental-mode” für jeden Worker, auf den über die Master-CLI zugegriffen wird. Zusammen mit “mcli-debug-mode” aktiviert er den Befehl auch auf dem Master. Er zeigt das Flag “x” in der Eingabeaufforderung der Master-CLI an.
Siehe auch “experimental-mode” in Abschnitt 9.3 und “mcli-debug-mode” in 9.4.1.
hard-reload
Dieser Befehl verhält sich wie der Befehl “reload” über die Master-CLI, beendet den vorherigen Prozess jedoch sofort (-st), statt ihn geordnet anzuhalten (-sf). Der vorherige Prozess wartet also vor dem Beenden auf keinen Abschluss, sodass alle Verbindungen geschlossen werden.
Siehe auch den Befehl “reload”.
mcli-debug-mode [on|off]
Dieses Schlüsselwort ermöglicht einen besonderen Modus der Master-CLI, der dort alle für eine Worker-CLI vorgesehenen Schlüsselwörter aktiviert und so die Fehlersuche im Masterprozess ermöglicht. Nach der Aktivierung lassen sich die neu verfügbaren Schlüsselwörter mit “help” auflisten. Zusammen mit “experimental-mode” oder “expert-mode” werden noch weitere Schlüsselwörter aktiviert. Das Flag “d” wird in der Eingabeaufforderung der Master-CLI angezeigt.
prompt
Wenn die Eingabeaufforderung aktiviert ist (über den Befehl “prompt”), zeigt sie den Kontext an, in dem die CLI arbeitet. Der Master wird durch die Zeichenkette “master” gekennzeichnet, andere Prozesse durch ihre PID. Ist das letzte Neuladen fehlgeschlagen, wird die Eingabeaufforderung des Masters zu “master[ReloadFailed]>” geändert. Dadurch wird sichtbar, dass der Prozess weiterhin mit der vorherigen Konfiguration läuft und die neue Konfiguration nicht betriebsbereit ist.
Die Eingabeaufforderung der Master-CLI kann mehrere Flags anzeigen, die die aktivierten Modi kennzeichnen: “d” für mcli-debug-mode, “e” für expert-mode und “x” für experimental-mode.
Beispiel:
reload
Der HAProxy-Masterprozess kann auch mit dem Befehl “reload” neu geladen werden. Dies entspricht einem kill -USR2 auf den Masterprozess, sofern der Benutzer mindestens über die Berechtigungsstufe “operator” oder “admin” verfügt.
Dieser Befehl ermöglicht ein synchrones Neuladen und gibt nach dessen Ausführung den Status zurück. Wenn die Ausgabe mit einem Werkzeug geparst wird, ist die Zeitüberschreitung zu beachten: Der Status wird erst zurückgegeben, nachdem die Konfiguration geparst und der neue Worker durch fork erzeugt wurde. Der Befehl “socat” verwendet standardmäßig eine Zeitüberschreitung von 0.5s. Dauert das Neuladen zu lange, beendet er sich daher, bevor die Meldung angezeigt wird. “ncat” hat standardmäßig keine Zeitüberschreitung. Bei Kompilierung mit USE_SHM_OPEN=1 kann der Befehl reload außerdem die startup-logs des Masters ausgeben.
Beispiel:
Der Befehl reload ist der letzte, der auf der Master-CLI ausgeführt wird; alle nachfolgenden Befehle werden ignoriert. Sobald der Befehl reload seinen Status zurückgibt, schließt er die Verbindung zur CLI.
Ein Neuladen schließt alle Verbindungen zur Master-CLI. Siehe auch den Befehl “hard-reload”.
show proc [debug]
Die Master-CLI stellt den Befehl ‘show proc’ zur Überwachung der Prozesse bereit.
Beispiel:
In diesem Beispiel wurde der Master 5 Mal neu geladen, aber einer der alten Worker läuft noch und hat 3 Neuladevorgänge überlebt. Über die CLI dieses Workers lässt sich untersuchen, was geschieht.
Der Parameter ‘debug’ zeigt Details zur Fehlersuche an, derzeit die FDs der IPC-Kommunikation. Zwischen haproxy-Versionen ist die Stabilität der Debugausgabe nicht gewährleistet.
show startup-logs
Für die korrekte Verwendung auf der Master-CLI muss HAProxy mit USE_SHM_OPEN=1 kompiliert werden; andernfalls sind nicht alle Meldungen sichtbar.
Wie sein Gegenstück auf dem Statistiksocket kann dieser Befehl die Startmeldungen von HAProxy anzeigen. Er gibt jedoch nicht die Startmeldungen des aktuellen Workers aus, sondern die des letzten Start- oder Neuladeversuchs. Damit kann er auch die Parsingmeldungen eines fehlgeschlagenen Neuladens ausgeben.
Diese Meldungen werden auch mit dem Befehl “reload” ausgegeben.
9.5. Statistikdatei (Stats-file)
Eine sogenannte Statistikdatei (stats-file) kann verwendet werden, um interne haproxy-Zähler beim Prozessstart mit Werten ungleich null vorzubelegen. Ihr Hauptzweck ist es, Statistiken von Workerprozessen über Neuladevorgänge hinweg zu erhalten. Eine stats-file enthält nur einen Teil aller von haproxy bereitgestellten Statistiken, da nur das Vorbelegen von Metrikwerten sinnvoll ist.
Derzeit unterstützt stats-file nur Proxyzähler. So lassen sich Werte für Frontends, Backends, Server und Listener vorbelegen. In einer stats-file werden jedoch nur Objektinstanzen mit einer nicht leeren GUID gespeichert. Dies stellt sicher, dass Werte für Objekte mit übereinstimmendem Typ und übereinstimmender GUID vorbelegt werden, auch wenn andere Parameter abweichen.
Der CLI-Befehl “dump stats-file” dient dazu, eine stats-file zu erzeugen. Das Format der stats-file ist intern definiert und kann künftig frei geändert und erweitert werden. Es ist auf Kompatibilität mindestens zwischen aufeinanderfolgenden stabilen haproxy-Versionszweigen ausgelegt. Wird eine stats-file in einen Prozess geladen, der eine ältere Version ausführt, kann jedoch eine optionale zusätzliche Konfiguration erforderlich sein.
31 - 10. Einfachere Konfigurationsverwaltung
Häufig verwenden zwei HAProxy-Knoten eines Clusters bis auf wenige Adressen genau dieselbe Konfiguration. Statt für jeden Knoten eine eigene Kopie zu pflegen, die zwangsläufig irgendwann abweicht, lassen sich Umgebungsvariablen in die Konfiguration einbinden. So können mehrere Konfigurationen dieselbe Datei verwenden und sich nur in wenigen systemweiten Umgebungsvariablen unterscheiden. Diese Möglichkeit wurde in Version 1.5 eingeführt, zunächst nur für Adressen. Version 1.6 unterstützt Umgebungsvariablen an beliebigen Stellen. Die Syntax entspricht der UNIX-Shell: Eine Variable beginnt mit einem Dollarzeichen (’$’), gefolgt von einer öffnenden geschweiften Klammer (’{’), dem Variablennamen und einer schließenden geschweiften Klammer (’}’). Außer in Adressen werden Umgebungsvariablen nur in Argumenten ausgewertet, die in doppelten Anführungszeichen stehen. Diese Einschränkung war nötig, damit bestehende Konfigurationen mit regulären Ausdrücken, die ein Dollarzeichen enthalten, weiterhin funktionieren.
Umgebungsvariablen erleichtern auch Konfigurationen für verschiedene Standorte, bei denen sich nur die Adresse ändert. Außerdem können sie dazu dienen, Passwörter aus manchen Konfigurationen zu entfernen. Im folgenden Beispiel liest das Startskript beim Start die Datei “site1.env” ein:
32 - 11. Bekannte Fallstricke vermeiden
Gelegentlich wird berichtet, dass der haproxy-Dienst nach einem Systemneustart nicht gestartet wurde, sich aber von Hand problemlos starten lässt. Meist wird dabei eine Lösung wie keepalived eingesetzt, die die Dienst-IP-Adresse nur dem Master-Knoten eines Clusters zuweist. Solange haproxy an 0.0.0.0 gebunden war, funktionierte dies; nach der Bindung an die virtuelle IP-Adresse nicht mehr. Beim Dienststart gehört die virtuelle IP-Adresse noch nicht zum lokalen Knoten. Wenn HAProxy sich daran binden möchte, lehnt das System dies ab, weil es keine lokale IP-Adresse ist. Die Lösung besteht nicht darin, den Start des haproxy-Dienstes zu verzögern, da dies bei einem Neustart nicht zuverlässig funktionieren würde. Stattdessen muss das System so konfiguriert werden, dass es die Bindung an nicht lokale Adressen erlaubt. Unter Linux lässt sich dies einfach erreichen, indem der sysctl-Parameter net.ipv4.ip_nonlocal_bind auf 1 gesetzt wird. Das ist auch nötig, um den IP-Datenverkehr, der HAProxy für eine bestimmte Zieladresse durchläuft, transparent abzufangen.
Konfigurationen mit mehreren Prozessen und Quellportbereichen scheinen zunächst zu funktionieren, führen unter hoher Last aber zu sporadischen Fehlern: Mehrere Prozesse können versuchen, denselben Quellport für eine Verbindung zum selben Server zu verwenden, was nicht möglich ist. Das System meldet einen Fehler, woraufhin ein erneuter Versuch mit einem anderen Port erfolgt. Ein hoher Wert für den Parameter “retries” kann diesen Effekt bis zu einem gewissen Grad verdecken, erhöht jedoch auch CPU-Auslastung und Verarbeitungszeit. Die Protokolle weisen ebenfalls eine gewisse Anzahl von Wiederholungsversuchen aus. Deshalb sollten Portbereiche in Konfigurationen mit mehreren Prozessen vermieden werden.
Da HAProxy SO_REUSEPORT verwendet und mehrere unabhängige Prozesse an dieselbe Kombination IP:port binden kann, kommt es bei der Fehlerbehebung vor, dass ein alter Prozess noch läuft, wenn ein neuer gestartet wird. Das führt zu widersinnigen Testergebnissen, die den Eindruck erwecken, Konfigurationsänderungen würden ignoriert. Selbst wenn der neue Prozess mit einer neuen Konfiguration neu gestartet wird, erhält und verarbeitet auch der alte Prozess noch eingehende Verbindungen und liefert unerwartete Ergebnisse. Im Zweifelsfall den neuen Prozess stoppen und erneut testen. Funktioniert der Dienst weiterhin, ist sehr wahrscheinlich noch ein alter Prozess aktiv, der gestoppt werden muss. Unter Linux hilft dabei “netstat -lntp”.
Beim Hinzufügen von ACL-Einträgen über die Befehlszeile, etwa zum Sperren einer Quelladresse, ist zu beachten, dass diese Einträge nicht mit der Datei synchronisiert werden. Lädt jemand die Konfiguration neu, gehen die Änderungen verloren. Beim Sperren ist dies oft erwünscht, kann aber den Erwartungen widersprechen, wenn die Änderung ein Problem beheben sollte. Siehe dazu die Aktion “add acl” der CLI-Schnittstelle.
33 - 12. Fehlerdiagnose und Leistungsprobleme
Mit der Option “-d” bleibt HAProxy im Vordergrund und gibt für jedes Ereignis eine Zeile aus, etwa für eine eingehende oder beendete Verbindung sowie für jede erkannte Headerzeile einer Anfrage oder Antwort. Diese Diagnoseausgabe entsteht vor der Verarbeitung des Inhalts und berücksichtigt deshalb keine lokalen Änderungen. Sie dient hauptsächlich dazu, Anfragen und Antworten ohne Netzwerkmitschnitt anzuzeigen. Bei mehreren parallelen Verbindungen ist die Ausgabe schwerer lesbar. Die Skripte “debug2ansi” und “debug2html” im Verzeichnis examples/ helfen dann durch farbliche Hervorhebung.
Lehnt HAProxy eine HTTP/1.x-Anfrage oder -Antwort als fehlerhaft ab, sollte über die CLI der Befehl “show errors” ausgeführt werden. Er zeigt für jedes Frontend und Backend die zuletzt erfasste fehlerhafte HTTP/1.x-Anfrage und -Antwort mit allen Angaben, die das erste abgelehnte Zeichen des Eingabestroms genau bestimmen. Dies kann nötig sein, um Kunden oder Entwicklern einen Fehler in ihrem Code nachzuweisen. Häufig lassen sich die Prüfungen mit “option accept-unsafe-violations-in-http-request” beziehungsweise für Serverantworten mit “option accept-unsafe-violations-in-http-response” lockern, während die Erfassung erhalten bleibt. Weitere Einzelheiten stehen im Konfigurationshandbuch.
Beispiel:
Die CLI-Ausgabe von “show info” enthält hilfreiche Informationen über die bisher höchste Verbindungsrate, die höchste SSL-Schlüsselrate und allgemein Daten, mit denen sich vorübergehende Probleme bei CPU- oder Speichernutzung erklären lassen. Beispiel:
Tritt ein Problem mit einer neuen HAProxy-Version scheinbar zufällig auf, etwa der Abbruch jeder zweiten Anfrage oder gelegentliche Abstürze, kann eine gezielte Vorbelegung des Speichers helfen. Dabei wird nach jedem malloc()-Aufruf der Speicherbereich mit einem konfigurierbaren Byte gefüllt. Standardmäßig ist dies 0x50, der ASCII-Wert für ‘P’. Jedes andere Byte ist ebenfalls möglich, auch Null, was wie calloc() wirkt und Probleme verschwinden lassen kann. Diese Speicherinitialisierung wird mit der Befehlszeilenoption “-dM” aktiviert. Sie beeinträchtigt die Leistung etwas und wird für den Produktionsbetrieb nicht empfohlen. Tritt ein Problem damit immer auf oder verschwindet es stets bei einer Vorbelegung mit Null, liegt eindeutig ein Fehler vor, der unbedingt gemeldet werden muss. Ändert sich dagegen nichts erkennbar, besteht kein Zusammenhang mit dieser Ursache.
Zur Untersuchung von Latenzproblemen sind sowohl strace und tcpdump auf dem lokalen Rechner als auch ein weiteres tcpdump auf dem entfernten System wichtig. Überall in der Verarbeitungskette können Verzögerungen entstehen. Nur wenn die Ursache bekannt ist, lässt sich gezielt eingreifen. Das lokale tcpdump zeigt, wann Eingabedaten eintreffen. strace zeigt, wann haproxy sie mit recv/recvfrom entgegennimmt. Achtung: OpenSSL verwendet read()/write() statt recv()/send(). strace zeigt außerdem, wann haproxy Daten sendet; tcpdump zeigt, wann das System sie an die Schnittstelle übergibt. Das entfernte tcpdump zeigt schließlich, wann die gesendeten Daten tatsächlich eintreffen, während der lokale Mitschnitt nur das Einreihen der Pakete in die Warteschlange erfasst. Der lokale Mitschnitt hat den Vorteil, dass strace und tcpdump dieselbe Referenzuhr verwenden. strace sollte mit “-tts200” ausgeführt werden, um vollständige Zeitstempel und ausreichend große, lesbare Datenausschnitte zu erhalten. tcpdump sollte mit “-nvvttSs0” ausgeführt werden, damit vollständige Pakete, tatsächliche Sequenznummern und vollständige Zeitstempel angezeigt werden.
In der Praxis nimmt haproxy eingehende Daten fast immer sofort entgegen, außer bei ausgelasteter CPU oder ungültigen Daten, die nicht zugestellt werden. Werden Daten empfangen, aber nicht gesendet, ist meist der Ausgabepuffer voll, weil der Empfänger die Daten nicht schnell genug verarbeitet. Bestätigen lässt sich dies daran, dass das Polling eine Zeit lang keine Schreibbereitschaft für den Ausgabedateideskriptor meldet. In der strace-Ausgabe ist es oft einfacher, zunächst das spätere Senden zu finden und dann rückwärts nach der Meldung der Schreibbereitschaft zu suchen. Dies fällt meist mit einem ACK des Empfängers zusammen, das tcpdump erfasst. Nach dem Senden können Daten noch eine Zeit lang untätig im System verbleiben. Auch hier kann das TCP-Überlastungsfenster die Übertragung begrenzen und auf ein ACK warten, das es öffnet. Ist der Datenverkehr ansonsten untätig und dauert das Senden 40 ms oder 200 ms, liegt eine andere, eigentlich normale Situation vor: Der Nagle-Algorithmus hält leere Pakete zurück, damit sie mit späteren Daten zusammengefasst werden können. Im reinen TCP-Modus und in Tunneln deaktiviert HAProxy Nagle automatisch. Beim Weiterleiten eines HTTP-Nachrichtenkörpers bleibt Nagle dagegen aktiviert, was durch weniger Pakete die Leistung verbessert. Manche nicht HTTP-konformen Anwendungen reagieren empfindlich auf diese Verzögerung bei der Übertragung unvollständiger HTTP-Antworten. Dann muss “option http-no-delay” aktiviert werden, um Nagle zu deaktivieren und die Einschränkung dieser Anwendungen zu umgehen. Andere Proxys in der Verarbeitungskette können jedoch ebenso betroffen sein. Zeigt tcpdump ein sofortiges Senden, während die Gegenseite die Daten erst später erhält, kann eine überlastete WAN-Verbindung oder ein überlastetes LAN mit aktiver Flusskontrolle die Ursache sein. Häufiger läuft HAProxy in einer virtuellen Maschine, und der Hypervisor hat aus irgendeinem Grund entschieden, die Daten nicht sofort zu senden. In virtualisierten Umgebungen verursacht fast immer die Virtualisierungsschicht solche Latenzprobleme. Um Zeit zu sparen, sollten daher zuerst tcpdump-Mitschnitte in der VM und auf den externen Komponenten verglichen werden. Jede Abweichung ist dem Hypervisor und seinen Treibern zuzurechnen.
Sind im tcpdump-Mitschnitt mit -vv TCP-SACK-Segmente sichtbar, hat die sendende Seite nachweislich einen Paketverlust festgestellt. Ihr Ausbleiben beweist nicht, dass keine Verluste auftreten; ihr Auftreten beweist jedoch, dass das Netzwerk Pakete verliert. Verluste sind in Netzwerken normal, allerdings in einem Ausmaß, bei dem SACKs mit bloßem Auge nicht auffallen. Treten sie häufig auf, sollte genau untersucht werden, was geschieht und wo Pakete verloren gehen. HTTP kommt mit TCP-Verlusten schlecht zurecht, da sie große Latenzen verursachen.
“netstat -i” zeigt Statistiken je Schnittstelle. Ein steigender Zähler Rx-Ovr bedeutet, dass dem System die Ressourcen fehlen, um alle eingehenden Pakete anzunehmen; sie gehen bereits vor der Verarbeitung durch den Netzwerktreiber verloren. Rx-Drp zeigt, dass empfangene Pakete im Netzwerk-Stack verloren gingen, weil die Anwendung sie nicht schnell genug verarbeitet. Dies kann auch bei Angriffen auftreten. Tx-Drp bedeutet, dass die Ausgabewarteschlangen voll waren und Pakete verworfen werden mussten. Bei TCP sollte dies sehr selten sein, kann aber auf eine ausgelastete ausgehende Verbindung hinweisen.
34 - 13. Sicherheitsaspekte
HAProxy ist für den Betrieb mit stark eingeschränkten Berechtigungen ausgelegt. Üblicherweise wird er in einer chroot-Umgebung isoliert und wechselt zu einem Benutzer ohne root-Rechte, der innerhalb dieser Umgebung keinerlei Berechtigungen hat. Sollte künftig eine Schwachstelle entdeckt werden, würde eine Kompromittierung damit nicht den Rest des Systems betreffen.
Für chroot muss der Prozess zunächst als root gestartet werden. Eine von Hand aufgebaute chroot-Umgebung, in der der Prozess gestartet wird, ist nicht sinnvoll: Solche Umgebungen sind aufwendig einzurichten, werden nie ausreichend gepflegt und enthalten stets wesentlich mehr Fehler als das eigentliche Dateisystem. Bei einer Kompromittierung könnte ein Angreifer zudem das eigens eingerichtete Dateisystem verwenden. Leider verwechseln viele Administratoren den Start als root mit dem dauerhaften Betrieb als root. Sie ändern die UID deshalb bereits vor dem Start von haproxy und verringern dadurch die wirksamen Sicherheitsbeschränkungen.
HAProxy muss als root gestartet werden, um:
- die Grenzen für Dateideskriptoren anzupassen
- sich an privilegierte Portnummern zu binden
- sich an eine bestimmte Netzwerkschnittstelle zu binden
- transparent auf einer fremden Adresse zu lauschen
- sich in der chroot-Umgebung zu isolieren
- zu einer anderen, nicht privilegierten UID zu wechseln
HAProxy muss möglicherweise dauerhaft als root laufen, um:
- sich für ausgehende Verbindungen an eine Schnittstelle zu binden
- sich für ausgehende Verbindungen an privilegierte Quellports zu binden
- sich für ausgehende Verbindungen transparent an eine fremde Adresse zu binden
Die meisten Nutzer benötigen den dauerhaften Betrieb als root nie. Der Start als root deckt dagegen die meisten Einsatzzwecke ab.
Eine sichere Konfiguration enthält:
- eine chroot-Anweisung, die auf ein leeres Verzeichnis ohne Zugriffsberechtigungen zeigt. Dieses lässt sich in der UNIX-Befehlszeile wie folgt vorbereiten:
Im global-Abschnitt der HAProxy-Konfiguration wird es so angegeben:
- sowohl eine uid/user- als auch eine gid/group-Anweisung im global-Abschnitt:
- einen stats-Socket, dessen mode, uid und gid zum Benutzer beziehungsweise zur Gruppe passen, die auf die CLI zugreifen dürfen, sodass niemand sonst Zugriff erhält:
13.1. Unterstützung für Linux-Capabilities
Seit Version v2.9 unterstützt haproxy Linux-Capabilities. Wird die Binärdatei mit USE_LINUX_CAP=1 kompiliert, kann sie beim Wechsel von root zu einem Benutzer ohne root-Rechte die mit dem Schlüsselwort ‘setcap’ angegebenen Capabilities beibehalten.
Seit Version v3.1 prüft haproxy außerdem mit dem Systemaufruf capget, ob die Administration die mit ‘setcap’ angegebenen Capabilities in der Permitted-Menge der Binärdatei gesetzt hat. Ist dies der Fall, übernimmt er diese mit capset in die Effective-Menge seines Prozesses, während er ohne root-Rechte läuft.
Damit sollen alle potenziellen Einsatzfälle vermieden werden, in denen haproxy als root startet und weiterläuft, etwa der transparente Proxy-Modus oder die Bindung an privilegierte Ports.
Das Schlüsselwort ‘setcap’ unterstützt folgende Netzwerk-Capabilities:
- cap_net_admin: transparentes Proxying, Bindung eines Sockets an eine bestimmte Netzwerkschnittstelle und Verwendung der Aktion set-mark;
- cap_net_raw (Teilmenge von cap_net_admin): transparentes Proxying;
- cap_net_bind_service: Bindung eines Sockets an einen privilegierten Port;
- cap_sys_admin: Erstellen eines Sockets in einem bestimmten Netzwerk-Namespace.
HAProxy übernimmt diese Capabilities niemals aus seiner Permitted-Menge in die Effective-Menge, wenn sie nicht als Argument von ‘setcap’ aufgeführt sind. Weitere Informationen zu ‘setcap’ und den unterstützten Capabilities enthält Kapitel 3.1 zur Prozessverwaltung und Sicherheit im Konfigurationshandbuch.
Die Administration kann die benötigten Capabilities mit folgendem Befehl zur Permitted-Menge der haproxy-Binärdatei hinzufügen:
Beispiel:
Nach dem Start sind die hinzugefügten Capabilities in der Permitted-Menge des Prozesses sichtbar. Sind dieselben Capabilities als Argumente von ‘setcap’ angegeben, können sie auch in der Effective-Menge des Prozesses erscheinen. Dies lässt sich mit folgendem Befehl prüfen:
Beispiel:
CapInh: 0000000000000000
CapPrm: 0000000000001400
CapEff: 0000000000001400
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000
Weitere Einzelheiten zu setcap und den Capability-Mengen stehen in den Linux-Handbuchseiten unter capabilities(7).
Bei manchen Einsatzzwecken, etwa transparentem Proxying oder dem Erstellen eines Sockets in einem bestimmten Netzwerk-Namespace, erkennt der Konfigurationsparser, dass cap_net_raw, cap_sys_admin oder andere unterstützte Capabilities benötigt werden. Während der Initialisierung prüft der haproxy-Prozess dann, ob diese in seine Effective-Menge übernommen werden können. Scheitert dies an einem Fehler bei capget oder capset, beispielsweise aufgrund von Systemaufrufbeschränkungen durch Sicherheitsmodule wie SELinux oder Seccomp, gibt der Prozess diagnostische Warnungen aus; dazu mit -dD starten.
Da zahlreiche Plattformen mit unterschiedlichen Systemeinstellungen unterstützt werden, kann der Parser aus der Konfigurationsdatei nicht ableiten, ob eine Bindung an privilegierte Ports erfolgen wird. Bei unzureichenden Berechtigungen im Betrieb ohne root-Rechte beendet sich der Prozess deshalb lediglich mit einer ALERT-Meldung wie der folgenden. Es ist dann Aufgabe des Benutzers, seine Konfiguration und die Capability-Menge der haproxy-Binärdatei erneut zu prüfen.
Beispiel: