In mindestens zwei Anwendungsfällen ist die geringe Laufzeit von Let’s Encrypt Zertifikaten lästig: Bei der Nutzung von HPKP (Public Key Pinning) und DANE. Beide Verfahren sollen HTTPS-Verbindungen zusätzlich absichern, indem genau spezifiziert wird, welche TLS-Zertifikate für eine Domain gültig sein sollen. Da mindestens alle 90 Tage ein anderes Let’s Encrypt -Zertifikat eingerichtet werden muss, müssen in diesem Zyklus auch die HPKP- und DANE-Einstellungen mehr oder weniger aufwendig aktualisiert werden.
Der Aufwand lässt sich jedoch mit einem Trick reduzieren: Da beide Verfahren auf der Untersuchung des Public Keys im öffentlichen Zertifikat beruhen, kann man dafür sorgen, dass sich dieser bei der Umstellung auf ein neues Zertifikat nichts ändert. Man verwendet daher bei der Beantragung eines neuen LE-Zertifikats also keinen neuen Private Key, sondern einen alten. (Der Public Key basiert auf dem Private Key). Um einen alten Key nutzen zu können, muss der Referenzclient von Let’s Encrypt im Zusammenspiel mit einem eigenen, gleich bleibenden Private Key und einer eigenen Zertifikatsanfrage (CSR) verwendet werden.
Zuerst wird ein neuer, privater Schlüssel erstellt:
openssl genrsa -out privkey.pem 4096
Für eine komfortablere Generierung der Zertifikatsanfrage wird eine Konfigurationsdatei „request.cnf“ mit diesem Inhalt erstellt:
[ req ] default_md = sha512 prompt = no encrypt_key = no distinguished_name = req_distinguished_name req_extensions = v3_req [ req_distinguished_name ] countryName = "DE" stateOrProvinceName = "Bayern" localityName = "Landshut" postalCode = "1234" streetAddress = "LE Strasse 42" organizationName = "trashserver.net" organizationalUnitName = "IT" commonName = "trashserver.net" emailAddress = "admin@domain.tld" [ v3_req ] subjectAltName = DNS:www.trashserver.net,DNS:xmpp.trashserver.net
Was unter „req_distinguished_name“ steht, hat für Let’s Encrypt Zertifikate keine Bedeutung, da diese Daten nicht in das Zertifikat aufgenommen werden. Ihr könnt hier Phantasienamen oder auch nichts eingeben ;) Wichtig ist hier nur der „commonName“: Das ist die Hauptdomain, für die das Zertifikat gelten soll. Alle weiteren Domains werden ganz unten nacheinander angegeben.
Nun wird mithilfe des Private Keys „privkey.pem“ und der Konfigurationsdatei eine Zertifikatsanfrage gestellt:
openssl req -config request.cnf -new -key privkey.pem -out request.csr -outform der
Im aktuellen Verzeichnis sollte sich nun eine Datei „request.csr“ befinden.
Ihr könnt die CSR jetzt verwenden, um bei Let’s Encrypt neue Zertifikate zu beantragen:
./letsencrypt-auto certonly -a manual --key-path privkey.pem --cert-path cert.pem --fullchain-path fullchain.pem --csr request.csr
Folgt dabei der üblichen Bestätigungsprozedur, die in diesem Artikel bereits erklärt wurde.
Danach findet ihr in eurem Verzeichnis ein paar neue Dateien:
- 0000_cert.pem: Euer neues Zertifikat
- 0000_fullchain.pem: Euer neues Zertifikat + Chain
Zertifikat erneuern
Sollte dieses neu generierte Zertifikat einmal ablaufen, braucht ihr dem Let’s Encrypt Client nur wieder die request.csr Datei übergeben und erhaltet ein neues Zertifikat. Falls ihr neue Domains in euer Zertifikat aufnehmen wollt, muss die request.cnf zuvor entsprechend erweitert und eine neue Zertifikatsanfrage „request.csr“ generiert werden.
Einsatz mit DANE
Im Zusammenspiel mit DANE spart man sich den Umstellungsaufwand nur, wenn dieses so konfiguriert ist, dass nicht auf dem ganzen Zertifikat der Hash berechnet wird, sondern nur auf den Public Key-Daten. Dafür wird der mittlere Zahlenparameter im TLSA-Record auf eine 1 statt einer 0 gesetzt, z.B. so:
_990._tcp.example.com IN TLSA 2 1 2 2CFC98A706BCF3683015...
Mehr zum Thema DANE und TLSA Records könnt ihr in diesem Beitrag nachlesen: DANE und TLSA Records erklärt
Noch ein Wort zur Sicherheit
Eigentlich sollte man für jedes neue Zertifikat einen neuen Private Key verwenden und den alten nicht mehr nutzen – das hat gute Gründe: Sollte der private Schlüssel von einer fremden Partei evtl. doch einmal in Erfahrung gebracht werden, kann der Datenverkehr nur für maximal 90 Tage mitgelesen werden. Nutzt man den privaten Schlüssel länger, sind auch neue Zertifikate nicht mehr sicher. Ich bin allerdings der Meinung, dass es vertretbar ist, denselben Schlüssel ein Jahr lang (= 3 Wiederverwendungen) zu nutzen, da kommerzielle Zertifikate auch mindestens ein Jahr lang mit demselben Private Key gültig sind. Nach einem Jahr sollte man allerdings ein neues Zertifikat mit einem neuen Private Key erzeugen.
https://www.julianmeyer.de
Das Problem mit HPKP lässt sich viel leichter lösten, den es ist möglich auch einfach das Intermidiate-Zertifikat (also das von Let’s Encrypt) als Pin zu verwenden. Wenn man diesen Pin als Backup-Pin verwendet, kann man immer das aktuell gültige als Haupt-Pin verwenden und wärend eines tausches dient der Backup-Pin als Validierung.
Bei DANE sollte es mit „Trust Anchor Assertion“ auch möglich sein, das Intermidiate Zertifikat als vertrausenswürdig zu beglaubigen. Damit kann dann nur noch LE Zertifikate ausstellen und da LE ein „Certificate Transparency“-Log führt kann jeder schritt nachvollzogen werden.
http://www.my-it-brain.de
Hallo Thomas,
ich bin in Deinem Beispiel zu HPKP über die beiden Parameter –cert-path cert.pem und –fullchain-path fullchain.pem gestolpert. Woher stammen denn in diesem Schritt das cert.pem und das fullchain.pem? Du schreibst leider nichts dazu wann und wie diese beiden Dateien erstellt werden.
MFG
Tronde
https://legacy.thomas-leister.de/ueber-mich-und-blog/
Hi, diese Dateien existieren zu dem Zeitpunkt noch nicht. Sie werden durch das Kommando erst erstellt.
LG Thomas
http://www.my-it-brain.de
Hi, Danke für den Hinweis und den guten Artikel.
LG
Tronde
Hallo!
Erstmal vielen Dank für die Anleitung, sie funktioniert auch gut.
Nur leider zeigen mir Debugger wie SSL-Tools.net nach erfolgter Erneuerung mit dem certbot und Restart von Postfix und co. weiterhin die ursprüngliche (Rest-)Gültigkeitsdauer, und nicht den neuen 90-Tages-Zeitraum an. Woran könnte das evtl. noch liegen? Auch eine Neugenerierung der request.csr hat nichts genützt.
Danke und Viele Grüße!
margau
https://legacy.thomas-leister.de/ueber-mich-und-blog/
Hi margau,
hast du daran gedacht, dass die Ergebnisse dieser SSL-Tester gecached werden? I.d.R gibt es mehr oder weniger versteckt einen Button, um den Test tatsächlich komplett neu durchzuführen.
LG Thomas
Hallo!
Ja, daran habe ich selbstverständlich gedacht. Ich habe die Tools immer schön „gezwungen“, neu zu testen.
Wie zu sehen ist, ist der Test gerade ein paar Minuten alt. Der letzte Refresh-Versuch wurde ebenfalls heute morgen durchgeführt:
https://de.ssl-tools.net/mailservers/margau-swec.de
Deswegen bin ich gerade etwas ratlos, und möchte das eigentlich so einrichten, dass es automatisch per Cron läuft, und ich nicht irgendwann böse Überraschungen in Form von Bounces erlebe, weil das Zertifikat abgelaufen ist, und ich dachte, dass es verlängert wird.
Mein Script löscht die fullchain.pem auch immer vor Erneuerung durch den certbot, d.h. dieser generiert es definitiv neu aus dem Private Key und dem CSR.
Viele Grüße!
margau
Hallo!
Das Problem hat sich mittlerweile erledigt, schuld war ein falscher Eintrag für smtpd.
Trotzdem Danke für die Hilfe!
Viele Grüße!
margau