SSL-Zertifikate von Let’s Encrypt

Seit Dezember 2015 gibt es die Möglichkeit über Let’s Encrypt kostenlos SSL-Zertifikate für Webanwendungen zu erhalten. Wie funktioniert das genau? Wie geht es am Einfachsten?

Verschlüsselung von Webseiten über HTTPS mittels SSL bzw. TLS gibt es schon eine geraume Zeit. Nichtsdestotrotz werden weiterhin eine Vielzahl gerade kleinerer Webseiten unverschlüsselt übertragen. Warum? Ganz einfach: Die Ausstellung eines Verschlüsselungszertifikats ist mit Kosten verbunden, typischerweise ab 40 Euro pro Jahr. Das ist für Seiten, die keine Einnahmen erzielen nicht rentabel. Dennoch möchte man bei Eingabeformularen für Benutzer oder gerade bei der Eingabe von Benutzernamen und Passwort eine Verschlüsselte Kommunikation haben, da sonst diese Daten unter Umständen von Dritten im Klartext gesehen werden können (wenn z.B. der Nutzer sich in einem öffentlichen WLAN befindet).

Die Zertifizierungsstelle Let’s Encrypt

Glücklicherweise hat die Internet Security Research Group (ISRG) mit Unterstützung durch ein paar Branchengrößen (Mozilla, Electronic Frontier Foundation, Cisco, Facebook, usw.) die Let’s Encrypt Initiative ins Leben gerufen. Seit Ende 2015 befindet sich das Programm in der öffentlichen Betaphase und kann von jedem für seine Webseiten genutzt werden. Voraussetzung ist dabei allerdings, dass man einen Konsolenzugriff zum Server hat, als auch die Konfigurationen des Webservers ändern kann.

Vorteile

  • Kostenlos
  • wird von den meisten Browsern erkannt

Nachteile

  • noch in der Public Beta
  • 90 Tage Gültigkeit der Zertifikate (Automatisierung erforderlich)
  • keine IDN unterstützt (internationale Domainnamen, z.B. mit Umlauten)

Verwendung

Wie können nun SSL-Zertifikate bei Let’s Encrypt beantragt werden?
Bei bisherigen Zertifizierungsstellen ist es meist so, dass man selbst auf seinem Server händisch die Schlüssel und einen zugehörigen Zertifizierungsantrag (Certificate Signing Request, CSR) erstellt, diesen dann beim Anbieter hochlädt und danach ein signiertes Zertifikat zurück erhält.

Der Let’s Encrypt Client

Bei Let’s Encrypt hat man sich zu diesem Vorgehen Gedanken gemacht und versucht, die Erstellung von Zertifikaten zu vereinfachen. Es wird einfach ein Programm auf dem Webserver ausgeführt, auf dem man Zertifikate nutzen möchte. Mit Hilfe dieses Let’s Encrypt Client können dann Zertifikate beantragt und verlängert werden. Der Let’s Encrypt Client hat für mich aber entscheidende Nachteile:

  • Zum einen startet der Client einen eigenen Webserver auf Port 80 – das unterbricht z.B. den Service für den Apache-Webserver, wenn dieser auf dem gleichen Rechner läuft. Es können also während der Zertifikat-Erneuerung keine normalen Webseiten vom Server ausgeliefert werden.
  • Weiterhin hat der Client erhebliche Abhängigkeiten, die dann erst auf einem Server installiert werden müssen. Das sorgt wieder für unnötigen „Overhead“.
  • Schließlich benötigt der Client auch Root-Berechtigungen, um den integrierten Webservice auf Port 80 starten zu können.

Ein alternativer Client

Aus diesen Gründen habe ich mich nach einer Alternative umgesehen und bin bei Github auf acme_tiny gestoßen. Das Skript hat keinerlei zusätzliche Abhängigkeiten, lässt sich also gut auf einem Server hinterlegen. Zudem lassen sich die Zertifikate mit acme_tiny auch erneuern ohne dass der Webserver beendet werden muss. Es kann also Unterbrechungsfrei erfolgen.

Verwendung von acme_tiny

Als erstes legen wir uns unter /opt/acme-tiny ein Arbeitsverzeichnis für die Verschlüsselung an. Dort laden wir dann auch mittels

wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py

den Acme_tiny Client herunter.

Eigenen Schlüssel und Account anlegen

Zuerst muss ein Let’s Encrypt Account-Schlüssel angelegt werden. Dabei handelt es sich um einen 4096-Bit RSA Schlüssel, der einfach mittels OpenSSL erzeugt werden kann:

openssl genrsa 4096 > account.key

Alternativ kann auch der offizielle Client verwendet werden. Danach müsste aber der Schlüssel konvertiert werden – Eine Anleitung dazu ist bei Acme_tiny verfügbar.

Account-Key sichern

Dieser Account-Key ist, genauso wie die privaten Domainschlüssel, die wir später erzeugen, geheim zu halten und zu sichern. Ohne den Account-Key können keine Zertifikate ausgestellt werden. Diese Schlüssel dürfen auch keinen Dritten zugänglich sein.

Domain private Key erzeugen

Der private Schlüssel für die zu verschlüsselnde Domain wird analog zum Account-Key erzeugt:

openssl genrsa 4096 > einbeispiel.key

Diesen privaten Schlüssel hinterlegt man dann auch gleich unter /etc/ssl/private/, da wir später den Webserver entsprechend auf diesen Pfad zugreifen lassen.

CSR erstellen

Nun haben wir unsere privaten Schlüssel erstellt und können eine Signaturanfrage stellen (Certificate Signing Request, CSR).

Hier gibt es zwei verschiedene Möglichkeiten: Entweder wir brauchen nur einen Domänennamen (z.B. einbeispiel.de), oder wir brauchen das Zertifikat für mehrere Domänennamen (einbeispiel.de, ein-beispiel.de). Das gilt auch, wenn wir Subdomains (wie www) mit dem Zertifikat abdecken wollen. Also wird meistens ein sogenannter Subject Alternate Name (SAN) benötigt.

ohne SubjectAltName

openssl req -new -sha256 -key einbeispiel.key -subj "/CN=einbeispiel.de" > einbeispiel.csr

mit SubjectAltName

openssl req -new -sha256 -key einbeispiel.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:einbeispiel.de,DNS:www.einbeispiel.de")) > einbeispiel.csr

Challenge hinterlegen

Ein Teil des Signatur-Prozesses ist die Prüfung, ob die Domain auch unter der eigenen Kontrolle steht. Dazu muss eine sogenannten Challenge hinterlegt werden, die vom Let’s Encrypt-Server dann abgefragt wird.

Dazu legen wir uns einen Challenges-Ordner an:

mkdir /var/www/challenges

Dieser muss dann bei der gewünschten Domain in der Apache-Konfiguration unter /etc/apache2/sites-available/einbeispiel.conf hinterlegt werden:

# Letsencrypt Challenges
Alias /.well-known/acme-challenge/ /var/www/challenges/

Danach ist die Konfiguration vom Webserver noch neu einzulesen (Apache reload), so dass das Verzeichnis auch korrekt angesprochen werden kann.

Zertifikat signieren lassen

Nun kommt der große Moment des Clients:

python acme_tiny.py --account-key ./account.key --csr ./einbeispiel.csr --acme-dir /var/www/challenges/ > ./einbeispiel.crt

Damit erhält man in der Datei einbeispiel.crt das signierte Zertifikat. Nun kann man diese Datei noch um das Zwischenzertifikat von Let’s Encrypt anreichern:

wget -O - https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem > intermediate.pem
cat einbeispiel.crt intermediate.pem > /etc/ssl/certs/einbeispiel.pem

Nun hat man den öffentlichen Schlüssel korrekt hinterlegt und kann die Dateien im Webserver einbinden.

Zertifikat in Apache einbinden

Grundsätzlich muss das Modul SSL geladen werden, damit Seiten per HTTPS ausgeliefert werden können. Erst dann ist ein Zugriff auf die folgenden Befehle möglich. Nun legen wir unseren VHost-Eintrag an:

<VirtualHost *:443>
ServerName einbeispiel.de
ServerAlias www.einbeispiel.de
DocumentRoot /var/www/
SSLEngine on
SSLCertificateFile /etc/ssl/certs/einbeispiel.pem
SSLCertificateChainFile /etc/ssl/certs/einbeispiel.pem
SSLCertificateKeyFile /etc/ssl/private/einbeispiel.key
# Letsencrypt Challenges
Alias /.well-known/acme-challenge/ /var/www/challenges/
</VirtualHost>

Nach einem Neustart des Apachen ist nun die Seite auch per HTTPS verfügbar. Hurra.

Automatisierung

Jetzt wird zwar die Webseite verschlüsselt übertragen, das zugehörige Zertifikat ist aber nur 90 Tage gültig. Also das Zertifikatsprozedere in 3 Monaten wiederholen? Nein, ein kleines Shell-Skript mit zugehörigem Cronjob schafft Abhilfe:

#!/bin/sh
python /opt/acme-tiny/acme_tiny.py --account-key /opt/acme-tiny/account.key --csr /opt/acme-tiny/einbeispiel.csr --acme-dir /var/www/challenges/ > /tmp/signed.crt || exit
wget -O - https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem > intermediate.pem
cat /tmp/signed.crt intermediate.pem > /etc/ssl/certs/einbeispiel.crt
service apache2 reload

Dieses Skript kann nun als Cronjob (geplanter Task) monatlich aufgerufen werden, und das Zertifikat wird automatisch erneuert. Man muss sich somit nicht wieder um die Webseiten-Verschlüsselung kümmern. Und das ist sogar ein Vorteil gegenüber kommerziellen SSL-Zertifikatsanbietern.

Fazit und Ausblick

Bei den Umgang mit den privaten Schlüsseln (sowohl Account als auch Domain) ist darauf zu achten, dass keine Unberechtigten Zugriff darauf haben. Es sollten also sowohl Verzeichnis als auch Dateirechte so gesetzt werden, dass nur der eigene Benutzer darauf lesend Zugriff hat.

Leider ist es aus der Sicherheitssicht nicht mit dem Einschalten der Verschlüsselung getan. Damit HTTPS auch wirklich sicher betrieben wird, sind weitere Einstellungen nötig. Eine gute Zusammenfassung dazu findet sich in den Empfehlungen von Mozilla.

Let’s Encrypt bietet eine tolle Möglichkeit für alle Webseitenbetreiber, die eigene Seite kostenlos im Internet verschlüsselt anzubieten. Mit Hilfe des acme_tiny Programms und den kleinen Shell-Skript ist die Erneuerung komplett automatisiert möglich und bedarf keiner weiteren Pflege.

Update Mai 2016: Der EFF Certbot bietet nun auch eine recht einfache Möglichkeit an, die Zertifikate automatisch zu erstellen und zu verlängern. Wer sich also nicht mit acme_tiny spielen will, dem sei diese Variante ans Herz gelegt.

3 Gedanken zu „SSL-Zertifikate von Let’s Encrypt“

  1. Hi,

    vielen Dank für die tolle Anleitung. Nur eins ist mir aufgefallen: Müsste es in dem Automatisierungsscript am Ende
    cat /tmp/signed.crt intermediate.pem > /etc/ssl/certs/einbeispiel.crt
    nicht so heißen
    cat /tmp/signed.crt intermediate.pem > /etc/ssl/certs/einbeispiel.pem
    ?
    Im Apache ist ja nur .pem hinterlegt.

    Gruß
    Florian

  2. Hallo Florian,

    vielen Dank für dein Feedback. crt/pem sind inhaltlich gleich, es ist also nur eine Dateierweiterung. Du kannst also natürlich auch .pem als Erweiterung nutzen.

    Ich würde übrigens wie im Update beschrieben den Certbot (https://certbot.eff.org/) als Automatisierung fürs Let’s Encrypt empfehlen.

    Viele Grüße
    Dieter

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.