Ein abgelaufenes TLS-Zertifikat legt einen Dienst sofort still: Browser zeigen eine Vollbild-Warnung, API-Clients brechen den Handshake ab. Certbot erneuert Let's Encrypt-Zertifikate vollautomatisch, aber nur wenn Timer, Challenge-Weg und Reload-Hook zusammenpassen. Diese Anleitung zeigt dir, wie du die Automatik einrichtest, testest und überwachst.
Wie erneuert certbot ein Zertifikat automatisch?
Certbot erneuert ein Zertifikat automatisch über den Befehl certbot renew, den ein systemd-Timer oder Cronjob zweimal täglich startet, und tauscht das Material nur aus, wenn die Restlaufzeit unter 30 Tage liegt.
Die Erneuerung ist damit kein separater Vorgang, den du neu konfigurierst. Certbot liest bei jedem Lauf die Dateien unter /etc/letsencrypt/renewal/ und wiederholt exakt die Parameter, mit denen das Zertifikat ursprünglich ausgestellt wurde: Authenticator, Domainliste, Schlüsseltyp und Account. Ändert sich an deinem Setup etwas (neuer Webserver, neuer Pfad für den Webroot), musst du diese Datei anpassen, sonst scheitert die Erneuerung Monate später ohne dein Zutun.
| Aufgabe | Passender Befehl |
|---|---|
| Neues Zertifikat ausstellen | certbot certonly |
| Alle fälligen Zertifikate erneuern | certbot renew |
| Ein bestimmtes Zertifikat erneuern | certbot renew --cert-name <deine-domain> |
| Ablauf testen ohne Ausstellung | certbot renew --dry-run |
Voraussetzungen
- Ein Linux-Host mit certbot 2.9 oder neuer (
certbot --version), idealerweise 4.x aus dem Snap- oder Distributionspaket - Mindestens ein bereits ausgestelltes Zertifikat unter
/etc/letsencrypt/live/ - Ein Benutzerkonto mit
sudo-Rechten - Eine öffentlich auflösbare Domain, deren A- oder AAAA-Record auf den Host zeigt
- Für http-01: eingehender Zugriff auf Port 80 aus dem Internet
Let's Encrypt deckt die meisten Fälle ab. Brauchst du dagegen Organisationsvalidierung, eine Haftungszusage oder ein Wildcard-Zertifikat mit vertraglichem Support, sind kommerzielle SSL-Zertifikate die passende Alternative. Die hier gezeigte Automatik betrifft ausschließlich ACME-Zertifikate.
Renewal-Konfiguration und Timer prüfen
Verwaltete Zertifikate anzeigen
Der erste Blick gilt dem Bestand. certbot certificates listet jedes verwaltete Zertifikat mit Ablaufdatum und Pfaden:
$ sudo certbot certificates
Found the following certs:
Certificate Name: example.com
Domains: example.com www.example.com
Expiry Date: 2026-10-04 11:22:31+00:00 (VALID: 48 days)
Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem
Private Key Path: /etc/letsencrypt/live/example.com/privkey.pemDer Certificate Name ist der Wert, den du später bei --cert-name einsetzt. Er entspricht dem Dateinamen der Renewal-Konfiguration:
# /etc/letsencrypt/renewal/example.com.conf
archive_dir = /etc/letsencrypt/archive/example.com
cert = /etc/letsencrypt/live/example.com/cert.pem
privkey = /etc/letsencrypt/live/example.com/privkey.pem
fullchain = /etc/letsencrypt/live/example.com/fullchain.pem
[renewalparams]
authenticator = nginx
installer = nginx
server = https://acme-v02.api.letsencrypt.org/directory
key_type = ecdsaStimmt authenticator nicht mehr mit der Realität überein, etwa weil du von nginx auf Apache umgestellt hast, korrigierst du den Wert hier direkt.
Timer oder Cronjob kontrollieren
Auf systemd-Hosts erledigt ein Timer die Ausführung. Je nach Installationsweg heißt er certbot.timer (Distributionspaket) oder snap.certbot.renew.timer (Snap):
$ systemctl list-timers 'certbot*' --all
NEXT LEFT LAST PASSED UNIT ACTIVATES
Tue 2026-08-18 03:14:22 UTC 9h left Mon 2026-08-17 11:47:03 UTC 6h ago certbot.timer certbot.serviceZeigt die Ausgabe keinen Treffer, aktivierst du den Timer:
$ sudo systemctl enable --now certbot.timerAuf Debian und Ubuntu liegt zusätzlich /etc/cron.d/certbot. Der Cronjob prüft selbst, ob systemd läuft, und startet certbot nur auf Hosts ohne systemd. Doppelte Läufe sind dadurch ausgeschlossen.
Passende Infrastruktur bei centron
Absicherung ab Werk: Cloud-Firewalls filtern den Traffic, bevor er die Instanz erreicht – zentral verwaltet. Cloud-Firewalls ansehen →
Wann genau erneuert certbot ein Zertifikat?
Certbot erneuert ein Zertifikat, sobald weniger als 30 Tage Restlaufzeit übrig sind, ab Version 2.9 zusätzlich dann, wenn die ACME Renewal Information (ARI) der Zertifizierungsstelle ein früheres Erneuerungsfenster meldet.
ARI ist der Grund, warum certbot renew zweimal täglich laufen soll, obwohl ein 90-Tage-Zertifikat das rechnerisch nicht braucht. Muss Let's Encrypt ein Zertifikat vorzeitig zurückziehen, signalisiert die CA das über ARI, und certbot erneuert innerhalb weniger Stunden statt erst in Wochen. Jeder Lauf, bei dem nichts fällig ist, endet mit einer Zeile im Log und ohne Netzwerklast bei der CA.
graph TD
A["systemd-Timer certbot.timer"] --> B["certbot renew"]
B --> C["/etc/letsencrypt/renewal/*.conf einlesen"]
C --> D{"Restlaufzeit unter 30 Tage oder ARI-Empfehlung?"}
D -->|nein| E["Zertifikat überspringen"]
D -->|ja| F["ACME-Challenge über Port 80 oder DNS"]
F --> G["Neues Zertifikat nach /etc/letsencrypt/live/"]
G --> H["Deploy-Hook ausführen"]
H --> I["Dienst lädt Zertifikat neu"]
Seit certbot 4.0 lassen sich über --preferred-profile außerdem Ausstellungsprofile der CA wählen, darunter deutlich kurzlebigere Zertifikate. Setze das nur ein, wenn deine Automatik nachweislich zuverlässig läuft: Bei einer Laufzeit von wenigen Tagen bleibt kein Puffer für einen fehlgeschlagenen Renewal-Lauf.
Erreichbarkeit der Challenge sicherstellen
Die http-01-Challenge verlangt, dass die CA http://<deine-domain>/.well-known/acme-challenge/ über Port 80 erreicht, und zwar aus dem gesamten Internet. Eine reine HTTPS-Konfiguration ohne offenen Port 80 bricht die Erneuerung ab, auch wenn die Seite selbst einwandfrei funktioniert. Redirects von 80 auf 443 sind unproblematisch, solange certbot den Pfad vorher ausliefert.
Steht vor dem Host eine stateful Cloud Firewall, gehören Port 80 und 443 dort auf eine Freigabe für 0.0.0.0/0 und ::/0. Eine Einschränkung auf einzelne Quell-IPs funktioniert nicht: Let's Encrypt validiert von wechselnden Adressen und mehrfach aus verschiedenen Regionen. Prüfe die Erreichbarkeit vor dem ersten Testlauf:
$ sudo mkdir -p /var/www/html/.well-known/acme-challenge
$ echo ok | sudo tee /var/www/html/.well-known/acme-challenge/test > /dev/null
$ curl -sS http://<deine-domain>/.well-known/acme-challenge/test
okWer Port 80 nicht öffnen kann oder will, wechselt auf dns-01. Diese Challenge braucht stattdessen API-Zugriff auf den DNS-Provider und ist die einzige Option für Wildcard-Zertifikate.
Erneuerung im Trockenlauf testen
Der Trockenlauf spielt den kompletten Ablauf gegen die Staging-Umgebung von Let's Encrypt durch. Es entstehen keine gültigen Zertifikate, die Dateien unter /etc/letsencrypt/live/ bleiben unverändert, und die Rate Limits der Produktivumgebung werden nicht belastet:
$ sudo certbot renew --dry-run
Processing /etc/letsencrypt/renewal/example.com.conf
Simulating renewal of an existing certificate for example.com and www.example.com
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/example.com/fullchain.pem (success)Diesen Test führst du nach jeder Änderung an der Webserver-Konfiguration aus, insbesondere nach neuen Redirects, geänderten Vhost-Pfaden oder einer neuen Firewall-Regel. Alles, was --dry-run bemängelt, würde auch den echten Lauf zerlegen.
Deploy-Hook für Dienste einrichten
Ein erneuertes Zertifikat auf der Festplatte ändert nichts am laufenden Prozess. nginx, Apache, Postfix und HAProxy halten das alte Material im Speicher, bis sie neu laden. Dafür gibt es Deploy-Hooks: ausführbare Skripte in /etc/letsencrypt/renewal-hooks/deploy/, die certbot nach jeder erfolgreichen Erneuerung startet.
#!/bin/sh
# /etc/letsencrypt/renewal-hooks/deploy/10-reload-nginx.sh
set -e
case "${RENEWED_LINEAGE}" in
/etc/letsencrypt/live/<deine-domain>)
nginx -t && systemctl reload nginx
;;
esacMache das Skript ausführbar, sonst überspringt certbot es kommentarlos bis auf eine Warnung im Log:
$ sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/10-reload-nginx.shDie Variable RENEWED_LINEAGE zeigt auf das Verzeichnis des gerade erneuerten Zertifikats, RENEWED_DOMAINS enthält die betroffenen Domains. Damit testest du den Hook unabhängig von einer echten Erneuerung:
$ sudo RENEWED_LINEAGE=/etc/letsencrypt/live/<deine-domain> /etc/letsencrypt/renewal-hooks/deploy/10-reload-nginx.shDienste, die den privaten Schlüssel als eigener Benutzer lesen, brauchen zusätzlich eine Kopie oder angepasste Rechte. Postfix und Dovecot lesen privkey.pem als root beim Start, ein systemctl reload genügt dort. Anwendungen in Containern brauchen meist einen Neustart des Containers statt eines Reloads.
Verifikation
Prüfe, welches Zertifikat der Dienst tatsächlich ausliefert, nicht nur welches auf der Platte liegt:
$ echo | openssl s_client -connect <deine-domain>:443 -servername <deine-domain> 2>/dev/null | openssl x509 -noout -dates -subject
notBefore=Aug 6 10:22:31 2026 GMT
notAfter=Nov 4 10:22:30 2026 GMT
subject=CN = <deine-domain>Weicht notAfter vom Wert aus certbot certificates ab, wurde das Zertifikat erneuert, der Dienst hat es aber nicht neu geladen. Das ist der klassische Hinweis auf einen fehlenden oder fehlerhaften Deploy-Hook.
Erneuerung überwachen
Let's Encrypt verschickt seit Juni 2025 keine Ablauf-Erinnerungen mehr per E-Mail. Die Überwachung liegt vollständig bei dir. openssl x509 -checkend liefert dafür einen Exit-Code, den jedes Monitoring auswerten kann. Der folgende Aufruf endet mit Status 1, wenn das Zertifikat in weniger als 14 Tagen abläuft:
$ openssl x509 -checkend 1209600 -noout -in /etc/letsencrypt/live/<deine-domain>/cert.pem
Certificate will not expire
$ echo $?
0Ergänzend gehört der Renewal-Lauf selbst ins Log-Monitoring. certbot schreibt ausführlich nach /var/log/letsencrypt/letsencrypt.log, der systemd-Lauf landet im Journal:
$ journalctl -u certbot.service --since "7 days ago" --no-pager
$ sudo grep -E 'error|failed' /var/log/letsencrypt/letsencrypt.log | tail -n 20Ein Alarm auf "Zertifikat läuft in unter 14 Tagen ab" ist die wichtigere Metrik als ein Alarm auf einen einzelnen fehlgeschlagenen Lauf: Bei einem Erneuerungsfenster von 30 Tagen darf certbot durchaus mehrfach scheitern, ohne dass Nutzer etwas merken.
Troubleshooting
Timeout during connect (likely firewall problem): Die CA erreicht Port 80 nicht. Prüfe Firewall-Regeln, Security Groups und ob der Webserver überhaupt auf 0.0.0.0:80 lauscht (sudo ss -tlnp | grep ':80'). Bei IPv6-fähigen Domains muss auch der AAAA-Record erreichbar sein, sonst validiert Let's Encrypt gegen einen toten Endpunkt.
Zertifikat erneuert, Browser zeigt weiter das alte: Der Deploy-Hook fehlt, ist nicht ausführbar oder bricht ab. Kontrolliere mit ls -l /etc/letsencrypt/renewal-hooks/deploy/ die Rechte und führe das Skript wie oben beschrieben manuell aus.
too many certificates already issued: Du bist in ein Rate Limit gelaufen, meist durch wiederholtes --force-renewal. Let's Encrypt erlaubt fünf identische Zertifikate pro Woche. Nutze für Tests ausschließlich --dry-run und warte das Zeitfenster ab, ein zweiter Account löst das Problem nicht.
Zwei ACME-Clients auf einem Host: Läuft neben certbot noch acme.sh oder ein Webserver mit eingebautem ACME-Support, überschreiben sich beide gegenseitig die Konfiguration. Entferne den nicht benötigten Client samt Timer und Cronjob.
Fazit
Die Automatik von certbot besteht aus vier Teilen, die alle stimmen müssen: ein aktiver Timer, eine korrekte Renewal-Konfiguration, ein erreichbarer Challenge-Weg und ein Deploy-Hook, der die Dienste neu lädt. Teste die Kette nach jeder Änderung an Webserver oder Firewall mit certbot renew --dry-run und lege einen Monitoring-Check auf die verbleibende Laufzeit. Damit fällt ein Problem Wochen vor dem Ablaufdatum auf und nicht erst, wenn der Handshake bricht.
Testen Sie Ihr Setup auf ccloud³
Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.