Letsencrypt - Expected cert.pem to be a symlink
Ein kleiner Quickie für meine eigenen Tipps & Tricks Box, falls mir das Problem nochmal passieren sollte.
Ich habe mal wieder einen Server migriert und dabei auch das Letsencrypt Verzeichnis aus /etc/letsencrypt/
mitgenommen.
Irgendwo in dem Prozess scheint ein cp -r
oder rsync
vorhandene Symlinks aufgelöst und daraus Dateien gemacht zu haben.
Oder die alte Letsencrypt Version war veraltet … lässt sich leider nicht mehr verifizieren, da der vorherige Server nicht mehr verfügbar ist.
Beim Setup des Webservers ist nichts aufgefallen und auch certbot
ließ sich ohne Murren installieren.
Auch ein Test des Befehls test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew
aus dem Cronjob /etc/cron.d/certbot
hat keine Fehlermeldung zutage gebracht.
An der Stelle fällt dem geneigten Leser auf, wieso ich den gesamten Befehl kopiert habe: JA, ich habe das -q übersehen
Ein paar Wochen nach dem Setup des Servers bekam ich vom Let’s Encrypt Expiry Bot eine typische Expiry-Email mit dem Titel Let’s Encrypt certificate expiration notice for domain “example.com”.
Randnotiz: wieder mal hat sich bewiesen, dass es sich lohnt die Email Adresse bei der Ausstellung des Zertifikats anzugeben.
Logfile und Fehler
Die Email war ein Weckruf und nach einer kurzen Recherche auf dem Server kam das Logfile /var/log/letsencrypt/letsencrypt.log
zu Tage und
eine Kontrolle eben jenes die Fehlermeldung:
DEBUG:certbot.main:certbot version: 0.40.0
DEBUG:certbot.main:Arguments: ['-q']
DEBUG:certbot.main:Discovered plugins: PluginsRegistry(PluginEntryPoint#manual,PluginEntryPoint#nginx,PluginEntryPoint#null,PluginEntryPoint#standalone,PluginEntryPoint#webroot)
DEBUG:certbot.log:Root logging level set at 30
INFO:certbot.log:Saving debug log to /var/log/letsencrypt/letsencrypt.log
WARNING:certbot.renewal:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/certbot/renewal.py", line 65, in _reconstitute
renewal_candidate = storage.RenewableCert(full_path, config)
File "/usr/lib/python3/dist-packages/certbot/storage.py", line 465, in __init__
self._check_symlinks()
File "/usr/lib/python3/dist-packages/certbot/storage.py", line 522, in _check_symlinks
raise errors.CertStorageError(
certbot.errors.CertStorageError: expected /etc/letsencrypt/live/example.com/cert.pem to be a symlink
2021-01-24 11:24:27,110:WARNING:certbot.renewal:Renewal configuration file /etc/letsencrypt/renewal/example.com.conf is broken. Skipping.
2021-01-24 11:24:27,110:DEBUG:certbot.renewal:Traceback was:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/certbot/renewal.py", line 65, in _reconstitute
renewal_candidate = storage.RenewableCert(full_path, config)
File "/usr/lib/python3/dist-packages/certbot/storage.py", line 465, in __init__
self._check_symlinks()
File "/usr/lib/python3/dist-packages/certbot/storage.py", line 522, in _check_symlinks
raise errors.CertStorageError(
certbot.errors.CertStorageError: expected /etc/letsencrypt/live/example.com/cert.pem to be a symlink
DEBUG:certbot.log:Exiting abnormally:
Traceback (most recent call last):
File "/usr/bin/certbot", line 11, in <module>
load_entry_point('certbot==0.40.0', 'console_scripts', 'certbot')()
File "/usr/lib/python3/dist-packages/certbot/main.py", line 1382, in main
return config.func(config, plugins)
File "/usr/lib/python3/dist-packages/certbot/main.py", line 1287, in renew
renewal.handle_renewal_request(config)
File "/usr/lib/python3/dist-packages/certbot/renewal.py", line 486, in handle_renewal_request
raise errors.Error("{0} renew failure(s), {1} parse failure(s)".format(
certbot.errors.Error: 0 renew failure(s), 1 parse failure(s)
Hervorzuheben ist der relevante Fehler:
Renewal configuration file /etc/letsencrypt/renewal/example.com.conf is broken. Skipping
Was aber nur ein Folgefehler ist des Problems:
certbot.errors.CertStorageError: expected /etc/letsencrypt/live/example.com/cert.pem to be a symlink
Jetzt könnte man hingehen und aus den echten Dateien wieder Symlinks machen, welche in das Verzeichnis /etc/letsencrypt/archive/example.com/
und dort auf die höchste durchnummerierte certX.pem
Datei zeigen.
Falls Du die Lösung bevorzugst, verifizieren lässt sich das Setup im Anschluss mit certbot update_symlinks
.
Meine Lösung
Einfacher ist den folgenden Befehl zu nutzen um alles loszuwerden:
rm -rf /etc/letsencrypt/{live,renewal,archive}/{example.com,example.com.conf}
Siehe auch hier.
Danach nutzt Du den von Dir bevorzugten Weg, um die Zertifikate neu auszustellen.
Das könnte sowas sein wie certbot nginx
oder certbot apache
oder certbot certonly --webroot -w /var/www/example.com -d example.com
.
P.S: Ja, rabiat aber funktional. Aber denk dran: es existiert ein hartes Limit, wie oft man seine Zertifikate in einem bestimmten Zeitraum komplett neu ausstellen lassen kann.