Ich verwende einen Ubuntu 14.04 (Linux) Server. Ich habe Postfix und OpenDKIM sehr gut auf dem Server installiert und konfiguriert . Ich kann E - Mails an mich mit Befehlen wie senden echo hi | sendmail root
und postfix / opendkim fügt Header wie Message-Id
, Date
und DKIM-Signature
, uns darauf , die E - Mail an meine persönliche E - Mail - Adresse, und alles funktioniert super.
Jetzt möchte ich eine Anwendung erstellen, die in einem Docker- Container ausgeführt wird und auf die gleiche Weise E-Mails senden kann. Insbesondere möchte ich mich nicht um das Hinzufügen von Headern wie kümmern Message-Id
und ich möchte nicht sehr viel Konfiguration oder Softwareinstallation innerhalb des Containers selbst durchführen.
Wie geht das am besten?
Gibt es eine Möglichkeit, den Container das sendmail
ausführbare Objekt auf dem Host ausführen zu lassen ?
Ich habe versucht, über das SMTP-Protokoll auf Port 25 von einem Container aus eine Verbindung zu Postfix herzustellen, aber Postfix scheint Nachrichten, die auf diese Weise empfangen wurden, anders zu behandeln. Ich glaube, es wurden keine Header hinzugefügt, sodass die Nachricht von Google Mail als Spam abgewiesen wurde (es war nicht einmal gut genug, um sie in meinem Spam-Ordner abzulegen).
Hier der Maillog-Inhalt
Sep 28 23:35:52 dantooine postfix/smtpd[4306]: connect from unknown[172.17.0.95]
Sep 28 23:35:52 dantooine postfix/smtpd[4306]: DD457889B: client=unknown[172.17.0.95]
Sep 28 23:35:52 dantooine postfix/cleanup[4309]: DD457889B: message-id=<>
Sep 28 23:35:52 dantooine spamd[3175]: spamd: connection from localhost [::1]:59471 to port 783, fd 6
Sep 28 23:35:52 dantooine spamd[3175]: spamd: handle_user (getpwnam) unable to find user: 'someone'
Sep 28 23:35:52 dantooine spamd[3175]: spamd: still running as root: user not specified with -u, not found, or set to root, falling back to nobody
Sep 28 23:35:52 dantooine spamd[3175]: spamd: processing message (unknown) for someone:65534
Sep 28 23:35:52 dantooine spamd[3175]: spamd: clean message (2.5/5.0) for someone:65534 in 0.0 seconds, 331 bytes.
Sep 28 23:35:52 dantooine spamd[3175]: spamd: result: . 2 - MISSING_DATE,MISSING_FROM,MISSING_MID,UNPARSEABLE_RELAY scantime=0.0,size=331,user=someone,uid=65534,required_score=5.0,rhost=localhost,raddr=::1,rport=59471,mid=(unknown),autolearn=no autolearn_force=no
Sep 28 23:35:52 dantooine opendkim[3179]: DD457889B: can't determine message sender; accepting
Sep 28 23:35:53 dantooine postfix/qmgr[3664]: DD457889B: from=<[email protected]>, size=275, nrcpt=1 (queue active)
Sep 28 23:35:53 dantooine postfix/smtpd[4306]: disconnect from unknown[172.17.0.95]
Sep 28 23:35:53 dantooine postfix/smtp[4311]: DD457889B: to=<[email protected]>, relay=gmail-smtp-in.l.google.com[2607:f8b0:4003:c05::1b]:25, delay=0.25, delays=0.12/0.01/0.03/0.09, dsn=5.7.1, status=bounced (host gmail-smtp-in.l.google.com[2607:f8b0:4003:c05::1b] said: 550-5.7.1 [fd17:8b70:893a:44bf:fe73:6c21] Our system has detected that 550-5.7.1 this message is likely unsolicited mail. To reduce the amount of spam 550-5.7.1 sent to Gmail, this message has been blocked. Please visit 550-5.7.1 http://support.google.com/mail/bin/answer.py?hl=en&answer=188131 for 550 5.7.1 more information. su20si7357528oeb.94 - gsmtp (in reply to end of DATA command))
Sep 28 23:35:53 dantooine postfix/cleanup[4309]: 254E688A0: message-id=<[email protected]>
Sep 28 23:35:53 dantooine postfix/bounce[4330]: DD457889B: sender non-delivery notification: 254E688A0
Sep 28 23:35:53 dantooine postfix/qmgr[3664]: 254E688A0: from=<>, size=3374, nrcpt=1 (queue active)
Sep 28 23:35:53 dantooine postfix/qmgr[3664]: DD457889B: removed
Sep 28 23:35:53 dantooine postfix/virtual[4331]: 254E688A0: to=<[email protected]>, relay=virtual, delay=0.01, delays=0/0/0/0, dsn=2.0.0, status=sent (delivered to maildir)
Sep 28 23:35:53 dantooine postfix/qmgr[3664]: 254E688A0: removed
To
Header, einenSubject
Header und einen einzeiligen Text. Ich bin mir nicht sicher, wie ich sagen soll, welche Header Postfix hatte, nachdem es die Milters durchlaufen hat. Weißt du wie? Hier ist die Ausgabe in / var / log / syslog, die zeigt, wie sie von Postfix verarbeitet und von Google Mail abgelehnt wurde: gist.github.com/DavidEGrayson/fbf65c8290c049a1f262Antworten:
Da Sie eine funktionierende Lösung haben, werde ich hier versuchen, ein anderes Verhalten zu erklären, wenn Sie Telnet zu Postfix (SMTP) und wenn Sie Sendmail (Nicht-SMTP) verwenden.
Zu Ihrer Information, OpenDKIM wird per Postfix mit Milter-Mechanismus aufgerufen . Über diese offizielle Dokumentation erhalten Sie einige Informationen zur Implementierung von Milter in Postfix . Hier das Diagramm von Milter Hook in Postfix.
Sie können sehen, dass sendmail-way (non-SMTP) und telnet-way (SMTP) unterschiedliche Verarbeitungsreihenfolgen haben.
Die Nicht-SMTP-E-Mail wird vor dem Einspritzen in milter bereinigt. Cleanup - Dämon war verantwortlich für das Hinzufügen von fehlenden Header: (Resent-) Von :, An :, Message-Id :, und Datum: . Daher hat Ihre E-Mail einen vollständigen Header, wenn sie in OpenDKIM Milter eingespeist wird, selbst wenn die ursprüngliche E-Mail einen unvollständigen Header hatte.
Die SMTP-E-Mail wird an OpenDKIM milter gesendet, bevor eine Bereinigung durchgeführt wird. Wenn Ihre ursprüngliche E-Mail daher einen unvollständigen Header hatte, kann es sein, dass opendkim die Signatur der E-Mail verweigert. Der From: -Header war obligatorisch (siehe RFC 6376 ). Wenn eine E-Mail nicht vorhanden ist, verweigert OpenDKIM das Signieren der E-Mail und gibt eine Warnung aus
Da ich docker nie benutze, weiß ich nicht, welche Einschränkungen sendmail / pickup innerhalb eines Containers hat. Ich denke, die Problemumgehung von David Grayson war sicher genug, um sicherzustellen, dass OpenDKIM die Nachricht signiert.
quelle
From:
Header in Ihre E-Mail hinzuzufügen :)Message-Id
denen ich nicht viel weiß und die ich wahrscheinlich falsch verstehen würde. Es scheint einfacher zu sein, den Cleanup-Daemon sich darum kümmern zu lassen.From
Header. Wenn Sie jedoch eine eigene Nachrichten-ID generieren möchten, können Sie eine Empfehlung wie diese verwenden. IETF DraftSie müssen auf
inet_interfaces
docker bridge (docker0
) in der Postfix-Konfiguration zeigen, die sich unter set befindet/etc/postfix/main.cf
Weitere interne Arbeitsdetails beim Senden von E-Mails vom Docker über Postfix, die auf dem Host installiert sind
quelle
172.17.0.0/16
ummynetworks
in/etc/postfix/main.cf
undservice postfix restart
.Dies ist eine halbe oder zumindest eine getestete Antwort, da ich derzeit das gleiche Problem bearbeite. Ich hoffe, dass jemand helfen kann, das, was ich verpasst habe, zu verdeutlichen.
Die Antwort vom OP (David Grayson) klingt für mich wie eine Neuerfindung der Postdrop-Mail-Spool, aber die Verwendung dieser Mail-Spool klingt nach einem vielversprechenden Ansatz.
Die von postfix bereitgestellte / usr / bin / sendmail-Kompatibilitätsschnittstelle übergibt Mail an postdrop (sgid postdrop), sodass Mail in der Maildrop-Warteschlange unter / var / spool / postfix / maildrop gespeichert werden kann. Dies sollte im Docker-Container geschehen. Der Rest des Postfix sollte hoffentlich nicht im Container laufen müssen.
Ich bin also Host-Mount / var / spool / postfix / maildrop und / var / spool / postfix / public. Ich kann E-Mails in der Host-Umgebung an / var / spool / postfix / maildrop senden lassen, da ich das Warteschlangenverzeichnis für Maildrop angehängt habe. Da ich gemountet habe
/var/spool/postfix/public
,maildrop
kann ich signalisierenpickup
, die Mail aus der Queue zu holen. Leider sind die beteiligten UIDs und GIDs, es sei denn, ich kümmere mich darum, was bedeutet, dass die Abholung im Hostverzeichnis die Spooldateien nicht lesen kann und die Postfix-Installation die Berechtigungen im Maildrop-Verzeichnis in der Hostumgebung durcheinander bringt.Trotzdem scheint dies zu funktionieren:
Obwohl es funktioniert, bin ich nicht sonderlich glücklich mit der harten Kodierung der Uids und Gids. Dies bedeutet, dass nicht überall derselbe Container gezählt werden kann. Ich denke jedoch, dass ich, anstatt das Volume vom Host aus zu mounten, es von einem Container aus mounte, auf dem Postfix ausgeführt wird, niemals Konflikte verursachen werde und ich nur eine Postfix-Installation benötige, um E-Mails von vielen Containern abzurufen. Ich habe diese Uids und Gids in einem Basis-Image festgelegt, von dem alle meine Container erben.
Ich frage mich allerdings, ob dies wirklich ein guter Ansatz ist. Bei einer so einfachen E-Mail-Konfiguration und wenn für den Container kein Daemon verwendet wird, um die Zustellung erneut zu versuchen, ist ein einfacher lokaler MTA wie msmtp möglicherweise besser geeignet. Es würde über TCP an ein Relay auf demselben Host übertragen, auf dem das Spoolen stattfinden würde.
Bedenken hinsichtlich des msmtp-Ansatzes umfassen:
Im Allgemeinen scheint die gemeinsame Postfix-Spool-Methode eher eine fragile Konfiguration zu sein, die eingerichtet werden muss. Es ist jedoch weniger wahrscheinlich, dass sie zur Laufzeit fehlschlägt (Relay nicht verfügbar, sodass E-Mails gelöscht werden).
quelle
Ich habe beschlossen, dass der Container E-Mails in eine Datei in einem bestimmten Verzeichnis schreibt, auf das sowohl vom Container als auch vom Host aus als Docker-Volume zugegriffen werden kann.
Ich habe ein Shell-Skript namens mailsender.sh erstellt, das Mails aus einem angegebenen Verzeichnis liest, sie an sendmail sendet und sie dann löscht:
Ubuntu verwendet Upstart, also habe ich eine Datei mit dem Namen erstellt
/etc/init/mailsender.conf
, um dieses Skript in einen Daemon zu verwandeln:Ich kann den Dienst mit starten und mit
start mailsender
beendenstop mailsender
. Ich kann mir die Logs anschauen/var/log/upstart/mailsender.log
und natürlich mit Hilfe der PID-Datei überwachen.Sie müssen das
/var/mailsend
Verzeichnis erstellen und dann über den Docker-Container zugänglich machen, indem Sie das Argument-v /var/mailsend:/var/mailsend
zu Ihremdocker run
Befehl hinzufügen .quelle