adr aequinox alix android apt apu artificial-intelligence asa asciidoc auswahl backup bash bewegung bom buecher c cfengine checklisten checkmk cisco citrix computernetz container crypto ddr debian denog deutschland dhcp docker dokumentieren duply dvcs ebtables email epub fairphone2 fairphone3 fairphone5 fedora firewall fossilscm git gns3 gre grep guug hardware i2c iproute ipsec iptables ipv6 kalender konferenz kpartx latex laufen lernen letsencrypt libgcrypt lighttpd linux lua lur make mexiko mikrotik monotone mount mysql netbox netflow nfdump nfsen openvpn openwrt pac paketfilter pcap performance perl podman podman-toolbox postfix programmieren projekt proxmox-ve proxy pxelinux python qubes-os rancid raspi reisen rezension rfc rpm rs232 schreiben script seriell sftp shell software spiel stehen switch sysadmin syslog system systemd termux test troubleshoot ubuntu uci vcs virtualbox virtuell vpn wine wireshark xen xml

Fehler suchen bei Let's Encrypt Zertifikatserneuerung

Bei einigen Servern verwende ich Zertifikate von Let's Encrypt Einer davon aktualisierte seine Zertifikate jedoch nicht automatisch.

Startete ich den Download des Zertifikats von Hand, funktionierte es wunderbar. Rief ich die automatische Aktualisierung auf, funktionierte es nicht.

Bei der Fehlersuche fiel mir auf, dass jedes Mal während der Aktualisierungsversuche folgendes in den Logs des Webservers zu finden war:

[mpm_prefork:notice] [...] AH00170: caught SIGWINCH, shutting down gracefully
[mpm_prefork:notice] [...] AH00163: Apache/2.4.67 (Debian) OpenSSL/3.0.20 configured -- resuming normal operations

Außerdem sah ich keinen Zugriff auf die Challenge-Datei außer den Tests von meinem Rechner, nicht jedoch von Let's Encrypt.

Da ich mit normaler Suche im Web zu keiner Lösung kam, versuchte ich es mit einem Chatbot (nein ich weiß nicht mehr mit welchem). Wirklich hilfreich war die Sitzung nicht, Vermutlich lag es daran, dass ich einerseits dem Chatbot nicht die richtigen Fragen stellte, andererseits zu wenig handfestes eigenes Wissen zum Problem hatte und darum das Geschwätz des Chatbots nicht sofort als Unfug abtat.

Das Problem liegt darin, dass systemd den apache2 runter und hochfährt, wenn eine HTTP-Anfrage via IPv6 kommt.

Das scheint mir im Nachhinein völliger Unsinn. Aber damals war ich ziemlich genervt von dem Problem und hatte mir das als Fazit der Sitzung und Hypothese für die weitere Fehlersuche notiert.

Einige Wochen später, kurz vor Ablauf des Zertifikats habe ich mich dem Problem noch einmal genähert und dazu erneut im Web gesucht. Bei hartnäckigen Fehlern schaue ich auch gern mal mit strace nach, was denn die Programme so veranstalten.

Zunächst schaute ich dem Webserver mit strace über die Schulter, aber da war tatsächlich keine Anfrage von Let's Encrypt zu sehen. Viel mehr gab die Auswertung auch nicht her.

Als nächstes schaute ich certbot bei der Arbeit zu:

sudo strace -f -o certbot.strace certbot renew --dry-run

Hier fand ich nun tatsächlich etwas interessantes:

...
execve("/etc/letsencrypt/renewal-hooks/pre/stop_services", ...
...
execve("/usr/bin/systemctl", ["systemctl", "stop", "apache2"], ...
...

Es war zwar systemd, der den Webserver beendete, aber nicht wegen einer IPv6-Anfrage, sondern weil certbot ihn darum bat.

Das Verzeichnis /etc/letsencrypt/renewal-hooks erregte meine Aufmerksamkeit. In der Certbot-Dokumentation fand ich dazu folgendes:

You can also specify hooks by placing files in subdirectories of Certbot’s configuration directory. Assuming your configuration directory is /etc/letsencrypt, any executable files found in /etc/letsencrypt/renewal-hooks/pre, /etc/letsencrypt/renewal-hooks/deploy, and /etc/letsencrypt/renewal-hooks/post will be run as pre, deploy, and post hooks respectively.

Auf dem betreffenden System sah das Verzeichnis so aus:

$ LANG=C tree /etc/letsencrypt/renewal-hooks
/etc/letsencrypt/renewal-hooks
|-- deploy
|-- post
|   `-- start_services
`-- pre
    `-- stop_services

Auf den anderen Systemen gab es keine Hooks. Ich wollte die Dateien nicht gleich löschen und schaute darum erst einmal hinein:

/etc/letsencrypt/renewal-hooks/pre/stop_services:

#!/bin/bash
echo "stopping service apache2"
systemctl stop apache2
echo "stopping service dovecot"
systemctl stop dovecot
echo "stopping service postfix"
systemctl stop postfix

/etc/letsencrypt/renewal-hooks/post/start_services:

#!/bin/bash
echo "starting service apache2"
systemctl start apache2
echo "starting service dovecot"
systemctl start dovecot
echo "starting service postfix"
systemctl start postfix

Nun war mir klar, was passierte. Beim Aufruf von certbot renewal fuhr certbot den Webserver herunter, bat Let's Encrypt um ein neues Zertifikat, bei dem die Challenge fehlschlug, weil der Webserver nicht erreichbar war. Anschließend startete certbot den Webserver wieder.

In der Datei stop_services entfernte ich die Zeilen, mit denen Apache beendet wurde. In der Datei start_services änderte ich den Aufruf zu systemctl restart apache2.

Damit funktioniert certbot renewal und ich muss mich nicht mehr selbst darum kümmern.

Posted 2026-06-28 Tags:

Fehler suchen bei Let's Encrypt Zertifikatserneuerung
Posted 2026-06-28
Systeme verstehen in Theorie und Praxis (3)
Posted 2026-06-18
Zusammenfassung Mai 2026
Posted 2026-06-07
Ubuntu 22.04 Python Downgrade
Posted 2026-05-25
Systeme verstehen in Theorie und Praxis (2)
Posted 2026-05-10
Zusammenfassung April 2026
Posted 2026-05-03
Container für Citrix ICA Client
Posted 2026-04-12
Zusammenfassung März 2026
Posted 2026-04-05
Systeme verstehen in Theorie und Praxis (1)
Posted 2026-03-31
GUUG Frühjahrsfachgespräch 2026
Posted 2026-03-08