Home Assistant ist ein leistungsfähiges System zur Heiimautomatisierung. Eine nicht über die Oberfläche konfigurierbare Integration namens ShellCommand soll es erlauben, Skripte direkt im OS des Systems auszuführen. Doch der Teufel steckt im Detail, wie ich schmerzlich erfahren musste. Mein Problem brachte mich schier zur Verzweiflung. Alle Suche im Internet ergab keine direkte Lösung aber ein Menge Hinweise, denen ich nachgehen konnte. Letztendlich habe ich einen Weg gefunden, mein Problem zu lösen. Doch alles der Reihe nach, das zu lösende Problem war nicht alltäglich.
Das Grundproblem war die Aktivierung von SSL für Home Assistant. Nichts leichter als das, es gibt doch die Let's-Encrypt-Erweiterung... Im Prinzip schon aber die half mir hier an dieser Stelle nicht weiter und das lag an der zugrunde liegenden Architektur, die in etwas so aussieht:
Der Router stellt zwei Eintrittspunkte zur Verfügung:
- Der Hauptserver erhält eine feste IP-Adresse vom Provider und hostet die Website. Er hat ein Lets Encrpyt-Zertifikat.
- Die Server VM ist unter einer dynamischen Adresse erreichbar. Die Adresse wird durch die Einwahl des Routers ins Internet bestimmt. Ein DynDNS-Dienst sorgt für die Erreichbarkeit unter einer festen URL. Diese virtuelle Instanz eines Servers besitzt ein Lets Encrypt Zertifikat.
- Home Assistant selbst soll SSL unterstützen. Es ist unter der selben festen DynDNS-Adresse erreichbar wie die Server VM, allerdings auf einem anderen Port. Es braucht also das gleiche Zertifikat wie die Server VM.
Die Server VM erneuert das Zertifikat selbstständig. Das Lets Encrypt-AddOn für Home Assistant kennt zwei Möglichkeiten, ein Zertifkat zu erhalten. Die Authentifizierung dazu kann über DNS oder HTTP erfolgen. Beide Möglichkeiten scheiden allerdings in meinem Fall aus, da der gewählte DynDNS-Dienst meines Providers derartige Möglichkeiten zur Authentifizierung nicht zur Verfügung stellt und HTTP/HTTPS von der Server VM zur Bereitstellung seiner Dienste benötigt.
Die Lösung schien also, das von der Server VM generierte Zertifikat auch für Home Assistant zu nutzen. Es muss lediglich dorthin übertragen werden. Kann ja mit Hilfe von SCP (Secure Copy Protocol) gemacht werden, denn SSH wird von Home Assistant ja unterstützt.
Home Assistant erwartet die Dateien 'fullchain.pem' und 'privkey.pem' im Verzeichnis /ssl. Das kopieren der beiden Dateien von der Server VM nach /ssl funktionierten im Terminal von Home Assistant wunderbar. Also packte ich die benötigten Anweisungen in ein Shell-Script und benutzte die ShellCommand-Integration in Home Assistant um dieses aufrufen zu können. Ein Test lies jedoch Ernüchterung aufkommen. Es gab keine Fehlermeldung in Home Assistant und im Log war lediglich vermerkt, dass die Automations-Aktion aufgerufen wurde. Allerdings waren keine Dateien im /ssl-Verzeichnis angekommen. Was ich auch versuchte mit angepassten Schreibweisen, es wollte nicht gelingen.
Die Suche im Internet brachte mich langsam auf die Spur des Phänomens: Ein Skipt wird in Home Assistant OS in einem Docker-Container ausgeführt - nämlich dem Docker-Container homeassistant:<Versionsnummer>.
Also müssen die Tests, ob das Script von diesem Container aus erreichbar ist und die Funktionsweise insgesamt innerhalb des Containers verifiziert werden. Um das zu erreichen ist die Eingabe innerhalb des Terminals von Home Assistant zu tätigen um den besagten Container ausfindig zu m achen:
docker ps
Aus der angezeigten Liste sind die ersten 3-4 Zeichen des betreffenden Containers gefragt - es muss nur für docker eindeutig sein. Dann ist folgende Eingabe nötig:
docker exec -it
Wenn alles geklappt hat, seid ihr jetzt innerhalb des Containers von Home Assistant. Zuerst einmal sucht eine Stelle, an der Home Assistant das Skript findet. Ich habe mich dafür entschieden das Verzeichnis /config zu benutzen. Hier drin liegt die Haupt-Konfigurationsdatei von Home Assistant (configuration.yaml) und die kann der Container ja lesen. Ich habe ein Unterverzeichnis angelegt /config/scripts und darin das auszuführende Shellscript hinterlegt. Ein Test aus dem Container lies mich die Datei finden und lesen. Erste Hürde also erfolgreich genommen. Die Ernüchterung folgte jedoch auf dem Fuß: Das Verzeichnis /ssl ist zwar vom Container aus erreichbar allerdings ist es nur-lesbar obwohl eigentlich für den Benutzer root Schreibrechte existieren. Leider wird das ganz /ssl-Verzeichnis als read-only Dateisystem eingebunden und das hat nun einmal Vorrang...
Fündig bin ich im Verzeichns /media geworden. Hierin könne Mediendatein geladen werden. Das Verzeichnis ist auch aus dem Container heraus beschreibbar. Also habe ich mein Shellscript angepasst und als Ziel der Zertifikatsdateien nicht /ssl sondern /media angegeben. Ein Test verlief positiv. Also konnten die entsprechenden Dateien jetzt von der Server VM nach Home Assistant transferiert werden.
Ein beherztes
exit
lies mich den Container verlassen. Ich war also wieder im originalen Terminal-Fenster von Home Assistant. Hier prüfte ich nochmals, ob in /media die Zertifikatsdateien zu liegen gekommen sind. Das war der Fall. Da ich ja aus dem Container heraus die Dateien nicht nach /ssl verschieben konnte, weil es ja read-only war und ich im äußeren System keine Skripte starten konnte, legte ich einfach symbolische Links an:
ln -s /media/fullchain.pem /ssl/fullchain.pem ln -s /media/privkey.pem /ssl/privkey.pem
Die Hauptverdrahtung war jetzt auch erledigt. Nun musste nur noch die configuration.yaml angepasst werden. Hier sind mindestens 3 Zeilen erforderlich:
http: ssl_certificate: /ssl/fullchain.pem ssl_key: /ssl/privkey.pem
Ein Neustart von Home Assistant schließt die ganze Konfiguration ab. Von nun an war Home Assistant bei mir per SSL gesichert ohne dass sich der Browser über das Zertifikat beschwerte.
Da ja die Zertifikate von Lets Encrypt nach ca. 3 Monaten erneuert werden müssen, habe ich einfach eine Automation in Home Assistant eingestellt, die mir das aktuelle Zertifikat per ShellCommand-Integration von der ServerVM holt und einen Neustart von Home Assistant veranlasst. Das scheint erst einmal zu laufen. Ich werde jetzt sehen, ob eine Zertifikatserneuerung ordentlich verarbeitet wird und werde ggf. berichten.