Let's Encrypt Zertifikate sind nur 90 Tage gültig. Automatische Erneuerung stellt sicher, dass Ihre Websites immer mit gültigen Zertifikaten geschützt sind.

Certbot installieren

Debian/Ubuntu

apt update
apt install certbot

# Für Nginx
apt install python3-certbot-nginx

# Für Apache
apt install python3-certbot-apache

CentOS/RHEL

dnf install epel-release
dnf install certbot python3-certbot-nginx

Erstes Zertifikat erstellen

Nginx

certbot --nginx -d example.com -d www.example.com

Apache

certbot --apache -d example.com -d www.example.com

Standalone (ohne Webserver)

certbot certonly --standalone -d example.com

# Port 80 muss frei sein!

Webroot (Webserver läuft)

certbot certonly --webroot -w /var/www/html -d example.com

Automatische Erneuerung

Systemd-Timer (Standard)

# Timer-Status prüfen
systemctl list-timers | grep certbot

# Timer aktivieren
systemctl enable --now certbot.timer

# Timer-Konfiguration
cat /lib/systemd/system/certbot.timer

Manueller Cron-Job

# /etc/cron.d/certbot

0 0,12 * * * root certbot renew --quiet --post-hook "systemctl reload nginx"

Test-Erneuerung

# Dry-Run (kein echtes Erneuern)
certbot renew --dry-run

# Erzwungene Erneuerung (Test)
certbot renew --force-renewal --dry-run

Post-Hooks

Nginx neu laden

certbot renew --post-hook "systemctl reload nginx"

Apache neu laden

certbot renew --post-hook "systemctl reload apache2"

Mehrere Services

certbot renew --post-hook "systemctl reload nginx && systemctl reload postfix"

Hook-Skript

#!/bin/bash
# /etc/letsencrypt/renewal-hooks/post/reload-services.sh

systemctl reload nginx
systemctl reload postfix
systemctl reload dovecot

# Logging
echo "$(date): Zertifikate erneuert" >> /var/log/certbot-renewal.log
chmod +x /etc/letsencrypt/renewal-hooks/post/reload-services.sh

Hook-Verzeichnisse

Struktur

/etc/letsencrypt/renewal-hooks/
├── pre/      # Vor Erneuerung
├── deploy/   # Nach erfolgreicher Erneuerung
└── post/     # Nach jedem Versuch

Pre-Hook (vor Erneuerung)

#!/bin/bash
# /etc/letsencrypt/renewal-hooks/pre/stop-nginx.sh

# Für Standalone-Modus
systemctl stop nginx

Deploy-Hook (nur bei Erfolg)

#!/bin/bash
# /etc/letsencrypt/renewal-hooks/deploy/notify.sh

# Benachrichtigung senden
curl -X POST https://hooks.slack.com/... \
  -d '{"text":"SSL-Zertifikate erneuert"}'

Wildcard-Zertifikate

DNS-Challenge

certbot certonly --manual --preferred-challenges dns \
  -d example.com -d *.example.com

Automatisierung mit DNS-Plugin

# Cloudflare
apt install python3-certbot-dns-cloudflare

# Credentials-Datei
# /etc/letsencrypt/cloudflare.ini
dns_cloudflare_api_token = your-api-token

chmod 600 /etc/letsencrypt/cloudflare.ini

# Zertifikat erstellen
certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d example.com -d *.example.com

Andere DNS-Provider

# Route53 (AWS)
pip install certbot-dns-route53

# DigitalOcean
pip install certbot-dns-digitalocean

# Hetzner
pip install certbot-dns-hetzner

Konfiguration anpassen

renewal.conf

# /etc/letsencrypt/renewal/example.com.conf

[renewalparams]
account = abc123
authenticator = nginx
server = https://acme-v02.api.letsencrypt.org/directory

[[ webroot ]]
example.com = /var/www/html
www.example.com = /var/www/html

Globale Konfiguration

# /etc/letsencrypt/cli.ini

email = admin@example.com
agree-tos = true
no-eff-email = true
preferred-challenges = http
key-type = ecdsa

Monitoring

Ablaufdatum prüfen

# Alle Zertifikate
certbot certificates

# Einzelnes Zertifikat
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -dates

Monitoring-Skript

#!/bin/bash
# /usr/local/bin/check-ssl-expiry.sh

DOMAIN="example.com"
WARN_DAYS=14

EXPIRY=$(echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))

if [ $DAYS_LEFT -lt $WARN_DAYS ]; then
    echo "WARNING: SSL-Zertifikat für $DOMAIN läuft in $DAYS_LEFT Tagen ab!"
    # E-Mail senden
    echo "SSL-Warnung: $DOMAIN" | mail -s "SSL läuft ab" admin@example.com
fi
# Cron-Job
0 8 * * * /usr/local/bin/check-ssl-expiry.sh

Prometheus-Exporter

# ssl_exporter installieren
docker run -d -p 9219:9219 \
  ribbybibby/ssl-exporter

# Abfrage
curl "http://localhost:9219/probe?target=example.com:443"

Mehrere Domains

Zertifikat erweitern

certbot --nginx -d example.com -d www.example.com -d shop.example.com

Separates Zertifikat

certbot --nginx --cert-name shop -d shop.example.com

SAN-Zertifikat

certbot certonly --nginx \
  -d example.com \
  -d www.example.com \
  -d api.example.com \
  -d shop.example.com

Troubleshooting

Erneuerung schlägt fehl

# Detailliertes Log
certbot renew --dry-run -v

# Logs prüfen
tail -f /var/log/letsencrypt/letsencrypt.log

Rate Limits

Let's Encrypt Rate Limits:
- 50 Zertifikate/Woche/Domain
- 5 doppelte Zertifikate/Woche
- 100 Namen/Zertifikat
# Staging-Umgebung für Tests
certbot --nginx --staging -d example.com

Port 80 blockiert

# Prüfen
netstat -tlnp | grep :80

# Firewall
ufw allow 80/tcp

Berechtigungsprobleme

# Verzeichnisrechte
ls -la /etc/letsencrypt/

# Reparieren
chown -R root:root /etc/letsencrypt/
chmod -R 755 /etc/letsencrypt/
chmod 600 /etc/letsencrypt/archive/*/privkey*.pem

Alternative: acme.sh

Installation

curl https://get.acme.sh | sh
source ~/.bashrc

Zertifikat erstellen

acme.sh --issue -d example.com -w /var/www/html

# Nginx
acme.sh --issue -d example.com --nginx

# Standalone
acme.sh --issue -d example.com --standalone

Automatische Erneuerung

# Cron wird automatisch eingerichtet
acme.sh --cron

# Manuell prüfen
crontab -l | grep acme

Zertifikat installieren

acme.sh --install-cert -d example.com \
  --key-file /etc/nginx/ssl/example.com.key \
  --fullchain-file /etc/nginx/ssl/example.com.crt \
  --reloadcmd "systemctl reload nginx"

Docker-Umgebung

Certbot im Container

# docker-compose.yml

services:
  certbot:
    image: certbot/certbot
    volumes:
      - ./certbot/conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"

Mit Nginx

services:
  nginx:
    image: nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./certbot/conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    ports:
      - "80:80"
      - "443:443"
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"

Best Practices

Empfehlungen

1. Automatische Erneuerung aktivieren (Systemd-Timer)
2. Hooks für Service-Reload konfigurieren
3. Monitoring für Ablaufdatum einrichten
4. Staging-Umgebung für Tests nutzen
5. Backups der Zertifikate anlegen

Backup

#!/bin/bash
# Letsencrypt-Backup

tar -czf /backup/letsencrypt-$(date +%Y%m%d).tar.gz /etc/letsencrypt

Wiederherstellung

tar -xzf letsencrypt-backup.tar.gz -C /
certbot renew --force-renewal

Zusammenfassung

| Befehl | Funktion | |--------|----------| | certbot --nginx | Zertifikat für Nginx | | certbot renew | Alle Zertifikate erneuern | | certbot renew --dry-run | Test-Erneuerung | | certbot certificates | Zertifikate auflisten | | certbot delete | Zertifikat löschen |

| Verzeichnis | Inhalt | |-------------|--------| | /etc/letsencrypt/live/ | Aktuelle Zertifikate | | /etc/letsencrypt/archive/ | Alle Versionen | | /etc/letsencrypt/renewal/ | Erneuerungskonfiguration | | /etc/letsencrypt/renewal-hooks/ | Hook-Skripte |

Fazit

Automatische SSL-Erneuerung mit Certbot ist unkompliziert und zuverlässig. Der Systemd-Timer erneuert Zertifikate automatisch vor Ablauf. Mit Post-Hooks werden Dienste automatisch neu geladen. Richten Sie Monitoring ein, um Probleme frühzeitig zu erkennen. Für Wildcard-Zertifikate sind DNS-Plugins die beste Lösung.