bg-tutorials

Wie man ein SSL-Zertifikat in HAProxy konfiguriert

HAProxy ist ein TCP- und HTTP-Load-Balancer, der TLS terminiert, das heißt, er entschlüsselt den Datenverkehr am Rand und leitet reines HTTP an Ihre Backend-Server weiter. Das macht ihn zur einzigen Maschine im Pfad, die das Zertifikat benötigt, und er erwartet dieses Zertifikat in einer bestimmten Form: eine Datei, die das Zertifikat, alle Zwischenzertifikate und den privaten Schlüssel enthält.

Dieser Leitfaden deckt den gesamten Ablauf ab: das Erzeugen eines CSR, das Zusammenstellen der PEM-Datei, das Schreiben von Frontend und Backend, das Überprüfen der Konfiguration und das Neuladen ohne aktive Verbindungen zu unterbrechen. Die Befehle wurden mit HAProxy 3.4 ausgeführt, dem aktuellen Long-Term-Support-Zweig, der im Juni 2026 veröffentlicht wurde und bis Q2 2031 gepflegt wird.

Was HAProxy erwartet: eine einzige PEM-Datei

Die meisten Server nehmen das Zertifikat, die Kette und den Schlüssel als drei separate Einstellungen entgegen. HAProxy nimmt nur eine. Das Konfigurationshandbuch beschreibt das Schlüsselwort crt als Bezeichnung für „eine PEM-Datei, die sowohl die erforderlichen Zertifikate als auch alle zugehörigen privaten Schlüssel enthält“, erstellt durch Zusammenfügen von PEM-Dateien, und fügt hinzu, dass „wenn Ihre CA ein Zwischenzertifikat erfordert, dieses ebenfalls in diese Datei eingefügt werden kann“.

Zwei Verhaltensweisen sind es wert, bevor Sie beginnen, gekannt zu werden, da sie später Arbeit ersparen:

  • Der Schlüssel kann neben dem Zertifikat statt darin liegen. Wenn die Datei keinen privaten Schlüssel enthält, sucht HAProxy nach demselben Pfad mit angehängtem .key. So funktioniert mydomain.pem plus mydomain.pem.key genauso gut wie eine kombinierte Datei.
  • Sie können crt auf ein Verzeichnis verweisen lassen. HAProxy lädt jede dort gefundene Datei und wählt das richtige Zertifikat pro Anfrage anhand von SNI aus. So bedienen Sie mehrere Websites von einem Frontend aus, ohne für jede eine eigene bind-Zeile zu benötigen.

CSR und privaten Schlüssel erzeugen

Ein CSR ist die codierte Anfrage, die Sie der Zertifizierungsstelle übergeben. Erzeugen Sie ihn auf der HAProxy-Maschine oder überall dort, wo Sie den privaten Schlüssel sicher aufbewahren können, da der Schlüssel niemals Ihre Seite verlässt.

openssl req -new -newkey rsa:2048 -nodes 
  -keyout mydomain.key -out mydomain.csr 
  -subj "/C=US/ST=California/L=San Jose/O=Your Company/CN=mydomain.com" 
  -addext "subjectAltName=DNS:mydomain.com,DNS:www.mydomain.com"

Die Zeile -addext ist in der Praxis nicht optional. Browser gleichen Hostnamen schon seit Jahren nicht mehr mit dem Common Name ab und lesen nur das Subject Alternative Name-Feld, sodass ein CSR, der nur einen CN enthält, ein Zertifikat erzeugt, das in jedem aktuellen Browser fehlschlägt. Listen Sie jeden Namen auf, den das Zertifikat abdecken muss, einschließlich der nackten Domain und der www-Form, falls Sie beide bedienen.

Lassen Sie die Optionen -subj und -addext weg, wenn Sie lieber für jedes Feld einzeln gefragt werden möchten. So oder so erhalten Sie zwei Dateien: mydomain.csr zum Einreichen und mydomain.key zum Aufbewahren. Bestätigen Sie vor dem Einreichen, dass der CSR das enthält, was Sie erwarten, entweder mit unserem CSR-Decoder oder lokal:

openssl req -noout -text -verify -in mydomain.csr

Prüfen Sie, ob die SAN-Einträge aufgelistet sind und die Signatur verifiziert wird. Wenn Sie die Kommandozeile lieber gar nicht verwenden möchten, erzeugt unser CSR-Generator dasselbe Paar im Browser. Weitere Hintergründe zu den zugrunde liegenden Befehlen finden Sie in unserem Leitfaden zu OpenSSL-Befehlen.

Zertifikat ausstellen lassen

Reichen Sie den CSR bei der CA ein, wählen Sie den Zertifikatstyp, der zu dem passt, was Sie schützen, und schließen Sie die Validierung ab. Ein Einzeldomain-Zertifikat deckt einen Hostnamen ab, ein Wildcard-Zertifikat deckt jede Subdomain der ersten Ebene ab, und ein Multi-Domain-Zertifikat (SAN) deckt eine Liste nicht zusammenhängender Namen ab. Hinter einem Load Balancer ist Multi-Domain die übliche Wahl, da eine HAProxy-Instanz meist mehrere Websites vorschaltet.

Die CA gibt ein Archiv zurück, das Ihr Zertifikat und die Zwischenzertifikatskette enthält, meist als CA-Bundle-Datei. Beide liegen bereits im PEM-Format vor, das Sie benötigen. Planen Sie die Erneuerung jetzt statt später: Seit dem 15. März 2026 kann ein öffentlich vertrauenswürdiges TLS-Zertifikat höchstens 200 Tage lang gültig sein, ab März 2027 sinkt dies auf 100 Tage und ab März 2029 auf 47 Tage, sodass ein manueller Austausch bald nicht mehr praktikabel ist.

Die PEM-Datei erstellen, die HAProxy lesen wird

Erstellen Sie ein Verzeichnis für Zertifikate und stellen Sie die Datei dort zusammen. Halten Sie alles von Anfang an an einem Ort; wenn Sie dies auf ein Home-Verzeichnis, /etc/haproxy und /etc/ssl aufteilen, bearbeiten Sie am Ende eine Datei, während HAProxy eine andere liest.

sudo mkdir -p /etc/haproxy/certs
sudo chmod 700 /etc/haproxy/certs

Fügen Sie das Zertifikat zusammen, dann die Zwischenzertifikate, dann den privaten Schlüssel. Die Umleitung muss als root laufen, also leiten Sie in tee um, statt sudo cat ... > /etc/haproxy/certs/... zu schreiben, was mit einem Berechtigungsfehler fehlschlägt, weil die Shell die Ausgabedatei als Ihr eigener Benutzer öffnet, bevor sudo überhaupt ausgeführt wird:

cat mydomain.crt intermediate.crt mydomain.key 
  | sudo tee /etc/haproxy/certs/mydomain.pem > /dev/null

Diese Datei enthält nun Ihren privaten Schlüssel im Klartext, sichern Sie sie also, bevor Sie weitermachen:

sudo chown root:root /etc/haproxy/certs/mydomain.pem
sudo chmod 600 /etc/haproxy/certs/mydomain.pem

Nur-root-Berechtigungen sind hier korrekt, kein Hindernis. HAProxy wird mit Superuser-Rechten gestartet, was laut Handbuch erforderlich ist, damit es anschließend zu seinem eigenen unprivilegierten Benutzer wechseln kann, und es liest das Zertifikat während dieses Starts. Es besteht keine Notwendigkeit, die Berechtigungen so zu erweitern, dass der Benutzer haproxy den Schlüssel lesen kann, und Sie sollten es auch nicht tun.

Wenn Sie den CSR auf einer anderen Maschine erstellt haben, kopieren Sie die Dateien zunächst hinüber und löschen Sie die Kopien anschließend aus dem Übertragungsverzeichnis:

scp mydomain.crt intermediate.crt mydomain.key sysadmin@haproxy-server:/home/sysadmin/

HAProxy konfigurieren

Öffnen Sie /etc/haproxy/haproxy.cfg in einem Terminal-Editor auf dem Server selbst, etwa nano oder vim. Bearbeiten Sie sie direkt vor Ort statt auf einer Arbeitsstation, damit Sie niemals eine Datei neu laden, die sich von der getesteten unterscheidet.

Das Frontend

Ein Frontend kann sowohl reines HTTP als auch HTTPS annehmen. Binden Sie Port 80 für die Weiterleitung, binden Sie Port 443 mit dem Zertifikat, und senden Sie alles andere an das Backend:

frontend web_frontend
    mode http
    bind *:80
    bind *:443 ssl crt /etc/haproxy/certs/mydomain.pem alpn h2,http/1.1

    http-request redirect scheme https code 301 unless { ssl_fc }

    default_backend web_servers

alpn h2,http/1.1 bietet HTTP/2 an und fällt auf HTTP/1.1 zurück. Die Weiterleitung greift nur, wenn die Anfrage nicht über TLS eingegangen ist, was ssl_fc prüft, sodass Anfragen auf Port 443 direkt durchgehen.

Setzen Sie jede TLS-Option auf diese eine bind-Zeile

Hier gehen HAProxy-Konfigurationen am häufigsten schief, und es scheitert leise. Anleitungen präsentieren TLS-Härtung häufig als zweiten Schritt und zeigen eine neue bind-Zeile für Port 443 mit zusätzlichen Optionen darauf. Wenn Sie diese Zeile hinzufügen, statt die vorhandene zu bearbeiten, landen Sie mit zwei bind-Zeilen für denselben Port, und HAProxy beschwert sich nicht. Es startet und öffnet zwei separate Listening-Sockets auf Port 443 mit unterschiedlichen TLS-Einstellungen. Auf welchem Socket eine bestimmte Verbindung landet, können Sie nicht steuern, sodass Ihre Härtung ungefähr die Hälfte Ihres Datenverkehrs abdeckt.

Auch die Konfigurationsprüfung erkennt dies nicht, und die eigene Dokumentation erklärt warum: -c „führt nur eine Prüfung der Konfigurationsdateien durch und beendet sich bevor versucht wird zu binden„. Ein doppelter Listener ist eine Bedingung, die erst beim Binden auftritt, sodass eine Syntaxprüfung sie niemals sehen wird.

Setzen Sie stattdessen globale Standardwerte, damit jede bind-Zeile in der Datei sie erbt und es nichts zu duplizieren gibt:

global
    ssl-default-bind-options ssl-min-ver TLSv1.2 prefer-client-ciphers
    ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256

Es lohnt sich zu wissen, bevor Sie diesen Block irgendwohin kopieren: ssl-min-ver ist laut HAProxy selbst bereits standardmäßig auf TLSv1.2 gesetzt. Es auf TLSv1.2 zu setzen, ändert nichts und dokumentiert nur die Absicht, was in Ordnung ist, aber es ist nicht die Sicherheitsverbesserung, als die es oft dargestellt wird. Die beiden Cipher-Einstellungen leisten echte Arbeit und sind bewusst getrennt: ssl-default-bind-ciphers gilt für TLS 1.2 und darunter, ssl-default-bind-ciphersuites gilt für TLS 1.3. Setzen Sie nur die erste, und Ihre TLS-1.3-Suiten bleiben bei ihren Standardwerten.

Das Backend

Geben Sie jedem Server eine echte Adresse. Das ist wichtiger, als es aussieht:

backend web_servers
    mode http
    balance roundrobin
    option httpchk GET /
    server web1 10.0.0.11:80 check
    server web2 10.0.0.12:80 check

Eine Server-Zeile, die wie server web1 :80 check geschrieben ist, wobei die Adresse fehlt, löst keinen Fehler aus. HAProxy akzeptiert sie und löst die fehlende Adresse zu 0.0.0.0 auf, was das Handbuch als speziellen Wert behandelt, der bedeutet, dass die Verbindung an dieselbe IP-Adresse weitergeleitet wird, mit der sich der Client verbunden hat. Diese Adresse ist HAProxy selbst, sodass das Backend still und leise auf HAProxys eigenen Port 80 zeigt, der das gerade konfigurierte Frontend ist. Der Datenverkehr läuft in die Umleitung zurück, statt eine Anwendung zu erreichen, und Health-Checks sehen gesund aus, weil dort tatsächlich etwas lauscht. Wenn ein Load Balancer jede HTTPS-Anfrage mit einer Weiterleitung auf sich selbst beantwortet, prüfen Sie zuerst die Server-Zeilen.

Da HAProxy TLS terminiert, erhalten die Backends reines HTTP auf Port 80 und benötigen kein eigenes Zertifikat. Wenn die Richtlinie eine Verschlüsselung auch auf dieser Teilstrecke verlangt, fügen Sie den Server-Zeilen ssl verify required und eine CA-Datei hinzu und lassen Sie sie stattdessen auf Port 443 zeigen.

Geben Sie das ursprüngliche Schema an das Backend weiter. Da das Backend jetzt reines HTTP erhält, erzeugt eine Anwendung, die absolute URLs generiert, wie WordPress, Django und Rails es alle tun, diese mit http://, was als gemischter Inhalt oder als eine von der Anwendung selbst erzeugte Weiterleitungsschleife in Erscheinung tritt. Fügen Sie dem Frontend eine Zeile hinzu:

http-request set-header X-Forwarded-Proto https if { ssl_fc }

und eine dem Backend, die auch die echte Client-IP-Adresse weitergibt:

option forwardfor

Die meisten Frameworks müssen dann angewiesen werden, diesen Headern zu vertrauen; dieser Teil wird in der Anwendung konfiguriert, nicht in HAProxy.

Die Konfiguration prüfen, bevor Sie sie anwenden

Starten Sie einen Load Balancer niemals mit einer unverifizierten Datei neu. Validieren Sie zuerst:

sudo haproxy -c -V -f /etc/haproxy/haproxy.cfg

Mit -V gibt es bei Erfolg Configuration file is valid aus und liefert den Exit-Status null zurück. Ohne diese Option verläuft der Erfolg still. Etwaige Warnungen werden unabhängig davon gemeldet, ob die Datei gültig ist, lesen Sie also die Ausgabe, statt dem Fehlen von rotem Text zu vertrauen.

Neu laden statt neu starten

sudo systemctl reload haproxy

Der Unterschied ist bei einem Load Balancer real. Ein Reload startet einen neuen Prozess und signalisiert dem alten, „das zu beenden, was er gerade tut, und dann zu verschwinden“, sodass bereits laufende Anfragen normal abgeschlossen werden. Ein Restart signalisiert dem alten Prozess, „sofort zu beenden, ohne das abzuschließen, was er gerade tat“, was aktive Verbindungen kappt, einschließlich Uploads und lang laufender API-Aufrufe. Verwenden Sie Restart nur, wenn ein Reload die Änderung nicht übernehmen kann, etwa nach Änderungen an den Prozesseinstellungen im globalen Abschnitt.

Bestätigen Sie, dass der Dienst wieder läuft und auf beiden Ports lauscht:

sudo systemctl status haproxy
sudo ss -tlnp | grep haproxy

Genau ein Listening-Socket pro Port ist hier das Ziel. Zwei auf Port 443 bedeuten, dass Sie die oben beschriebene doppelte bind-Zeile haben.

Überprüfen, dass das Zertifikat ausgeliefert wird

Prüfen Sie, was HAProxy tatsächlich präsentiert, einschließlich der Kette, direkt vom Server aus:

openssl s_client -connect mydomain.com:443 -servername mydomain.com < /dev/null

Lesen Sie den Abschnitt Certificate chain oben in der Ausgabe. Ihr Zertifikat sollte auf Tiefe 0 erscheinen und das Zwischenzertifikat auf Tiefe 1. Fehlt Tiefe 1, hat es das Zwischenzertifikat nicht in die PEM-Datei geschafft, und die Website wird in manchen Browsern funktionieren, in anderen fehlschlagen. Ignorieren Sie bei dieser Beurteilung die Zeile Verify return code: Sie meldet nur das Ketten-Urteil und kann in Situationen als erfolgreich gelesen werden, die nichts mit dem zu tun haben, was Sie testen.

Bestätigen Sie es dann von außen, wo das Ergebnis widerspiegelt, was echte Besucher erhalten. Unser SSL Checker meldet das Zertifikat, die Kette und das Ablaufdatum.

Erneuerungen und Automatisierung

Das Ersetzen der PEM-Datei ist der gesamte Erneuerungsvorgang: bauen Sie sie aus dem neuen Zertifikat und demselben oder einem neuen Schlüssel neu auf und laden Sie dann neu. Nichts in der HAProxy-Konfiguration verweist auf das Ablaufdatum, sodass keine Konfigurationsänderung nötig ist, solange der Dateipfad gleich bleibt.

Da sich die Gültigkeitsdauern von Zertifikaten verkürzen, lohnt es sich, jetzt Automatisierung einzurichten. HAProxy erhielt in Version 3.2 einen eingebauten ACME-Client, der über einen acme-Abschnitt konfiguriert wird. Betrachten Sie ihn vorerst eher als Vorschau denn als Produktionsinfrastruktur: Er ist in 3.4 noch als experimentell gekennzeichnet und erfordert expose-experimental-directives im globalen Abschnitt, unterstützt nur die Challenge-Typen http-01, dns-01 und dns-persist-01, und von ihm erzeugte Zertifikate müssen aus dem Stats-Socket ausgeleitet werden, um auf die Festplatte zu gelangen. Der in 3.4 hinzugefügte Typ dns-persist-01 verwendet einen statischen TXT-Eintrag, der einmal gesetzt wird und sich zwischen Erneuerungen nie ändert, sodass bei jeder Erneuerung kein Schreibzugriff auf die API des DNS-Anbieters erforderlich ist. Die etablierte Alternative besteht darin, einen externen ACME-Client laufen zu lassen und dessen Deploy-Schritt die PEM-Datei neu erstellen und HAProxy neu laden zu lassen, was demselben Muster entspricht, das in unserem ACME-Leitfaden für Apache und NGINX beschrieben ist.

Häufig gestellte Fragen

In welcher Reihenfolge stehen Zertifikat, Kette und Schlüssel in der PEM-Datei?

Zuerst Ihr Zertifikat, dann alle Zwischenzertifikate, dann der private Schlüssel. Das Handbuch von HAProxy beschreibt die Datei als eine, die durch Zusammenfügen von PEM-Dateien erstellt wird, und sagt, dass das Zwischenzertifikat mit hineingefügt werden kann. Wenn Sie den Schlüssel lieber getrennt halten möchten, lassen Sie ihn ganz weg und speichern Sie ihn unter demselben Pfad mit angehängtem .key, was HAProxy automatisch lädt.

Warum leitet sich meine HTTPS-Website in einer Schleife auf sich selbst um?

Meist eine Backend-Server-Zeile ohne Adresse, wie server web1 :80 check. HAProxy löst die leere Adresse zu 0.0.0.0 auf, und diese Adresse bedeutet, dass die Verbindung an dieselbe IP-Adresse weitergeleitet wird, mit der sich der Client verbunden hat, also HAProxy selbst. Das Backend zeigt daher auf HAProxys eigenen Port 80, der das Frontend ist, das die Weiterleitung von HTTP zu HTTPS ausgibt. Geben Sie jeder Server-Zeile eine echte IP-Adresse oder einen Hostnamen.

Kann ich zwei bind-Zeilen für Port 443 im selben Frontend haben?

Sie können, und genau das ist das Problem. HAProxy führt sie weder zusammen noch warnt es, und haproxy -c läuft erfolgreich durch, weil es sich beendet, bevor es versucht zu binden. Sie erhalten zwei Listening-Sockets auf einem Port mit welchen unterschiedlichen TLS-Optionen auch immer jede Zeile trägt, sodass eine nur auf einer der beiden vorhandene Einstellung nur auf einen Teil Ihres Datenverkehrs zutrifft. Behalten Sie eine bind-Zeile pro Port bei und legen Sie gemeinsame TLS-Einstellungen in ssl-default-bind-options ab.

Härtet das Hinzufügen von ssl-min-ver TLSv1.2 irgendetwas?

Nicht für sich allein. HAProxy dokumentiert den Standardwert von ssl-min-ver bereits als TLSv1.2, sodass das Setzen auf denselben Wert nur Ihre Absicht festhält, ohne das Verhalten zu ändern. Echte Härtung kommt von den Cipher-Einstellungen, und denken Sie daran, dass TLS 1.3 ssl-default-bind-ciphersuites benötigt, während TLS 1.2 und darunter ssl-default-bind-ciphers verwenden.

Brauchen auch meine Backend-Server Zertifikate?

Nicht im Standardaufbau. HAProxy terminiert TLS am Rand und leitet reines HTTP weiter, weshalb nur der Load Balancer das Zertifikat besitzt. Fügen Sie ssl verify required mit einer CA-Datei nur den Server-Zeilen hinzu, wenn Ihre Richtlinie verlangt, dass auch die interne Strecke verschlüsselt ist.

Wie bediene ich mehrere Domains von einer HAProxy-Instanz aus?

Lassen Sie crt auf ein Verzeichnis statt auf eine Datei zeigen. HAProxy lädt jedes darin enthaltene Zertifikat und wählt anhand von SNI das richtige pro Anfrage aus, sodass eine einzige bind-Zeile alle abdeckt. Ein Multi-Domain-Zertifikat (SAN) ist die andere Möglichkeit und eignet sich für eine Gruppe von Namen, die gemeinsam erneuert werden.

Welche HAProxy-Version sollte ich verwenden?

Zweig 3.4, veröffentlicht im Juni 2026, ist die aktuelle Long-Term-Support-Version und wird bis Q2 2031 gepflegt. Die geradzahligen Zweige von HAProxy sind die LTS-Versionen mit rund fünf Jahren Wartung, während ungeradzahlige Zweige wie 3.3 12 bis 18 Monate erhalten. Alles in diesem Leitfaden gilt für 3.0 und neuer; nur der eingebaute ACME-Client erfordert 3.2 oder neuer.

Wenn das Zertifikat installiert ist, Browser aber weiterhin Beschwerden zeigen, decken unsere Leitfäden zu häufigen SSL-Fehlern die üblichen Ursachen ab, meist eine unvollständige Kette oder ein Name, den das Zertifikat nicht aufführt.

Sparen Sie 10% auf SSL-Zertifikate, wenn Sie noch heute bestellen!

Schnelle Ausstellung, starke Verschlüsselung, 99,99% Browser-Vertrauen, engagierter Support und 25-tägige Geld-zurück-Garantie. Gutscheincode: SAVE10

A detailed image of a dragon in flight
Geschrieben von

Erfahrener Content-Autor, spezialisiert auf SSL-Zertifikate. Verwandeln Sie komplexe Cybersicherheitsthemen in klare, ansprechende Inhalte. Tragen Sie durch wirkungsvolle Narrative zur Verbesserung der digitalen Sicherheit bei.

Avatar of Sergiu Rosca
Technical Review by Sergiu Rosca

Sergiu Rosca is the core web developer behind SSL Dragon. He manages the technical infrastructure, platform performance, and backend integrations that keep the site running smoothly and securely. At SSL Dragon, Sergiu shares practical insights on web development, site optimization, and technical troubleshooting.

All SSL Dragon installation guides are tested on live server environments and undergo a strict peer-review process to ensure your infrastructure remains secure. Read our full Editorial Policy.