Korzystam z serwera Ubuntu 14.04 (Linux). Zainstalowałem i skonfigurowałem Postfix i OpenDKIM bardzo ładnie na serwerze; Mogę wysyłać e-maile do siebie za pomocą poleceń takich jak echo hi | sendmail root
, i postfix / opendkim doda nagłówki takie jak Message-Id
, Date
i DKIM-Signature
, przesyła e-maila do mojego osobistego adresu e-mail, a wszystko działa świetnie.
Teraz chciałbym utworzyć aplikację, która działa w kontenerze Docker i może wysyłać wiadomości e-mail z taką samą łatwością. W szczególności nie chcę się martwić dodawaniem nagłówków, takich jak Message-Id
, i nie chcę przeprowadzać dużej konfiguracji ani instalacji oprogramowania w samym kontenerze.
Jak najlepiej to zrobić?
Czy jest jakiś sposób, aby kontener mógł uruchomić sendmail
wymaganie na hoście?
Próbowałem nawiązać połączenie z Postfix z kontenera za pomocą protokołu SMTP na porcie 25, ale Postfix wydaje się traktować wiadomości otrzymane w ten sposób inaczej; Myślę, że nie dodał żadnych nagłówków, więc wiadomość została odrzucona jako spam przez Gmaila (nie była nawet wystarczająco dobra, aby umieścić ją w folderze Spam).
Oto treść maillog
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
nagłówek,Subject
nagłówek i treść jednowierszową. Nie jestem pewien, jak powiedzieć, jakie nagłówki miał po tym, jak Postfix przejrzał go przez miltersy, wiesz jak? Oto wynik w / var / log / syslog pokazujący, jak został przetworzony przez Postfix i odrzucony przez Gmaila: gist.github.com/DavidEGrayson/fbf65c8290c049a1f262Odpowiedzi:
Ponieważ masz działające rozwiązanie, w tym miejscu postaram się wyjaśnić inne zachowanie podczas łączenia się telnet z postfixem (SMTP) i podczas korzystania z sendmaila (nie SMTP).
Do Twojej wiadomości, OpenDKIM zostanie wywołany przez postfiks z mechanizmem Miltera . Możesz uzyskać informacje o tym, jak milter implementacji w Postfiksie za pośrednictwem tej oficjalnej dokumentacji . Oto schemat haka miltera w postfiksie.
Widać, że sendmail-way (non-SMTP) i telnet-way (SMTP) ma inną kolejność przetwarzania.
Wiadomość e-mail inna niż SMTP zostanie przetworzona przez czyszczenie przed wstrzyknięciem do programu milter. Oczyszczanie demon był odpowiedzialny za dodanie brakujących nagłówków: (Resent-) Od :, Do :, Message-ID :, i Data: . Dlatego twój e-mail będzie miał pełny nagłówek po wstrzyknięciu do OpenDKIM, nawet oryginalny e-mail miał niekompletny nagłówek.
Wiadomość e-mail SMTP zostanie wstrzyknięta do Miltera OpenDKIM przed jakimkolwiek przetwarzaniem czyszczenia. Dlatego jeśli twój oryginalny e-mail miał niekompletny nagłówek, opendkim może odmówić podpisania e-maila. From: header było obowiązkowe (patrz RFC 6376 ) oraz jeśli e-mail nie ma, OpenDKIM odmówi podpisania e-mail i daje ostrzeżenie
Ponieważ nigdy nie korzystam z dokera, nie wiem, jakie ograniczenie wysyłania / odbierania w kontenerze. Myślę, że obejście Davida Graysona było wystarczająco bezpieczne, aby zapewnić podpisanie wiadomości przez OpenDKIM.
źródło
From:
nagłówka w eMessage-Id
których nie wiem zbyt wiele i prawdopodobnie pomyliłbym się… wydaje się, że łatwiej jest zająć się tym demon czyszczenia.From
nagłówkiem. Ale jeśli chcesz wygenerować własny identyfikator wiadomości, możesz użyć rekomendacji takiej jak ten IETF DraftMusisz wskazać
inet_interfaces
na docker bridge (docker0
) w konfiguracji Postfiksa znajdującej się w zestawie/etc/postfix/main.cf
Więcej wewnętrznych szczegółów roboczych na temat wysyłania wiadomości e-mail-z-dokera-przez-Postfiksa-zainstalowanego na hoście
źródło
172.17.0.0/16
namynetworks
w/etc/postfix/main.cf
iservice postfix restart
.To jest połowa odpowiedzi lub przynajmniej połowa przetestowana, ponieważ obecnie pracuję nad tym samym problemem. Mam nadzieję, że ktoś może pomóc w zrozumieniu tego, co przegapiłem.
Odpowiedź od OP (David Grayson) brzmi dla mnie jak ponowne wynalezienie szpuli pocztowej, ale użycie tej szpuli brzmi jak obiecujące podejście, więc tutaj doszedłem.
Interfejs kompatybilności / usr / bin / sendmail zapewniany przez postfix przekazuje pocztę do postdropa, czyli sgid postdrop, pozwalając mu przechowywać pocztę w kolejce maildrop w / var / spool / postfix / maildrop. Powinno to nastąpić w kontenerze dokera. Pozostała część postfiksa nie powinna być uruchamiana w kontenerze.
Więc jestem hostem montującym / var / spool / postfix / maildrop i / var / spool / postfix / public. Mogę dostać pocztę dostarczoną do / var / spool / postfix / maildrop w środowisku hosta, ponieważ zamontowałem katalog kolejek maildrop. Ponieważ mam zamontowane
/var/spool/postfix/public
,maildrop
może sygnalizować,pickup
aby odebrać pocztę z kolejki. Niestety, zaangażowane identyfikatory i identyfikatory, chyba że się tym zajmę, co oznacza, że pobieranie w katalogu hosta nie może odczytać zbiorów buforowych, a co gorsza instalacja Postfiksa zakłóca uprawnienia do katalogu maildrop w środowisku hosta.Wydaje się jednak, że to działa:
Chociaż działa, nie jestem zbytnio zadowolony z twardego kodowania UID i GID. Oznacza to, że nie można policzyć tego samego kontenera, aby uruchomić go wszędzie. Wydaje mi się jednak, że jeśli zamiast montować wolumin z hosta, podłączę go z kontenera z postfixem, to nigdy nie spowoduje konfliktu i potrzebuję tylko jednej instalacji postfixa, aby wydostać pocztę z wielu kontenerów. Uids i gids ustawię na podstawowym obrazie, z którego odziedziczą wszystkie moje pojemniki.
Zastanawiam się jednak, czy to naprawdę dobre podejście. Przy tak prostej konfiguracji poczty i braku kontenera używanego w kontenerze do ponownej próby dostarczenia, bardziej odpowiedni może być prostszy lokalny MTA, taki jak msmtp. Dostarczałby przez TCP do przekaźnika na tym samym hoście, gdzie miałoby miejsce buforowanie.
Obawy związane z podejściem msmtp obejmują:
Ogólnie rzecz biorąc, współużytkowane buforowanie postfiksów wydaje się bardziej prawdopodobne, że jest to delikatna konfiguracja do skonfigurowania, ale rzadziej zawiedzie w czasie wykonywania (przekaźnik niedostępny, więc poczta spadła).
źródło
Zdecydowałem, że sposób, w jaki kontener wysyła pocztę, polega na zapisaniu jej do pliku w określonym katalogu, który będzie dostępny zarówno z kontenera, jak i hosta jako „wolumin” Dockera.
Stworzyłem skrypt powłoki o nazwie mailsender.sh, który odczytuje wiadomości z określonego katalogu, wysyła je do sendmaila, a następnie usuwa je:
Ubuntu używa upstart, więc utworzyłem plik o nazwie,
/etc/init/mailsender.conf
aby zmienić ten skrypt w demona:Mogę uruchomić usługę
start mailsender
i zatrzymać jąstop mailsender
. Mogę patrzeć na jego logi/var/log/upstart/mailsender.log
i oczywiście mogę monitorować za pomocą pliku PID.Musisz utworzyć
/var/mailsend
katalog, a następnie udostępnić go z kontenera Docker, dodając argument-v /var/mailsend:/var/mailsend
dodocker run
polecenia.źródło