
HAProxy Reverse Proxy mit Let’s Encrypt Zertifikaten unter OPNsense 20.1
In dieser Anleitung will ich kurz darstellen, wie man einen Reverse Proxy mit Let’s Encrypt unter OPNsense 20.1 betreibt. Wir richten auch die automatische Verlängerung der Zertifikate ein und passen die SSL Einstellungen so an, dass wir bei SSL Labs ein Grade A + erhalten.
Meine OPNsense GUI ist auf Englisch gestellt, eventuell heißen die nachfolgenden Optionen bei euch anders. Wichtig ist auch, dass die OPNSense GUI nicht über Port 443 erreichbar ist. Bei mir nutze ich Port 444.
Vorbereitungen im DNS:
In dieser Anleitung verwende ich die HTTP-01 validation von Let’s Encrypt. Das heißt, dass die Server von Let’s Encrypt eine Datei von der Firewall abholen wollen welche der Let’s Encrypt Client in einem bestimmten Pfad ablegt. Damit das funktioniert muss ein funktionierender DNS Eintrag hierfür angelegt sein.
Wenn Ihr also ein Zertifikat für blog.meinedomain.de haben wollt müsst ihr bei eurem DNS Provider einen DNS A-Record anlegen der blog.meinedomain.de heißt und auf eure externe IP Adresse zeigt. Alternativ kann man auch einen CNAME-Record verwenden.
blog.meinedomain.de -> meintollerblog.duckdns.org.
Dies ist bei dynamischen IP Adressen nützlich.
Auf AAAA / IPv6 und Wildcard Zertifikate mittels DNS validation werde ich in diesem Post nicht eingehen.
Installation der benötigten Plugins
Zunächst müssen im Webinterface der Firewall unter
System -> Firmware -> Plugins
folgende Plugins installiert werden:
- os-acme-client
- os-haproxy
Beide Plugins tauchen nach erfolgreicher Installation unter „Services“ auf.
Konfiguration des Let’s Encrypt Plugin
Services -> Let’s Encrypt -> Settings

- „Enable Plugin“ aktivieren.
- „Auto Renewal“ aktivieren.
- Let’s Encrypt Environment“ stellen wir auf „Staging Environment“. Falls wir etwas falsch konfigurieren und diese Option auf „Production Environment“ gestellt haben kann es sein, dass die
- Server von Let’s Encrypt uns für einen Zeitraum von 60 Minuten oder mehr sperren.
- Haken bei „HAProxy Integration“.
- „Log Level“ auf „extendet“, falls wir die Logs analysieren müssen.
Reiter „Update Schedule“

Mit diesen Einstellungen versucht das Plugin jeden Tag um 22 Uhr seine Zertifikate zu erneuern. Mit Save speichern. Danach mit Apply die Einstellungen übernehmen. Zur Sicherheit noch einmal auf „Test Config“ klicken. Wenn alles in Ordnung ist geht’s weiter.
Services -> Let’s Encrypt -> Accounts
Rechts unten auf das kleine „+“ klicken. Die Einstellungen sind selbsterklärend:

Es wäre sinnvoll unter „E-Mail Address“ eine Adresse zu hinterlegen auf die ihr auch Mails empfangt. Let’s Encrypt schickt Mails wenn Zertifikate ablaufen an diese Adresse. Falls also das automatische erneuern aus irgendeinem Grund nicht funktionieren sollte bekommt ihr immerhin eine E-Mail.
Services -> Let’s Encrypt -> Validation Methods:
Rechts unten auf das kleine „+“ klicken.

“Challenge Typ” hier wie bereits am Anfang beschrieben „HTTP-01“. Den Rest bitte aus dem Screenshot übernehmen.
Services -> Let’s Encrypt -> Automation
Rechts unten auf das kleine „+“ klicken.

Hier legen wir eine Automatisierung an die ausgeführt wird wenn ein neues Zertifikat erstellt oder vorhandene erneuert werden. Wir starten HAProxy neu um das neue Zertifikat einzulesen.
Services -> Let’s Encrypt -> Certificates
Rechts unten auf das kleine „+“ klicken.

„Common Name“ ist die URL zu der Ihr das Zertifikat haben wollt. „LE Account“, „Validation Method“ und „Automations“ haben wir vorher angelegt. Auto Renewal braucht einen Haken. Renewal Interval scheint kaputt zu sein. Ich habe da den Wert 5 eingesetzt.
Konfiguration des HAProxy Plugin
Services -> HAProxy -> Settings -> Reiter Settings

Enable HQProxy aktivieren. Ich deaktiviere immer „Show introduction pages“ müsst ihr aber nicht. Die Navigation innerhalb der Einstellungen des Plugins ist dann etwas anders.
Services -> HAProxy -> Settings -> Reiter Real Servers
Hier werden die Server eingetragen die wir später von Außen erreichen wollen. Der Eintrag acme_challenge_host wurde automatisch erstellt. Bitte nicht löschen.
Rechts unten auf das kleine „+“ klicken.

„FQDN or IP“ muss die interne IP des Servers sein den ihr erreichen wollt. Der Port ist der Zielport auf dem zu erreichenden Server. Bei einem Webserver wäre es statt der 12345 eher die 80.
Services -> HAProxy -> Settings -> Reiter Virtual Services -> Backend Pools
Auch hier gibt es wieder einen Eintrag durch das Let’s Encrypt Plugin. Bitte nicht löschen!
Rechts unten auf das kleine „+“ klicken.

Hier sieht es erstmal wild aus aber es muss nur folgendes konfiguriert werden:
- “Name”: Bezeichung für den Pool
- “Servers”: Den eben erstellten Server auswählen. In unserem Beispiel „Test“
Services -> HAProxy -> Settings -> Reiter Rules & Checks -> Conditions
Auch hier gibt es wieder einen Eintrag durch das Let’s Encrypt Plugin. Bitte nicht löschen!
Rechts unten auf das kleine „+“ klicken.

Diese Condition brauchen wir um später anfragen korrekt zuordnen zu können. HAProxy ist halt ein Loadbalancer. Host String sollte der gleiche sein wie euer Zertifikat.
Danach erstellt ihr noch eine zweite Rule. Diese benötigen wir später um eingehende Anfragen von 80 auf 443 zu schieben:

Als nächstes muss noch eine weitere condition angelegt werden, damit die Lets Encrypt reneweals funktioniere. Ihr müsst die vorhande condition “find_acme_challenge” duplizieren, den namen ändern in “no_acme_challenge” und “Negate condition” aktivieren:

Services -> HAProxy -> Settings -> Reiter Rules & Checks -> Rules
Rechts unten auf das kleine „+“ klicken.

In „Use backend pool“ und „Select conditions“ wählen wir unsere bereits erstellten aus. Name ist wie immer frei wählbar.
Services -> HAProxy -> Settings -> Reiter Virtual Services -> Public Services
Hier bereiten wir die Weiterleitungen vor die wir auf Port 80 benötigen um die LE Zertifikate zu bekommen.
Rechts unten auf das kleine „+“ klicken.
Folgende Dinge ändern:
- “Listen Addresses”: 0.0.0.0:80
- “Select Rule”: redirect_acme_challenge
Jetzt müssen wir noch eine Kleinigkeit an den Firewall Regeln anpassen und dann können wir probieren ob das Ausstellen der Zertifikate klappt.
Firewall -> Rules -> Dein WAN-Interface
Rechts oben auf „Add“.

- „Protocol: TCP
- „Destination“: This Firewall
- „Destination port range from“: http „to“ http
Danach das gleiche noch einmal für HTTPS:

- „Protocol: TCP
- „Destination“: This Firewall
- „Destination port range from“: http „to“ http
Zertifikat anfordern
Jetzt probieren wir uns ein Zertifikat zu holen. Dazu Services -> Let’s Encrypt -> Certificates
Auf „Issue/Renew Certificates“ klicken. Wenn es jetzt irgendwelche Probleme gibt. Könnt ihr über Services -> Let’s Encrypt -> Certificates -> Log File das Log ansehen. Alternativ per SSH auf die Firewall und mittels tail -f /var/log/acme.sh.log gucken.
Wenn alles beim testen geklappt hat könnt ihr nun unter Services -> Let’s Encrypt -> Settings „Let’s Encrypt Environment“ auf „Production Environment“ umstellen und das Log wieder auf „normal“ drehen.
Nach diesen Änderungen nun noch einmal „Issue/Renew Certificates“ anklicken. Wenn alles geklappt hat sind wir mit dem LE Plugin fertig und können den Rest im HAProxy einstellen.
Services -> HAProxy -> Settings -> Reiter Virtual Services -> Public Services
Rechts unten auf das kleine „+“ klicken.
Hier ist wieder einiges los:

Folgendes müsst ihr anpassen:
- Listening Address: 0.0.0.0:443
- Haken bei „SSL offloading
- Unter Certificates müsste das per Let’s Encrypt Plugin erstellte Zertifikat auftauchen. Das auswählen.
- Unter Rules -> Select Rules ist eure erstellte Regel von vorher auszuwählen.
Damit wäre das schlimmste schon geschafft. Ihr solltet euren Server nun von außen erreichen.
Wir machen aber noch ein paar Sachen damit das ganze so richtig hübsch wird.
HTTP redirect
Services -> HAProxy -> Settings -> Reiter Rules & Checks -> Rules
Rechts unten auf das kleine „+“ klicken.

- „Name“: Sucht euch was aus.
- „Select conditions“: SSLEstablished, no_acme_challenge
- „Execute function“: http-request redirect
- „http Redirect“: scheme https code 301
Services -> HAProxy -> Settings -> Reiter Virtual Services -> Public Services
Hier haben wir einen Eintrag mit 0.0.0.0:80 angelegt. Diesen editieren. Unter Rules -> Select Rules steht jetzt „redirect_acme_challenges“ dort müssen wir unsere eben erstellte Rule hinzufügen. Die ACME Rule bleibt weiterhin eingetragen. Jetzt wird auch alles was über 80 von außen ankommt auf die 443 redirectet.
SSL Labs Grade A+
Services -> HAProxy -> Settings -> Reiter Settings -> Global Parameters

- Maximum SSL DH Size erhöhen wir auf 2048.
- Unter Bind options: no-sslv3, no-tlsv10, no-tlsv11, no-tls-tickets.
- Cipher List:
ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
Nachdem ihr das gespeichert habt müsst ihr euch noch einmal unter Services -> HAProxy -> Settings -> Reiter Virtual Services -> Public Services euren Service für Port 443 ansehen. Manchmal werden die Bind Options und Cipher Lists nicht korrekt übertragen, dann nachtragen.
Das war es dann auch für heute. Wenns Fragen gibt – ab in die Kommentare damit!
Hallo. Vielen Dank für die super Anleitung. Leider funktioniert es bei mir scheinbar nicht ganz so !? Sobald ich den Public Service anlege oder aktiviere („Listen Addresses“: 0.0.0.0:80) beendet sich der HAProxy Dienst. Wird der Public Service z.B. deaktiviert, lässt sich HAProxy wieder starten …
Ich vermute, dass Problem hängt mit dem Binding auf Port 80 zusammen – wenn ich einen anderen Port angebe, hat HAProxy keine Schwierigkeiten – allerdings funktioniert dann natürlich das Ganze nicht 😉
Ich finde allerdings keine Konfiguration, die irgendwie meinen Port 80 belegen könnte…
Vielleicht hat ja noch jemand eine Idee ? Ich bin am verzweifeln…
Hallo Tobi,
kann es sein, dass du Port 80 bereits für das Webinterface der OPNsense benutzt? System->Settings-Administration->Protocol
Hallo waitforit. Danke für die rasche und hilfreiche Antwort. Ich habe zwar schon auf das HTTPS Protokoll und Port 444 für die GUI umgestellt, aber ohne die Aktivierung der Einstellung “HTTP Redirect -> Disable web GUI redirect rule” war noch ein Binding auf Port 80.
Damit konnte ich jetzt erstmal das erste Zertifikat erstellen und mache mich an den Rest des Tutorials…
Allerdings find ich keine Info, wie du die Kondition “SSLEstablished” konfiguriert hast ? Könntest du mir da bitte noch sagen, welchen Condition Type du verwendet hast ?
Hi Tobi,
ich habe das oben nochmal nachgetragen. Es werden nun zwei conditions erstellt.
Hallo waitforit,
nochmals vielen Dank. Ich kann jetzt das erste Zertifikat erfolgreich nutzen. Allerdings hangle ich mich momentan von einem Problem zum nächsten 🙁
Der Versuch ein zweites Zertifikat zu generieren, schlug nach der Anlage von Condition, Rule, Backend Pool und Real Server fehl. Die neue Rule wurde auf dem Public Service für SSL/HTTP zusätzlich eingetragen…
Nach vielen Versuchen hat es den Anschein, dass die Zertifikatsgenerierung wg. dem Redirect auf HTTPS auf dem HTTP Public Service fehlschlägt !?
Wird diese Regel vor der Generierung (temporär) entfernt, scheint es zu klappen…
Es wäre jetzt natürlich möglich immer vor der Generierung diese Regel zu entfernen, allerdings ist das keine schöne Lösung und viel wichtiger ist, dass ich nicht weiß ob damit auch die automatischen Renewals der Zertifikate fehlschlagen ? Damit wäre es für mich ein No-Go…
Hast du vielleicht in diesem Zusammenhang mehr Erfahrungen ?
Hallo Tobi,
stimmt dieser Fehler existiert. Ich habe den auch schon behoben aber nie den Post angepasst;) Ich habe die nötigen Änderungen jetzt im Post untergebracht. Du musst zunächst die “finde_acme_challenge” condition duplizieren und negieren und dann in der redirect rule sowohl SSLEstablished als auch no_acme_challenge angeben. Dann wird der traffic nur umgebogen wenn er HTTP ist und KEIN acme challenge. Dadurch funktionieren sowohl die reneweals als auch das Anlegen von neuen Hosts/Zertifikaten. Hoffe dir damit geholfen zu haben!
Wow. Werde das heute gleich nochmal ausprobieren. Würde dir für deine Hilfe gerne mal einen (oder mehrere) Kaffee ausgeben…
Jetzt kann ich versuchen meine restliche pfSense Konfig nach opnSense zu migrieren…
Nochmals vielen vielen Dank !!!
Hallo waitforit,
kann man mit deiner Anleitung beliebibg viele Server mit verschiedenen Domains im Backend ansteuern?
Ich hätte 4 Subdomains für die ich Zertifikate über LE beziehen möchte. Mein Anschluss hat eine feste IP Adresse.
Wird hier mit SNI gearbeitet oder wie genau wird das Backend gematched?
LG Patrick
Hallo Patrick,
das ist ohne Probleme möglich. Ich selbst habe auch mehrere Subdomains in benutzung.
Gruß
Hi, vielen Dank für den Guide, damit habe ich es immerhin geschafft mein Zertifikat ans laufen zu bekommen. Leider funktioniert es nicht mit SSH Seiten. Ich will vor allem eine Pulse Secure Appliance ans laufen bekommen, allerdings habe ich jetzt auch nochmal verschiedene andere interne HTTPS Seiten versucht und bekomme jedes mal einen Fehler. Hättest du eine Idee?
LG Marie
Hi,
ich vermute du meinst SSL Seiten. Falls ja, das habe ich noch nicht probiert.
Viele Grüße
Hallo Marie,
heute hatte ich auch die Aufgabenstellung eine mit SSL Verschlüsselte Seite über den HAProxy freizugeben.
Eigentlich musst du dafür nicht viel machen. In der HAProxy Konfiguration unter “Real Servers” muss du
in die Einstellungen des Servers gehen und den Haken bei: “SSL” setzen. “Verify SSL Certificate” darfst du
nicht aktivieren wenn die CA der OPNsense nicht bekannt ist.
Hoffe dir damit geholfen zu haben.
Der HAProxy wäre echt TOP – wenn er funktionieren würde… Alles nach Anleitung gemacht und kling auch logisch für mich das ganze Setting…. aber es funktioniert nicht egal was ich mache… Jemand eine Hilfe zur Hand?
Danke
Hallo reni,
kannst du vielleicht etwas mehr Infos geben? “Funktionier nicht” ist kein Fehler:)
Viele Grüße
Hallo, danke für die super Anleitung. Es hat auf anhieb alles geklappt.
Nun habe ich jedoch eine Frage. Ich habe im Public Server SSL mehrere Subdomains hinterlegt. Das klappt auch super.
Jedoch möchte ich nun nur bestimmte Subdomains mit einen Basic Auth belegen, wie stelle ich das am besten an?
Einen eigener Publicserver scheint nicht zu funktionieren, zumindet hab ich das nicht hinbekommen. Gibt es da eine andere Möglichkeit?
Gruß
Lindi
Hi Lindi,
das habe ich noch nicht probiert. Am besten du guckst mal in die HAProxy Doku:
http://www.haproxy.org/#docs
Viele Grüße!
Hallo waitforit,
die Tücke steckt im Detail. Gehört in ein Backend nur ein realer Server / eine Subdomain oder können es mehrere sein? Für jede der Subdomains existiert schon ein Zertifikat. Aber ich sehe nicht, wie und wo den Subdmains ihr jeweiliges Zertifikat zugeordnet wird.
VG Ralph
Hallo Ralph,
die Zertifikate werden unter werden unter dem public service für Port 443 eingetragen. Einfach alle reinballern. HAProxy nimmt dann beim aufruf das richtige.
VG
Hallo,
diese Anleitung liest sich gut. Ich habe sie nun auch schon ein halbes Dutzend Mal Punkt für Punkt nachvollzogen. Das/die LE-Zertifikate konnte ich erstellen lassen. Aber der Aufruf der Seiten endet immer mit einem “Too Many Redirects”.
Ich bin mit meinem Letain am Ende. Was läuft hier falsch?
Danke für Hilfestellung
und viele Grüße!
Hallo Ralph,
das problem kenne ich leider nicht.
VG