Sicherer Zugriff auf FHEM per Client-Zertifikat

Sie befinden sich hier:
Smart Home Lösungen
»
Sicherer Zugriff auf FHEM per Client-Zertifikat

Smart Home komfortabel und sicher steuern

Um den Zugriff auf Ihr Smart Home von überall aus zu ermöglichen (z.B. über ein Smartphone), ist der Zugriff per Client-Zertifikat eine sichere Sache. Ein lästiges Eingeben von Benutzername / Passwort entfällt ebenso.

Welche Schritte hierzu notwendig sind, möchte ich kurz beschreiben. Dabei gehe ich von einer FHEM-Installation auf einem Raspberry PI aus.

DynDNS-Eintrag einrichten

Üblicherweise haben Sie als privater Internetnutzer keine feste IP-Adresse, sondern Sie erhalten täglich - nach der nächtlichen Zwangstrennung - eine neue IP. Damit Sie trotzdem Ihre heimische Installation permanent ansprechen können, ist ein dynamischer DNS Eintrag notwendig (DynDNS). D.h. wenn sich Ihre IP-Adresse ändert, folgt der DynDNS-Eintrag automatisch.

Es gibt viele DynDNS-Anbieter, die diesen Service auch kostenlos anbieten. Ich bin aktuell bei selfhost.de, einem deutschen Anbieter. Hier werden Sie nur einmal monatlich zur Bestätigung Ihrer Adressdaten aufgefordert. Mehr Aufwand ist nicht nötig. Der Dienst läuft stabil.

Nachdem Sie sich einen DynDNS-Eintrag besorgt haben, richten Sie ihn auf Ihrem Router ein. Wie dies genau funktioniert, ist natürlich Router abhängig. Bei der Fritzbox geht es über Internet » Freigaben » DynDNS. Hinterlegen Sie hier die geforderten Informationen.

Funktionstest:
Nehmen wir an, Ihr DynDNS-Eintrag lautet myHome.DynDnsAnbieter.de. Öffnen Sie an Ihrem PC ein Command-Fenster und geben ein:


ping myHome.DynDnsAnbieter.de

→ Die zurückgelieferte IP-Adresse muss mit der IP-Adresse, die in Ihrem Router steht, übereinstimmen.


Apache auf dem Raspberry PI installieren

Die Client-Authentifizierung erfolgt über einen Apache-Webserver, der als Reverse Proxy der eigentlichen FHEM-Installation, die auf Port 8085 läuft (Smartphone-Variante), vorgeschaltet ist. D.h. wenn Sie Ihre FHEM-Oberfläche im lokalen Netzwerk aufrufen, gehen Sie weiterhin über http://192.168....:8085. Nur wenn Sie von „Außen" auf Ihre FHEM-Oberfläche zugreifen wollen, gehen Sie über den Apache.

Zur Installation benötigen Sie neben dem Apache auch noch das Proxy Modul und SSL-Unterstützung. Schließlich soll der Apache über den SSL-Port (443) angesprochen werden.

Hier die notwendigen Schritte kurz zusammengefasst:


sudo apt-get install apache2
sudo a2enmod proxy proxy_http ssl

-- den zukünftigen Servernamen in der Konfiguration hinterlegen:
sudo vi /etc/apache2/apache2.conf
-- hinzufügen
Servername myHome.DynDnsAnbieter.de

-- so wenig wie möglich Informationen über den Webserver nach Außen geben, deshalb folgende Anpassung:
sudo vi /etc/apache2/conf-available/security.conf
-- ändern auf
ServerTokens Prod
ServerSignature Off

-- Port 80 kann deaktiviert werden, da die Kommunikation über den SSL Port (443) erfolgt:
sudo vi /etc/apache2/ports.conf
-- die folgende Zeile auskommentieren
Listen 80

-- Check der Installation und Restart des Apache
sudo apachectl configtest
apachectl -t -D DUMP_MODULES
sudo service apache2 restart


Port forwarding auf Router einrichten

Als nächster Schritt kann ein Port forwarding auf Ihrem Router eingerichtet werden. Nehmen wir an, Ihr Raspberry PI, auf dem der Apache läuft, hat die IP-Adresse 192.168.0.10, so richten Sie eine Weiterleitung auf Ihrem Router ein, damit alle Anfragen, die von Außen auf Port 443 kommen, an die IP 192.168.0.10 Port 443 weitergeleitet werden.

Wie dies genau funktioniert, ist natürlich wieder Router abhängig. Bei der Fritzbox finden Sie den Menüpunkt unter Internet » Freigaben » Portfreigaben.

Funktionstest:
Rufen Sie in Ihrem Webbrowser Ihren DynDNS-Eintrag wie folgt auf: https://myFHEM.DynDnsAnbieter.de → Sie erhalten zwar eine Fehlermeldung, da noch kein Zertifikat vorhanden ist, prinzipiell sollte es aber funktionieren.


Zertifikate erstellen

Üblicherweise werden die Zertifikate von einer offiziellen Zertifizierungsstelle wie Thawte oder Symantec ausgestellt und signiert. Dies kostet meist über 100 Euro / Jahr, was mir für diesen Zweck eindeutig zu viel ist. Selbstsignierte Zertifikate sind die kostenlose Alternative. Aus Security-Sicht gibt es keine Unterschiede. Die Verbindung ist genauso sicher.

Erstellen Sie sich hierzu Ihre eigene Zertifizierungsstelle (CA), mit der Sie die eigenen Zertifikate signieren können.

In Summe sind folgende Schritte notwendig:

  • eigene Zertifizierungsstelle erstellen (CA)
  • Server-Zertifikat erstellen
  • Server-Zertifikat mit der eigenen CA signieren
  • Client-Zertifikat erstellen
  • Client-Zertifikat mit der eigenen CA signieren
  • Client-Zertifikat mit privatem Schlüssel exportieren, um es danach im Browser zu importieren

Ich habe mich bei der Erstellung der CA und des Server-Zertifikates an folgende Anleitung gehalten: https://thomas-leister.de/selbst-signierte-tls-zertifikate-mit-eigener-ca/. Die Anleitung ist sehr ausführlich und hat bei mir funktioniert. Insofern ist es nicht unbedingt sinnvoll, diese Schritte hier nochmal zu wiederholen.

Das Client-Zertifikat habe ich mit folgenden Befehlen erzeugt:


-- Key für Client-Zertifikat
openssl genrsa -out client.key -aes256 4096 -days 3650

-- Client-Zertifikat Request erstellen
openssl req -config myopenssl.cnf -sha512 -new -key client.key -out client.req

-- Client-Zertifikat mit eigener CA signieren
openssl ca -in client.req -out client.crt -config myopenssl.cnf

-- export als PKCS#12
openssl pkcs12 -export -inkey client.key -in client.crt -out client.pfx

Anmerkung:
myopenssl.cnf ist eine Kopie der Standard-Konfiguration (openssl.cnf) und enthält meine persönlichen Einstellungen. Das erspart einerseits Tipparbeit und andererseits sind die persönlichen Einstellungen später wieder nachvollziehbar und auch gleich protokolliert.


Zertifikate im Apache hinterlegen

Die soeben erstellten Zertifikate (CA und Server) müssen nun noch im Apache eingebunden werden. Hierzu sind folgende Anpassungen in der default-ssl.conf notwendig, wobei Sie Zertifikatsnamen und Pfade natürlich an Ihre Gegebenheiten anpassen müssen:


sudo vi /etc/apache2/sites-available/default-ssl.conf

-- anpassen
SSLCertificateFile /etc/ssl/certs/server.crt
SSLCertificateKeyFile /etc/ssl/certs/server.key
SSLCertificateChainFile /etc/ssl/certs/ca.crt

SSLCACertificateFile /etc/ssl/certs/ca.crt


Aktivierung der Client-Zertifikat-Authentifizierung und Konfiguration des Reverse Proxy

Anschließend muss die Authentifizierung per Client-Zertifikat noch aktiviert und die Proxy-Umleitung konfiguriert werden. Hierzu sind die folgenden Anpassungen in der proxy.conf notwendig:


sudo vi /etc/apache2/mods-available/proxy.conf

<Proxy *>
	Order deny,allow
	Allow from all
	SSLRequireSSL
	SSLVerifyClient require
	SSLVerifyDepth 3
	SSLRequire ( %{SSL_CLIENT_S_DN_O} eq "myOrg" and %{SSL_CLIENT_S_DN_OU} in {"myOUnit"} )
</Proxy>

--- am Ende ergänzen
SSLProxyEngine On
ProxyRequests Off
ProxyPass / http://127.0.0.1:8085/
ProxyPassReverse / http://127.0.0.1:8085/

Wie Sie vielleicht bemerken, habe ich als zusätzliches Feature eine Abfrage von Zertifikatseigenschaften eingebaut. So muss in der Eigenschaft „Organisation“ der Eintrag „myOrg“ und in der „OrganisationUnit“ der Eintrag „myOUnit“ enthalten sein, damit das Zertifikat als valide akzeptiert wird.

Wozu dieses zusätzliche Feature?
Über das Client-Zertifikat kann jeder Anwender, der Zugriff auf Ihr Smartphone hat, Ihr Smart Home aufrufen. D.h. wenn Ihr Smartphone gestohlen würde, so haben Sie auf diese Art die Möglichkeit, das Client-Zertifikat zu sperren. Stellen Sie einfach ein neues Zertifikat mit anderen Eigenschaften aus und lassen nur noch Zertifikate mit diesen neuen Eigenschaften zu. Damit haben Sie quasi das alte Zertifikat ausgesperrt.

Normalerweise müsste es ausreichend sein, wenn Sie das Zertifikat einfach per „revoke“ für ungültig erklären. Aus welchen Gründen auch immer hat dies bei mir nicht funktioniert. Somit habe ich diese zweitbeste Lösung gewählt. Für konstruktive Lösungsvorschläge bin ich diesbezüglich offen.

Mit dem Aktivieren der ssl-Website, dem Deaktivieren der Standard-Website, diversen Tests und einem Restart des Apache schließen Sie die Installation ab.


sudo a2ensite default-ssl
sudo a2dissite 000-default

sudo apachectl configtest
apachectl -t -D DUMP_MODULES
sudo service apache2 restart


Client-Zertifikat ausrollen

Installieren Sie Ihre Zertifikate in Ihrem Browser. Laden Sie hierzu das CA-Zertifikat in den Ordner der vertrauenswürdigen Stammzertifizierungsstellen und Ihr Client-Zertifikat (das .pfx-File) in den Ordner der eigenen Zertifikate. Führen Sie einen Funktionstest durch, indem Sie die URL https://myHome.DynDnsAnbieter.de aufrufen.
→ Sie werden zur Bestätigung des Client-Zertifikates aufgefordert und die Authentifizierung sollte funktionieren. Es sollten keine Warnungen, Fehlermeldungen etc. erscheinen und der Browser sollte die Website als „sicher“ einstufen.

Wenn dies geglückt ist, können Sie zum finalen Schritt übergehen und das CA-Zertifikat mit dem .pfx-File auf Ihr Smartphone kopieren (in meinem Fall ein Android Gerät). Installieren Sie danach das CA-Zertifikat unter „Zertifikate verwalten“ auf Ihrem Smartphone und rufen Sie anschließend die URL https://myHome.DynDnsAnbieter.de auf Ihrem Smartphone auf. Die Webseite verlangt nach einem Client-Zertifikat und bietet die Optionen „Installieren“ und "Zulassen" an. Wählen Sie einfach "Zulassen". Danach sollte alles ohne Warnungen o.ä. funktionieren.


Was tun, bei "Post-Handshake Authentication“ Fehler nach Upgrade auf Debian Bullseye?

Nachdem ich meine Umgebung auf eine zu diesem Zeitpunkt aktuelle Debian Version (Bullseye) migriert hatte, funktionierte die Client-Zertifikat-Authentifizierung leider nicht mehr, sondern es kam im Browser die Fehlermeldung
"You don't have permission to access this resource. Reason: Cannot perform Post-Handshake Authentication".

Durch die Aktualisierung meines Systems erfolgt standardmäßig die SSL-Kommunikation über das moderne TLSv1.3 Protokoll und nicht mehr über TLSv1.2. Leider zieht dies den besagten Fehler nach sich.

Die Lösung kann browserspezifisch erfolgen z.B. im Firefox security.tls.enable_post_handshake_auth = true setzen (about:config). Ich habe mich aber letztendlich für eine serverseitige Lösung entschieden, d.h. am Webserver das TLSv1.3 Protokoll ausgeschlossen, wodurch die Kommunikation automatisch wieder über das TLSv1.2 Protokoll erfolgt.

Dies geht wie folgt:


sudo vi /etc/apache2/mods-available/ssl.conf

#SSLProtocol all -SSLv3
SSLProtocol all -SSLv3 -TLSv1.3
						

Sicherlich kann man darüber diskutieren, ob es aus Security-Sicht die ideale Lösung ist, das modernste Protokoll auszuschließen. Ich denke, für meine Zwecke ist TLSv1.2 ausreichend. Da ein Großteil der SSL-Webseiten aktuell über dieses Protokoll kommuniziert, kann es (noch) nicht so falsch sein.


Fazit

Sicherlich sind einige Schritte notwendig, um eine Client-Authentifizierung per Zertifikat zu ermöglichen. Das mag auf dem ersten Blick auch etwas komplex wirken. Letztendlich ist es aber gar nicht so kompliziert, wenn man die Schritte step-by-step abarbeitet. Das Ergebnis ist ein komfortabler Zugang auf sein Smart Home von überall, ohne lästiges Eingeben von Benutzername / Passwort und mit einer erhöhten Sicherheit durch das Zertifikat.

Kontakt

Senden Sie mir Ihre Fragen oder Anregungen über die Kontaktbox oder direkt per Email. Sie können mich natürlich auch über die gängigen sozialen Netze erreichen.

kontakt@kaempf-nk.de

Fragen / Anregungen?

Sicherheitsabfrage:
Datenschutzhinweis: Die eingegebenen Daten werden nicht an Dritte weitergegeben.