Newsletter-Krimi

Der verschwundene Newsletter

Seit Jahren liefen die Newsletter des Kunden wie ein Uhrwerk. Max hatte das System damals programmiert:

  • Ein täglicher Newsletter mit frischen Meldungen.
  • Ein wöchentlicher Newsletter mit Zusammenfassungen.

Beide liefen über denselben Mailserver, denselben DKIM-Record, dieselben Routinen. Alles funktionierte. Bis zu jenem Tag, an dem Irmi eine Nachricht weiterleitete:

„Ein Empfänger beschwert sich – er bekommt keine Tages-Newsletter mehr.“

Max runzelte die Stirn. „Komisch. Am Code habe ich nichts geändert.“

Gemeinsam stiegen sie in die Logfiles ein. Schon bald fanden sie eine Spur:

„Reject due to policy restrictions“ – Absender: web.de.

Irmi nickte. „Also blockt nur Web.de?“

„Sieht so aus“, murmelte Max. „Und guck mal: dkim=fail. Aber nur beim Tages-Newsletter. Der Wochen-NL geht problemlos durch.“

Das passte nicht ins Bild. Beide Newsletter liefen durch den gleichen Prozess, nutzten denselben DKIM-Record.

„Vielleicht der DNS-Key?“, überlegte Irmi. Erste Prüfungen bestätigten kleine Formatierungsfehler im DKIM-Record. Sie korrigierten das sofort – doch das Problem blieb.

Die beiden Experten saßen ratlos vor den Kopfzeilen der Mails. „Warum schlägt die Signatur nur beim täglichen Newsletter fehl?“, grübelte Max.

Da kam ihnen die Idee: ChatGPT fragen.

Das KI-Tool untersuchte die Header und erklärte nüchtern:
„Der Fehler liegt nicht am DNS-Key. Die Signaturprüfung scheitert, weil der Body-Hash nicht stimmt. Mit anderen Worten: Der Mail-Body wurde nach dem Signieren verändert.“

Irmi starrte den Bildschirm an. „Der Body wurde nach dem Signieren verändert? Aber wie?“

Nach weiteren Tests zeigte sich: Der HTML-Text des täglichen Newsletters war lang, sehr lang. Manche Zeilen liefen ohne Umbruch über hunderte Zeichen. Und wenn ein weiterleitender Server beschloss, die Zeilen nachträglich zu umbrechen, änderte sich der Body – und damit zerbrach die DKIM-Signatur.

ChatGPT schlug schließlich eine konkrete Code-Änderung vor:

// 3) Body base64-codieren und sauber umbrechen
$body = rtrim(chunk_split(base64_encode($html), 76, "\r\n"));

$headers[] = 'Content-Type: text/html; charset=UTF-8';
$headers[] = 'Content-Transfer-Encoding: base64';

Sie probierten es aus. Newsletter raus – Header prüfen – und da stand es:
dkim=pass

Irmi lachte erleichtert. „Also waren es die unschönen Zeilenumbrüche.“

Max nickte zufrieden. „Genau. Mit base64 und 76 Zeichen pro Zeile erzwingen wir konsistente Umbrüche. \r\n sorgt für saubere Canonicalization. Und UTF-8 plus base64 verhindert, dass ein Relay den Body unterwegs nochmal anfasst.“

Der Fall war gelöst. Der Täter: fehlende Zeilenumbrüche im Body.

Irmi lehnte sich zurück. „Manchmal ist IT wie ein Krimi.“

Max grinste. „Und wir haben den Mörder gefunden.“