PQ-Leitfaden: HAProxy

12. Februar 2026

EN | DE

HAProxy steht vor einer Menge Infrastruktur. Wenn Sie es als TLS-Terminierungspunkt einsetzen—und das tun Sie wahrscheinlich—dann ist die Kryptografie, die es aushandelt, die Kryptografie, die Ihren Datenverkehr schützt. Was braucht es also, um Post-Quantum Key Exchange zum Laufen zu bringen?

Weniger als man denkt. Und mehr, als Anbieter Ihnen verraten.

HAProxy macht keine Kryptografie

Als jemand GitHub Issue #3171 eröffnete und PQC-Unterstützung für HAProxy anforderte, schlossen die Maintainer das Issue als „works as designed“. Die Antwort ist architekturbedingt: HAProxy delegiert sämtliche TLS-Operationen an OpenSSL. Es implementiert selbst weder Cipher Suites noch Key-Exchange-Algorithmen.

Kein HAProxy-PQC-Patch, auf den man warten müsste. Kein Feature-Flag, das man aktivieren könnte. Wenn die darunterliegende OpenSSL-Bibliothek ML-KEM unterstützt, kann HAProxy es aushandeln. Die Frage ist, ob Ihre OpenSSL-Version es unterstützt und ob Ihre HAProxy-Konfiguration danach verlangt.

Zwei getrennte Probleme. Sie werden ständig miteinander verwechselt.

Schritt 1: Die richtige OpenSSL-Version

OpenSSL 3.5+ (veröffentlicht im April 2025) bietet native PQC-Unterstützung. Die Standard-Gruppenliste sendet jetzt zwei Key Shares: X25519MLKEM768 und X25519. Wenn Sie HAProxy gegen OpenSSL 3.5 linken, funktioniert hybrider PQC Key Exchange direkt out of the box.

Für OpenSSL 3.0–3.4 benötigen Sie den OQS-Provider. Er funktioniert, erhöht aber die Build-Komplexität. Wenn Sie bei Null anfangen, nehmen Sie direkt 3.5.

Prüfen Sie, was bei Ihnen läuft:

haproxy -vv | grep OpenSSL

Wenn dort eine Version unter 3.5 steht, ist das Ihr erstes Problem.

Die meisten distributionspaketierte HAProxy-Installationen linken gegen die OpenSSL-Version, die die Distribution mitliefert. Ubuntu 24.04 liefert OpenSSL 3.0 und HAProxy 2.8—keines von beiden bringt mit, was Sie für native PQC benötigen. Debian 12 liefert OpenSSL 3.0. RHEL 9 liefert OpenSSL 3.0.

Ihre Optionen: HAProxy aus dem Quellcode gegen OpenSSL 3.5 bauen (und diesen Build dauerhaft pflegen—jeden Sicherheitspatch, jedes Update), ein Container-Image mit der richtigen Bibliothek verwenden, oder auf Distributions-Upgrades warten. Warten ist die Standard-Strategie im Enterprise-Umfeld—deshalb werden die meisten HAProxy-Deployments noch bis weit ins Jahr 2027 klassischen Key Exchange aushandeln.

Schritt 2: Beide Seiten konfigurieren

Die richtige OpenSSL-Version allein reicht nicht. Sie müssen HAProxy mitteilen, welche Gruppen angeboten werden sollen. Und zwar sowohl im Frontend als auch im Backend.

Für das Frontend (clientseitig):

global
    ssl-default-bind-curves X25519MLKEM768:X25519:secp256r1:secp384r1

Oder pro Bind-Direktive:

frontend https
    bind *:443 ssl crt /etc/haproxy/certs/site.pem curves X25519MLKEM768:X25519:secp256r1:secp384r1

HAProxy wählt die erste Gruppe aus dieser Liste, die auch der Client unterstützt. X25519MLKEM768 an erster Stelle bedeutet: PQC wenn verfügbar, klassisch als Fallback.

Für die Backend-Seite (Origin-Server)—und hier hören die meisten auf—hat HAProxy 2.9 ssl-default-server-curves eingeführt:

global
    ssl-default-server-curves X25519MLKEM768:X25519:secp256r1:secp384r1

Wenn Sie HAProxy als TLS-Terminierungsproxy betreiben, der zum Backend hin erneut verschlüsselt, und nur das Frontend konfigurieren, haben Sie die letzte Meile geschützt, aber die erste Meile klassisch belassen. Das ist die häufigste Fehlkonfiguration, die wir in PQC-Migrationsanalysen sehen.

Versionshinweis: ssl-default-server-curves erfordert HAProxy 2.9+. Wenn Sie auf 2.8 sind (der Standard bei Ubuntu 24.04), existiert diese Direktive nicht. Mozillas ssl-config-generator hatte tatsächlich einen Bug, bei dem ssl-default-server-curves für HAProxy-2.8-Konfigurationen generiert wurde. Wenn Sie eine generierte Konfiguration übernommen haben und HAProxy sie ablehnte, wissen Sie jetzt warum.

Schritt 3: Die TCP-Passthrough-Falle beachten

Über diesen Fehlermodus sollte eigentlich jeder schreiben.

Wenn Sie HAProxy im TCP-Modus für SNI-basiertes Routing einsetzen—also TLS durchreichen, ohne es zu terminieren—werden PQC-Clients Ihr Setup zum Scheitern bringen. GitHub Issue #3148 dokumentiert das Problem: Wenn OpenSSL-3.5+-Clients standardmäßig X25519MLKEM768 senden, kann das größere ClientHello (~1.700 Bytes) Verbindungsabbrüche verursachen, wenn HAProxy es mit req.ssl_sni inspiziert.

Die Konfiguration, die das Problem auslöst:

frontend ft_443
    mode tcp
    bind :443
    use_backend %[req.ssl_sni,lower,map_str(/etc/haproxy/maps.tls-sni-backends)]

Der Melder beobachtete bei etwa 10% der Verbindungen ein Scheitern mit TCP RST oder FIN direkt nach dem ClientHello. Das Issue wurde als „works as designed“ geschlossen—dieselbe architekturbedingte Antwort. Der req.ssl_sni Sample Fetch muss das ClientHello parsen, um den SNI zu extrahieren, und die größeren PQC Key Shares treiben das ClientHello über die Grenze eines einzelnen Pakets hinaus.

Das ist dieselbe Fehlerklasse, die auf tldr.fail dokumentiert ist: Software, die davon ausgeht, dass ein ClientHello in einen einzelnen TCP read() passt. Klassische ClientHellos sind klein genug, dass diese Annahme in der Regel hält. PQC-ClientHellos sprengen sie. Der X25519MLKEM768 Key Share allein umfasst 1.216 Bytes, verglichen mit 32 Bytes für X25519.

Wenn Sie HAProxy im TCP-Passthrough-Modus betreiben: Testen Sie das mit PQC-fähigen Clients, bevor OpenSSL 3.5 zum Standard in den großen Distributionen wird. Andernfalls entdecken Ihre Nutzer das Problem für Sie.

Workaround: Erhöhen Sie tune.bufsize, um das größere ClientHello aufzunehmen—die Standardgröße von 16.384 Bytes reicht für PQC Key Shares aus, aber falls Sie Verbindungsabbrüche beobachten, erhöhen Sie auf 32.768 (tune.bufsize 32768 in der global-Sektion). Oder wechseln Sie in den TLS-Terminierungsmodus. Das HAProxy-Team hat an der Buffer-Behandlung für große ClientHellos gearbeitet—prüfen Sie, ob Ihre Version den Fix enthält.

Schritt 4: Verifizieren

Hier endet die Konfiguration und das Probing beginnt.

curves X25519MLKEM768 in Ihrer Konfiguration zu setzen bedeutet nicht, dass es auch tatsächlich ausgehandelt wird. OpenSSL könnte stillschweigend zurückfallen. Eine Middlebox könnte den Key Share entfernen. Das Backend könnte es nicht unterstützen. Sie werden es nicht wissen, solange Sie nicht prüfen.

Mit pqprobe:

pqprobe scan your-haproxy-endpoint.example.com:443

Sie suchen nach X25519MLKEM768 in der ausgehandelten Gruppe. Wenn Sie stattdessen X25519 oder secp256r1 sehen, stimmt etwas zwischen Ihrer Konfiguration und dem Netzwerk nicht.

Mit openssl:

openssl s_client -connect your-endpoint:443 -tls1_3 2>&1 | grep "Server Temp Key"

Für die Backend-Seite scannen Sie Ihre Origin-Server unabhängig:

pqprobe scan your-origin-server:443

Wenn diese klassische Gruppen zurückliefern, ändert auch die Konfiguration der serverseitigen Kurven in HAProxy nichts—der Origin-Server muss PQC ebenfalls unterstützen.

Scannen Sie beide Seiten. Vergleichen Sie. Das ist der einzige Weg herauszufinden, ob Sie durchgängiges PQC haben oder nur eine PQC-Fassade am Frontend.

Was ist mit QUIC?

HAProxy’s QUIC-Unterstützung hängt von QuicTLS ab—einem Fork von OpenSSL, der seit dem 3.3-Fork im April 2024 kein neues Release mehr gesehen hat. QuicTLS verfügt nicht über die native PQC-Unterstützung von OpenSSL 3.5. Wenn Sie QUIC auf HAProxy terminieren, steht PQC Key Exchange auf diesem Pfad nicht zur Verfügung.

Jüngste HAProxy-Commits verweisen auf Kompatibilitätsarbeiten mit der neuen QUIC-API von OpenSSL 3.5, aber die Lücke besteht heute real. Wenn Sie PQC-kritische Pfade haben, routen Sie diese vorerst über TLS 1.3 auf TCP. QUIC-Traffic wächst, und wenn Ihr PQC-Migrationsplan nur TLS auf TCP abdeckt, tracken Sie diese Lücke explizit—sie sollte keine Überraschung sein, wenn Auditoren danach fragen.

Performance

Beim Key Exchange ist der Overhead geringer, als die meisten erwarten. AWS hat hybriden X25519+ML-KEM gegen klassisches ECDH gemessen: rund 1.600 zusätzliche Bytes pro Handshake und 80–150 Mikrosekunden zusätzliche Rechenzeit. Der X25519MLKEM768 Key Share umfasst 1.216 Bytes gegenüber 32 Bytes für X25519—größer, aber es sind einmalige Handshake-Kosten, die sich über alle Requests auf dieser Verbindung amortisieren.

Das betrifft ausschließlich den Key Exchange. Post-Quantum-Signaturen sind eine andere Geschichte. ML-DSA-65-Signaturen umfassen ~3.309 Bytes gegenüber ~72 Bytes für ECDSA P-256. Eine Zertifikatskette mit ML-DSA-Signaturen kann 10–18 KB erreichen und allein durch TCP-Fragmentierung Hunderte von Millisekunden Latenz verursachen. Aber PQC-Zertifikatsketten sind noch nicht breit im Einsatz—was Sie heute in HAProxy konfigurieren, ist hybrider Key Exchange mit klassischen Zertifikaten. Wenn PQC-Zertifikate kommen, ist das eine eigene Performance-Diskussion.

Der Engpass in realen Deployments ist derzeit selten die PQC-Key-Exchange-Berechnung. Es sind fehlkonfigurierte TLS-Einstellungen—etwa deaktivierte Session Resumption, die bei jeder Verbindung einen vollständigen Handshake erzwingt—die Kosten verstärken, die sonst vernachlässigbar wären.

Die Checkliste

Voraussetzungen:

  • OpenSSL 3.5+ mit HAProxy gelinkt (haproxy -vv | grep OpenSSL)
  • HAProxy 2.9+, wenn Sie PQC zum Backend benötigen (ssl-default-server-curves)

Konfigurieren:

  • Frontend: ssl-default-bind-curves X25519MLKEM768:X25519:secp256r1:secp384r1
  • Backend: ssl-default-server-curves X25519MLKEM768:X25519:secp256r1:secp384r1

Testen:

  • Bei TCP-Passthrough mit req.ssl_sni: Mit PQC-fähigen Clients auf Verbindungsabbrüche testen
  • Frontend mit pqprobe scannen—bestätigen, dass X25519MLKEM768 ausgehandelt wird
  • Backends unabhängig scannen—bestätigen, dass die Origin-Server PQC ebenfalls unterstützen
  • QUIC-Endpunkte separat prüfen—dort ist PQC noch nicht verfügbar

Das große Ganze

HAProxy zeigt ein Muster, das sich über den gesamten Infrastruktur-Stack wiederholt: Die Software selbst muss keine „PQC-Unterstützung hinzufügen“. Sie muss gegen eine Bibliothek linken, die das tut, und dann entsprechend konfiguriert werden. Die Lücke zwischen „unterstützt“ und „deployt“ besteht aus Bibliotheksversionen, Konfigurationsdirektiven, protokollspezifischen Einschränkungen und operativen Sonderfällen, die erst unter realem Traffic zutage treten.

Diese Lücke ist es, die pqprobe trackt. Nicht ob PQC in Ihrem Stack möglich ist, sondern ob es tatsächlich stattfindet—auf jedem Port, bei jedem Protokoll und auf beiden Seiten jedes Proxys.


Quellen:


Scannen Sie Ihre HAProxy-Endpunkte mit pqprobe, um zu sehen, wo Sie tatsächlich stehen.