
Let’s Encrypt ist eine nicht gewinnorientierte Zertifizierungsstelle (Certificate Authority, CA), die kostenlose X.509-TLS-Zertifikate anbietet. Zertifikate von Let’s Encrypt finden aktuell auf über 265 Millionen Webseiten Anwendung. Der Service von Let’s Encrypt ist 2015 gestartet und wird unter anderem von der Electronic Frontier Foundation (EFF), der Mozilla Foundation, dem Hoster OVH, Cisco Systems, Facebook, Google, AWS, Nginx und der Bill and Melinda Gates Foundation gesponsort. Let’s Encrypt hat es sich zum Ziel gesetzt, dass weltweit alle Webseiten durch den Einsatz von HTTPS sicherer und datenschutzfreundlicher werden.
Das Besondere an Let’s Encrypt und warum ich dieses als Werkzeug in meinem Blog erwähne, ist die Möglichkeit binnen Sekunden für eine beliebige eigene Domäne ein kostenloses HTTPS-Zertifikat zu generieren und komplett automatisiert aktuell zu halten.
Das Zertifikat
Zertifikate von Let’s Encrypt sind 90 Tage gültig und können über die Clientsoftware Certbot vollautomatisiert erneuert werden.
Seit 2018 unterstützt Let’s Encrypt Wildcard-Zertifikate. Ein Wildcard-Zertifikat für den Eintrag *.pflugradts.de
gilt z.B. nicht nur für die Hauptseite https://pflugradts.de, sondern auch für sämtliche Subdomänen wie https://christians-blog.pflugradts.de.
Let’s Encrypt bietet keine Organization-Validation- oder Extended-Validation-Zertifikate. Große Organisationen werden also eher auf eine kostenpflichtige Alternative setzen.
ACME
Zur vollautomatisierten Ausstellung und Aktualisierung von Zertifikaten hat Let’s Encrypt ein eigenes Kommunikationsprotokoll zur Interaktion zwischen der Zertifizierungsstelle und dem Server, der ein Zertifikat beheimatet, entwickelt. ACME steht für Automatic Certificate Management Environment und bietet in der aktuellen API Version 2 die Challenge-Response-Verfahren HTTP und DNS.
Beim HTTP-Verfahren werden JSON-Nachrichten zwischen der Zertifizierungsstelle und einem Webserver auf dem Server, auf dem sich das Zertifikat befindet, ausgetauscht. Der Webserver dient dabei als Beweis, dass dem Anforderer des Zertifikates die angegebene Domäne auch tatsächlich gehört. Das DNS-Verfahren wird für Wildcard-Zertifikate verwendet und stellt sicher, dass der Eigentümer des Zertifikats Kontrolle über die gesamte Domäne hat. Bei diesem Verfahren muss der Eigentümer als Beweis dafür einen TXT Resource Record für die Domäne erstellen.
ACME ist in RFC 8555 spezifiziert.
Certbot und Boulder
Der Zertifikatsaustellungsprozess basiert auf einer Client- und einer Serverkompontente. Beide sind Open Source, auf GitHub gehostet und am Ende des Beitrags verlinkt.
Der Server trägt den Namen Boulder und ist in Go geschrieben. Boulder ist eine Implementierung einer ACME-basierten CA und ist daher nicht strikt mit Let’s Encrypt verknüpft, sondern kann von beliebigen Zertifizierungsstellen eingesetzt werden, die Zertifikate über ACME ausstellen möchten.
Der Client trägt den Namen Certbot und ist in den gängigen Repositories wie z.B. dem von Ubuntu enthalten. Der Certbot ist ein in Python geschriebenes Kommandozeilenwerkzeug, mit dem sich Zertifikate anfordern lassen. Über einen einzigen Aufruf kann er sämtliche lokal vorhandene Zertifikate aktualisieren. Für das Challenge-Response-Verfahren über HTTP kann der Certbot sowohl einen vorhandenen Apache oder Nginx verwenden, oder einen eigenen Webserver temporär hochfahren, wenn Port 80 nicht belegt ist. Der Client spricht standardmäßig mit Let’s Encrypt, kann per Parameter aber auch andere ACME-Server ansteuern.
Ein neues Zertifikat mit dem Certbot einrichten
Im Folgenden zeige ich, wie ich ein Zertifikat für meinen bei Strato gehosteten Server via Let’s Encrypt installiere. Da ich das Zertifikat nur herunterladen möchte, rufe ich den Certbot mit dem Parameter certonly
auf.
Ich beabsichtige das Zertifikat ohne eigenen Webserver aufzusetzen. Meinen Traefik-Webserver, der auf Port 80 läuft, habe ich daher zuvor heruntergefahren. Hat man einen Apache oder Nginx auf dem Port laufen, so kann man als Argument --apache
bzw. --nginx
an den Befehl anhängen. Wenn man die Webserverkonfiguration dann auch gleich automatisch anpassen möchte, so dass Apache/Nginx das Zertifikat verwendet, lässt man certonly
weg.
certbot certonly
Nach Eingabe dieses Befehls fragt mich der Certbot, ob er einen eigenen Webserver hochfahren soll, oder ich die Challenge für die ACME-Authentifizierung im Webroot eines bestehenden Webservers ablegen möchte:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Spin up a temporary webserver (standalone)
2: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):
Ich habe mich für Ersteres entschieden, als Nächstes muss ich den/die DNS-Namen eingeben, für den/die das Zertifikat ausgestellt werden soll:
Plugins selected: Authenticator standalone, Installer None
Please enter in your domain name(s) (comma and/or space separated) (Enter 'c'
to cancel):
Nach Eingabe des DNS-Namens, der hier meinem Strato-Hostnamen entsprach, da ich für meine Domain pflugradts.de
bereits ein Zertifikat habe, wird der Installationsprozess abgeschlossen:
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for hXXXXXXX.stratoserver.net
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/hXXXXXXX.stratoserver.net/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/hXXXXXXX.stratoserver.net/privkey.pem
Your cert will expire on 2022-10-27. 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
Dieses Zertifikat ist nun 90 Tage gültig. Um es und alle anderen Let’s-Encrypt-Zertifikate auf dem Server zu erneuern, genügt ein einfacher Aufruf des Certbots:
certbot renew
Dies führt zu folgender Ausgabe:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/hXXXXXXX.stratoserver.net.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/pflugradts.de.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following certs are not due for renewal yet:
/etc/letsencrypt/live/hXXXXXXX.stratoserver.net/fullchain.pem expires on 2022-10-27 (skipped)
/etc/letsencrypt/live/pflugradts.de/fullchain.pem expires on 2022-09-01 (skipped)
No renewals were attempted.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Wie man an der Ausgabe erkennt, prüft der Certbot nicht nur das eben neu erzeugte Zertifikat, sondern auch das bereits vorhandene für die Domäne pflugradts.de
. Der Certbot vermeldet auch, dass es keine tatsächliche Erneuerung gegeben hat. Zertifikate werden erst ab 30 Tage vor Ablauf erneuert. Da das Ablaufdatum lokal geprüft werden kann, belastet ein häufiger Aufruf von certbot renew
nicht die Serverkompontente von Let’s Encrypt.
Ich persönlich habe bei mir einen Cronjob hinterlegt, der die Zertifikate einmal die Woche überprüft und ggf. aktualisiert:
@weekly certbot renew
Ein Wildcard-Zertifikat anlegen
Der Certbot bietet mit dem Parameter --manual-auth-hook
die Möglichkeit zur Erweiterung. Da für Wildcard-Zertifikate eine DNS-Challenge fällig ist und dabei ein DNS-Eintrag eingerichtet werden muss, lässt sich dieser Vorgang mit dem Certbot allein nicht vollständig automatisieren. Für mich als Kunden von Strato bietet sich dafür der Strato-Certbot an, der auf GitHub verfügbar und am Ende des Beitrags verlinkt ist. Der Strato-Certbot ist ein einfaches Python-Skript, das über den oben genannten Parameter in den Authentifizierungsprozess eingebunden werden kann und über die Strato-API den erforderlichen DNS-Eintrag anlegt. Für jeden Domänen-Provider, der eine Programmierschnittstelle für die Domänenverwaltung anbietet, lässt sich der Vorgang damit komplett automatisieren.
Staging-Umgebung zum Experimentieren
Let’s Encrypt hat diverse Rate Limits definiert. So darf es pro Konto und Domäne beispielsweise nur fünf fehlgeschlagene Validierungen pro Stunde geben. Funktioniert der Zertifikatsbezug nicht auf Anhieb, etwa weil man einen eigenen Apache oder Nginx verwenden möchte und dieser nicht so konfiguriert ist, dass er gut mit dem Certbot zusammenspielt, so bietet es sich an, den Prozess erst gegen die Staging-Umgebung laufen zu lassen, bis alles funktioniert. Dies geht ganz einfach, indem man dem Certbot-Aufruf den Parameter --test-cert
anhängt.
- RFC 8555 (ACME) - Boulder auf GitHub - Certbot auf GitHub - Strato-Certbot auf GitHub