Saya menjalankan server Ubuntu 14.04 (Linux). Saya telah menginstal dan mengkonfigurasi Postfix dan OpenDKIM dengan sangat baik di server; Saya dapat mengirim email ke diri dengan perintah seperti echo hi | sendmail root
, dan postfix / opendkim akan menambahkan header seperti Message-Id
, Date
, dan DKIM-Signature
, meneruskan email ke alamat email pribadi saya, dan semuanya bekerja besar.
Sekarang saya ingin membuat aplikasi yang berjalan dalam wadah Docker dan dapat mengirim email dengan mudah. Secara khusus, saya tidak ingin khawatir tentang menambahkan header seperti Message-Id
, dan saya tidak ingin melakukan banyak konfigurasi atau instalasi perangkat lunak di dalam wadah itu sendiri.
Apa cara terbaik untuk melakukan ini?
Apakah ada cara untuk membiarkan kontainer menjalankan sendmail
exectuable pada host?
Saya mencoba membuat koneksi ke Postfix dari sebuah wadah menggunakan protokol SMTP pada port 25, tetapi Postfix tampaknya memperlakukan pesan yang diterima dengan cara yang berbeda; Saya pikir itu tidak menambahkan header sehingga pesan langsung ditolak sebagai spam oleh gmail (itu bahkan tidak cukup baik untuk dimasukkan ke folder Spam saya).
Di sini konten 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
tajuk,Subject
tajuk, dan satu baris. Saya tidak yakin bagaimana cara mengetahui header apa yang dimilikinya setelah Postfix menjalankannya melalui milters, apakah Anda tahu caranya? Ini adalah keluaran di / var / log / syslog yang menunjukkan bagaimana prosesnya oleh Postfix dan ditolak oleh Gmail: gist.github.com/DavidEGrayson/fbf65c8290c049a1f262Jawaban:
Karena Anda memiliki solusi yang berfungsi, di sini saya akan mencoba menjelaskan perilaku yang berbeda ketika Anda telnet ke postfix (SMTP) dan ketika Anda menggunakan sendmail (non-SMTP).
FYI, OpenDKIM akan dipanggil oleh postfix dengan mekanisme Milter . Anda bisa mendapatkan info bagaimana implementasi yang lebih ringan di postfix melalui dokumentasi resmi ini . Di sini diagram dari kait kait dalam postfix.
Anda dapat melihat bahwa sendmail-way (non-SMTP) dan telnet-way (SMTP) memiliki urutan pemrosesan yang berbeda.
Email non-SMTP akan diproses dengan pembersihan sebelum disuntikkan ke milter. Daemon cleanup bertanggung jawab untuk menambahkan header hilang: (Resent-) Dari :, Untuk :, Pesan-Id :, dan Tanggal: . Karenanya email Anda akan memiliki tajuk lengkap ketika disuntikkan ke OpenDKIM milter, bahkan email asli pun memiliki tajuk tidak lengkap.
Email SMTP akan disuntikkan ke OpenDKIM milter sebelum pemrosesan pembersihan dilakukan. Karenanya, jika email asli Anda memiliki tajuk yang tidak lengkap, maka opendkim dapat menolak untuk menandatangani email. The Dari: Header adalah wajib (lihat RFC 6376 ) dan jika email tidak memilikinya, OpenDKIM akan menolak untuk menandatangani email dan memberikan peringatan
Karena saya tidak pernah menggunakan buruh pelabuhan, saya tidak tahu apa batasan sendmail / pickup di dalam wadah. Saya pikir solusi David Grayson cukup aman untuk memastikan bahwa OpenDKIM menandatangani pesan.
sumber
From:
header di email Anda :)Message-Id
yang saya tidak tahu banyak tentang dan saya mungkin akan salah ... sepertinya lebih mudah untuk membiarkan daemon pembersihan mengurus hal itu.From
header. Tapi, jika Anda ingin membuat ID-Pesan Anda sendiri, Anda dapat menggunakan rekomendasi seperti Draft IETF iniAnda harus menunjuk
inet_interfaces
ke docker bridge (docker0
) di konfigurasi postfix yang terletak di set/etc/postfix/main.cf
Detail kerja internal yang lebih banyak pada pengiriman-email-dari-docker-melalui-postfix-instal-di-host
sumber
172.17.0.0/16
untukmynetworks
di/etc/postfix/main.cf
danservice postfix restart
.Ini adalah setengah jawaban, atau setidaknya setengah diuji, karena saya saat ini sedang mengerjakan masalah yang sama. Saya berharap seseorang dapat membantu menyempurnakan apa yang saya lewatkan.
Jawaban dari OP (David Grayson) bagi saya terdengar seperti penemuan ulang spool mail postdrop, tetapi menggunakan spool mail itu kedengarannya seperti pendekatan yang menjanjikan, jadi di sinilah saya mendapatkan.
Antarmuka kompatibilitas / usr / bin / sendmail yang disediakan oleh postfix meneruskan mail ke postdrop, yang merupakan postdrop sgid, memungkinkannya untuk menyimpan email ke dalam antrian maildrop di / var / spool / postfix / maildrop. Ini harus terjadi dalam wadah buruh pelabuhan. Sisa postfix semestinya tidak harus berjalan dalam wadah.
Jadi, saya host host / var / spool / postfix / maildrop dan / var / spool / postfix / public. Saya dapat mengirim surat ke / var / spool / postfix / maildrop di lingkungan host, karena saya telah memasang direktori antrian maildrop. Karena saya sudah mount
/var/spool/postfix/public
,maildrop
bisa memberi sinyalpickup
untuk mengumpulkan email dari antrian. Sayangnya, uids dan gids terlibat kecuali saya mengatasinya, artinya pickup di direktori host tidak dapat membaca file spool, dan lebih buruk lagi instalasi postfix mengacaukan izin pada direktori maildrop di lingkungan host.Namun, ini sepertinya berhasil:
Sementara itu berfungsi, saya tidak terlalu senang dengan pengkodean yang sulit pada uids dan gids. Ini berarti bahwa wadah yang sama tidak dapat dihitung untuk menjalankan yang sama di mana-mana. Saya pikir meskipun jika daripada memasang volume dari host saya me-mount-nya dari sebuah wadah yang menjalankan postfix, maka itu tidak akan pernah konflik, dan saya hanya perlu satu instalasi postfix untuk mengeluarkan email dari banyak kontainer. Saya akan mengatur uids dan gids dalam gambar dasar yang menjadi asal semua wadah saya.
Saya bertanya-tanya apakah ini benar-benar pendekatan yang bagus. Dengan konfigurasi surat yang begitu sederhana, dan tidak ada daemon yang digunakan pada wadah untuk mencoba ulang pengiriman, MTA lokal yang lebih sederhana seperti msmtp mungkin lebih tepat. Itu akan mengirimkan melalui TCP ke relay pada host yang sama, di mana spooling akan terjadi.
Kekhawatiran dengan pendekatan msmtp meliputi:
Secara umum, pendekatan spool postfix bersama tampaknya lebih cenderung menjadi konfigurasi rapuh untuk diatur, tetapi lebih kecil kemungkinannya gagal pada waktu berjalan (relai tidak tersedia, jadi surat dijatuhkan).
sumber
Saya memutuskan bahwa cara wadah akan mengirim surat adalah dengan menuliskannya ke file di direktori tertentu, yang akan dapat diakses dari wadah dan host sebagai "volume" Docker.
Saya membuat skrip shell bernama mailsender.sh yang membaca email dari direktori yang ditentukan, mengirimkannya ke sendmail, dan kemudian menghapusnya:
Ubuntu menggunakan pemula, jadi saya membuat file bernama
/etc/init/mailsender.conf
untuk mengubah skrip ini menjadi daemon:Saya dapat memulai layanan dengan
start mailsender
dan menghentikannyastop mailsender
. Saya dapat melihat log-nya/var/log/upstart/mailsender.log
, dan tentu saja saya bisa memantaunya menggunakan file PID.Anda perlu membuat
/var/mailsend
direktori dan membuatnya dapat diakses dari wadah Docker dengan menambahkan argumen-v /var/mailsend:/var/mailsend
kedocker run
perintah Anda .sumber