Connecting to a SMTP server on localhost:25 without auth?

What are the correct settings passed to ./discourse-setup for connecting to an smtp server on localhost:25 without auth?

I’m very surprised that this isn’t supported OOTB; it’s the default config on most linux installs…

My server runs postfix locally; it is not accessible from the Internet. It works fine, for example, when running the mail command. I found a few unofficial guides on the Internet suggesting changes to /var/discourse/containers/app.yml, and I finally got it to install & start with the following settings:

  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

Note that if I omit the DISCOURSE_SMTP_USER_NAME or DISCOURSE_SMTP_PASSWORD variables, your install script yells at me stating that they’re required (bug?).

And now when I click the “Resend Activation Email” button in the Discourse wui, this entry pops-up in the log file (/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

…But my authentication type is ‘none’. What should the correct setting be for no authentication?

EDIT: also, can someone link me to the doc that defines all of the possible “DISCOURSE_SMTP_*” variables and all of their valid values?

EDIT2: this is proving to be far more difficult than it should be. I think ‘localhost’ is resolving inside the docker container to the Discourse docker container itself (app) – not the docker host that is running my postfix smtp server. That’s further complicated by postfix’s mynetworks and iptables (which were configured by the discourse-setup script or its children scripts). What’s the correct config here to just have Discourse use the smtp server on which I want to run Discourse, with no smtp auth?

إعجاب واحد (1)

I think that hasn’t been very true for about 20 years.

You can’t use discourse-setup for situations like yours because few people have non password protected smtp servers, even behind a firewall.

What I would do is configure smtp passwords for my mail server. There really isn’t much downside.

If you don’t want to do that I think that instead of “none” for authentication you might want “” (and similarly for the password and username).

I think so too. You might try using the container name. I think that you need to see that they are both on the same docker network.

إعجابَين (2)

In 2019, it’s the default config for postfix on RHEL/CentOS. Postfix binds only to the loopback interface and drops all smtp requests that don’t originate from 127.0.0.0/8. No auth required. I’m not sure about debian, but I’d imagine exim has a similar default config.

A couple relevant topics on these forums from other users who hit this issue:

There doesn’t appear to be a topic for how to set this up on RHEL/Cent OS with the necessary changes to both Discourse and postfix, so I’m documenting this here.

This does not appear to be possible with the discourse-setup script, but I did get this to work.

First, I had to figure out the IP address of the docker host as the docker container sees it. Using 127.0.0.1 won’t work because the docker container will see 127.0.0.1 as itself. Rather, we need to specify the IP address or hostname of the docker host that is running the postfix SMTP server, and one that is addressible by the docker container (so not your docker host’s Internet-facing IP address if you want your SMTP server to not be Internet-accessible, for example).

I extracted the relevant IP address of the docker host (172.17.0.1) from the docker0 interface by executing this on the docker host:

[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 ~]$

Then I edited my Discourse app’s yaml file, setting the “DISCOURSE_SMTP_ADDRESS” to 172.17.0.1 from above.

[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]$ 

Note that I first tried to use the internal docker hostname host.docker.internal for this, but apparently this hostname isn’t available to linux docker users

Because the default postfix configuration in RHEL/Cent OS binds only to 127.0.0.1 (which is good), you’ll need to change /etc/postfix/main.cf so it also binds to the docker0 interface and add that subnet to the mynetworks group so that SMTP traffic coming from docker containers will be accepted by 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]$ 

After those changes, rebuild Discourse and it should now be able to send emails out through your docker host’s postfix.

/var/discourse/launcher rebuild app

While this works, I have a few questions:

  1. Is there some other environment variable or hostname that already points to the docker host (172.17.0.1 in this case)?

I noticed that there is a DISCOURSE_HOST_IP environment variable “injected” by launcher. Is it possible to set this DISCOURSE_SMTP_ADDRESS yaml key to the same value as the other’s yaml key with something like this?

DISCOURSE_SMTP_ADDRESS: $DISCOURSE_HOST_IP
  1. In general, how durable is the 172.17.0.1 IP of the docker host? Is it always this IP on RHEL/Cent OS systems? Will it ever change on me?
3 إعجابات

@maltfield Just wanted to say thank you for the instructions.

I ran into same issue on Debian… Could create a separate mail user for Discourse I suppose and have it connect and log in to site:465 but connecting to port 25 from the inside is more logical, in my opinion.

And by the way, on Debian 10 with docker.io from the repositories - docker0 is still 172.17.0.1/16.

Maybe you are misunderstanding what @maltfield is saying?

For as long as I can remember (which goes further back than 20 years), Linux ( / Unix / BSD / Solaris) systems have an SMTP server running which is configured by default to be happy to relay anything received from localhost without any questions. This relieves any other application running on that machine from having to worry about and configure SMTP settings themselves.

إعجابَين (2)

Yes, most linux servers don’t require auth to send mail (either by default or after installl & configuring). Nor is it necessary if they don’t relay from anywhere but the local network. The default Discourse install scripts won’t work for most servers. It’s designed for a narrow set of docker-based cloud solutions.

You can read my full comprehensive instructions for installing Discourse on a dedicated, baremetal server running RHEL/CentOS 7 on the Open Source Ecology wiki. Note the section on SMTP here:

إعجابَين (2)

Well, I almost always defer to you on such matters! I guess it’s been a good number of years since I’ve run an SMTP server on localhost, so it’s a good bet that I don’t know what I’m talking about.

More evidence that I’m wrong! :man_shrugging:

Nice!

But discourse-setup is only ever going to be for people who know virtually nothing about system administration. If you know how to install an SMTP server, you can edit a yml file.

3 إعجابات

If the host where the container is running has a name you can get via DNS, it works just to specify that:

DISCOURSE_SMTP_ADDRESS: real.machine.example.com

Postfix will still see that the source of the mail is local and handle it that way.

إعجاب واحد (1)

هل سيؤدي تطابق 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. لدى الجامعة التي أعمل بها بروتوكولات صارمة جدًا بشأن استخدام الاتصالات غير المشفرة وغير المصادق عليها (حتى داخل إعداد شبكة محلية مثل هذا). إنهم قلقون للغاية من أنه يمكن إساءة استخدامها من قبل طالب مستاء.

إعجاب واحد (1)

إذًا، اكتشفت أن هناك شيئًا مريبًا بشأن استخدام نفس اسم المضيف لكل من خادم 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!

إعجابَين (2)

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

إعجابَين (2)

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

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


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


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

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

إعجاب واحد (1)

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

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

إعجابَين (2)