Tutorials  /  Security

TLS-Zertifikate mit certbot automatisch erneuern

LLudwig · August 2026 ·11 Min. Lesezeit ·Security, Tutorial

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:

Konsole
$ 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.pem

Der Certificate Name ist der Wert, den du später bei --cert-name einsetzt. Er entspricht dem Dateinamen der Renewal-Konfiguration:

ini
# /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 = ecdsa

Stimmt 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):

Konsole
$ 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.service

Zeigt die Ausgabe keinen Treffer, aktivierst du den Timer:

Konsole
$ sudo systemctl enable --now certbot.timer

Auf 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.

SEC

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:

Konsole
$ 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
ok

Wer 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:

Konsole
$ 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.

bash
#!/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
    ;;
esac

Mache das Skript ausführbar, sonst überspringt certbot es kommentarlos bis auf eine Warnung im Log:

Konsole
$ sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/10-reload-nginx.sh

Die 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:

Konsole
$ sudo RENEWED_LINEAGE=/etc/letsencrypt/live/<deine-domain> /etc/letsencrypt/renewal-hooks/deploy/10-reload-nginx.sh

Dienste, 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:

Konsole
$ 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:

Konsole
$ openssl x509 -checkend 1209600 -noout -in /etc/letsencrypt/live/<deine-domain>/cert.pem
Certificate will not expire
$ echo $?
0

Ergä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:

Konsole
$ journalctl -u certbot.service --since "7 days ago" --no-pager
$ sudo grep -E 'error|failed' /var/log/letsencrypt/letsencrypt.log | tail -n 20

Ein 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.

Jetzt 200 € Guthaben sichern

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.

Ludwig Technische Redaktion

Schreibt bei centron über Linux-Administration, Container und Datenbanken – mit Fokus auf Anleitungen, die im Betrieb tatsächlich funktionieren.

Kategorie Security
Teilen
Noch offene Fragen?

Unser Team hilft Ihnen bei Ihrem konkreten Setup weiter – von Menschen, die die Plattform selbst betreiben.

War dieses Tutorial hilfreich?

Ihre Antwort wird anonym gespeichert und hilft uns, die Tutorials zu verbessern.

Kommentare

Noch keine Kommentare – stellen Sie die erste Frage zu diesem Tutorial.

Zum Kommentieren anmelden

Kommentare stehen centron-Kunden offen. Melden Sie sich in Ihrem Konto an, um eine Frage zu diesem Tutorial zu stellen.

Weiterlesen

Das könnte Sie auch interessieren

Jetzt kostenlos anfangen

Melden Sie sich an und erhalten Sie in den ersten 60 Tagen ein Guthaben von 200 € bei centron.

Dieses Werbeangebot gilt nur für neue Konten. Angebot ausschließlich für Gewerbetreibende.

Jetzt loslegen Sales kontaktieren