Sebastian Kraus — 14.06.2014
Wenn ein Server von einem kompromittierten Account zum Spammen missbraucht wird, dann möchte man diese Mails gezielt aus der Queue des Mailservers entfernen. Eine Kurzanleitung.
Um bei Postfix bestimmte Mails aus der Queue zu löschen, ist eine erweiterte Kenntnis von Bash-Script-Fuu erforderlich, wenn man diese Vorgänge automatisiern will. Postfix bringt ein eigenes Werkzeug mit, um die Mailqueue zu verwalten und einzusehen.
# postqueue -p
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
BB134DC06EF 298287 Thu Jun 12 10:45:29 mail@example.invalid
(connect to example.invalid[127.0.0.1]:25: Connection timed out)
info@example.invalid
75A7FDC0726 298923 Thu Jun 12 11:37:15 mail@example.invald
(connect to example.invalid[127.0.0.1]:25: Connection refused)
info@example.invalid
-- $n Kbytes in $m Requests.
Erkennbar sind in diesem (anonymisierten) Beispiel, dass sich zwei Emails in der Queue befinden. Jeder Eintrag startet mit der Queue-ID, gefolgt von Datum, Absender, Status und Zieladresse. Mittels des Befehls
# postcat /var/spool/postfix/deferred/7/75A7FDC0726
lässt sich der Inhalt der Email, der Header und einiger Statusinformationen anzeigen:
*** ENVELOPE RECORDS /var/spool/postfix/deferred/7/75A7FDC0726 ***
message_size: 765 188 1 0 765
message_arrival_time: Thu Jun 12 15:04:34 2014
create_time: Thu Jun 12 15:04:34 2014
named_attribute: rewrite_context=local
sender_fullname: root
sender: root@node01.cluster.ticktoo.net
*** MESSAGE CONTENTS ***
Received: by node01.cluster.ticktoo.net (Postfix, from userid 0)
id ...; Thu, 12 Jun 2014 15:04:34 +0200 (CEST)
To: info@example.invalid
Subject: Nachricht
From: "Sender"
Message-Id: <20140612130434.75A7FDC0726@node01.cluster.ticktoo.net>
Date: Thu, 12 Jun 2014 15:04:34 +0200 (CEST)
(INHALT....)
*** MESSAGE FILE END ***
Wenn sie diese Email aus der Queue löschen möchten, verwenden Sie folgenden Befehl:
# postsuper -d 75A7FDC0726
Mit ein wenig Bash-Scripting lässt sich dieses Problem recht einfach lösen. Wir nehmen an, wir wollen alle Mails mit dem Absender "mail@example.invalid" aus der Queue löschen:
# for m in $(postqueue -p | grep "mail@example.invalid" | cut -d\ -f1); do echo postsuper -d $m; done
Wir lassen mittels "postqueue -p" die Queue auslesen und filtern alle Zeilen aus, die uns interessieren. Diese Zeilen schneiden wir mit "cut" auseinander, um nur die erste Spalte mit der Queue-ID zu erhalten. Das ganze läuft in einer for-Schleife, die Message-ID wird in die Variable "m" gespeichert. Anschließend wird mittels echo der Löschbefehl ausgegeben. Wenn das Ergebnis plausibel aussieht (also in etwa der gewünschten Anzahl zu löschender Mails entspricht), kann man mit einem angehängten " | bash" den Befehl tatsächlich ausführen:
# for m in $(postqueue -p | grep "mail@example.invalid" | cut -d\ -f1), do echo postsuper -d $m; done | bash
Anschließend sind alle Mails mit dieser Absenderadresse entfernt.
Will man die Queue anhand von Headerdaten filtern, die nicht in der Queueliste angezeigt werden, kann man direkt auf die Queue zugreifen. Wir wollen in unserer Mailqueue alle Mails löschen, die im Betreff das Wort "VIAGRA" enthalten
# cd /var/spool/postfix/deferred/
# for m in $(fgrep -r "VIAGRA" ./* | sed "s/ matches//g | cut -d/ -f3 ); do echo postsuper -d $m; done
Wir starten mit fgrep direkt im Spool-Verzeichnis eine rekursive Suche in den Queue-Dateien. Wenn ein Treffer gefunden wird, filtern wir mit "sed" ein bisschen Ballast weg und schneiden wieder mit "cut" die relevante Information, die Queue-ID heraus. Der rest läuft wie beim vorherigen Beispiel: der Löschbefehl wird per echo ausgegeben. Ist der Ergebnis plausibel, lässt sich der Befehl mit " | bash" scharfschalten:
# cd /var/spool/postfix/deferred/
# for m in $(fgrep -r "VIAGRA" ./* | sed "s/ matches//g | cut -d/ -f3 ); do echo postsuper -d $m; done | bash
Postfix arbeitet die Nachrichten in der Warteschlange selbständig nach den Regeln der Konfiguration und der einschlägigen RFCs für SMTP ab. Wenn man dennoch den Queue einen Stubs geben möchte, um die Bearbeitung zu starten, hilft folgender Befehl:
# postqueue -f