====== Let's Encrypt ======
Bei [[https://letsencrypt.org/|Let's Encrypt]] handelt es sich um eine offene Zertifizierungsstelle, bei der man kostenlos [[https://de.wikipedia.org/wiki/X.509|X.509]]-Zertifikate für TLS((Transport Layer Security)) (ehemals SSL) erstellen kann. Gegründet wurde das Projekt 2014 von der EFF((Electronic Frontier Foundation; NGO, die sich für Grundrechte im Internet einsetzt)), Mozilla und der University of Michigan. Am 3. Dezember 2015 startete die öffentliche Beta-Phase, ab der man ohne vorherige Einladung mithilfe des in Python geschriebenen ''[[https://github.com/letsencrypt/letsencrypt|letsencrypt]]''-Clients weitestgehend automatisiert Zertifikate für den eigenen Server erhalten kann.
==== Let's Encrypt-Client heißt nun Certbot ====
Seit Mai 2016 läuft der offizielle Let's Encrypt-Client ''letsencrypt'' unter dem Namen "''certbot''" und wird weiterhin wie zuvor hauptsächlich von der EFF betreut, ist nun aber ein EFF-Projekt, siehe dazu die [[https://www.eff.org/deeplinks/2016/05/announcing-certbot-new-tls-robot|offizielle Mitteilung]]. Zugleich wurde mit der Umbenennung eine neue Webseite gestartet, https://certbot.eff.org/. Auf dieser muss nur der verwendete Server sowie das Betriebssystem ausgewählt werden, um die passende Anleitung zu erhalten. Um weiterhin problemlos Zertifikate zu erhalten, muss in bisherigen Skripten der Befehl ''letsencrypt'' durch ''certbot'' ersetzt werden. Das zugehörige GitHub-Repository lautet entsprechend [[https://github.com/certbot/certbot|certbot/certbot]], der ursprüngliche Link führt dorthin.
===== Installation ohne Wrapper =====
Unter Arch Linux befindet sich der ''certbot''-Client in den Community-Quellen und kann mittels
# pacman -S certbot
einfach installiert werden. Anstatt alle Einstellungen als Argumente zu übergeben, besteht auch die Möglichkeit, eine Konfigurationsdatei zu erstellen. Standardmäßig sucht der Client nach ''/etc/letsencrypt/cli.ini''. Im Folgenden will ich alles weitestgehend automatisieren und erstelle Domain-spezifische Konfigurationsdateien.
# vim /etc/letsencrypt/domain.tld.cnf
In diese Datei kommt der folgende Inhalt:
# Use a 4096 bit RSA key instead of 2048
rsa-key-size = 4096
# use the webroot authenticator
authenticator = webroot
webroot-path = /tmp/letsencrypt/
# Use acme-v01 server (public beta), should be used by default
#server = https://acme-v01.api.letsencrypt.org/directory
# Uncomment and update to register with the specified e-mail address
email = mail@domain.tld
renew-by-default
agree-tos
# domain list
domains = domain.tld, www.domain.tld, subdomain.domain.tld
# Uncomment to use a text interface instead of ncurses
text = True
Bei der erstmaligen Verwendung wird ein Benutzerkonto angelegt, das mit der E-Mail-Adresse verknüpft ist und unter ''/etc/letsencrypt/accounts'' wichtige Dateien wie den Private Key ablegt.
==== nginx ====
Bevor die Zertifikate ausgestellt werden, wird nach dem ACME((Automated Certificate Management Environment))-Protokoll dem Challenge-Response-Verfahren folgend eine mit dem Private Key verifizierte Challenge erstellt. Um den Besitz der Domains zu überprüfen, versucht der ACME-Server die jeweilige Challenge passend zur (Sub-)Domain unter ''(subdomain.)domain.tld/.well-know/acme-challenge/kryptographischerstring'' abzurufen. Dazu müssen wir ''nginx'' beibringen, wie es die Challenge ausliefert. Dazu in jeden ''server {}'' Block, zu dem ein Zertifikat ausgestellt werden soll, die folgende ''location'' einfügen:
location ~ '/.well-known/acme-challenge' {
default_type "text/plain";
root /tmp/letsencrypt;
}
Danach mit
# systemctl restart nginx
den ''nginx''-Server neustarten, damit die Änderungen übernommen werden.
Damit haben wir die Vorbereitungen abgeschlossen und können mit der Ausstellung der Zertifikate beginnen.
==== Ausführung ====
Zuerst erstellen wir den unter ''webroot-path'' angegebenen Pfad, da sich der ''certbot''-Client ansonsten mit einer Fehlermeldung beendet:
$ mkdir /tmp/letsencrypt
Nun können wir den Vorgang mit
# certbot certonly -c /etc/letsencrypt/domain.tld.cnf
starten. Das Ganze dauert ein wenig; was aktuell ausgeführt wird, kann durch hinzufügen der Flag ''-v'' am Ende des Befehls angezeigt werden. War alles erfolgreich, müssen wir nur noch die Zertifikate in nginx einbinden.
Sollte etwas schief gelaufen sein, kann unter ''/var/log/letsencrypt/letsencrypt.log'' der Log des letzten Vorgangs eingesehen werden.
==== Zertifikate in nginx ====
Die fertigen Zertifikate werden unter ''/etc/letsencrypt/live/domain.tld'' abgespeichert. Entsprechend müssen wir die Pfade in die jeweiligen ''server {}'' Blöcke der ''nginx.conf'' einfügen:
ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
Dabei wird ''ssl_trusted_certificate'' nur für [[https://en.wikipedia.org/wiki/OCSP_stapling|OCSP Stapling]] benötigt. Soll OCSP Stapling aktiviert werden, sollte Folgendes im ''http {}'' Block der ''nginx.conf'' stehen:
# enable ocsp stapling (reduces amount of time until first byte)
ssl_stapling on;
ssl_stapling_verify on;
Zum Schluss noch mit
# systemctl restart nginx
den ''nginx''-Server neustarten.
Mehr zu ''nginx'' und den SSL/TLS spezifischen Einstellungen für mehr Sicherheit kann [[server:nginx#sicherheit|hier]] gefunden werden.
===== Erneuerung der Zertifikate =====
Das Erneuern der Zertifikate ist denkbar einfach und läuft analog zu der erstmaligen Ausführung ab. Da alle Einstellungen in einer Konfigurationsdatei hinterlegt sind, kann mit dem Aufruf von
# certbot certonly -c /etc/letsencrypt/domain.tld.cnf
die Erneuerung angestoßen werden. Ist das Skript durchgelaufen, muss der Server nur noch mit
# systemctl restart nginx
neugestartet werden, um die neuen Zertifikate zu laden. Fertig.
===== Automatisierung mittels cron =====
Der Vorteil von Let's Encrypt besteht darin, dass nach Möglichkeit alles automatisch ablaufen soll und einem der Client das erstellen von Certificate Signing Requests etc. abnimmt. Aus diesem Grund sind die Zertifikate auch aktuell nur auf eine Laufzeit von 90 Tagen ausgelegt. Später, wenn alles gut läuft, soll die Gültigkeit auf nur 30 Tage herabgesetzt werden. Aus diesem Grund kann es von Vorteil sein, wenn der Server sich automatisch ohne Zutun von außen um die Erneuerung der Zertifikate kümmert.
Dazu habe ich folgendes Bash-Skript erstellt, welches dafür sorgt, dass das verwendete ''webroot''-Verzeichnis existiert, die Zertifikate erneuert werden und bei erfolgreicher Ausstellung ''nginx'' neugestartet wird:
#!/usr/bin/bash
# Automate certificate renewal for a given domain, assuming all necessary config parameters are set in /etc/letsencrypt/domain.tld.cnf
# Usage: /etc/letsencrypt/renew.sh domain.tld
DOMAIN=${1?"No argument given! Please provide the domain which should be renewed"}
EMAIL=$(awk '/email/ {print $3}' /etc/letsencrypt/$DOMAIN.cnf)
if [ ! -f /etc/letsencrypt/$DOMAIN.cnf ]; then
echo "Config file /etc/letsencrypt/$DOMAIN.cnf does not exist!"
exit 1;
fi
# Renew Let's Encrypt SSL cert
mkdir -p /tmp/letsencrypt
certbot certonly -c /etc/letsencrypt/$DOMAIN.cnf
if [ $? -ne 0 ]; then
ERRORLOG=`tail /var/log/letsencrypt/letsencrypt.log`
echo -e "The Lets Encrypt Cert has not been renewed!\n\n" $ERRORLOG | mail -s "Lets Encrypt Cert Alert" $EMAIL
else
systemctl restart nginx
fi
rm -rf /tmp/letsencrypt
exit 0
Ist das Skript ausführbar
# chmod +x /etc/letsencrypt/renew.sh
muss es mit der Domain aufgerufen werden, die erneuert werden soll:
# /etc/letsencrypt/renew.sh domain.tld
Sollte etwas schief laufen, wird eine E-Mail an ''admin@domain.tld'' gesendet, vorausgesetzt, der Server ist dazu eingerichtet, Mails versenden zu können.
Dieses Skript können wir mittels ''cron'' in definierten Zeitintervallen ausführen lassen, wozu ein Befehl in ''crontab'' hinzugefügt wird. Mit
# crontab -e
können neue Befehle hinzugefügt werden. Wird etwas geändert, lädt ''cron'' die neuen Befehle automatisch. Mit
# crontab -l
können alle registrierten ''cron''-Jobs angezeigt werden.
Sollen die Zertifikate z. B. alle zwei Wochen erneuert werden, und zwar montags um 5 Uhr nachts, können wir folgendes mit ''crontab -e'' eintragen:
# renew letsencrypt certificates for domain domain.tld every other monday at 5:00
0 5 * * 1 expr `date +\%W` \% 2 > /dev/null || /etc/letsencrypt/renew.sh domain.tld
==== cron-Regeln testen ====
Sollten die ''cron''-Regeln eher kryptisch anmuten, ist es mit der [[http://www.dataphyx.com/cronsandbox/cronsandboxgui.php|Cron Sandbox]] möglich, sich die nächsten Termine anzeigen zu lassen, die mit der jeweiligen Regel zutreffen.
===== Komplett manuell ohne Client =====
Es ist auch möglich, komplett manuell ohne Verwendung des ''certbot''-Clients Zertifikate zu beziehen. Dazu hat jemand eine statische Seite geschrieben, bei der man sich selbst um die Arbeit kümmern muss: https://gethttpsforfree.com/. Dazu sollte man jedoch wissen, wie man Zertifikate mit einem [[server:openssl|CSR]] beantragt.