messagelabs.com SMTP bricht RFC821/RFC2821?

Erstellt: 17.01.2008, 21:00 | Editiert: 26.10.2018, 05:57 | 7.056 mal angesehen | Eintrag drucken | Kategorie(n): Internet, Linux, qmail

So. Einige Mails von deutschen Firmen werden seit letzter Woche in der Arbeit bis zu 70 Mal innerhalb ca. 4 Tagen eingeliefert. An der infrastruktur oder der Konfiguration im Haus wurde nichts geändert.

Nachdem sichergestellt wurde, daß die Mails sich nicht intern vermehren, sodern wirklich zu Hauf per SMTP abgegeben werden, steht folgendes fest:

  • Es handelt sich um Mails von 4 deutschen Firmen, die auf den ersten Blick nichts gemeinsam haben. Auf den 2. Blick fällt auf, dass alle über Server von messagelabs.com senden. Prima, Outsourcing!
  • recordio vor qmail-smtpd zeigt, dass keine der Mails einen 4xx SMTP-Fehler provoziert, der den sendenden Server denken lassen könnte, die Zustellung wäre fehlgeschlagen.
  • Es zeigt auch, dass der sendende Server keine Mail-Abgabe nach dem Ende (<crlf>.<crlf>) mit einem QUIT beendet, und auch nicht wartet, bis sich mein qmail-Server nach einigen Minuten vergeblichen Wartens mit einem 250 ok xxxxxxxxxxxxx qp xxxxxx bedankt. – Er trennt die Verbindung vorher ([EOF]) und bekommt deswegen das 250 ok ... wahrscheinlich garnicht mehr mit.

muss mein qmail-smtpd ein QUIT abwarten?

In RFC821, Abschnitt 4.1.1., "COMMAND SEMANTICS", steht:

QUIT (QUIT)

This command specifies that the receiver must send an OK reply, and then close the transmission channel.

The receiver should not close the transmission channel until it receives and replies to a QUIT command (even if there was an error). The sender should not close the transmission channel until it send a QUIT command and receives the reply (even if there was an error response to a previous command).

If the connection is closed prematurely the receiver should act as if a RSET command had been received (canceling any pending transaction, but not undoing any previously completed transaction), the sender should act as if the command or transaction in progress had received a temporary
error (4xx).

[…]

The last command in a session must be the QUIT command. The QUIT command can not be used at any other time in a session.

Auf Deutsch:

Der Empfänger sollte den Übertragungskanal nicht schließen, bis er ein QUIT empfangen und bearbeitet hat.

Der Sender sollte den Übertragungskanal nicht schließen, bis er ein QUIT gesendet und die Antwort empfangen hat.

Das letzte kommando in einer Session muss das QUIT-Kommando sein. Das QUIT-Kommando kann zu keiner anderen Zeit in einer session verwendet werden.

RFC 821 ist zwar abgelöst, aber in der nachfolgenden RFC2821, Abschnitt 4.1.1.10, "QUIT (QUIT)" steht:

This command specifies that the receiver MUST send an OK reply, and then close the transmission channel.

The receiver MUST NOT intentionally close the transmission channel until it receives and replies to a QUIT command (even if there was an error). The sender MUST NOT intentionally close the transmission channel until it sends a QUIT command and SHOULD wait until it receives the reply (even if there was an error response to a previous command). If the connection is closed prematurely due to violations of the above or system or network failure, the server MUST cancel any pending transaction, but not undo any previously completed transaction, and generally MUST act as if the command or transaction in progress had received a temporary error (i.e., a 4yz response).

The QUIT command may be issued at any time.

Auf Deutsch:

Dieses Kommando spezifiziert, dass der Empfänger eine OK-Antwort senden und danach den Übertragungskanal schließen muss.

der Empfänger DARF NICHT absichtlich den Übertragungskanal schließen, bevor er ein QUIT-Kommando empfangen und darauf geantwortet hat (Auch nach Fehlern).

Der Sender DARF NICHT absichtlich den Übertragungskanal schließen, bevor er ein QUIT-Kommando gesendet hat und SOLLTE auf eine Antwort darauf warten. (Auch wenn auf das vorherige Kommando eine Fehler-Antwort kam).

Mr. Bernstein

D. J. Bernstein, der Autor von qmail schreibt:

Clients will close connections without QUIT in some circumstances, for example because of a crash, or a message I/O error or timeout after DATA. Servers must not throw away messages that they accepted during such connections.

Was mit RFC2821 absolut einhergeht:

  • Als Client nicht abslichtlich trennen ohne vorhergehendes QUIT
  • Als Server nichts rückgängig machen, was bisher getan wurde

Meine Logs

Erklärung: "< ", also "rechts nach links" ist mein Empfang, ">", also "links nach rechts" ist was ich sende.

So wär’s richtig

Dialog mit einem fremden Mailserver, der "normal" ist:

2008-01-17 18:11:00.720143500 22823 < ------=_Part_4949241_6324
2008-01-17 18:11:00.720146500 22823 <
2008-01-17 18:11:00.720148500 22823 < .
2008-01-17 18:11:00.720151500 22823 < QUIT
2008-01-17 18:11:55.222277500 22823 > 250 ok 1200589915 qp 22844
2008-01-17 18:11:55.222289500 22823 > 221 mail.xxxxxxxxx.de running a Microsoft Exchange replacement that works!
2008-01-17 18:11:55.222550500 tcpserver: end 22823 status 0
2008-01-17 18:11:55.222788500 22823 > [EOF]

Er sendet <crlf>.<crlf> zum Beenden der Mail, danach QUIT, da er keine weiteren Mails mehr für mich hat. 55 Sekunden später antworte ich 250 ok ....

Oder so (auch normaler Server):

2008-01-17 18:17:30.021800500 23325 < ------=_Part_199924_6949
2008-01-17 18:17:30.021828500 23325 <
2008-01-17 18:17:30.021854500 23325 < .
2008-01-17 18:17:30.021881500 23325 < QUIT
2008-01-17 18:18:52.965812500 23325 > 250 ok 1200590332 qp 23339
2008-01-17 18:18:52.966059500 23325 > 221 mail.xxxxxxxxx.de running a Microsoft Exchange replacement that works!
2008-01-17 18:18:52.966411500 23325 > [EOF]
2008-01-17 18:18:52.966757500 tcpserver: end 23325 status 0

Er sendet auch <crlf>.<crlf> zum Beenden der Mail, danach QUIT. 1:22 Minuten später antworte ich 250 ok .... Bissl spät, aber was soll’s. War noch nie ein Problem, wie gesagt.

So geht’s nicht

Das st eine Mail, die von serverXX.towerYY.messagelabs.com kommt:

2008-01-17 16:29:51.975112500 12573 < ------_=_NextPart_001_01C858-
2008-01-17 16:29:51.975115500 12573 < .
2008-01-17 16:33:51.957547500 12573 < [EOF]
2008-01-17 16:34:52.425670500 12573 > 250 ok 1200584092 qp 12584
2008-01-17 16:34:52.426139500 12573 > [EOF]
2008-01-17 16:34:52.426434500 tcpserver: end 12573 status 256

Ein <crlf>.<crlf>, kein QUIT. Stattdessen nach 4 Minuten ohne Antwort von mir ein Disconnect, mein 250 ok ... hört er nicht mehr.

So auch nicht:

2008-01-17 16:44:46.869105500 13972 < delete the material from your it-system.
2008-01-17 16:44:46.869114500 13972 <
2008-01-17 16:44:46.869116500 13972 < .
2008-01-17 16:48:46.775874500 13972 < [EOF]
2008-01-17 16:49:47.253506500 13972 > 250 ok 1200584987 qp 13989
2008-01-17 16:49:47.253651500 tcpserver: end 13972 status 256
2008-01-17 16:49:47.253817500 13972 > [EOF]

Das selbe, nach exakt 4 Minuten ein Disconnect.

Und so auch nicht:

2008-01-17 18:04:43.727334500 22298 < Danke und ciao.
2008-01-17 18:04:43.727336500 22298 < 
2008-01-17 18:04:43.727339500 22298 <
2008-01-17 18:04:43.727341500 22298 < .
2008-01-17 18:08:43.677168500 22298 < [EOF]
2008-01-17 18:09:44.105791500 22298 > 250 ok 1200589784 qp 22315
2008-01-17 18:09:44.106070500 tcpserver: end 22298 status 256
2008-01-17 18:09:44.106159500 22298 > [EOF]

Und wieder nach 4 Minuten.

Zusammenfassung – Meine Seite

Nach RFC2821 verhalte ich mich (fast) korrekt:

This command specifies that the receiver MUST send an OK reply, and then close the transmission channel.

Mache ich, wenn ich das QUIT bekomme.

The receiver MUST NOT intentionally close the transmission channel until it receives and replies to a QUIT command (even if there was an error).

Tue ich nicht. Der Sender trennt.

If the connection is closed prematurely due to violations of the above or system or network failure, the server MUST cancel any pending transaction, but not undo any previously completed transaction …

Ich mache keine ausgeführten Aktionen rückgängig. Die Mail wird zugestellt. Jeeeedes verdammte Mal…

… and generally MUST act as if the command or transaction in progress had received a temporary error (i.e., a 4yz response).

Ich kann nicht mehr antworten, wenn getrennt wurde. Ganz einfach.

Zusammenfassung – Messagelabs

The sender MUST NOT intentionally close the transmission channel until it sends a QUIT command…

Das tut Messagelabs aber – entgegen der RFC.

…and SHOULD wait until it receives the reply (even if there was an error response to a previous command).

Das interessiert Messagelabs nicht.

The QUIT command may be issued at any time.

Sollte Messagelabs.

muss mein qmail-smtpd auf . antworten?

In RFC2821, Abschnitt 4.2.5 "Reply Codes After DATA and the Subsequent ." steht:

When an SMTP server returns a positive completion status (2yz code) after the DATA command is completed with ., it accepts responsibility for:

Wenn ich mit einem 2xx ok... antworte, bin ich für die Mail verantwortlich.

When an SMTP server returns a permanent error status (5yz) code after the DATA command is completed with ., […] The SMTP client retains responsibility for delivery of […]

Wenn ich mit einem 5xx-Fehler antworte, ist der Client für die Mail verantwortlich. Soweit noch nichts von "ich muss antworten". Doch in Abschnitt 6.1, "Reliable Delivery and Replies by Email" steht:

To avoid receiving duplicate messages as the result of timeouts, a receiver-SMTP MUST seek to minimize the time required to respond to the final . end of data indicator. See RFC 1047 [28] for a discussion of this problem.

Also die Antwortzeit von empfangenen <crlf>.<crlf> bis zur Antwort muss vom Server möglichst gering gehalten werden. qmail antwortet hier 4 Minuten nicht.

Ein Fehler in qmail?

RFC1047, "DUPLICATE MESSAGES AND SMTP", sagt:

When the receiving mailer receives this final dot, it is expected to do its final message processing and either confirm receipt of the message (with a 250 reply) or reject the message with any one of several error codes.

Ok, nach <crlf>.<crlf> bearbeiten und Antworten.

Until the sending mailer gets the 250 reply, it must assume the message was not delivered. After the receiving mailer has decided to accept the message, it must assume the message has been delivered to it. If the communications link fails during this synchronization gap, then the message has been duplicated. Both mailers have active copies of the message that they will try to deliver.

Bingo.

Many mailers delay responding to the final dot because they are doing sophisticated processing of the message, in an attempt to confirm that they can deliver the message.

… oder Spamassassin kotzt sich mit der "Alles-auch-in-HTML-Mail" einen ab.

Some mailers can be configured to do more or less processing upon receipt of the final dot. In such situations, the mailer should always be configured to do less processing.

qmail-scanner-queue.pl hat die Mail jeweils laut Log in ca. 5-25 Sekunden durchgecheckt, und auch das Umstellen von qmail-scanner auf sa_fast (Socket statt Netzwerk-Verbindung zu spamd) bringt nichts. Schon ausprobiert.

Weiter heißt es:

Finally, some mailers allow remote mailers only a minute or two to acknowledge the final dot before timing out and trying again. Given the increasing round-trip times on the Internet, and that some processing after the final dot is required, the timeout for reply to the final dot should probably be at least 5 minutes and a timeout of 10 minutes would not be unreasonable.

Ende

Messagelabs wartet exakt 4 Minuten, und trennt dann die Verbindung, ohne ein QUIT zu senden. Das ist gegen die RFC.

Warum qmail nicht gleich auf <crlf>.<crlf> antwortet, ist mir momentan unerklärlich. Kommt ein <crlf>.<crlf> gefolgt von einem QUIT, antwortet qmail innerhalb kürzester Zeit.

Eine Idee wäre ein qmail-SPP Plugin, das nach <crlf>.</crlf> immer mit 220 ok antwortet – aber es gibt keinen Hook für <crlf>.<crlf>, nur für DATA.

Mal sehen, was noch so passiert. Morgen qmail noch einmal kompilieren und weitertesten.

ITStudent.org und andere Seiten berichten auch über wiederkehrende (andere) Probleme mit Messagelabs.

Ähnliches

Seiten und Einträge, gefunden nach Tags.

Schreibe einen Kommentar

Captcha * Time limit is exhausted. Please reload CAPTCHA.