Ich versuche zu verstehen, wie genau eine E-Mail von Postfix verarbeitet wird - und einige der feineren Details von SMTP-Mail-Transaktionen. Mein kurzfristiges Ziel ist das Debuggen eines proprietären (binären, geschlossenen Quell-) SMTP-Clients, aber ich dachte zuerst, ich würde untersuchen, was bei einer erfolgreichen SMTP-Transaktion passiert.
Ich habe vor, ausgehendes SMTP (Port 25) an unserer LAN-Firewall zu blockieren. Daher habe ich Postfix als internen Mailserver konfiguriert, um E-Mails von (primitiver) lokaler Client-Software zu akzeptieren, die E-Mails nur über nicht authentifiziertes SMTP (über Port 25) senden kann.
Ich habe das Debuggen des Postfix- smtpd
Prozesses aktiviert , indem ich das -v
ausführliche Flag angehängt habe, master.cf
wie unter Fehlerbehebung mit Postfix-Protokollen beschrieben . Ich habe dann eine E-Mail von meiner eigenen Workstation mit Cygwin Mutt mit sSMTP gesendet (eine minimale Implementierung von sendmail
).
Die Postfix-Protokolle zeigen, dass RCPT TO:
Postfix smtpd
der Transaktion nach erfolgreicher Verarbeitung der Leitung und akzeptabler Empfängeradresse eine Warteschlangen-ID zugewiesen und dem SMTP-Client (sSMTP) mit a geantwortet hat 250 OK
.
Anstatt jedoch einen DATA
Befehl auszugeben , gab der SMTP-Client einen aus RSET
, um die aktuelle Mail-Transaktion zurückzusetzen / abzubrechen, und Postfix antwortete mit einem 250 OK
.
Ich habe einige Nachforschungen angestellt, was dieser Befehl bewirkt, und es überrascht nicht, dass das Simple Mail Transfer Protocol, RFC 2821 , die umfassendsten Informationen lieferte:
Dieser Befehl gibt an, dass die aktuelle Mail-Transaktion abgebrochen wird. Alle gespeicherten Absender-, Empfänger- und E-Mail-Daten MÜSSEN verworfen und alle Puffer und Statustabellen gelöscht werden. Der Empfänger MUSS eine Antwort "250 OK" auf einen RSET-Befehl ohne Argumente senden. Ein Rücksetzbefehl kann vom Client jederzeit ausgegeben werden. Es entspricht effektiv einem NOOP (dh wenn es keine Wirkung hat), wenn es unmittelbar nach EHLO ausgegeben wird, bevor EHLO in der Sitzung ausgegeben wird, nachdem ein Datenende-Indikator gesendet und bestätigt wurde oder unmittelbar vor einem QUIT. Ein SMTP-Server darf die Verbindung NICHT als Ergebnis des Empfangs eines RSET schließen. Diese Aktion ist für QUIT reserviert (siehe Abschnitt 4.1.1.10).
Da EHLO eine zusätzliche Verarbeitung und Antwort durch den Server impliziert, ist RSET normalerweise effizienter als die erneute Ausgabe dieses Befehls, obwohl die formale Semantik dieselbe ist.
Entgegen der Absicht dieser Spezifikation gibt es Umstände, unter denen ein SMTP-Server möglicherweise einen Hinweis erhält, dass die zugrunde liegende TCP-Verbindung geschlossen oder zurückgesetzt wurde. Um die Robustheit des Mailsystems zu gewährleisten, MÜSSEN SMTP-Server auf diesen Zustand vorbereitet sein und ihn so behandeln, als ob vor dem Verschwinden der Verbindung ein QUIT empfangen worden wäre.
All dies geschah innerhalb einer Sekunde, sodass es keine Probleme mit Timeouts geben sollte.
In der nächsten Sekunde hat der Client einen weiteren gesendet, RSET
aber der Client hat dann ganze 10 Sekunden gewartet, bevor er mit neu gestartet MAIL FROM:
hat. RCPT TO:
Diesmal folgt er jedoch und gibt den DATA
Befehl aus und die Transaktion wird abgeschlossen (alle innerhalb derselben Sekunde gemäß den Protokollen).
Im Wesentlichen frage ich mich, warum ein SMTP-Client seine eigene Transaktion unterbricht, indem er RSET
Befehle anstelle eines DATA
Befehls ausgibt.
Anmerkungen:
Ich kann die Frage so bearbeiten, dass sie einen Auszug aus der E-Mail-Protokolldatei enthält, aber beim
-v
Debuggen sind sie sehr ausführlich und ich möchte die Leute nicht mit einer Menge irrelevanter Daten überwältigen.Ich habe den sSMTP-Quellcode durchsucht, aber keine Erwähnung gefunden
RSET
.
Antworten:
TLDR
Ich hatte mich gefragt, warum ein SMTP-Client seine eigene Transaktion unterbrechen würde, indem er RSET-Befehle anstelle des DATA-Befehls ausgibt. Die kurze Antwort ist, dass es nicht würde; Dies ist ein Symptom dafür, dass SMTP-Verbindungen von Antivirensoftware abgefangen werden.
Client-Protokollierung
Ich habe die Debug-Option in der Konfiguration für sSMTP aktiviert, aber es hat einige Zeit gedauert, bis ich herausgefunden habe, wie Syslog in Cygwin installiert und konfiguriert wird, damit Nachrichten von Cygwin-Prozessen
/var/log/messages
anstelle der Windows-Ereignisanzeige protokolliert werden .Es wurden jedoch nur die ersten
MAIL FROM:
und dieRCPT TO:
Befehle protokolliert . Es gab keinen Hinweis darauf, dass diese Befehle mehr als einmal gesendet wurden - oder dasssSMTP
jemals einRSET
Befehl gesendet wurde .Wie in meiner Frage erwähnt, hatte ich den sSMTP-Quellcode überprüft, aber es gibt keinen Code zum Senden eines
RSET
Befehls.Symantec Abfangen des SMTP-Verkehrs
Der Benutzer masegaloeh schlug vor, dass Antivirensoftware möglicherweise die SMTP-Pakete ändert - und er hatte Recht: Ich habe Symantec Endpoint Protection auf meinem Computer vorübergehend deaktiviert und die SMTP-Transaktionen wurden wie gewohnt fortgesetzt.
Nach dem erneuten Aktivieren von Symantec Endpoint Protection überwachte ich TCP-Verbindungen mit dem TCPView- Dienstprogramm von Windows Sysinternals und stellte fest, dass der Symantec-
ccSvcHst.exe
Prozess den gesamten TCP-Verkehr mit dem Zielport 25 übertrug.Ich habe eine Verbindung zu Port 25 auf dem Mailserver hergestellt (Netcat funktioniert möglicherweise aufgrund des Abfangens von Symantec nicht ordnungsgemäß), um eine Testmail mithilfe der manuellen Eingabe von SMTP-Befehlen zu senden. Gleichzeitig hatte ich ein anderes Terminalfenster mit einer SSH-Verbindung zum E-Mail-Host geöffnet,
sudo tail -F /var/log/maillog
um gleichzeitig zu überwachen, was der SMTP-Server sah.Das Abfangen durch den Symantec-Proxy ist subtil. Aus Sicht des Mail-Clients gibt es kaum Anzeichen dafür, dass er nicht direkt mit dem SMTP-Server kommuniziert. Die meisten Befehle werden beim Senden an den Mailserver weitergeleitet, und die Antworten entsprechen Ihren Erwartungen. Erst als ich den
DATA
Befehl eingab, begann der Symantec-Proxy, Dinge zu ändern: Er antwortete mit:Dies scheint normal zu sein, aber in Wirklichkeit hätte die Antwort von meinem Postfix-Server sein müssen
Außerdem: Der
DATA
Befehl wurde erst an Postfix weitergeleitet, nachdem ich den Nachrichtentext ausgefüllt und mit einem gefolgt hatteQUIT
.Hinweis: Während ich den Inhalt der Testnachricht eingab, hielt der Symantec-Proxy seine Verbindung zum Postfix-Server durch Ausgabe von
NOOP
Befehlen aufrecht.Umgang mit fehlerhaften SMTP-Clients
In meiner Frage erwähnte ich, dass mein letztendliches Ziel darin bestand, einen proprietären (binären, geschlossenen Quell-) Mail-Client zu beheben, der von meiner Organisation verwendet wird. Ich habe festgestellt, dass dieser Client wirklich fehlerhaft ist: Er sendet einen ungültigen
HELO
Befehl (ohne Hostnamen) und gibt dann einfach auf und wird beendet, nachdem er vom SMTP-Server höflich darüber informiert wurde, dass seine Syntax falsch ist - obwohl ich Postfix so konfiguriert hatte, dass kein erforderlich istHELO
(gültig oder anderweitig).Ich habe dieses Problem behoben, indem ich einen neuen Server mit CentOS 7 installiert habe, dessen Postfix-Version aktuell genug ist, damit ich die Postfix-HELO-Prüfungen vollständig deaktivieren kann (ähnlich wie MS Exchange ungültige HELO-Befehle einfach ignoriert).
Allgemeine Verwendung von RSET
Ich hatte mich auch über die allgemeine Verwendung
RSET
in SMTP-Transaktionen gewundert und im ursprünglichen RFC 821 für SMTP Folgendes gefunden :RSET
würde verwendet werden, wenn sich herausstellen würde, dass die E-Mail-Adresse des Empfängers für einen nicht existierenden Benutzer war. Die folgende SMTP-Transaktion ist ein Beispiel für ein abgebrochenes SMTP-Transaktionsszenario .Wiederverwendung von SMTP-Verbindungen
SMTP-Clients können dieselbe SMTP-Verbindung verwenden, um mehrere Nachrichten an dasselbe Ziel zu senden. Diese Funktion wird von Postfix als SMTP-Verbindungs-Caching bezeichnet . Bei Verwendung dieser Leistungsfunktion sendet Postfix
RSET
vor jedemMAIL FROM
Befehl eine, um zu überprüfen, ob die SMTP-Verbindung noch verwendet werden kann (siehe Postfix-Verbindungscache ).quelle
RSET
wird Postfix diese senden, wenn mehrere E-Mails über dieselbe Verbindung gesendet werden