🌅 Wenn der Mailserver nicht mehr will – wie ein Debian-Update meinen Mailcow-Stack lahmlegt

Ich wache also morgens auf, trinke gemĂŒtlich meinen Kaffee, öffne mein Mail-Interface – und
 Stille. Kein Mailversand, kein Empfang.
Das Login-Interface meiner Mailcow-Instanz (auf einem Hetzner ARM64-Server) lud zwar noch, aber die Mails steckten fest. Der Server konnte nicht einmal mehr eine IP curlen.

Ich ahnte schon: Das war wohl das Debian-Update von letzter Nacht. 🙈


🐍 Der erste VerdĂ€chtige: Unbound

Ein Blick ins docker compose ps offenbarte:

mailcowdockerized-unbound-mailcow-1   ...   unhealthy

Und das Log zeigte den ÜbeltĂ€ter:

curl: (28) Failed to connect to www.internic.net port 443 ...

Unbound wollte beim Start die Root-Hints von internic.net ziehen – doch ohne funktionierendes DNS (ja, Henne-Ei-Problem) blieb er stecken.

Das Resultat:
Mailcow startete zwar, aber alle Container, die auf DNS angewiesen sind – von Postfix bis Rspamd – liefen ins Leere.


⚙ Schritt 1 – Docker wieder Internet geben

Das Debian-Update hatte offenbar das Netzwerk-Setup oder systemd-resolved durcheinandergebracht.
Lösung: Docker bekommt feste Resolver.

cat >/etc/docker/daemon.json <<'JSON'
{
  "dns": ["1.1.1.1", "9.9.9.9"]
}
JSON
systemctl restart docker

Damit hat jeder Container beim Start Zugriff auf Cloudflare und Quad9.


âšĄïž Schritt 2 – Root-Hints manuell nachladen

Da Unbound sich die Root-Zone-Datei nicht mehr ziehen konnte, hab ich sie selbst bereitgestellt:

curl -fsSL https://www.internic.net/domain/named.root -o /tmp/root.hints
docker cp /tmp/root.hints mailcowdockerized-unbound-mailcow-1:/etc/unbound/root.hints
docker exec -it mailcowdockerized-unbound-mailcow-1 sh -c \
  'unbound-anchor -a /var/lib/unbound/root.key -v; chown unbound:unbound /var/lib/unbound/root.key'
docker compose restart unbound-mailcow

Nach einem Neustart war der Container endlich wieder healthy. 🎉


📬 Schritt 3 – „Temporary lookup failure“ beim Mailversand

Doch kaum dachte ich, das System sei wieder heil, kam der nÀchste Schlag:

451 4.3.0 Temporary lookup failure
warning: texthash:/opt/mailcow-dockerized/data/conf/postfix/transport-extra.cf ...

Postfix beschwerte sich ĂŒber eine fehlende Transport-Map.
Diese transport-extra.cf wird standardmĂ€ĂŸig referenziert, existierte aber schlicht nicht mehr.


🔧 Schritt 4 – Postfix in Docker richtig konfigurieren

Das Problem: In den Konfig-Dateien stand ein Host-Pfad (/opt/mailcow-dockerized/...), den der Container gar nicht kennt.
Im Container-Kontext muss die Variable ${config_directory} verwendet werden – sie zeigt auf /etc/postfix.

Ein beherztes Suchen & Ersetzen brachte die Rettung:

grep -Rin "transport-extra\.cf|transport_maps" /opt/mailcow-dockerized/data/conf/postfix
sed -i 's#/opt/mailcow-dockerized/data/conf/postfix/transport-extra\.cf#${config_directory}/transport-extra.cf#g' \
  /opt/mailcow-dockerized/data/conf/postfix/*.cf

Und natĂŒrlich eine leere Datei angelegt, falls sie nicht existiert:

touch /opt/mailcow-dockerized/data/conf/postfix/transport-extra.cf
chmod 644 /opt/mailcow-dockerized/data/conf/postfix/transport-extra.cf
docker compose restart postfix-mailcow

Ab da: keine Lookup-Fehler mehr. đŸ„ł


✅ Fazit – Fehlerursache & Lessons Learned

Der ganze Crash kam durch eine Kettenreaktion:

  1. Debian-Update → systemd-resolved / Docker-DNS gebrochen
  2. Unbound konnte keine Root-Hints laden → „unhealthy“
  3. Postfix bekam keine DNS-Antworten → Lookup-Fehler
  4. ZusĂ€tzlich: Falscher Pfad zu transport-extra.cf → 451-Fehler bei RCPT

Dauerhafte Lösung:

  • Docker mit festen Resolvern (1.1.1.1, 9.9.9.9)
  • Unbound-Root-Hints und Trust-Anchor manuell initialisiert
  • Postfix-Maps auf ${config_directory} umgestellt
  • Leere transport-extra.cf bereitgestellt

Seitdem lĂ€uft der Mailcow-Stack wieder sauber – und ich trinke meinen Kaffee wieder entspannt. ☕

🧠 Bonus-Tipp:
Nach grĂ¶ĂŸeren System-Updates lohnt sich ein schneller Testlauf:

docker inspect -f '{{.State.Health.Status}}' mailcowdockerized-unbound-mailcow-1
docker exec -it mailcowdockerized-postfix-mailcow-1 postconf -n | grep transport_maps

So merkt man sofort, ob Unbound oder Postfix zickt – bevor das erste „Warum bekomme ich keine Mails mehr?“ eintrifft. 😉

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden.