Inhalt
- 1 Zertifikate von Let’s Encrypt
- 2 Überprüfungs-Prozeduren (Challenges)
- 3 Let’s Encrypt certbot installieren
- 4 Das Zertifikat manuell beantragen
- 5 Die Heimnetz-Domain
- 6 Den DNS TXT-Record erzeugen
- 7 Weiter mit certbot
- 8 Das Zertifikat in omv nutzen
- 9 Automatisierung der DNS-Challenge
- 10 Automatische Zertifikats-Erneuerung
- 11 Fazit
- 12 Nachtrag: crontab und system trigger
- 13 Nachtrag 2: Umzug des certbot
Mit einigen Vorkehrungen lassen sich Let’s-Encrypt-Zertifikate auch für interne Netze nutzen, die nicht vom Internet erreichbar sind.
Zertifikate von Let’s Encrypt
Let’s Encrypt [1] bietet schon seit einigen Jahren kostenlose SSL-Zertifikate für einzelne Domains an. Seit kurzem werden auch Wildcard-Zertifikate ausgestellt, die für alle Subdomains einer Domain gültig sind. Wird ein solches Zertifikat zum Beispiel für *.home.kunz.de ausgestellt, gilt es auch für alle Subdomains, also zum Beispiel auch für hinz.home.kunz.de.
Damit lässt sich relativ einfach ein Zertifikat generieren, dass für alle Server im Heim-Netz gültig ist und nicht - wie ein selbstsigniertes Zertifikat - von Web-Browsern als unsicher markiert wird. Die Let’s-Encrypt-Zertifikate sind allerdings nur jeweils 60 Tage gültig. Deswegen macht es Sinn, die Erneuerung des Home-Zertifikats automatisch ablaufen zu lassen.
Überprüfungs-Prozeduren (Challenges)
Während der Beantragung oder Erneuerung der Zertifikate muss der Let’s Encrypt Server überprüfen, dass die Domain dem Beantrager gehört oder von ihm administriert wird. Dafür gibt es mehrere Möglichkeiten, unter anderem die webroot- und die DNS-Prozedur.
Die webroot Prozedur erwartet eine Seite mit vorgegebenem Inhalt im Wurzel-Verzeichnis des Webservers. Das lässt sich zwar sehr leicht automatisieren, aber zur Überprüfung muss der Server vom Internet aus erreichbarr sein, was im Heimnetz Portweiterleitungen auf dem Internet-Router erforderlich macht.
Bei der DNS-Prozedur muss beim DNS-Server der Zone ein TXT-Record mit vorgegebenem Namen und Inhalt eingestellt werden. Dieser Eintrag wird bei der Beantragung vom Let’s Encrypt Server abgerufen. Dafür muss die Domain selbst nicht erreichbar sein, was die Nutzung für Domains in privaten Netzen sehr vereinfacht. Für Wildcard-Zertifikate ist die DNS-Challenge die einzig mögliche Überprüfungs-Prozedur.
Let’s Encrypt certbot installieren
Zunächst muss auf einem Server im Heimnetz das Let’s Encrypt certbot Paket installiert werden. Bei mir ist dieser Server ein ständig laufender RaspberryPI mit dem Debian-Stretch-basierten NAS-System openmediavault 4 (omv).
Bei Debian Stretch befindet sich das certbot-Paket im stretch-backports-Repository, das bei omv 4 bereits in den Paketquellen eingetragen ist.
$ sudo apt-get install certbot -t stretch-backports
Das Zertifikat manuell beantragen
Jetzt können wir certbot benutzen, um das Zertifikat zu beantragen. Der certonly Schalter bewirkt, dass das Zertifikat nur abgerufen, aber nicht installiert wird. Wildcard-Zertifikate werden nur vom acme-v02 Server ausgestellt, der mit dem server Schalter angegeben werden muss. Unter -d wird die Wildcard-Domain angegeben, für die das Zertifikat ausgestellt werden soll.
Da die einzige unterstützte Prüfungsart die DNS-Challenge ist, muss sie mit preferred-challenges dns ausgewählt werden. Der manual Schalter gibt an, dass der TXT-Record manuell eingetragen wird. Zur Automatisierung später mehr.
# certbot certonly --server https://acme-v02.api.letsencrypt.org/directory -d *.home.kunz.de --email webmaster@kunz.de --preferred-challenges dns --manual Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator manual, Installer None Obtaining a new certificate Performing the following challenges: dns-01 challenge for home.kunz.de ------------------------------------------------------------------------------- NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you're running certbot in manual mode on a machine that is not your server, please ensure you're okay with that. Are you OK with your IP being logged? ------------------------------------------------------------------------------- (Y)es/(N)o: y ------------------------------------------------------------------------------- Please deploy a DNS TXT record under the name _acme-challenge.home.kunz.de with the following value: dhfjknfhuioOHoihHohoioioih568_nvihUGüj87ui87 Before continuing, verify the record is deployed. ------------------------------------------------------------------------------- Press Enter to Continue
Nachdem man sein Einverständnis mit der Aufzeichnung seiner IP-Adresse erklärt hat, druckt der certbot Namen und Inhalt des TXT-Records aus, der nun beim zuständigen DNS-Zonenverwalter - bei mir FreeDNS - eingetragen werden muss. Dazu öffnen wir ein zweites Terminal.
Die Heimnetz-Domain
Als Heimnetz-Domain wird eine Subdomain einer offiziellen Domain benutzt. Sie wird als Subdomain beim gleichen Provider eingetragen, der auch für die Basis-Domain verantwortlich ist.
Wenn man vorhat, auch vom Internet aus auf Server in der Heim-Domain zuzugreifen, muss man auf die Dienste eines dynDNS-Providers zurückgreifen. Einzelheiten beschreibt der Artikel DynDNS für eine eigene Domain einrichten.
Im folgenden arbeiten wir mit dem DynDNS-Provider FreeDNS, auf den die Namensauflösung bei meinem Domain-Provider delegiert wurde.
Den DNS TXT-Record erzeugen
Nach Anmeldung bei FreeDNS wählen wir aus dem Menü links den Eintrag Dynamic DNS aus und klicken im Titel der Tabelle der DNS-Records auf Add. Als Typ wählen wir TXT aus. Die Domain bleibt bei home.kunz.de. Unter Subdomain wird der geforderte Challenge-Name und unter Destination der Text in doppelten Anführungszeichen eingetragen.
Nach dem Klicken auf Save checken wir per nslookup, ob der TXT-Record schon verfügbar ist, Das kann je nach TTL einige Zeit dauern. Bei FreeDNS steht die TTL fest auf 60 Sekunden, so dass spätestens nach etwa ein bis zwei Minuten der TXT-Record abrufbar sein sollte.
$ nslookup > set type=TXT > _acme-challenge.home.kunz.de Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: _acme-challenge.home.kunz.de text = "dhfjknfhuioOHoihHohoioioih568_nvihUGüj87ui87"
Weiter mit certbot
Jetzt kann im ersten Terminal der certbot mit Return fortgesetzt werden:
Waiting for verification... Cleaning up challenges IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/home.kunz.de/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/home.kunz.de/privkey.pem Your cert will expire on 2018-09-30. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le #
Geht alles gut, liegen am Ende Schlüsseldatei und Zertifikat unter /etc/letsencrypt/live/home.kunz.de und können direkt verwendet werden.
Das Zertifikat in omv nutzen
Um das Zertifikat für openmediavault verfügbar zu machen, wählt man im omv-Menü Zertifikate aus, klickt auf den SSL Tab und wählt unter Hinzufügen den Eintrag Importieren aus. Unter Privater Schlüssel wird der Inhalt von privkey.pem und unter Zertifikat der Inhalt von fullchain.pem eingetragen. In’s Kommentarfeld gehört eine möglichst eindeutiger Text, um das Zertifikat später identifizieren zu können.
Zuletzt wählt man unter Allgemeine Einstellungen bei Sichere Verbindung das neue Zertifikat aus und sichert die Einstellungen.
Ab jetzt sollte der Browser die omv-Seite als Sicher markieren, wenn sie mit dem vollständigen Namen, also zum Beispiel mit omv.home.kunz.de, aufgerufen wird.
Dieses Zertifikat können alle Server mit einer Subdomain unter home.kunz.de benutzen; sie werden dann ebenfalls als Sicher eingestuft.
Automatisierung der DNS-Challenge
Das Überprüfungsverfahren der DNS-Challenge kann mit einem Script automatisiert werden. Der manual-auth-hook [2.1] wird aufgerufen, bevor die Überprüfung der Challenge stattfindet. In diesem Script muss der geforderte TXT-Record beim DNS-Provider erzeugt werden.
Für einige, vorwiegend amerikanische DNS-Provider existieren vordefinierte auth-Scripts [2.2]. Für alle anderen muss man das Script selbst erzeugen. Die nötigen Werte wie Name und Inhalt des TXT-Records werden vom certbot als Umgebungsvariablen übergeben [2.1]. Uns interessiert im Moment lediglich die Variable CERTBOT_VALIDATION, in der der erforderliche Inhalt des TXT-Records übergeben wird.
Bei FreeDNS [3] kann der Inhalt eines bestehenden TXT-Records mit folgendem CURL-Kommando geändert werden:
curl -b "dns_cookie=XXXXXXXXXX" -d "type=TXT" -d "subdomain=_acme-challenge" -d "domain_id=0000" -d "data_id=0000" -d "address=%22some_text%22" https://freedns.afraid.org/subdomain/save.php?step=2
Die Variablen data_id, domain_id und dns_cookie müssen aus der FreeDNS Web-Seite abgelesen werden:
- Die data_id findet man unter dem Menueintrag Subdomains im Link zum editieren des TXT-Records.
- Die domain_id steckt auf der gleichen Seite im add Link hinter der Basis-Domain.
- Den Inhalt des DNS-Cookies kann man aus dem dns_cookie für freedns.afraid.org ablesen
(Bei Chrome: chrome://settings/cookies/detail?site=freedns.afraid.org).
Hat man alle Angaben zusammen, kann man die Funktion zunächst auf der Kommandozeile prüfen. Im Erfolgsfalle erzeugt curl dabei keine Ausgabe, sondern kehrt Kommentarlos zum Prompt zurück. Mit nslookup können wir nach ein bis zwei Minuten prüfen, ob der TXT-Record auch propagiert wird:
# nslookup -type=TXT _acme-challenge.home.kunz.de Server: 192.168.2.1 Address: 192.168.2.1#53 Non-authoritative answer: _acme-challenge.home.kunz.de text = "some_text"
Das curl Komando stecken wir nun in das Script freedns-txt.sh, dass der certbot dann als manual-auth-hook benutzen kann:
#!/bin/bash # dns_cookie="xxxxxxxxxxxx" domain_id="0000" data_id="0000" ttl=60 # curl -S -b "dns_cookie=$dns_cookie" -d "type=TXT" -d "subdomain=_acme-challenge" -d "domain_id=$domain_id" -d "data_id=$data_id" -d "address=%22$CERTBOT_VALIDATION%22" https://freedns.afraid.org/subdomain/save.php?step=2 sleep $ttl
Der Schalter -S (oder --silent) bewirkt, dass curl keine Fortschrittsanzeige, wohl aber Fehlernachrichten ausgibt. Am Ende wartet das Script, bis die TTL des (alten) DNS-Eintrags abgelaufen ist, was bei FreeDNS nach 60 Sekunden geschieht.
Automatische Zertifikats-Erneuerung
Das renew-Kommando des certbot wird für einen Test mit dem Pfad zu obigem Script ergänzt und mit --dry-run getestet:
# certbot renew --manual-auth-hook=/root/freedns-txt.sh --dry-run Saving debug log to /var/log/letsencrypt/letsencrypt.log ------------------------------------------------------------------------------- Processing /etc/letsencrypt/renewal/home.kunz.de.conf ------------------------------------------------------------------------------- Cert not due for renewal, but simulating renewal for dry run Plugins selected: Authenticator manual, Installer None Renewing an existing certificate Performing the following challenges: dns-01 challenge for home.kunz.de Waiting for verification... Cleaning up challenges ------------------------------------------------------------------------------- new certificate deployed without reload, fullchain is /etc/letsencrypt/live/home.kunz.de/fullchain.pem ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/home.kunz.de/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) -------------------------------------------------------------------------------
Wenn alles wie hier funktioniert, kann dieses Kommando nun in die geplanten Aufgaben des omv eingetragen werden, damit täglich überprüft wird, ob das Zertifikat erneuert werden muss.
Die Verteilung und Installation des Zertifikats kann man ebenfalls automatisieren. Mit dem deploy-hook kann man ein Shell-Script angeben, dass nach einer erfolgreichen Zertifikatserneuerung aufgerufen wird. Da mein privater Server-Park aber noch überschaubar ist, verzichte ich im Moment darauf.
Fazit
Mit einem Let’s Encrypt Zertifikat lassen sich mit wenig Aufwand auch Server absichern, die nicht vom Internet erreichbar sind. Die Zertifikats-Erneuerung lässt sich automatisieren. Damit sollten auch im Heimnetz die Zeiten unverschlüsselter Übertragungen vorbei sein.
Nachtrag: crontab und system trigger
Das Debian-Paket certbot enthält schon sowohl einen crontab-Job als auch einen System Trigger, die zwei mal täglich versuchen, das Zertifikat zu erneuern. In meinem Falle läuft das schief, weil certbot lediglich mit
certbot renew -q
aufgerufen wird. Wegen des fehlenden manual-auth-hook scheitert dieser Versuch immer mit einer Fehlermeldung in /var/log/letsencrypt/letsencrypt.log.
Man kann jetzt entwder den Aufruf von certbot im Service certbot und im crontab ändern, oder beide stillegen und weiterhin den crontab-Eintrag im omv benutzen.
Ich habe mich für letzteres entschieden, weil dann alle cron-Jobs an einer Stelle übersichtlich über die omv Web-Oberfläche zu verwalten sind.
Um den crontab-Eintrag zu entfernen, löscht man einfach die Datei /etc/cron.d/certbot. Service und Trigger werden mit folgenden Kommandos entfernt:
systemctl stop certbot systemctl stop certbot.timer systemctl disable certbot systemctl disable certbot.timer systemctl daemon-reload
Jetzt sollte letsencrypt.log sauber bleiben.
Nachtrag 2: Umzug des certbot
[26.11.2018] Vor kurzem war der Umzug des certbot auf einen anderen Server nötig. Dazu wird auf dem neuen Server zunächst das certbot Paket installiert:
apt-get install certbot
Das manual-auth-hook Script wird vom alten Server an die gleiche Stelle (bei mir: /root/freedns-txt.sh) auf dem neuen Server kopiert. Zusätzlich kopiert man die alten Zertifikatsdaten aus /etc/letsencrypt des alten Servers, am einfachsten per tar-Archiv:
cd /etc/letsencrypt tar cfv trans.tar accounts archive csr keys live renewal
Das Archiv trans.tar wird in /etc/letsencrypt des neuen Servers kopiert und entpackt:
cd /etc/letsencrypt tar xvf trans.tar
Falls nicht ohnehin vorhanden, muss noch das beim manual-auth-hook benutzte curl Paket nachinstalliert werden:
apt-get install curl
Jetzt kann man die Automatische Zertifikats-Erneuerung wie oben beschrieben testen und als cron-Job eintragen.
Quellen und Links:
- Let’s Encrypt Homepage: letsencrypt.org
- Certbot Dokumentation: certbot.eff.org/docs/using.html
- FreeDNS Homapage: freedns.afraid.org





