Ana bilgisayarın Postfix'i ile Docker kapsayıcısından posta gönderme


18

Bir Ubuntu 14.04 (Linux) sunucusu çalıştırıyorum. Ben yüklü ve yapılandırılmış olması Postfix'i ve OpenDKIM sunucuda çok güzel; Ben gibi komutlarla kendime e-posta gönderebilirsiniz echo hi | sendmail rootve postfix / opendkim gibi başlıkları katacak Message-Id, Dateve DKIM-Signatureileri email benim kişisel e-posta adresine ve her şey iyi çalışıyor.

Şimdi bir Docker kapsayıcısında çalışan ve aynı kolaylıkla e-posta gönderebilen bir uygulama oluşturmak istiyorum . Özellikle, gibi üstbilgiler eklemek konusunda endişelenmek Message-Idistemiyorum ve kabın içinde çok fazla yapılandırma veya yazılım yüklemesi yapmak istemiyorum.

Bunu yapmanın en iyi yolu nedir?

Konteynerin sendmailana bilgisayarda exectuable'ı çalıştırmasına izin vermenin bir yolu var mı ?

Bağlantı noktası 25 üzerinde SMTP protokolü kullanarak bir kapsayıcıdan Postfix bağlantısı kurmaya çalıştım, ancak Postfix bu şekilde alınan iletileri farklı şekilde ele alıyor gibi görünüyor; Mesajın gmail tarafından spam olarak reddedilmesi için herhangi bir üstbilgi eklemediğini düşünüyorum (Spam klasörüne yerleştirilecek kadar iyi değildi).

İşte maillog içeriği

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=<whoever@example.com>, 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=<someone@gmail.com>, 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=<20140928233553.254E688A0@myserver.example.com>
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=<whoever@example.com>, 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

Lütfen e-postanızın başlığını (GMAIL tarafından spam olarak tanımlanmış olanı)
gönderin

Göndermeye çalıştığım e-postanın sadece bir Tobaşlığı, Subjectbaşlığı ve tek satırlık bir gövdesi vardı. Postfix'in tersine çevirdikten sonra hangi başlıkları söyleyeceğinden emin değilim, nasıl biliyor musunuz? / Var / log / syslog dosyasında
David Grayson

Yanıtlar:


8

Çalışan bir çözümünüz olduğundan, burada postfix'e (SMTP) telnet yaptığınızda ve sendmail (SMTP olmayan) kullandığınızda farklı davranışları açıklamaya çalışacağım.

FYI, OpenDKIM Milter mekanizması ile postfix ile çağrılacaktır . Bu resmi belgelerle postfix'te nasıl milter uygulanacağı hakkında bilgi edinebilirsiniz . İşte postfix'teki milter kancası şeması.

             SMTP-only       non-SMTP
             filters         filters
                ^ |            ^ |
                | v            | |
Network ->  smtpd(8)           | |
                       \       | V
Network ->  qmqpd(8)    ->  cleanup(8)  ->  incoming
                       /
            pickup(8)
               :
Local   ->  sendmail(1)

Sendmail yolunun (SMTP olmayan) ve telnet yolunun (SMTP) farklı işlem sırasına sahip olduğunu görebilirsiniz.

  • SMTP olmayan e-posta, milter'e enjekte edilmeden önce temizleme yoluyla işlenir. Temizleme cini : Eksik başlıkları ekleyerek sorumluydu :, için :, Message-Id itibaren (Resent) :, ve tarihi: . Bu nedenle, OpenDKIM milter'a enjekte edildiğinde e-postanız tam bir başlığa sahip olacak, hatta orijinal e-postada başlık eksikti.

  • Herhangi bir temizleme işlemi gerçekleştirilmeden önce SMTP e-postası OpenDKIM milter'a enjekte edilecektir. Bu nedenle, orijinal e-postanızın başlığı eksikse, opendkim e-postayı imzalamayı reddedebilir. Gönderen: başlık (bkz zorunluydu 6376 RFC ) ve email bunu yoksa, OpenDKIM email imzalamayı reddeden ve size bir uyarı verecektir

    can't determine message sender; accepting
    

Asla docker kullanmadım, bir konteyner içinde sendmail / pickup üzerinde hangi sınırlamayı bilmiyorum. David Grayson'un çözümü OpenDKIM'in mesajı imzalamasını sağlayacak kadar güvenli olduğunu düşünüyorum.


Bu aydınlatıcıydı; teşekkür ederim. Ne yazık ki, hala mevcut çözümümden daha iyi bir çözüm göremiyorum (cevabımda açıklanan).
David Grayson

Açık nedeni From:e-postanıza başlık eklemek için uygulamayı düzeltmek oldu :)
masegaloeh

Ama aynı zamanda Message-Idçok fazla bilmediğim şeyler de eklemeliyim ve muhtemelen yanlış anlarım ... temizleme cininin bununla ilgilenmesine izin vermek daha kolay görünüyor.
David Grayson

Aslında, RFC 6376'nın dediği gibi Message-ID zorunlu değildi . Varsayılan olarak, zorunlu başlık yalnızca Frombaşlıktı. Ancak, kendi Mesaj Kimliğinizi oluşturmak istiyorsanız, bu IETF Taslağı
masegaloeh


5

Şu anda aynı problem üzerinde çalıştığım için, bu yarı cevap veya en azından yarı test edilmiş bir soru. Birisinin kaçırdığım şeyi etmesine yardımcı olabileceğini umuyorum.

OP'nin (David Grayson) cevabı bana postdrop posta makarasının yeniden icadı gibi geliyor, ancak bu posta makarasını kullanmak umut verici bir yaklaşım gibi geliyor, bu yüzden burada aldım.

Postfix tarafından sağlanan / usr / bin / sendmail uyumluluk arabirimi, postayı postdrop'a geçirir; sgid postdrop, postayı / var / spool / postfix / maildrop adresindeki posta bağlantı kuyruğuna depolamasını sağlar. Bu docker kapsayıcısında gerçekleşmelidir. Postfix'in geri kalanının kapsayıcıda çalıştırılması gerekmez.

Yani, / var / spool / postfix / maildrop ve / var / spool / postfix / public dizinine ev sahipliği yapıyorum. Maildrop kuyruk dizinini bağladığım için ana bilgisayar ortamında / var / spool / postfix / maildrop'a posta gönderebilirim. Ben monte Çünkü /var/spool/postfix/public, maildropişaret edebilir pickupkuyruktan posta toplamak için. Ne yazık ki, ben bunu sürece sürece uids ve gids dahil, yani ana dizinde alma biriktirme dosyaları okuyamıyor ve daha kötü sonrası düzeltme yükleme ana bilgisayar ortamında maildrop dizini izinlerini berbat.

Yine de, bu işe yarıyor gibi görünüyor:

$ cat Dockerfile 
FROM debian:jessie
# Ids from parent environment

    RUN groupadd -g 124 postfix && \
        groupadd -g 125 postdrop && \
    useradd -u 116 -g 124 postfix

    RUN apt-get update && \
      DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
        postfix \
        bsd-mailx

    CMD echo test mail | mail myemail@example.com

$ sudo docker build   .
...
Successfully built 16316fcd44b6

$ sudo docker run   -v /var/spool/postfix/maildrop:/var/spool/postfix/maildrop \
  -v /var/spool/postfix/public:/var/spool/postfix/public 16316fcd44b6

Çalışırken, uids ve gids'i kodlamaktan çok mutlu değilim. Bu, aynı kabın her yerde aynı şekilde çalışacak şekilde sayılamayacağı anlamına gelir. Ben ana bilgisayardan birim yerine yerine postfix çalışan bir kapsayıcı monte eğer o zaman hiç çatışmayacak ve birçok kapsayıcılardan posta almak için sadece bir postfix kurulum gerekir anlıyorum. Bu uids ve gids'i tüm kaplarımın miras aldığı bir temel görüntüde ayarladım.

Yine de bunun gerçekten iyi bir yaklaşım olup olmadığını merak ediyorum. Böyle basit bir posta yapılandırması ve yeniden denemek için kapsayıcıda kullanılan herhangi bir arka plan programı olmadığında, msmtp gibi daha basit bir yerel MTA daha uygun olabilir. Biriktirmenin gerçekleşeceği aynı ana bilgisayardaki bir röleye TCP üzerinden teslim eder.

Msmtp yaklaşımıyla ilgili endişeler şunları içerir:

  • gönderdiği smtp rölesi yoksa posta kaybetme olasılığı daha fazladır. Aynı ana bilgisayarda bir geçiş varsa, ağ sorunlarının olasılığı düşüktür, ancak geçiş kabını nasıl yeniden başlattığım konusunda dikkatli olmalıyım.
  • verim?
  • Büyük bir posta patlaması olursa, posta bırakılmaya başlar mı?

Genel olarak, paylaşılan postfix biriktirme yaklaşımının kurulum için daha kırılgan bir yapılandırma olması daha olasıdır, ancak çalışma zamanında başarısız olma olasılığı daha düşüktür (geçiş kullanılamaz, bu nedenle posta bırakılır).


4

Konteynerin posta gönderme yolunun, onu hem konteynerden hem de ana bilgisayardan bir Docker "birimi" olarak erişilebilecek belirli bir dizindeki bir dosyaya yazmak olduğuna karar verdim.

Belirtilen dizindeki postaları okuyan, onları sendmail'e gönderen ve silen mailsender.sh adlı bir kabuk komut dosyası yaptım:

#!/bin/bash
# Runs on the host system, reading mails files from a directory
# and piping them to sendmail -t and then deleting them.

DIR=$1

if [ \! \( -d "$DIR" -a -w "$DIR" \) ]
then
  echo "Invalid directory given: $DIR"
  exit 1
fi

echo "`date`: Starting mailsender on directory $DIR"

cd $DIR

while :
do
  for file in `find . -maxdepth 1 -type f`
  do
    echo "`date`: Sending $file"
    sendmail -t < $file
    rm $file
  done
  sleep 1
done

Ubuntu upstart kullanır, bu yüzden /etc/init/mailsender.confbu komut dosyasını bir arka plan programına dönüştürmek için adlı bir dosya oluşturdum :

description "sends mails from directory"
start on stopped rc RUNLEVEL=[2345]
stop on runlevel[!2345]
respawn
exec start-stop-daemon --start --make-pidfile --pidfile /var/run/mailsender.pid --exec
/path/to/mailsender.sh /var/mailsend

Hizmeti ile başlatabilir start mailsenderve durdurabilirim stop mailsender. Günlüklerine bakabilirim /var/log/upstart/mailsender.logve tabii ki PID dosyasını kullanarak izleyebilirim.

Sen oluşturmak için gereken /var/mailsenddizin ve sonra argüman ekleyerek Docker kabından erişilebilir hale -v /var/mailsend:/var/mailsendsizin için docker runkomuta.


Belki mini_sendmail gibi bir şey yardımcı olacaktır? Kaplar ana bilgisayar sistemindeki kapsayıcılar izole uygulaması ve sendmail sunucusu arka plan programı arasında bir köprü gibi kaplarda kullanılır. cyberciti.biz/tips/... acme.com/software/mini_sendmail
MIKL

E-postayı SMTP aracılığıyla Postfix'e gönderiyorsa, Postfix'in e-postayı temizleyeceğini sanmıyorum. Belki daha yapılandırılabilir bir MTA'nız varsa (ya da Postfix'i nasıl daha iyi yapılandıracağımızı anladık) işe yarayacaktır.
David Grayson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.