Let's Encrypt renewal mit systemd

In einem früheren Post sprach ich ja davon meinen Blog nun unter anderem mit Zertifikat auszuliefern. Ein paar Leute haben mir noch Tipps gegeben wie ich ein paar Dinge noch verbessern kann und mittlerweile läuft das auch ganz gut. Keine negativen Rückmeldungen, keine Ausfälle, keine zusätzlichen Kosten, alles vollautomatisch.

In diesem Post beschreibe ich kurz, wie man die automatische Erneuerung der Let's Encrypt Zertifikate unter Ubuntu 16.04 LTS in Kombination mit Nginx und dem offiziellen Let's Encrypt Client einrichtet. Damit das eben vollautomatisch läuft, genau so, wie es gedacht ist.

Zuerst braucht man einen Let's Encrypt Renewal Service, den man unter /etc/systemd/system/letsencrypt.service mit folgendem Inhalt anlegt:

[Unit]
Description=Renew Let's Encrypt certificates
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/bin/letsencrypt renew --agree-tos

Hinter /usr/bin/letsencrypt renew --agree-tos ist es übrigens nicht nötig, irgendeine Konfiguration oder dergleichen anzugeben – das macht der Client automatisch.

Die zweite Datei ist der dazugehörige Timer, welcher den Service einmal pro Woche laufen lässt. Kann man im Prinzip auch täglich machen (um beispielsweise Downtimes auf der Serverseite von Let's Encrypt zu umgehen), muss man aber nicht. Ich wurde zudem noch per E-Mail auf die Option RandomizedDelaySec hingewiesen, welche den Timer zufällig um ein paar Stunden später starten lässt. Das hat den Hintergrund, dass man die Server nicht zwangsweise immer zum gleichen Zeitpunkt belasten will, etwa um 18:00 jeden Freitag. Wenn einer das macht ist das kein Problem, wenn ein paar hunderttausend Nutzer das so machen allerdings schon. Daher wird der Startzeitpunkt etwas randomisiert. Gekippt wird der Inhalt in die Datei /etc/systemd/system/letsencrypt.timer:

[Unit]
Description=Renew Let's Encrypt certificates

[Timer]
OnCalendar=weekly
RandomizedDelaySec=24h
Persistent=true
Unit=letsencrypt.service

[Install]
WantedBy=basic.target

Die dritte Datei sorgt dafür, dass der Webserver neu gestartet wird – in meinen Falle Nginx. Dazu legt man folgende Datei unter /etc/systemd/system/letsencrypt.service.d/nginx.conf an:

[Service]
ExecStartPost=/bin/systemctl reload nginx.service

Um das ganze nun laufen zu lassen genügt es, den letsencrypt.timer zu aktivieren:

# systemctl enable letsencrypt.timer

Und das wars dann auch schon. Testen ob das alles wirklich funktioniert kann man, indem man einmalig den Let's Encrypt Service startet (systemd start letsencrypt.service) und via journalctl dies entsprechend überprüft, sieht dann in etwa so aus:

# journalctl -f
[…] systemd[1]: Starting Renew Let's Encrypt certificates...
[…] letsencrypt[3078]: Processing /etc/letsencrypt/renewal/kopfkrieg.org.conf
[…] letsencrypt[3078]: The following certs are not due for renewal yet:
[…] letsencrypt[3078]:   /etc/letsencrypt/live/kopfkrieg.org/fullchain.pem (skipped)
[…] letsencrypt[3078]: No renewals were attempted.
[…] systemd[1]: Reloading A high performance web server and a reverse proxy server.
[…] systemd[1]: Reloaded A high performance web server and a reverse proxy server.
[…] systemd[1]: Started Renew Let's Encrypt certificates.
^C
#

Wie man sehen kann wurde der Prozess gestartet, erfolgreich beendet und anschließend auch der Hook für den Reload des Webserver ausgeführt. Hach, systemd♥ (aber ernsthaft: Mit Upstart oder *schauder* SysVinit wäre das nicht einmal annähernd so schön einfach umzusetzen).