Mit dem Certbot kann man zumindest theoretisch sehr einfach zu einem kostenlosen und von den meisten Browsern anerkannten
Server Zertifikat kommen. In der Praxis gibt es jedoch hin und wieder ein paar Stolperfallen, die das Ausrollen des Zertifikats
zu einem Problem lassen werden können.
certbot certonly --rsa-key-size 4096 --webroot -w /var/www/html -d example.com
würde funktionieren, wenn /var/www/html lokal wäre, was bei einer Reverse Proxy Konfiguration i.d.R. nicht der Fall ist.
Der certbot nimmt jedoch nur die URL /.well-known/ für sich in Anspruch, so dass im http Abschnitt der Reverse Proxy Konfiguration
eine Lösung möglich ist. https Configs sind für den certbot nicht relevant, der gibt dem Let’s Encrypt Validation Server immer eine http://… URL mit.
In allen VirtualHost Abschnitten löst folgende Config das Reverse Proxy Problem:
Alias "/.well-known/" "/var/www/html/.well-known/"
RedirectMatch 301 ^(?!/\.well-known/.*) https://example.com
Beim Nginx ist ebenfalls kein großer Config Aufwand notwendig:
location ~ /.well-known/ {
root "/var/www/html/letsencrypt";
}
Jetzt sollte ein certbot Aufruf zu Congratulations… und dem gewünschten Zertifikat führen. Der automatische Renew sollte
auch im Livebetrieb der Anwendung funktionieren, was man mit
certbot renew --dry-run
testen kann. Einmal in der Woche sollte ein
certbot renew --quiet
ausgeführt werden. Im Falle des Zertifikatsupdates muss evtl. der Webserver (Reverse Proxy) neu gestartet werden.
Bei Debian/Ubuntu hat das CLI Tool den Namen letsencrypt und nicht certbot. Hier in Kürze die Aufrufe für Debian artige Distributionen:
letsencrypt certonly --agree-tos --email [email protected] --rsa-key-size 4096 --webroot -w /var/www/html/letsencrypt -d www.example.com -d www2.example.com
letsencrypt renew --dry-run --agree-tos --email [email protected]
letsencrypt renew --quiet --agree-tos --email [email protected]
Wer ein API für seinen DNS Server nutzen kann, kann nun auch sehr einfach Let's Encrypt Wildcard Zertifikate ausstellen lassen:
# New Cert
certbot -d 'example.com' -d '*.example.com' --server https://acme-v02.api.letsencrypt.org/directory --preferred-challenges dns certonly --dns-cloudflare --dns-cloudflare-credentials /usr/local/etc/certbot/cloudflare.ini --rsa-key-size 4096
# Renew
certbot renew --preferred-challenges dns --dns-cloudflare --dns-cloudflare-credentials /usr/local/etc/certbot/cloudflare.ini
Die hier referenzierte Datei cloudflare.ini muss wie folgt aufgebaut sein:
# Cloudflare API credentials used by Certbot
dns_cloudflare_email = [email protected]
dns_cloudflare_api_key = 1234567890...
Den API Key kann man sich nach dem Login bei Cloudflare erstellen bzw. anzeigen lassen.
Wurde das Zertifikat automatisch erneuert, dann sollten die betroffenen Services ebenfalls automatisch neu gestartet werden. Das macht die Option –renew-hook, sie ruft ein Skript auf.
certbot renew --renew-hook /usr/local/bin/renew-letsencrypt
Das Skript kann z.B. folgenden Inhalt haben:
#!/bin/bash
MODE="RELOAD"
WHAT="cf-nginx"
echo "/opt/cftools/renew-letsencrypt called: $RENEWED_DOMAINS"
failed() {
echo "$msg"
exit 1
}
cd /etc/letsencrypt/live/ || ( failed "cd /etc/letsencrypt/live/ failed" )
for i in cert.pem fullchain.pem chain.pem; do
find . -name "$i" | while read line; do
openssl x509 -noout -in "$line" > /dev/null 2> /dev/null
if [ $? -ne 0 ]; then
failed "$line is not a valid certificate"
fi
done
done
find . -name "privkey.pem" | while read line; do
openssl rsa -noout -in "$line" > /dev/null 2> /dev/null
if [ $? -ne 0 ]; then
openssl ec -noout -in "$line" > /dev/null 2> /dev/null
if [ $? -ne 0 ]; then
failed "$line is not a valid private key"
fi
fi
done
for i in "$WHAT"; do
if [ $MODE == "RESTART" ]; then
echo "restart $i"
systemctl stop $i
sleep 2
systemctl start $i
else
echo "reload $i"
systemctl reload $i
fi
done
Geht auch, allerdings signiert Let’s Encrypt mit dem RSA Zertifikat, also bringt das hier noch nichts. Zum Testen kann man natürlich einen eigenen CSR erstellen und es dann damit probieren:
letsencrypt certonly --csr /usr/local/nginx/ssl/example.com.csr --agree-tos --email [email protected] --webroot -w /usr/local/nginx/html -d example.com
Das Thema ist bei Let’s Encrypt aber schon in Arbeit.
Für Postfix, Dovecot etc. ist die Erstellung eines Zertifikats mit certbot ebenfalls kein Problem. Auf dem Mailserver muss die Firewall Port 80 zulassen, da dort jedoch kein http Server läuft, kann certbot diesen temporär bereitstellen.
certbot certonly --standalone -rsa-key-size 4096 -d mail.example.com -d mailin.example.com
Das Let’s Encrypt Zertifikat wird dann wie üblich im Postfix/Dovecot eingebunden.