In meinen Tutorials zu Nextcloud/ownCloud verweise ich ja gerne auf SSL-Zertifikate von Let’s Encrypt. Mit dieser Zertifizierungsstelle können auf einfache Weise TLS-/SSL-Zertifikate erzeugt werden. Auch wenn im privaten Umfeld ein sog. selbst signiertes Zertifikat ausreichen würde, bieten Zertifikate von Let’s Encrypt einen entscheidenden Vorteil: Es handelt sich hierbei um „trusted“ Zertifikate, d.h. dass alle gängigen Browser/Clients stufen diese als vertrauenswürdig ein.
Auch wenn die Erzeugung eines Zertifikats über Let’s Encrypt einfach und schnell von der Hand geht, wird als Kritikpunkt häufig die begrenzte Gültigkeitsdauer aufgeführt: Diese Zertifikate sind aus Sicherheitsgründen nur für einen Zeitraum von 90 Tagen gültig und müssen danach neu generiert werden.
Der folgende Artikel zeigt eine einfache Möglichkeit, wie die Erneuerung von Let’s Encrypt Zertifikaten ganz einfach automatisiert per Cron durchgeführt werden kann.
Update-Historie- 08.01.2018:
- Der Output des Befehls zum Neustarten des Webservers im Cronjob wird nach > /dev/null 2>&1 weitergeleitet, so dass keine E-Mails mehr verschickt werden, wenn ein MTA auf dem System eingerichtet ist.
Warum kein selbst signiertes Zertifikat verwenden?
Selbst signierte Zertifikate haben zwei entscheidende Vorteile:
- Kostenlos, da die Zertifikat-Dateien selbst erzeugt werden können, z.B. mittels OpenSSL (Zertifizierungsstellen lassen sich ihre Dienste immer fürstlich bezahlen).
- Den Gültigkeitszeitraum kann man dabei selbst bestimmen (z.B. 10 Jahre). Einmal generiert, muss man sich in der Regel nicht mehr um das Zertifikat kümmern.
Allerdings gibt es hier immer auch einen massiven Nachteil: Selbst signierte Zertifikate werden von Client-Anwendungen nicht als vertrauenswürdig eingestuft, weil ja kein Dritter (die Zertifizierungsstelle) die Echtheit der Website bestätigen kann. Folglich zeigen Browser hier beispielsweise immer eine sehr deutliche Warnung an:

Andere Clients (z.B. Windows Smartphones bei der Synchronisierung von CardDAV/CalDAV) versagen bei selbst signierten Zertifikaten ihren Dienst.
Diesen Nachteil kann man relativ einfach umgehen: Man installiert das selbst signierte Zertifikat einfach auf sämtlichen Clients. Wie dies z.B. unter Windows bewerkstelligt werden kann, zeigt der Artikel ownCloud auf Ubuntu Server mit nginx, MariaDB und PHP (Abschnitt Zertifikat installieren (nur bei selbst signierten Zertifikaten)).
Dies ist in den meisten Fällen allerdings einfacher gesagt als getan: Solange z.B. für eine selbst gehostete Cloud-Anwendung die Anzahl der Clients überschaubar ist, hält sich der Aufwand hierfür in Grenzen. Aber spätestens wenn viele Clients zum Einsatz kommen, auf die man als Administrator keinen direkten Zugriff hat, wird die Sache kompliziert.
Trotz alledem ist die Verwendung eines selbst signierten Zertifikats nicht unsicher. Solange das Zertifikat richtig erzeugt und eingebunden wurde, ist die Verbindung verschlüsselt (und genau darum geht es ja primär im privaten Umfeld).
Zertifikate mit Let’s Encrypt
Mit einem Zertifikat von Let’s Encrypt hat man die oben genannten Probleme nicht. Wie diese Zertifikate erzeugt werden und beim Webserver nginx eingebunden werden, habe ich bereits im Artikel ownCloud 9 auf Ubuntu Server 16.04 LTS mit nginx, MariaDB, PHP 7 und Let’s Encrypt ausführlich erklärt. Hier nochmal im Schnelldurchgang, ohne auf die genaue Konfiguration des Webservers einzugehen (diese wurde detailliert im oben genannten Artikel erläutert):
Der Webserver muss auf Port 80 erreichbar sein und über eine Domain angesprochen werden können. Hier reicht auch eine DynDNS-Adresse. Ich verwende hier beispielhaft die Adresse meineseite.goip.de (wer auf der Suche nach einem guten, kostlosen DynDNS-Anbieter ist, sollte mal bei GoIP vorbei schauen). Eine IP ist für den Zertifizierungsvorgang übrigens nicht ausreichend.
Zunächst installiert man Let’s Encrypt. Unter Ubuntu Server 16.04 LTS verwendet man dazu folgende Befehle:
apt-get update && apt-get upgrade -V apt-get install letsencrypt
Anschließend kann das Zertifikat erzeugt werden:
letsencrypt certonly --webroot -w /var/www/letsencrypt -d meineseite.goip.de --rsa-key-size 4096
Die Zertifikat-Dateien sind dann im Verzeichnis /etc/letsencrypt/live/meineseite.goip.de zu finden.
Das generierte Zertifikat hat eine Gültigkeitsdauer von 90 Tagen. Spätestens vor dem Ablauf dieser Frist muss das Zertifikat erneuert werden. Dazu ist folgender Befehl ausreichend, damit sämtliche bekannten Zertifikate erneuert werden:
letsencrypt renew
Dies ist zwar nur ein Befehl auf der Kommandozeile und geht recht schnell, aber man sollte dies auf keinen Fall vergessen: Wenn das Zertifikat ungültig wird, werden wieder die Warnungen im Browser angezeigt und man hat wieder die gleichen Probleme wie mit einem selbst signierten Zertifikat.
Automatisierung mit Cron
Diese wichtige Aufgabe kann allerdings auch mittels Cron automatisiert werden. Dazu nutzen wir crontab:
sudo -s crontab -e
Durch das sudo -s ist sicher gestellt, dass der folgende Befehl mit Root-Rechten ausgeführt wird.
Die zu öffnende Datei wird anschließend mit nano (oder jedem anderen beliebigen Texteditor) bearbeitet und folgender Inhalt eingetragen:
40 3 * * 0 letsencrypt renew >> /var/log/letsencrypt-renew.log && /etc/init.d/nginx reload > /dev/null 2>&1
Dieser Befehl sorgt für die Erneuerung der Let’s Encrypt Zertifikate um 03:40 jeden Sonntag. Im Zweiten Schritt wird dann nginx anschließend neu geladen (damit das neue Zertifikat auch korrekt eingebunden wird). Der Zeitpunkt des Cronjobs ist hier willkürlich gewählt. Praktischerweise sollte man einen Zeitpunkt wählen, zu dem der Webserver nicht gerade unter last steht.
Der Output der Zertifikat-Erneuerung wird in der Datei /var/log/letsencrypt-renew.log ausgegeben. Hier kann dann kontrolliert werden, ob der Befehl richtig ausgeführt wurde und ob tatsächlich Zertifikate erneuert wurden (dies ist in der Regel abhängig vom Alter der bestehenden Zertifikate – normalerweise werden Zertifikate erst erneuert, wenn die Gültigkeitsdauer weniger als 30 Tage beträgt).
Die neuen Zertifikate sind anschließend im Verzeichnis /etc/letsencrypt/live zu finden. Von dieser Stelle werden sie auch von nginx eingebunden, daher reicht auch ein reload des Webservers nach dem Aufruf von letsencrypt. Damit für das Neustarten des Webservers keine E-Mail versendet wird – dies passiert automatisch, wenn ein passender MTA (Mail Transfer Agent) konfiguriert ist – wird der Output dieses Befehl mitttels > /dev/null 2>&1 ins „Nirvana“ weitergeleitet.
Die alten Zertifikate werden in den Ordner /etc/letsencrypt/archive verschoben. Werden die archivierten Zertifikate nicht mehr benötigt, kann man diese problemlos löschen.
Trusted Zertifikat mit praktisch unbegrenzter Gültigkeitsdauer
Der Artikel hat gezeigt, wie man mit wenig Aufwand die Erneuerung von Let’s Encrypt Zertifikaten automatisieren kann. Damit hat man immer ein As im Ärmel: ein Zertifikat, welches von allen Clients als vertrauenswürdig eingestuft wird und praktisch eine unbegrenzte Gültigkeitsdauer hat.
Daher nach wie vor mein Tipp: Bevor ihr einfach auf selbst signierte Zertifikate setzt, gebt Let’s Encrypt eine Chance. Ihr werdet damit als Administrator weniger Verwaltungsaufwand haben und die Clients, die auf eure Web-Anwendung zugreifen, werden es euch danken.
Weiterführende Artikel
- ownCloud 9 auf Ubuntu Server 16.04 LTS mit nginx, MariaDB, PHP 7 und Let’s Encrypt
- HTTPS für alle: SSL-Zertifikate mit Let’s Encrypt und nginx
Links
- Let’s Encrypt Homepage (englisch)
- Offizielle Nextcloud Homepage (englisch)
- Offizielle ownCloud Homepage (englisch)
- GoIP (kostenloser DynDNS-Anbieter)
- Why ninety-day lifetimes for certificates? (letsencrypt.org)
- Digitales Zertifikat (Wikipedia)
- Zertifizierungsstelle (Wikipedia)
- Cron (Wikipedia)
- Offizielle OpenSSL Homepage (englisch)
- Mail Transfer Agent (Wikipedia)
Hallo, wie immer ne klasse Anleitung. Für mich als nicht Profi sind alle Anleitungen auf dieser Seite sehr verständlich.
Vielen Dank dafür!
da schließe ich mich gerne an!
einfach super!
Gruß Bernd
Ich hab mal eine Frage zu den angeschlossenen Nextcloud Clients. Wenn ich mich per Nextcloud Windows Client auf den Nextcloud Server verbinde, nehme ich ja auch die https URL des Servers. Dabei muss ich ebenfalls ein Zertifikat annehmen. Muss ich dies dann auch jedesmal annehmen, wenn das Let`s Encrypt Zertifikat erneuert wird?
Danke im Voraus.
Hallo Michael,
wenn das Let’s Encrypt-Zertifikat erfolgreich erstellt und eingebunden wurde, sollte eigentlich keine Warnung mehr in den Nextcloud Clients kommen. Diese Warnung zeigt ja eben genau an, dass etwas mit dem Zertifikat nicht stimmt (nicht trusted, falscher Hostname, der nicht zum Zertifikat passt, etc.).
Was besagt die Warnung bei dir genau? Kannst mir auch gern eine Mail mit Screenshot schicken.
Gruß,
Jan
Danke für die Anleitung. Soweit so gut, aber wie mache ich das, wenn ich ein Zertifikat für Webmail benötige? Das muss ja in die config von roundcube eingetragen werden, habe bisher keinen Weg gefunden, wie man das per Cron lösen kann.
Vielleicht weiß ja jemand mehr? Das Zertifikat von Plesk ist hier keine Lösung.
Edit: im neuen Plesk Onyx kann man jetzt auch ein Zertifikat für Webmail erstellen. Somit hat sich das Problem erledigt.
Hallo Jan,
weißt du zufällig wie lange die alten Zertifikate im Archiv aufbewahrt werden?
Bei jeder Erneuerung wird im Archiv Verzeichnis immer wieder ein neuer Ordner angelegt.
/etc/letsencrypt/archive
Zudem erhalten ich einmal im Monat folgende Info.
Cron lletsencrypt renew >> /var/log/letsencrypt-renew.log && /etc/init.d/nginx reload
Mit dem Inhalt Reload ngnix configuration (via systemctl): ngnix.service
Zusätzlich muss ich dann letsencrypt renew ausführen und erhalte erst dann neue Zertifikate.
Vielen Dank
Gruß Hans
Hi Hans,
wie lange die Zertifikate im Archiv aufbewahrt werden weiß ich leider nicht. Im Zweifelsfall werden die Zertifikat-Dateien jedes mal dort hin kopiert und bleiben einfach dort. Was stört dich daran? Das sind ja keine großen Datenmengen. Wenn du diese unbedingt löschen möchtest, könntest du natürlich den Cronjob entsprechend anpassen oder einen neuen anlegen, der dir dann automatisiert die alten Zertifikate löscht.
Ich verstehe nur nicht, was du mit der zweiten Frage meinst: Wo bekommst du diese Meldung (in einer Log-Datei)? Was mir hier spontan nur auffällt, ist das doppelte ‚l‘, wenn es sich nicht um einen Tippfehler handelt. Einfach mal per contab -e checken, ob die Befehle hier richtig eingegeben wurden. Mein Cronjob läuft schon seit Ewigkeiten problemlos und ich muss mich um das Erneuern der Zertifikate gar nicht mehr kümmern.
Gruß,
Jan
Hallo Jan, habe ich von Postfix bekommen.
Die Zertifikate werden per Cron nicht automatisch erneuert und ich erhalte vom Postfix die genannte Meldung.
Gruß Hans
Hi Hans,
wenn das manuelle Erneuern der Zertifikate klappt, dann stimmt wohl etwas an dem Cron-Job nicht. Daher nochmal kontrollieren.
Was steht im Logfile (/var/log/letsencrypt-renew.log)?
Gruß,
Jan
Hallo Jan,
das Log schaut soweit ganz gut aus. Die Zertifikate müssen am 18.12 erneuert werden, dass warte ich jetzt mal ab und würde mich ggf. dann nochmal melden.
Gruß Hans
Hallo Jan,
im Log (/etc/letsencrypt/renewal/letsencrypt.log) befindet sich folgender Fehler.
Beim Seitenaufruf erhalte ich den Fehler das dass Zertifikat nicht mehr gültig ist.
Traceback (most recent call last):
File „/usr/bin/letsencrypt“, line 9, in
load_entry_point(‚letsencrypt==0.4.1‘, ‚console_scripts‘, ‚letsencrypt‘)()
File „/usr/lib/python2.7/dist-packages/letsencrypt/cli.py“, line 1946, in main
args = prepare_and_parse_args(plugins, cli_args) File „/usr/lib/python2.7/dist-packages/letsencrypt/cli.py“, line 1638, in prepare_and_parse_args
return helpful.parse_args()
File „/usr/lib/python2.7/dist-packages/letsencrypt/cli.py“, line 1206, in parse_args
parsed_args = self.parser.parse_args(self.args)
File „/usr/lib/python2.7/dist-packages/configargparse.py“, line 216, in parse_args
env_vars = env_vars)
File „/usr/lib/python2.7/dist-packages/configargparse.py“, line 349, in parse_known_args
self, args=args, namespace=namespace)
File „/usr/lib/python2.7/argparse.py“, line 1733, in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
File „/usr/lib/python2.7/argparse.py“, line 1939, in _parse_known_args
start_index = consume_optional(start_index)
File „/usr/lib/python2.7/argparse.py“, line 1879, letsencrypt.log
Gruß Hans
Hi Hans,
also bei mir kann ich das Problem nicht nachvollziehen, hier läuft der Cron-Job ordentlich durch.
Hast du an deinem System irgend etwas verändert/neu aufgesetzt? Der Fehler sieht nicht nach einem Fehler in der Webserver-Konfiguration aus, sondern nach einem Fehler in LE selbst.
Daher würde ich erst einmal probieren, was passiert, wenn du die Befehle manuell ausführst, also einfach sudo letsencrypt renew. Wenn hier eine ordentliche Meldung kommt („The following certs are not due for renewal yet“ oder dass das entsprechende Zertifikat korrekt erneuert wurde), dann stimmt etwas mit der Definition des Cron-Jobs nicht. Wenn hier der gleiche Fehler kommt, dann stimmt irgend etwas bei der LE-Installation nicht. Dann würde ich mal die „Erst-Ausstellung“ des Zertifikats probieren (letsencrypt certonly –webroot -w /var/www/letsencrypt -d meineseite.goip.de –rsa-key-size 4096).
Wenn alle Stricke reißen, dann würde ich Lets Encrypt mal neu installieren.
Gruß,
Jan
Hallo,
ich habe gehofft das ich um eine Neuinstallation herum komme.
Leider nein!
Danke jedoch für den Tipp!
Gruß Hans
Hi Hans,
hat es mit der Neuinstallation von LE zumindest funktioniert?
Kamen beim Ausführen der manuellen Kommandos die gleichen Fehlermeldungen?
Gruß,
Jan
Hi Jan,
die gleichen Fehler. Inzwischen erhalte ich diese Meldung.
An unexpected error occurred:
There were too many requests of a given type :: Error creating new cert :: too many certificates already issued for exact set of domains
File „/usr/bin/letsencrypt“, line 9, in
load_entry_point(‚letsencrypt==0.4.1‘, ‚console_scripts‘, ‚letsencrypt‘)()
File „/usr/lib/python2.7/dist-packages/letsencrypt/cli.py“, line 1986, in main
return config.func(config, plugins)
File „/usr/lib/python2.7/dist-packages/letsencrypt/cli.py“, line 706, in obtain_cert
_, action = _auth_from_domains(le_client, config, domains, lineage)
File „/usr/lib/python2.7/dist-packages/letsencrypt/cli.py“, line 474, in _auth_from_domains
lineage = le_client.obtain_and_enroll_certificate(domains)
File „/usr/lib/python2.7/dist-packages/letsencrypt/client.py“, line 269, in obtain_and_enroll_certificate
certr, chain, key, _ = self.obtain_certificate(domains)
File „/usr/lib/python2.7/dist-packages/letsencrypt/client.py“, line 252, in obtain_certificate
return self.obtain_certificate_from_csr(domains, csr) + (key, csr)
File „/usr/lib/python2.7/dist-packages/letsencrypt/client.py“, line 229, in obtain_certificate_from_csr
authzr)
File „/usr/lib/python2.7/dist-packages/acme/client.py“, line 319, in request_issuance
headers={‚Accept‘: content_type})
File „/usr/lib/python2.7/dist-packages/acme/client.py“, line 652, in post
return self._check_response(response, content_type=content_type)
File „/usr/lib/python2.7/dist-packages/acme/client.py“, line 568, in _check_response
raise messages.Error.from_json(jobj)
Error: urn:acme:error:rateLimited :: There were too many requests of a given type :: Error creating new cert :: too many certificates already issued for exact set of domains
Gruß Hans
Hi Hans,
LE unterstützt hat eine Begrenzung für ausgestellte Zertifikate pro Domain: 20/Woche pro registrierter Domain und 5/Woche für erneuerte Zertifikate für eine (Sub-)Domain (siehe hier).
In dieses Problem kann man schnell kommen, wenn man bei einem großen Free-DynDNS-Anbieter ist, wo für viele Subdomains auch viele Zertifikate ausgestellt werden. Die einzige Lösung, die mir dazu spontan einfällt: Eine eigene Sub-Domain, die man als DynDNS-Domain verwendet. Das bieten bereits einige Webspace-Provider an. Hier kommt man dann nicht so schnell ans Limit, außer man versucht in zu kurzer Zeit zu viele Zertifikate für die gleiche Subdomain ausstellen will.
Gruß,
Jan
Hi Jan,
ich nutze ebenfalls die automatische Zertifikats-Erneuerung per Cronjob, wie Du es hier beschrieben hast. Allerdings wurde ich stutzig, dass bereits zwei 90-Tage-Zeiträume abgelaufen sind und ich trotzdem jeden Sonntag eine Mail erhalte, dass noch keine Erneuerung des Zertifikats ansteht. Aber trotzdem habe ich ein aktuelles Zertifikat, denn Zertifikats-Warnung im Browser erhalte ich beim Aufruf meiner Nextcloud nicht. In der Datei /var/log/letsencrypt-renew.log finden sich auch nur Einträge „No renewals were attempted.“.
Dann habe ich gesehen, dass in /var/log/letsencrypt/ für jeden Tag je zwei letsencrypt*.log liegen, die kurz vor 12 Uhr und kurz vor 24 Uhr entstehen. Und hier habe ich dann je eine Datei vom 16. März (Freitag) und 15. Mai (Dienstag) gefunden, in denen die Zertifikats-Erneuerung dokumentiert ist. Das erklärt dann, warum in den Sonntags-Mails keine Erneuerung vermeldet werden konnte. Aber nun meine Frage: Braucht es dann den cronjob sonntags 3:40 Uhr überhaupt? Hat vielleicht das Installieren von Letsencrypt einen Cronjopb, der zweimal täglich läuft, generiert?
Hi Tino,
genau, auf Debian-like Systemen wird bei der Installation von Certbot automatisch ein Certbot-Cronjob eingerichtet, der die Erneuerung der Zertifikate übernimmt. Hier ist es also nicht mehr notwendig, einen Conjob manuell einzurichten.
Sollte eigentlich laufen, wenn nicht, dann kann man später immer noch einen Cronjob per Hand einrichten.
Gruß,
Jan