الاتصال بخادم SMTP على localhost:25 بدون مصادقة؟

ما هي الإعدادات الصحيحة التي يجب تمريرها إلى ./discourse-setup للاتصال بخادم SMTP على localhost:25 بدون مصادقة؟

أنا مندهش جدًا من أن هذا غير مدعوم افتراضيًا (OOTB)؛ فهو الإعداد الافتراضي في معظم تثبيتات لينكس.

يعمل خادمي محليًا باستخدام Postfix؛ ولا يمكن الوصول إليه من الإنترنت. يعمل بشكل جيد، على سبيل المثال، عند تشغيل أمر mail. عثرت على بعض الأدلة غير الرسمية على الإنترنت تقترح تغييرات في /var/discourse/containers/app.yml، وأخيرًا تمكنت من تثبيته وتشغيله باستخدام الإعدادات التالية:

  DISCOURSE_SMTP_ADDRESS: localhost
  DISCOURSE_SMTP_PORT: 25
  DISCOURSE_SMTP_USER_NAME: discourse@opensouceecology.org
  DISCOURSE_SMTP_PASSWORD: "none"
  DISCOURSE_SMTP_AUTHENTICATION: none
  DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none
  DISCOURSE_SMTP_ENABLE_START_TLS: false

لاحظ أنه إذا حذفت متغيري DISCOURSE_SMTP_USER_NAME أو DISCOURSE_SMTP_PASSWORD، فإن برنامج التثبيت يصيح قائلاً إنهما مطلوبان (هل هذا خطأ؟).

والآن، عند النقر على زر “إعادة إرسال بريد التفعيل” في واجهة المستخدم الرسومية لـ Discourse، يظهر هذا الإدخال في ملف السجل (/var/discourse/shared/standalone/log/rails/production.log):

Started PUT "/finish-installation/resend-email" for 127.0.0.1 at 2019-11-07 13:15:31 +0000
Processing by FinishInstallationController#resend_email as HTML
  Parameters: {"authenticity_token"=>"SzQCvRWiqdXsBKzOjIB0X7KkvXro7Od6SdP8Qa8vvrskPeNYZNos5ORHJfyDUrHiKShZR/txM6NHuqHHCQCR1w=="}
  Rendering finish_installation/resend_email.html.erb within layouts/finish_installation
  Rendered finish_installation/resend_email.html.erb within layouts/finish_installation (Duration: 0.7ms | Allocations: 103)
  Rendered layouts/_head.html.erb (Duration: 0.5ms | Allocations: 103)
Completed 200 OK in 98ms (Views: 3.0ms | ActiveRecord: 0.0ms | Allocations: 4763)
  Rendering layouts/email_template.html.erb
  Rendered layouts/email_template.html.erb (Duration: 0.5ms | Allocations: 141)
Delivered mail c4ca58ca-345e-46c4-81bc-6d0eac7afa04@discourse.opensourceecology.org (11.3ms)
Job exception: wrong authentication type none

…لكن نوع المصادقة الخاص بي هو بالفعل ‘none’. ما هو الإعداد الصحيح لعدم وجود مصادقة؟

تحرير: أيضًا، هل يمكن لأحد أن يرسل لي رابطًا للوثيقة التي تحدد جميع متغيرات “DISCOURSE_SMTP_*” الممكنة وجميع قيمها الصالحة؟

تحرير 2: يبدو أن هذا الأمر أكثر صعوبة بكثير مما ينبغي. أعتقد أن ‘localhost’ يتم حلها داخل حاوية Docker إلى حاوية Docker الخاصة بـ Discourse نفسها (app) – وليس المضيف الذي يشغل خادم SMTP الخاص بـ Postfix. هذا الأمر معقد أكثر بسبب إعدادات mynetworks و iptables الخاصة بـ Postfix (والتي تم تكوينها بواسطة برنامج discourse-setup أو البرامج الفرعية التابعة له). ما هو الإعداد الصحيح هنا لجعل Discourse يستخدم خادم SMTP الذي أريد تشغيل Discourse عليه، دون أي مصادقة SMTP؟

أعتقد أن هذا لم يكن دقيقًا جدًا منذ حوالي 20 عامًا.

لا يمكنك استخدام discourse-setup لمواقف مثل وضعك لأن قلة قليلة من الأشخاص لديهم خوادم SMTP غير محمية بكلمة مرور، حتى خلف جدار الحماية.

ما سأفعله هو إعداد كلمات مرور SMTP لخادم البريد الخاص بي. في الواقع، لا توجد عيوب كبيرة في ذلك.

إذا لم ترغب في القيام بذلك، فأعتقد أنه بدلاً من “none” للمصادقة، قد ترغب في استخدام “” (وبالمثل لكلمة المرور واسم المستخدم).

أعتقد ذلك أيضًا. يمكنك تجربة استخدام اسم الحاوية. أعتقد أنك بحاجة إلى التأكد من أنهما على نفس شبكة Docker.

في عام 2019، يُعد هذا التكوين الافتراضي لـ Postfix على أنظمة RHEL/CentOS. يرتبط Postfix فقط بواجهة الحلقة (loopback interface) ويرفض جميع طلبات SMTP التي لا تنشأ من 127.0.0.0/8. لا يتطلب أي مصادقة. لست متأكدًا بشأن Debian، لكنني أتخيل أن exim لديه تكوين افتراضي مشابه.

إليك بعض المواضيع ذات الصلة في هذه المنتديات من مستخدمين آخرين واجهوا هذه المشكلة:

لا يبدو أن هناك موضوعًا حول كيفية إعداد هذا على RHEL/CentOS مع التغييرات اللازمة على كل من Discourse و Postfix، لذا سأقوم بتوثيق ذلك هنا.

لا يبدو أن هذا ممكن باستخدام سكريبت discourse-setup، لكنني تمكنت من جعله يعمل.

أولاً، كان عليّ معرفة عنوان IP لمضيف Docker كما يراه حاوية Docker. استخدام 127.0.0.1 لن يعمل لأن حاوية Docker سترى 127.0.0.1 على أنها هي نفسها. بدلاً من ذلك، نحتاج إلى تحديد عنوان IP أو اسم المضيف الخاص بمضيف Docker الذي يشغل خادم SMTP الخاص بـ Postfix، والذي يمكن الوصول إليه من قبل حاوية Docker (لذا ليس عنوان IP الموجه للإنترنت الخاص بمضيف Docker إذا كنت لا تريد أن يكون خادم SMTP الخاص بك متاحًا عبر الإنترنت، على سبيل المثال).

استخرجت عنوان IP ذي الصلة لمضيف Docker (172.17.0.1) من واجهة docker0 بتنفيذ الأمر التالي على مضيف Docker:

[maltfield@osestaging1 ~]$ ip address show docker0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:80:35:65:a1 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:80ff:fe35:65a1/64 scope link 
       valid_lft forever preferred_lft forever
[maltfield@osestaging1 ~]$

ثم قمت بتعديل ملف yaml الخاص بتطبيق Discourse، مع تعيين “DISCOURSE_SMTP_ADDRESS” إلى 172.17.0.1 من الأعلى.

[maltfield@osestaging1 ~]$ cd /var/discourse/
[maltfield@osestaging1 discourse]$ grep SMTP containers/app.yml
  DISCOURSE_SMTP_ADDRESS: 172.17.0.1
  DISCOURSE_SMTP_PORT: 25
  DISCOURSE_SMTP_AUTHENTICATION: none
  DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none
  DISCOURSE_SMTP_ENABLE_START_TLS: false
[maltfield@osestaging1 discourse]$ 

لاحظ أنني حاولت أولاً استخدام اسم المضيف الداخلي لـ Docker host.docker.internal لهذا الغرض، لكن يبدو أن هذا الاسم غير متاح لمستخدمي Docker على Linux.

بما أن تكوين Postfix الافتراضي على RHEL/CentOS يرتبط فقط بـ 127.0.0.1 (وهو أمر جيد)، ستحتاج إلى تغيير /etc/postfix/main.cf بحيث يرتبط أيضًا بواجهة docker0 وإضافة هذا النطاق الفرعي إلى مجموعة mynetworks حتى يتم قبول حركة مرور SMTP القادمة من حاويات Docker بواسطة Postfix.

[maltfield@osestaging1 postfix]$ grep -ir '172.17' /etc/postfix/*
/etc/postfix/main.cf:inet_interfaces = 127.0.0.1, 172.17.0.1
/etc/postfix/main.cf:mynetworks = 127.0.0.0/8, 172.17.0.0/16
[maltfield@osestaging1 postfix]$ 

بعد هذه التغييرات، أعد بناء Discourse ويجب أن يكون الآن قادرًا على إرسال رسائل البريد الإلكتروني عبر Postfix الخاص بمضيف Docker.

/var/discourse/launcher rebuild app

بينما يعمل هذا، لدي بعض الأسئلة:

  1. هل هناك متغير بيئة أو اسم مضيف آخر يشير بالفعل إلى مضيف Docker (172.17.0.1 في هذه الحالة)؟

لاحظت أن هناك متغير بيئة DISCOURSE_HOST_IP يتم “حقنه” بواسطة launcher. هل من الممكن تعيين مفتاح yaml DISCOURSE_SMTP_ADDRESS هذا إلى نفس قيمة مفتاح yaml الآخر باستخدام شيء مثل هذا؟

DISCOURSE_SMTP_ADDRESS: $DISCOURSE_HOST_IP
  1. بشكل عام، ما مدى متانة عنوان IP 172.17.0.1 الخاص بمضيف Docker؟ هل هو دائمًا هذا العنوان على أنظمة RHEL/CentOS؟ هل سيتغير في أي وقت؟

@maltfield أردت فقط أن أقول شكرًا لك على التعليمات.

واجهت نفس المشكلة في Debian… يمكنني بالتأكيد إنشاء مستخدم بريد منفصل لـ Discourse وجعله يتصل ويسجل الدخول إلى site:465، لكن الاتصال بالمنفذ 25 من الداخل يبدو أكثر منطقية، في رأيي.

وبالمناسبة، في Debian 10 مع docker.io من المستودعات، لا يزال docker0 هو 172.17.0.1/16.

ربما كنت تسيء فهم ما يقوله @maltfield؟

طوال ما أذكره (وهو ما يعود إلى ما قبل 20 عامًا)، كانت أنظمة لينكس (/ يونكس / بي إس دي / سولاريس) تحتوي على خادم SMTP يعمل ويتم تكوينه افتراضيًا ليكون مستعدًا لإعادة توجيه أي شيء يتم استلامه من localhost دون طرح أي أسئلة. هذا يخفف أي تطبيق آخر يعمل على تلك الآلة عن القلق بشأن إعدادات SMTP وتكوينها بنفسه.

نعم، لا تتطلب معظم خوادم لينكس مصادقة لإرسال البريد الإلكتروني (إما افتراضيًا أو بعد التثبيت والإعداد). كما أنه ليس ضروريًا إذا لم تقوم بالتمرير من أي مكان سوى الشبكة المحلية. لن تعمل سكريبتات تثبيت Discourse الافتراضية مع معظم الخوادم. فهي مصممة لمجموعة محدودة من حلول السحابة القائمة على Docker.

يمكنك قراءة تعليماتي الشاملة الكاملة لتثبيت Discourse على خادم مخصص وعاري يعمل بنظام RHEL/CentOS 7 في ويكي Open Source Ecology. انتبه للقسم الخاص بـ SMTP هنا:

حسنًا، أنا دائمًا تقريبًا أترك الأمر لك في مثل هذه المسائل! أعتقد أنه مرت عدد لا بأس به من السنوات منذ أن شغّلت خادم SMTP على localhost، لذا من المرجح أنني لا أعرف ما أتحدث عنه.

أدلة أكثر على أنني مخطئ! :man_shrugging:

رائع!

لكن discourse-setup مخصص دائمًا للأشخاص الذين لا يعرفون تقريبًا شيئًا عن إدارة الأنظمة. إذا كنت تعرف كيفية تثبيت خادم SMTP، فيمكنك تعديل ملف yml.

إذا كان للمضيف الذي يعمل عليه الحاوية اسم يمكن الحصول عليه عبر DNS، فإن الأمر يعمل ببساطة بتحديد ذلك:

DISCOURSE_SMTP_ADDRESS: real.machine.example.com

سيظل Postfix يرى أن مصدر البريد محليًا ويتعامل معه على هذا النحو.

هل سيؤدي تطابق DISCOURSE_HOSTNAME و DISCOURSE_SMTP_ADDRESS إلى حدوث مشاكل؟

لقد قمت بإعداد Postfix و Dovecot على مضيف Docker لقبول الطلبات المصادق عليها عبر TLS. لدي شهادات صالحة لخادمي، ولكن بغض النظر عن التكوين الذي أجربه، لا يمكنني جعل Discourse يرسل رسائل البريد الإلكتروني بشكل صحيح إلى Postfix الذي يعمل على مضيف Docker.

إذا استخدمت اسم المضيف (discourse.[myhost].com) فلن يعمل (لن يتصل حتى). إذا استخدمت عنوان IP لمضيف Docker (172.17.0.1)، أحصل على

hostname "172.17.0.1" does not match the server certificate

من الواضح أنني بحاجة إلى استخدام اسم النطاق المؤهل بالكامل (FQDN) الذي تم استخدامه لإنشاء الشهادات. إذا حاولت تعيين DISCOURSE_SMTP_ENABLE_START_TLS إلى false فسيقول إنه يجب علي إصدار أمر start TLS. أنا لا أرغب حقًا في فتح Postfix بدون TLS، لذلك لا أرى هذا كخيار قابل للتطبيق على أي حال.

استخدام مرحل SMTP خارجي ليس خيارًا أيضًا لأنني لا أرغب في الدفع أكثر فقط لضمان عدم وصول رسائل البريد الإلكتروني إلى مجلدات البريد العشوائي/غير المرغوب فيه لدى الأشخاص.

يجب أن أقول، لدي فهم أساسي فقط لشبكات Docker، وفهم أقل لإعداد خادم Postfix SMTP مع Dovecot للمصادقة، ولكني لست مبتدئًا تمامًا، ولكن الحصول على هذا الإعداد بطريقة آمنة/موثوقة يثبت أنه صعب للغاية.

@maltfield لقد قرأت مقالتك عن Open Source Ecology ولكنني لا أرغب في استخدام الاتصال غير المصادق عليه عبر المنفذ 25. لدى الجامعة التي أعمل بها بروتوكولات صارمة جدًا بشأن استخدام الاتصالات غير المشفرة وغير المصادق عليها (حتى داخل إعداد شبكة محلية مثل هذا). إنهم قلقون للغاية من أنه يمكن إساءة استخدامها من قبل طالب مستاء.

إذًا، اكتشفت أن هناك شيئًا مريبًا بشأن استخدام نفس اسم المضيف لكل من خادم Discourse وخادم SMTP.

يكشف المزيد من التحقيق أن حاوية Docker تضيف الإدخال التالي إلى ملف hosts:

172.17.0.2	discourse.[mydomain].com discourse

لذلك، فإن أي محاولة لاستخدام نفس اسم المضيف للحاوية قيد التشغيل ومضيف Docker ستتسبب في توجيه جميع الطلبات الصادرة من الحاوية إلى الحاوية نفسها وليس إلى مضيف Docker.

يا له من فشل! لماذا لا يوفر Discourse خادم SMTP افتراضي مُكوَّن في الحاوية؟!
أو يجعل من السهل استخدام Discourse بدون Docker!

يومان من حياتي ضاعا بسبب هذه المشكلة.

في النهاية، أقبل حقيقة أنني لا أستطيع استخدام TLS للتواصل مع SMTP الذي يعمل على مضيف Docker (دون الحصول على شهادات باستخدام اسم مضيف مختلف). لكي يعمل هذا أخيرًا، كان علي التأكد من إضافة 172.17.0.0/16 إلى المتغير mynetworks في ملف Postfix main.cf:

mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 172.17.0.0/16

هذا يسمح لـ Postfix برؤية أي حاوية Docker تعمل على هذا الخادم على أنها جزء من الشبكة.

كان التغيير الآخر الذي كان علي إجراؤه هو التأكد من تعيين smtpd_sasl_security_options إلى noanonymous لمنع “الغرباء” من استخدام Postfix كـ SMTP relay. تأكد من عدم تعيين الخيار noplaintext هنا وإلا فإن Postfix سيسمح فقط بالمصادقة باستخدام TLS.

smtpd_sasl_security_options = noanonymous

مع إعدادات التكوين هذه، يمكنني تحديد الإعدادات التالية في app.yml:

  DISCOURSE_SMTP_ADDRESS: 172.17.0.1                            # عنوان IP لمضيف Docker (كما يُرى من داخل هذه الحاوية)
  DISCOURSE_SMTP_PORT: 25
  DISCOURSE_SMTP_USER_NAME: discourse
  DISCOURSE_SMTP_PASSWORD: pa$$word
  DISCOURSE_SMTP_ENABLE_START_TLS: false                           # (اختياري، الافتراضي صحيح)
  DISCOURSE_SMTP_DOMAIN: discourse.[mydomian].com                # (مطلوب من قبل بعض مقدمي الخدمة)
  DISCOURSE_NOTIFICATION_EMAIL: noreply@discourse.[mydomain].com # (العنوان لإرسال الإشعارات منه)

لقد أنشأت أيضًا حساب مستخدم محلي على مضيف Docker فقط لغرض مصادقة SASL.
مع هذه التغييرات، تمكنت أخيرًا من إرسال رسائل البريد الإلكتروني من الحاوية ولكن لا يسعني إلا الشعور بأن هذا تكوين غير مثالي. من الناحية المثالية، يجب أن يكون من الممكن استخدام اسم المضيف المطلوب لمضيف Docker وأن يتم توجيه الطلبات إلى discourse.[mydomain].com إلى المكان الصحيح.

الآن أحتاج إلى إعداد SPF و DKIM لوضع رسائل البريد الإلكتروني في صناديق الوارد الخاصة بالأشخاص (بدلاً من مجلدات البريد العشوائي). آمل حقًا أن يتم أتمتة هذه العملية المؤلمة في يوم من الأيام. ربما تقديم بعض التعليمات حول كيفية تكوين discourse دون استخدام Docker (بحيث يمكن استخدامه مع cPanel على سبيل المثال ..) أو جعل إعداد البريد الإلكتروني أقل إيلامًا من خلال توفير نوع من تكوين SMTP الافتراضي مباشرة في حاوية Docker!

إذا عدت إلى أوائل التسعينيات، كان الأمر كما ترغب. الأشياء التي تتحدث عنها كانت تعمل ببساطة. لكن مرسلي البريد العشوائي تسببوا في تعقيد الأمر كثيرًا. ستصبح العملية أكثر صعوبة فقط، ولهذا السبب التوصية هي استخدام خدمة تتعامل مع العديد من التعقيدات نيابة عنك.

يسعدني أن إعداد البريد لديك يعمل!

هناك بعض التحديثات على دليل استكشاف أخطاء البريد الإلكتروني منذ الأمس. إذا كنت لا تزال غير راضٍ عن إعداد البريد الخاص بك، فربما تجربه مرة أخرى!


يمكن حلها باستخدام:


… مجرد حل DNS الافتراضي لاسم المجال إلى عنوان IP.

لا تفهمني خطأ. أنا أتفهم أهمية SPF و DKIM. إنه أمر مزعج فقط. كنت أتمنى لو كان من الممكن تثبيت هذا على خوادم cPanel الحالية لدينا حيث تم تكوين هذه الأشياء بالفعل.

هذا ما كنت أفتقده. إنه يعمل الآن مع TLS.

لقد نجحت أيضًا في تفعيل DKIM، لذا يجب ألا يتم إرسال رسائل البريد الإلكتروني كرسائل غير مرغوب فيها بعد الآن.