FHEM Forum

FHEM - Hausautomations-Systeme => MQTT => Thema gestartet von: dennisk am 20 Oktober 2022, 22:37:59

Titel: [gelöst] MQTT2_SERVER neustarten
Beitrag von: dennisk am 20 Oktober 2022, 22:37:59
Hallo zusammen,

ich bin dabei auf MQTT-TLS umzustellen. Habe dafür eine neue Instanz MQTT2_SERVER mit SSL 1 erzeugt. Zertifikat ist von Let's Encrypt. Klappt alles soweit.
Jetzt muss ich noch die automatische regelmäßige Erneuerung des Zertifikats implementieren. Dabei stellt sich mir eine Frage: Wenn ich beispielsweise im NGINX das Zertifikat erneuere, dann muss ich diesen neustarten bzw. über reload neu initialisieren. Ich vermute, dass ich das bei FHEM und MQTT2_SERVER auch machen muss. Liege ich da richtig? Falls ja, gibt es eine Möglichkeit, vielleicht nur die MQTT2_SERVER-Instanz neu zu initialisieren oder neu zu starten? Ich würde es gerne vermeiden, nur wegen dem Zertifikatswechsel FHEM komplett neu zu starten.

Vielen Dank schon mal.
Titel: Antw:MQTT2_SERVER neustarten
Beitrag von: rudolfkoenig am 20 Oktober 2022, 23:16:57
Ein Zertifikatswechsel benoetigt einen Neustart oder ein rereadcfg, was mehr oder weniger einem Neustart gleichzusetzen ist.

Ich biete an ein "set MQTT2_SERVER reopen" zu implementieren, im Gegenzug fuer eine verstaendliche Beschreibung, wie man LetsEncrypt-Zertifikate in FHEM verwendet bzw. erneuert.
Pluspunkte gibt es, wenn man dafuer keine weitere Software wie Apache oder nginx benoetigt :)
Titel: Antw:MQTT2_SERVER neustarten
Beitrag von: dennisk am 22 Oktober 2022, 11:04:50
Zitat von: rudolfkoenig am 20 Oktober 2022, 23:16:57
Ein Zertifikatswechsel benoetigt einen Neustart oder ein rereadcfg, was mehr oder weniger einem Neustart gleichzusetzen ist.
Vielen Dank für die Bestätigung!
Zitat von: rudolfkoenig am 20 Oktober 2022, 23:16:57
Ich biete an ein "set MQTT2_SERVER reopen" zu implementieren, im Gegenzug fuer eine verstaendliche Beschreibung, wie man LetsEncrypt-Zertifikate in FHEM verwendet bzw. erneuert.
Pluspunkte gibt es, wenn man dafuer keine weitere Software wie Apache oder nginx benoetigt :)

Vielen Dank für das Angebot! Der Bitte versuche ich gerne nachzukommen. Vielleicht erstmal direkt hier im Thread, kann man dann ja später, falls gewünscht, woanders ablegen.

TLS-Verschlüsselung für FHEM, konkret am Beispiel des MQTT2_Servers, via DNS-Challenge und dem DNS-Anbieter Cloudflare:
Da ich einige Dienste betreibe, für die TLS-Verschlüsselung aktiviert ist, habe ich mich dazu entschlossen, via Let's Encrypt ein Wildcard-Zertifikat zu beantragen. Damit ich den gesamten Zertifikats-Verwaltungsprozess (Ausrollen, Erneuern) von meinem Heimnetzwerk aus machen kann, nutze ich das Verfahren DNS-01-Challenge - üblich ist sonst HTTP-01-Challenge. Bei diesem Verfahren muss die Challenge nicht auf einem aus dem Internet erreichbaren Webserver hinterlegt werden, sondern diese wird im Nameserver der Domain eingetragen. Da ich außerdem noch die DNS-Dienste des Anbieters Cloudflare nutze, kann ich bequem das entsprechende Plugin des Certbots verwenden, s.a. https://certbot-dns-cloudflare.readthedocs.io/en/stable/. Alternative DNS-Anbieter, die auch kompatibel zum Verfahren DNS-01-Challenge sind, finden sich z.B. unter: https://community.letsencrypt.org/t/dns-providers-who-easily-integrate-with-lets-encrypt-dns-validation/86438

Folgende Schritte sind durchzuführen, um das Wildcard-Zertifikat unter Linux zu beantragen und an die richtige Stelle in FHEM zu deployen. Es wird vorausgesetzt, dass FHEM und Let's Encrypt Certbot mit dem o.g. Plugin bereits installiert sind sowie ein kostenloser Cloudflare-Account besteht und die gewünschte DNS-Zone dort eingerichtet worden ist.
1. In Cloudflare einloggen, das eigene Profil aufrufen (rechts oben im Account-Menü auf My Profile klicken)
2. Links auf API Tokens klicken und dort einen API Token erzeugen, im nächsten Schritt das Template 'Edit zone DNS' auswählen, dort dann drauf achten, dass unter Permissions 'Zone, DNS, Edit' und unter Zone Resources 'Include, Specific zone, gewünschte DNS-Zone' ausgewählt sind und den API Token erstellen.
3. Den soeben erstellten API Token in die ini-Datei für das Certbot-Plugin eintragen, z.B. /root/.cloudflare.ini (Permissions der Datei am besten auf 600:

dns_cloudflare_api_token = erstelltes API-Token

4. Den folgenden Befehl als user root ausführen, Ergebnis sollte dann die erfolgreiche Erstellung des Zertifikats ein, ansonsten entsprechend der Fehlermeldung vorgehen:

certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /root/.cloudflare.ini \
  -d domain.de

5. Die erforderlichen Zertifikatsdateien sollten nun unter /etc/letsencrypt/live/domain.de/ liegen.
6. Nun folgende Befehle ausführen, um die relevanten Zertifikatsdateien FHEM am richtigen Ort zur Verfügung zu stellen. Möglicherweise muss das Verzeichnis /usr/share/fhem/certs erst noch erstellt werden. Wichtig ist, dass das Verzeichnis sowie die dann kopierten Zertifikatsdateien vom Benutzer, unter dem der FHEM-Prozess läuft, gelesen werden können.:

cp /etc/letsencrypt/live/domain.de/fullchain.pem /usr/share/fhem/certs/server-cert.pem
cp /etc/letsencrypt/live/domain.de/privkey.pem /usr/share/fhem/certs/server-key.pem

7. In FHEM der MQTT2_Server-Instanz das Attribut 'SSL 1' zuweisen und den Port auf 8883 ändern. Anschließend FHEM neustarten. Konfiguriert man nun bei einem MQTT-Client entsprechend die Nutzung von TLS und ändert den Port auf 8883, sollte die Kommunikation mit dem MQTT2_Server wieder funktionieren, nun aber eben verschlüsselt. (Hinweis: Wenn man möchte, kann man sich für TLS auch einfach eine zweite MQTT2_Server-Instanz anlegen, dann bleibt die alte erhalten und man kann am Anfang, gerade bei Problemen, leicht hin- und herwechseln.)
8. Damit das Zertifikat regelmäßig erneuert wird, auch in FHEM, sollte noch geprüft werden, ob der entsprechende Systemd-Service bzw. Systemd-Timer aktiviert ist, z.B. systemctl status certbot-renew.timer (der Name des Service bzw. Timers kann je nach Betriebssystem ggf. abweichen). Für den Schritt, dass das aktualisierte Zertifikat dann auch für die Nutzung in FHEM bereitgestellt wird, kann noch ein sogenannter deploy-hook eingerichtet werden, der immer dann, wenn das Zertifikat aktualisert wurde, ausgeführt wird. Dazu unter /etc/letsencrypt/renewal-hooks/deploy (ggf. müssen die Verzeichnisse angelegt werden) ein Shellscript mit folgendem Inhalt anlegen und ausführbar machen:

#!/bin/sh
cp /etc/letsencrypt/live/domain.de/fullchain.pem /usr/share/fhem/certs/server-cert.pem
cp /etc/letsencrypt/live/domain.de/privkey.pem /usr/share/fhem/certs/server-key.pem


Das wars im Wesentlichen. Entspricht das inhaltlich und von der Methodik ungefähr dem, was Du Dir vorgestellt hast? Ich bin gespannt auf Dein Feedback und nehme auch gerne noch Anpassungen vor.

Ergänzung, nachdem rudolfkoenig netterweise einen entsprechenden Mechanismus eingebaut hat:
Das Bash-Script aus dem letzten Schritt könnte man z.B. wie folgt erweitern:

#!/bin/sh
cp /etc/letsencrypt/live/domain.de/fullchain.pem /usr/share/fhem/certs/server-cert.pem
cp /etc/letsencrypt/live/domain.de/privkey.pem /usr/share/fhem/certs/server-key.pem
curl 'http://127.0.0.1:8083/fhem?cmd=set%20Name_des_MQTT2_Server_Device%20reopen%20&XHR=1'

Für die letzte Zeile gibt es sicherlich noch Alternativen, wie z.B. per Telnet.
Titel: Antw:MQTT2_SERVER neustarten
Beitrag von: rudolfkoenig am 24 Oktober 2022, 15:51:36
Vielen Dank fuer die Beschreibung!

Bin zwar nicht sicher, ob Cloudflare Accounts in FHEM Umfeld verbreitet sind, aber es ist eine Alternative, und man kann womoeglich auch fuer andere Wege daraus lernen.

Ich habe dem MQTT2_SERVER "set reopen" spendiert, damit sollte ein Zertifikatwechsel keinen Neustart erfordern.
Bestehende Verbindungen werden damit nicht geschlossen, nur der Serverport. Habe es kurz getestet, mit und ohne SSL, fuer ein Feedback unter "echten" Bedingungen waere ich dankbar.

Und wenn ich schon dabei war: das Gleiche gibts auch fuer FHEMWEB.
Titel: Antw:MQTT2_SERVER neustarten
Beitrag von: Wernieman am 24 Oktober 2022, 20:59:05
certbot kann auch Zertifikate gehen 80 Abgleichen. Kann dann auch mit eingebauten "Webserver" arbeiten.

Allerdings muß dann Port 80 von außen erreichbar sein (und auf das System zeigen, wo der certbot arbeitet.

Und wegen DNS:
Geht auch gegen andere Anbieter, wie z.B. Google-DNS. Eigentlich alle DNS-Anbieter, welche eine API zur DNS-Änderung anbieten. Nur .. z.B. strato macht es mit Absicht nicht. Mann kann aber bei diesen Anbietern meistens auch einen externen DNS-Verwalter (wie cloudflare) nehmen und nur die Domain Verwaltung ...

Und noch eine Kleinigkeit:
Für certbot giebt es auch offizielle Docker-Container. Wenn jemand sein System "sauber" haben will .....
Titel: Antw:MQTT2_SERVER neustarten
Beitrag von: dennisk am 30 Oktober 2022, 13:35:15
Zitat von: rudolfkoenig am 24 Oktober 2022, 15:51:36
Vielen Dank fuer die Beschreibung!

Bin zwar nicht sicher, ob Cloudflare Accounts in FHEM Umfeld verbreitet sind, aber es ist eine Alternative, und man kann womoeglich auch fuer andere Wege daraus lernen.

Ich habe dem MQTT2_SERVER "set reopen" spendiert, damit sollte ein Zertifikatwechsel keinen Neustart erfordern.
Bestehende Verbindungen werden damit nicht geschlossen, nur der Serverport. Habe es kurz getestet, mit und ohne SSL, fuer ein Feedback unter "echten" Bedingungen waere ich dankbar.

Und wenn ich schon dabei war: das Gleiche gibts auch fuer FHEMWEB.

Vielen Dank für die Umsetzung! Ich konnte das gestern mal ausprobieren und auch bei mir scheint es wie gewünscht zu funktionieren! Ich werde es beobachten und nochmal Rückmeldung geben, wenn es Probleme gibt.

Was Cloudflare angeht stimme ich zu, dass sicherlich nicht jeder genau diesen Dienst nutzen wird. Dafür hatte ich im Text den Link zu einer Liste von DNS-Diensten angegeben, auf die Certbot mittels API zugreifen kann: https://community.letsencrypt.org/t/dns-providers-who-easily-integrate-with-lets-encrypt-dns-validation/86438. Vorteil ist, dass Port 80 eben nicht öffentlich erreichbar sein muss - auch nicht temporär. Macht aus meiner Sicht die Automatisierung einfacher.

Wenn gewünscht, dann kann ich gerne versuchen, die Anleitung zu verallgemeinern, sprich Cloudflare rausnehmen und allgemein den Weg mittels DNS-01-Challenge beschreiben.
Soll ich den Thread auf gelöst setzen? Oder damit noch warten?

Zitat von: Wernieman am 24 Oktober 2022, 20:59:05
certbot kann auch Zertifikate gehen 80 Abgleichen. Kann dann auch mit eingebauten "Webserver" arbeiten.

Allerdings muß dann Port 80 von außen erreichbar sein (und auf das System zeigen, wo der certbot arbeitet.

Und wegen DNS:
Geht auch gegen andere Anbieter, wie z.B. Google-DNS. Eigentlich alle DNS-Anbieter, welche eine API zur DNS-Änderung anbieten. Nur .. z.B. strato macht es mit Absicht nicht. Mann kann aber bei diesen Anbietern meistens auch einen externen DNS-Verwalter (wie cloudflare) nehmen und nur die Domain Verwaltung ...

Und noch eine Kleinigkeit:
Für certbot giebt es auch offizielle Docker-Container. Wenn jemand sein System "sauber" haben will .....

Danke Wernieman für Deine Ergänzungen!
Titel: Antw:MQTT2_SERVER neustarten
Beitrag von: Wernieman am 30 Oktober 2022, 13:48:05
Nur noch als Ergänzung:
Man kann Certbot auch mit Scripten erweitern .. also gehen sogar exotische Anbieter, wenn die eine Automatisierung (API) in irgendeiner form anbieten und man Scripten kann .....

Und nur noch mals als Erinnerung:
Certbot giebt es auch in einen Offiziellen Container. Genau so einfach zu verwenden, wie certbot normal. Das Problem mit certbot ist, das er z.B. für Google-DNS (Bei CloudFlare bin ich mir nicht sicher) einiges per CPAN nachinstalliert. Macht das nächte Update komplizierter .......

Wenn Du Hilfe brauchst, kann ich Dir gerne Doku nachliefern .. wenn ich eine "Hülle" bekomme ...
Titel: Antw:MQTT2_SERVER neustarten
Beitrag von: rudolfkoenig am 31 Oktober 2022, 11:28:02
ZitatSoll ich den Thread auf gelöst setzen?
Wenn aus deiner Sicht das Problem erledigt ist: gerne.
Aber bitte nicht schliessen, womoeglich will jemand noch was dazu sagen.