Wer sich in den letzten Tagen mit der Webseite des Datenkanals verbinden wollte, erhielt unter Umständen eine Fehlermeldung vom Browser. Jens ist dem Problem auf den Grund gegangen und jetzt funktioniert alles, wie es soll. Woran lag das Problem?
Wir setzen beim Datenkanal auf ein Zertifikat von Let’s Encrypt. Unser erstes Zertifikat wurde Ende 2015 ausgestellt und im März gab es eine Erneuerung des Zertifikats. Zur selben Zeit gab Let’s Encrypt eine Erneuerung der Intermediate-Zertifikate bekannt.
Jens stellte zuerst Probleme fest, als er sich mit dem Tor-Browser zum Datenkanal verbinden wollte. Ein Chromium v50 sowie ein Firefox v45 funktionierten problemlos. Eine Nachfrage beim Twitter ergab ein bunt durchmischtes Bild:
Wer von euch bekommt eine HTTPS-Warnung beim Besuch von https://t.co/a2XtkPupso (welcher Client/Browser)?
/cc @datenkanal
— Jens Kubieziel (@qbi) 24. April 2016
Chromium v49 warnte. Bei anderen warnte weder Chromium noch der Tor-Browser. Schließlich hatte Hanno den entscheidenden Hinweis: Browser speichern die Informationen über die Zertifikatskette zwischen. In seinem Blogbeitrag Incomplete Certificate Chains and Transvalid Certificates ist das detailliert erklärt. Woran lag dann also unser Problem?
Die Ausstellung und Erneuerung der Zertifikate übernimmt das Shellskript lets_encrypt.sh. Das stammt von lukas2511/letsencrypt.sh ab. Im Skript finden sich folgende Zeilen:
:> grep ROOTCERT lets_encrypt.sh
ROOTCERT=“public-lets-encrypt-x1-cross-signed.pem”
cat “${BASEDIR}/${ROOTCERT}” >> “${BASEDIR}/${domain}/${domain}-certchain.pem”
printf “ ”; openssl verify -CApath $rootcerts ${ROOTCERT}
printf “ ”; openssl verify -CApath $rootcerts -untrusted ${ROOTCERT} ${domain}/${domain}-certchain.pem
curl -sS -L -o ${BASEDIR}/${ROOTCERT} https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem
Das heißt, es wird eine Umgebungsvariable namens ROOTCERT angelegt und dort der Name des Let’s-Encrypt-Intermediate-Zertifikats gespeichert. Die Zeile, die mit cat beginnt, kopiert das Intermediate-Zertifikat an das Ende des eigenen Zertifikats und die mit curl beginnende Zeile lädt die Datei herunter.
Das erneuerte Zertifikat hat jedoch ein x3 statt x1 im Namen. Damit kopierte das Skript also das falsche Zertifikat in die Datei. Der Fehler ließ sich schnell beheben.
Wir fanden den Fehler anfangs nicht und begannen alternativ mit Neilpang/acme.sh zu experimentieren. Denn das Skript machte bei der Challenge immer noch Probleme. Die Challenge schien mit acme.sh gegen den Testserver von Let’s Encrypt zu funktionieren. Daher entschieden wir uns, das live zu testen. Die Challenge funktionierte, ein Zertifikat wurde erstellt. Doch, oh weh, die Zertifikatskette war wieder unvollständig. Allerdings zeigte sich bei einem Blick in die lokal gespeicherte Zertifikatsdatei, dass das Intermediate-Zertifikat fehlte. Das kopierte ich mit hinein und schon haben wir funktionierendes TLS. Jetzt muss unser Sysadmin nur noch die DH-Parameter anpassen und alles ist grün.