Discourse SMTP sendet „EHLO localhost“ statt Domain, was Google smtp-relay unterbricht

Einige Kontextinformationen: Emails have stopped sending - end of file reached

Vor etwa einer Woche (13. Januar 2021) begannen E-Mails, die über den SMTP-Relay-Server von Google (smtp-relay.gmail.com) gesendet werden sollten, zu versagen (dies ist eine zulässige und beabsichtigte Nutzung für Google Apps-Benutzer).

Sidekiq meldete die Fehler mit EOFErrors:

Jobs::HandledExceptionWrapper: Wrapped EOFError: end of file reached

Und /logs meldete ebenfalls die fehlgeschlagenen Aufgaben:

Job exception: end of file reached

Der Backtrace ist im anderen Beitrag verfügbar.

===================

Die Untersuchung ergab, dass Discourse-Installationen mit dem aktuellen Stand SMTP-Relays mit ‘EHLO localhost’ verbinden – und Google hat dies vor etwa einer Woche abgelehnt.

Aus tcpdump auf einer Produktionsinstanz:

0x0030:  d10f f8e4 4548 4c4f 206c 6f63 616c 686f  ....EHLO.localho
	0x0040:  7374 0d0a                                st..
...
	0x0030:  de62 f0c3 3432 3120 342e 372e 3020 5472  .b..421.4.7.0.Tr
	0x0040:  7920 6167 6169 6e20 6c61 7465 722c 2063  y.again.later,.c
	0x0050:  6c6f 7369 6e67 2063 6f6e 6e65 6374 696f  losing.connectio
	0x0060:  6e2e 2028 4548 4c4f 2920 6a31 3673 6d34  n..(EHLO).j16sm4
	0x0070:  3831 3932 3976 736d 2e31 202d 2067 736d  81929vsm.1.-.gsm
	0x0080:  7470 0d0a                                tp..

Und eine Nachbildung mit telnet ergibt das gleiche Ergebnis:

root@conversation:~# telnet smtp-relay.gmail.com 587
Trying 74.125.137.28...
Connected to smtp-relay.gmail.com.
Escape character is '^]'.
220 smtp-relay.gmail.com ESMTP ls8sm507258pjb.6 - gsmtp
ehlo localhost.localdomain
421 4.7.0 Try again later, closing connection. (EHLO) ls8sm507258pjb.6 - gsmtp
Connection closed by foreign host.

Ein domainspezifisches EHLO funktioniert jedoch ordnungsgemäß:

root@conversation:~# telnet smtp-relay.gmail.com 587
Trying 74.125.137.28...
Connected to smtp-relay.gmail.com.
Escape character is '^]'.
220 smtp-relay.gmail.com ESMTP p10sm668563uaw.3 - gsmtp
ehlo conversation.sevarg.net
250-smtp-relay.gmail.com at your service, [64.227.96.27]
250-SIZE 157286400
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8

======

Basierend auf den Logs habe ich die Datei identifiziert, die zur Prüfung der Korrektur geändert werden muss (im Docker-Image):

/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb

Ändern von

DEFAULTS = {
      :address              => 'localhost',
      :port                 => 25,
      :domain               => 'localhost.localdomain',

in

    DEFAULTS = {
      :address              => 'conversation.sevarg.net',
      :port                 => 25,
      :domain               => 'conversation.sevarg.net',

hat das Problem behoben (nach einem Neustart der Instanz). Der EHLO-Befehl wird nun mit dem Domänenstring gesendet, und E-Mails werden von meiner Instanz ordnungsgemäß versendet.

================

Gewünschtes Verhalten: Beim Versenden von E-Mails verwendet die Standard-Discourse-Installation den konfigurierten Domänennamen für die initiale Verbindung zum SMTP-Server. Alternativ gibt es eine Konfigurationsoption, um die gesendete Domäne zu überschreiben. Falls diese existiert, konnte ich sie durch Suchen nicht finden.

5 „Gefällt mir“

Ich glaube, dass ich diesen Fehler bereits von anderen Personen gesehen habe (die möglicherweise auch keine Google Domains verwendet haben).

Eine langfristige Lösung besteht darin, etwas Magie in deine app.yml einzubauen, die diese Umleitung automatisch für dich durchführt. Hoffentlich wird jedoch stattdessen eine echte Lösung bereitgestellt.

Wenn es einen Weg gibt, dies mit app.yml zu beheben, bin ich natürlich interessiert – mein Domain-Namen im Code hart zu kodieren, damit E-Mails funktionieren, ist eindeutig keine „richtige

Tolle investigative Arbeit, @Syonyk!

Könntest du bitte deine SMTP-Einstellungen aus der Datei app.yml teilen?

2 „Gefällt mir“

Darin befinden sich nichts weiter als die üblichen erforderlichen Einstellungen.

  DISCOURSE_SMTP_ADDRESS: smtp-relay.gmail.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: [E-Mail-Benutzername]
  DISCOURSE_SMTP_PASSWORD: [Passwort]

Könntest du bitte versuchen, eine neue Zeile mit

DISCOURSE_SMTP_DOMAIN: conversation.sevarg.net

hinzuzufügen und es erneut zu versuchen?

3 „Gefällt mir“

Ich habe diese Zeile hinzugefügt und die App neu erstellt (gibt es einen Weg, diesen Schritt zu umgehen?).

Jetzt sehe ich „domain

2 „Gefällt mir“

Dies kann in diesem Block in der Standard-Beispieldatei app.yml hinzugefügt werden:

Halten Sie dies für hilfreich?

1 „Gefällt mir“

Solange es irgendwo dokumentiert ist, bin ich zufrieden.

Allerdings, falls es nicht gesetzt ist, könnte der Code dann den Wert von DISCOURSE_HOSTNAME verwenden (was in fast allen einfachen Fällen korrekt wäre)? Das Senden von ‘localhost’ in EHLO ist im Allgemeinen falsch (zumindest bei der Kommunikation mit einem Server, der sich nicht auf localhost befindet).

Ich denke, es ist eine gute Idee, es in standalone.yml und web_only.yml aufzunehmen.

Ich stimme zu, dass es wahrscheinlich standardmäßig DISCOURSE_HOSTNAME sein sollte. Das scheint auf jeden Fall besser als localhost zu sein. Hat sich das kürzlich geändert?

[quote=“Syonyk, Beitrag: 9, Thema: 176755”]
Wenn es jedoch nicht gesetzt ist, könnte der Code dann den Wert von DISCOURSE_HOSTNAME verwenden (was in fast allen einfachen Fällen korrekt wäre)? Das Senden von „localhost

4 „Gefällt mir“

OK. Ich stimme zu, dass es wahrscheinlich vernünftig ist, auf Nummer sicher zu gehen, aber ich vermute, dass jeder Mailserver, der localhost akzeptiert, auch DISCOURSE_HOSTNAME akzeptieren würde. Ich habe dazu allerdings keine harten Daten. :wink: Dass es in den Standardvorlagen enthalten ist, dürfte wahrscheinlich „gut genug

1 „Gefällt mir“

Ja, aber das Senden von ‘localhost’ (an einen entfernten Host) ist ebenfalls laut RFC falsch.

Meine Hervorhebung.

Ältere RFCs besagen, dass der Server Clients nicht aufgrund der EHLO-Zeichenkette ablehnen sollte, was Google offenbar tut, aber ich sehe diese Formulierung in 5321 nicht.

Ich würde erwarten, dass jeder entfernte Mailserver, der localhost toleriert, auch eine FQDN toleriert (und bevorzugt), wie es der RFC vorschreibt. Ich verstehe den Wunsch, nichts zu beschädigen, aber wie ich die relevanten RFCs lese, ist Discourse standardmäßig schlicht falsch, und dass es funktioniert, ist das Ergebnis übermäßig nachsichtiger entfernter SMTP-Server.

1 „Gefällt mir“

Ich würde mich freuen, einen PR nach ./discourse-setup zu mergen, der dies standardmäßig auf denselben Wert wie DISCOURSE_HOSTNAME setzt, sofern sichergestellt ist, dass dies bei den gängigsten SMTP-Diensten, die wir zur Nutzung empfehlen, unbedenklich ist.

2 „Gefällt mir“

Ich kann die vollständige End-to-End-E-Mail-Zustellung nicht testen, da ich keine Konten habe, aber:

Mailgun

% nc smtp.mailgun.com 587
220 Mailgun Influx ready
ehlo conversation.sevarg.net
250-smtp-out-n04.prod.us-west-2.postgun.com
250-AUTH PLAIN LOGIN
...

Sendgrid

% nc smtp.sendgrid.net 587
220 SG ESMTP service ready at ismtpd0021p1las1.sendgrid.net
ehlo conversation.sevarg.net
250-smtp.sendgrid.net
250-8BITMIME
...

Mailjet

 % nc smtp.mailjet.com 587
220 in.mailjet.com ESMTP Mailjet
ehlo conversation.sevarg.net
250-smtpin.mailjet.com
250-PIPELINING
...

ElasticMail

… reagiert wirklich nicht auf irgendeine Art von Helo- oder Ehlo-Befehl. o.O Weder auf localhost noch auf echte Domains.

Ich denke, die Einstellung während der Einrichtung vorzunehmen, ist die richtige Lösung, da sie zumindest für die Nutzer sichtbar ist und bei Bedarf geändert werden kann.

6 „Gefällt mir“

Es gibt ein weiteres verwandtes Problem: discourse-doctor scheint die Domain nicht ordnungsgemäß zu setzen und schlägt weiterhin fehl, selbst wenn die eigentliche Installation E-Mails versenden kann.

Bei der funktionierenden Konfiguration meldet discourse-doctor weiterhin das Fehlerereignis „End of file reached".

======================================== ERROR ========================================
                                    UNEXPECTED ERROR

end of file reached

====================================== SOLUTION =======================================
Dies ist kein häufiger Fehler. Es gibt keine empfohlene Lösung!

Bitte melden Sie die genaue Fehlermeldung oben unter https://meta.discourse.org/
(und eine Lösung, falls Sie eine finden!)
=======================================================================================

Im Testskript wird SMTP_DOMAIN nicht erwähnt.

root@conversation:/var/discourse# grep SMTP_DOMAIN discourse-doctor
root@conversation:/var/discourse#

Und tcpdump zeigt, dass discourse-doctor beim Ausführen weiterhin „localhost" im EHLO-Befehl sendet. Auch dies muss behoben werden.

	0x0030:  cccd b12c 4548 4c4f 206c 6f63 616c 686f  ...,EHLO.localho
	0x0040:  7374 0d0a                                st..
...
	0x0030:  e247 1aa5 3432 3120 342e 372e 3020 5472  .G..421.4.7.0.Tr
	0x0040:  7920 6167 6169 6e20 6c61 7465 722c 2063  y.again.later,.c
	0x0050:  6c6f 7369 6e67 2063 6f6e 6e65 6374 696f  losing.connectio
	0x0060:  6e2e 2028 4548 4c4f 2920 6e6d 3773 6d31  n..(EHLO).nm7sm1
	0x0070:  3032 3832 3139 706a 622e 36 20 2d20 6773  028219pjb.6.-.gs
	0x0080:  6d74 700d 0a                             mtp..

Das ist nicht discourse-doctor, sondern emails.rake:

Ah, und es scheint, als würde es localhost verwenden. Ich vermute, es sollte auf #{ENV["DISCOURSE_SMTP_PORT"]} verweisen – oder vorerst auf DISCOURSE_SMTP_DOMAIN.

@falco sind wir uns sicher, dass dies schon immer so war und es sich nicht um einen kürzlich aufgetretenen Fehler handelt?

Ich erinnere mich an Probleme im Zusammenhang mit dem Senden von

ehlo {invalid domain}

aus sehr früher Zeit, daher würde es mich sehr wundern, wenn wir ehlo localhost über einen langen Zeitraum hinweg falsch gesendet hätten?

1 „Gefällt mir“

Entschuldigung, ich melde nur, was ich sehe. Ich bin mir ziemlich sicher, dass auch ‘localhost’ dort falsch ist. Meine Webentwicklung ist größtenteils veraltet; es ist über ein Jahrzehnt her, dass ich professionell mit solchen Dingen gearbeitet habe. Bis zu dem Punkt, den ich erreicht habe, hat einige Zeit gedauert. Docker & Ruby & Ähnliches sind allesamt relativ neu für mich. tcpdump hingegen… das kenne ich. :wink:

Ich bleibe trotzdem dabei: ‘localhost’ an einen entfernten Server zu senden, ist in jeder Situation das falsche Verhalten.

1 „Gefällt mir“

Nur zur Information: Wir erleben seit dem 13. Januar exakt das gleiche Problem. Die letzte erfolgreich gesendete E-Mail war am 13. Januar, und wir verwenden ebenfalls smtp-relay.gmail.com. Wir haben noch nicht herausgefunden, wie wir dies umgehen können (ohne den Quellcode zu ändern).