Mail Bounce Management

M

martin zj

Guest
Hallo zusammen

Ich bin gerade nebenbei daran ein kleines Newslettertool zu erstellen. Dieses sollte natürlich ein Bounce Management beinhalten.

Aber genau dieses macht mir ein bisschen Sorgen, denn nun bemerkte ich, dass ich bei den Hard Bounces keine Referenz mehr zu der Mailadresse habe, zu welcher das Mail eigentlich gesendet werden sollte.

Gibt es dafür andere Lösungsansätze als den Inhalt der Mails nach Mailadressen zu durchsuchen?

Freundliche Grüsse, Martin

 
Pack 'ne ID in den Mailfuss. Am besten Schriftfarbe=Hintergrundfarbe.

Hab zwar keine Erfahrung in dem Bereich, aber funktionieren sollte das.
smile.gif
 
Hm, dann müsste man einfach jeweils die Anhänge der Mails durchsuchen, da das versendete Mail meist dort aufzufinden ist. Theoretisch könnte man einem Attribut auch einfach eine ID vergeben die würde der Newsletterempfänger dann auch nicht sehen.

Hat hier noch niemand so etwas realisiert?
 
Ich kenne zwei verschiedene Ansätze. Den einen hatte ich implementiert, war irre aufwendig - und wurde so dann doch nie richtig genutzt. Der andere läuft seit ein paar Wochen auf Server-Daten - und scheint das Problem insgesamt sehr effizient zu lösen:

Erste Technik: Den Mailserver so konfigurieren, daß eine Unzustellbarkeitsnachricht an ein bestimmtes Mailkonto geschickt wird. Das regelmäßig abfragen, die Mail (die bei Microsoft-SMTP als Multipart ankommt) in die Teile zerlegen, das decodieren, im Header der ursprünglichen Mail einen eindeutigen Zufallsschlüssel mitschicken, der ausgelesen und auf die Datenbank, dort auf die Tabelle mit den Mails abgebildet wird.

Zweite Technik, die inzwischen implementiert ist und seit einigen Wochen von mehreren Kunden genutzt wird: Der Datenbankserver startet einen Job, der das Versenden ausführt. Zunächst werden die Mailadressen aus einer Tabelle zusammengesammelt und die Mail individualisiert (Anrede, Abmeldelink bzw. Hinweis zu den Logindaten und zum Nutzernamen). Das wird pro Mail an eine externe gespeicherte Prozedur geschickt, die effektiv eine .NET - Prozedur aufruft. Diese prüft (geht über einen Betriebssystemaufruf von NsLookup), ob es den Domainnamen gibt und ermittelt den MX-Datensatz dafür. Wenn das scheitert, geht das mit einer entsprechenden Fehlernummer zurück. Anschließend wird mit dem TcpClient - Objekt eine Session auf Port 25 zu diesem Server aufgemacht mit im Prinzip folgender Befehlsfolge:

QUOTE HELO intern.server-daten.de (also das übliche Sich-Vorstellen)
MAIL FROM: <Absendermail>
RCPT TO: Empfängermail
QUIT


Läuft das alles korrekt durch, dann gibt es die Mail, anschließend wird die Mail an den lokalen SMTP-Server ausgeliefert, der die Mail tatsächlich verschickt. Gibt es einen Fehler (Antwort beginnt mit 5, bsp. Konto unbekannt), dann liefert die .NET-Prozedur das über einen Statuswert zurück. Das Ergebnis (positiv/negativ) protokolliert die aufrufende Routine in einer Tabelle. Bei einem Fehler wird die Mail als invalide markiert, so daß sie nicht mehr zum Versenden genutzt wird.

Allerdings gab es beim ersten derartigen Versuch stapelweise Fehler. Hintergrund war, daß diverse Mailserver einen merkwürdigen Spamschutz implementieren: Gibt es ein Tripel von Absendemail, Empfänger und Server zum ersten Mal, dann wird die Mail mit einem 450, 451 oder anderem temporären Fehler der 400-Klasse abgelehnt: Try again, greylistet, greylistet - retry in 300 seconds usw. Ein gewöhnlicher Mailserver schickt die Mail einfach nach wenigen Minuten nochmals. Das mußte dann auch für diese Routine implementiert werden - Mails mit 400-Fehler werden in eine Tabelle zwischengespeichert, diese wird nach 6 Minuten erneut abgearbeitet, erneutes Zwischenspeichern der 400-Fehler, erst nach dem dritten Versuch beendet sich diese Routine schließlich.

Praktisch ist das inzwischen ein sehr leistungsfähiges Tool geworden.

Technisch läuft das als einmaliger Sql-Server - Job direkt auf dem Datenbankserver, der Code braucht durchaus eine halbe bis dreiviertel Stunde, falls es solche GreyListed - Mails gibt.
 
Meine Lösung war damals die...

Beim NL-Versand im Header als "From" die normale Mail-adresse und als Return-path eine Adresse folgender Form:
bounce-EINDEUTIGE_ID@domain.de
Ohne in den Quelltext der Mail zu schauen sieht der User i.d.R. den Return-path nicht. Dann für ...@domain.de einen CatchAll eingerichtet und alle Mails die in das CatchAll Postfach eingehen werden untersucht. Ich war zu faul die Bounces zu untersuchen, weshalb einfach alle Mail-Adressen, die einen Bounce erhalten, gelöscht werden.

Geht im Prinzip in Richtung von TSc's Idee, nur dass die ID leichter ohne RegExp o.ä. und zuverlässiger rauszufischen ist.
 
QUOTE (Christian Leo @ Sa 7.02.2009, 00:38) Meine Lösung war damals die...

Beim NL-Versand im Header als "From" die normale Mail-adresse und als Return-path eine Adresse folgender Form:
bounce-EINDEUTIGE_ID@domain.de
Ohne in den Quelltext der Mail zu schauen sieht der User i.d.R. den Return-path nicht. Dann für ...@domain.de einen CatchAll eingerichtet und alle Mails die in das CatchAll Postfach eingehen werden untersucht. Ich war zu faul die Bounces zu untersuchen, weshalb einfach alle Mail-Adressen, die einen Bounce erhalten, gelöscht werden.

Geht im Prinzip in Richtung von TSc's Idee, nur dass die ID leichter ohne RegExp o.ä. und zuverlässiger rauszufischen ist.

Besten Dank für die Informationen.

Sehe ich das richtig dass du für jeden Newsletterempfänger ein eigenes Postfach eingerichtet hast bzw. was bedeutet ein "CatchAll"?

Beste Grüsse Martin
 
Hallo,

Wichtig ist, dass der Server exziplit für den Massenmailversand konfiguriert ist, wenn mehr als 1000 Mails versendet werden - wer bei einem Hosting beispielsweise Massenmails versendet, riskiert bei den meisten Anbietern Schadenersatzforderungen und eine fristlose Kündigung. Rein von der Arbeitsweise würde ich max. 1 Mail pro Sekunde an den Server übergeben, so wird die Warteschlange nicht überlastet (bezogen auf einen normalen Rootserver). Das ganze Zeitmanagement würde ich per Cronjob realisieren.

Gruss Marc
 
Habe gerade gesehen, dass mein Hoster schon sein längerem keine Email Catchall-Funktion zur Verfügung stellt.

Bezüglich dem Versenden hatte ich den Ansatz ca. alle 15min eine bestimmte Anzahl Mails zu versenden, oder gibt es Möglichkeiten rauszufinden wie gross die Warteschleife ist und so direkt jenach Auslastung die zu versendenden Mails zu regulieren?
 
QUOTE (martin zj @ Sa 7.02.2009, 12:47)Bezüglich dem Versenden hatte ich den Ansatz ca. alle 15min eine bestimmte Anzahl Mails zu versenden, oder gibt es Möglichkeiten rauszufinden wie gross die Warteschleife ist und so direkt jenach Auslastung die zu versendenden Mails zu regulieren?

Durch die oben erwähnte Prüfung liegen bei mir ohnehin drei bis fünf Sekunden zwischen zwei Verschickungen.

Angesichts der Dinge, die hier mit PHP erwähnt werden: Verschicken diese Scripte die Mail eigentlich immer direkt oder leiten die das an einen lokalen SMTP-Server weiter, der bsp. die Mail nach 10 Minuten automatisch nochmals zuzustellen versucht, falls der Zielserver nicht erreichbar war?

Das eigentliche Versenden funktioniert innerhalb von Server-Daten immer über einen solchen lokalen SMTP-Server. Der versucht das innerhalb von zwei Tagen nochmals ein paar Mal.


Wenn ein Empfänger so eine oben erwähnte Greylisting-Technik nutzt, dann würde ein direktes Versenden immer per 450/451 beantwortet werden und damit scheitern.
 
Ich liege aber schon richtig damit, dass ich mit PHP keine Möglichkeit habe rauszufinden, ob es eine Mailadresse wirklich gibt? Das einzige was ich rausfinden kann ist, ob es auf einem bestimmter Domain ein MX Eintrag existiert, so würden dann jegliche *gmx.net Adressen zum Beispiel als gültig gelten?

Die Überprüfung auf die Existenz der Mailadressen würde einmal pro Woche statt finden und nicht immer beim Versenden des Newsletters.
 
QUOTE (martin zj @ So 8.02.2009, 19:49)Ich liege aber schon richtig damit, dass ich mit PHP keine Möglichkeit habe rauszufinden, ob es eine Mailadresse wirklich gibt?

Möglich ist das schon.

PHP bietet Unterstützung für Sockets, da kann man dann genau dasselbe machen, was ich in .NET über das TcpClient - Objekt mache.

Das ist eben fummelige Low-Level-Programmierung.
 
QUOTE (Jürgen Auer @ So 8.02.2009, 21:15)
QUOTE (martin zj @ So 8.02.2009, 19:49)Ich liege aber schon richtig damit, dass ich mit PHP keine Möglichkeit habe rauszufinden, ob es eine Mailadresse wirklich gibt?

Möglich ist das schon.

PHP bietet Unterstützung für Sockets, da kann man dann genau dasselbe machen, was ich in .NET über das TcpClient - Objekt mache.

Das ist eben fummelige Low-Level-Programmierung.

Damit kann man dann eigentlich schon den schlimmsten Hard Bounces aus dem Weg gehen und müsste sich nur noch um Hard Bounces kümmern bezüglich Spam oder der genannten Greylist?

Wenn die ReplyAdresse im System bekannt ist, kann man direkt davon ausgehen dass es sich um einen Soft Bounce handelt?
 
QUOTE (martin zj @ So 8.02.2009, 20:35)Damit kann man dann eigentlich schon den schlimmsten Hard Bounces aus dem Weg gehen und müsste sich nur noch um Hard Bounces kümmern bezüglich Spam oder der genannten Greylist?

Wenn die ReplyAdresse im System bekannt ist, kann man direkt davon ausgehen dass es sich um einen Soft Bounce handelt?

Das kann man so allgemein nicht sagen.

Der Server kann temporär nicht erreichbar sein - und die erreichbaren Mailserver schicken einem alles mögliche.

Da kommt auch mal eine Fehlermeldung der 400-Kategorie, wenn das Mailkonto voll oder unbekannt ist, dieselbe Fehlernummer kann es aber wegen so einer Greylisting-Geschichte geben.

400-Fehlerklassen signalisieren 'eigentlich' temporäre Probleme - aber wenn ein 'temporäres Problem' zwei Tage anhält, dann ist die Mail effektiv nicht zustellbar.


Und dein Server muß natürlich so konfiguriert sein, daß er nicht auf eine Spamliste kommt.
 
Ich habe nun mal etwas mit den Sockets ausprobiert. Es ist eigentlich der gleiche Aufruf wie oben erwähnt wurde. Anfgangs dachte ich auch, dass es funktionieren würde, doch dann probierte ich ein paar Adressen aus, von denen ich als Bounce bereits eine 550 zurückbekam. Allerdings wurde mir nun über den Socket Aufruf eine 220 zurückgegen, obwohl die Mailadressen nicht existieren sollten.

Liegt dies am falsch konfigurierten Mailserver meinerseits, oder ist dies eine Spammassnahme der anderen Mailserver, dass einfach alle Anfragen mit einer 220 beantwortet werden, damit man nicht rausfinden kann, ob eine Mailadresse existiert?
 
QUOTE (martin zj @ Mo 9.02.2009, 00:12)Anfgangs dachte ich auch, dass es funktionieren würde, doch dann probierte ich ein paar Adressen aus, von denen ich als Bounce bereits eine 550 zurückbekam. Allerdings wurde mir nun über den Socket Aufruf eine 220 zurückgegen, obwohl die Mailadressen nicht existieren sollten.

Für mich hört sich das danach an, daß deine Socketlogik noch fehlerhaft ist.

Vermutung: Du schickst die Befehle alle hintereinander und siehst aktuell bloß den ersten Teil der Reaktion auf das eröffnende HELO.


Teste das zunächst interaktiv mit

telnet mailserver 25

etwa dem von meiner Hauptdomain sql-und-xml.de:

telnet mx01.schlund.de 25

Dann schicke eine Mail an karlbert@sql-und-xml.de - sprich, an ein eigenes Konto, das definitiv nicht existiert (immer, wenn bei mir karlbert auftaucht
tongue.gif
)


Sofern dein Server nicht blacklistet ist, ist die Reaktion auf das HELO immer freundlich = 220.
 
Für mich funktioniert folgender, simpler Ansatz ganz gut:

Im Header einfach einen eigenen X-Header Eintrag mit eindeutiger ID machen. Da bei einem Bounce zu 99,9% der Original-Header zurückgeliefert wird, muss man nur noch alles nach dem eigenen X-Header Eintrag parsen. Natürlich sollte man was wählen, das immer eindeutig ist:

X-IDmeinesEmpfaengers: 1234567890

 
Zurück
Oben