Dies ist die archivierte Version des Blogs vom 05.01.2017. Aktuelle Beiträge findest du unter thomas-leister.de
 

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.


Post published on 3. Januar 2016 | Last updated on 9. Januar 2016
Tags:               

Diesen Blog unterstützen

Wenn Dir der Beitrag gefallen hat, freue ich mich über einen kleinen Obolus :-) Bitcoin QR Code

PayPal-Seite: https://www.paypal.me/ThomasLeister
Meine Bitcoin-Adresse: 15z8 QkNi dHsx q9WW d8nx W9XU hsdf Qe5B 4s

Siehe auch: Unterstützung

Informationen zum Autor

Thomas Leister

Geb. 1995, Kurzhaar-Metaller, Geek und Blogger. Nutzt seit Anfang 2013 ausschließlich Linux auf Desktop und Servern. Student der Automobilinformatik an der Hochschule für angewandte Wissenschaften in Landshut.

8 thoughts on “Let’s Encrypt Zertifikate mit Public Key Pinning und DANE

  • 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.

  • 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

  • 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

    • 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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.