Beim Aufräumen/Optimieren meines “Home-Servers” habe ich auch die Domains für externe und interne Zugriffe angepasst. Letsencrypt-Wildcard-SSL-Zertifikate können da ganz praktisch sein. Zum einen muss man nicht jedes mal ein neues Zertifikat ausstellen, wenn man eine neue Sub-Domain braucht, zum anderen kann man auch Zertifikate für Server erstellen, die vielleicht nur im lokalen LAN genutzt werden.

Zum Aktualisieren der Letsencrypt-Zertifikate nutze ich das Tool “dehydrated”. Die Authentifizierung des Servers erfolgt mit dehydrated standardmäßig via http-01. D.h. Letsencrypt fragt http://<domain>/.well-known/acme-challenge/<token> ab. Bei Wildcard-Domains kann man allerdings keine http-01-Challenge mehr nutzen, sondern muss dns-01 verwenden. Damit authentifiziert man nicht den Webserver gegenüber Letsencrypt, sondern weist sich als Besitzer der root-Domain aus.

Das funktioniert kurz gesagt so, dass Letsencrypt ein Token erzeugt. Nun muss man einen TXT-Record mit diesem Token für die Domain beim zuständigen Nameserver anlegen, um Letsencrypt damit quasi zu beweisen, dass man Eigentümer der Domain ist. Es ist möglich, das händisch über die DNS-Config-Oberfläche bei IONOS zu machen, aber es geht auch eleganter. IONOS stellt eine API zum Modifizieren der DNS-Einträge zu Verfügung und man muss dehydrated nur beibringen, diese zu nutzen.

Für certbot gibt es da schon fertige Lösungen, wie z.B. hier. Aber ich mag dehydrated und wollte es mal damit versuche. Folgendes ist dafür zu tun:

Zunächst mal muss man bei IONOS den Zugriff auf die DNS-API erlauben. Im IONOS-Control Panel bei den Domain/DNS-Einstellungen findet sich ein Punkt “API-Portal öffnen”. Dort kann man dann die API-Zugriffsschlüssel verwalten und einen neuen anlegen. Man bekommt dann einen Prefix wie z.B. c68c84d8d51440419d584098b4dba05c und einen zugehörigen Verschlüsselungs-Key, wie z.B. Pzc-c4Tu7N_dm5CUs2k9BjpSqz-rGLiYKT41jaiXlaEhp-xSsLW3syU3ha-Tg8xe7B-vrJjouej79GVvB036xg. Diese unbedingt kopieren, der Verschlüsselungs-Key kann später nicht mehr abgefragt werden!

In der dehydrated-Config (in Debian unter /etc/dehydrated zu finden) sind zwei Einträge wichtig:

CHALLENGETYPE="dns-01"
HOOK=/etc/dehydrated/hook.py

Damit wird die dns-01 Challenge aktiviert und als Hook-Script ein Python-Script eingestellt. Dazu kommen wir gleich noch.

Außerdem ist es ggf. noch sinnvoll, zum Testen zunächst die Testumgebung von Letsencrypt zu nutzen. Dazu trägt man in die Config folgendes ein:

CA="https://acme-staging-v02.api.letsencrypt.org/directory"

Diesen Eintrag kann man dann wieder löschen/auskommentieren, wenn alles funktioniert.

In der domain.txt wird nun noch die Wildcard-Domain konfiguriert. Um ein Zertifikat für die root- und all sub-Domains zu erstellen:

zu-hause.domain.de *.zu-hause.domain.de

Jetzt fehlt noch das Python-Script, das als /etc/dehydrated/hook.py angelegt wird: hook.py hook.py@gist

Im Python-Script muss der API-Key eingetragen werden. Dieser setzt sich zusammen aus dem Präfix einem Dezimalpunkt-Zeichen und dem Verschlüsselungs-Key:

API_KEY = 'c68c84d8d51440419d584098b4dba05c.Pzc-c4Tu7N_dm5CUs2k9BjpSqz-rGLiYKT41jaiXlaEhp-xSsLW3syU3ha-Tg8xe7B-vrJjouej79GVvB036xg'

WICHTIG: Das Skript sollte nur für root lesbar und ausführbar sein! Dort steht der API-Zugang zum DNS-Server drin. In den falschen Händen kann man damit schlimme Dinge anstellen. Daher ist auf meinem Server das root-Filesystem auch immer komplett verschlüsselt. Wird der Server gestohlen oder man hat den Verdacht, jemand hat sich dort root-Zugriff verschafft, sollte man den API-Key bei IONOS sofort löschen! Das Debug-Logging im Python-Script sollte auch nur zum Testen aktiviert werden, da der API-Schlüssel damit nach STDOUT geloggt wird!

sudo chown root:root /etc/dehydrated/hook.py
sudo chmod ag=,u=rwx /etc/dehydrated/hook.py

Jetzt kann man das ganze testen:

sudo dehydrated -c

Will man das mehrfach testen, kann man erzwingen, dass die dns-01-Challenge erneut durchgeführt wird:

dehydrated --force-validation -c -x