localhost:25 の SMTP サーバーへの認証なし接続は可能か?

./discourse-setup に渡す正しい設定は、localhost:25 上の SMTP サーバーに認証なしで接続するためには何でしょうか?

これは OOTB(初期状態)でサポートされていないことに非常に驚いています。これはほとんどの Linux インストールのデフォルト設定です。

私のサーバーはローカルで 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 の WUI で「アクティベーションメールを再送信」ボタンをクリックすると、ログファイル(/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 コンテナ内部で、Postfix SMTP サーバーを実行している Docker ホストではなく、Discourse Docker コンテナ自体(app)に解決されていると思います。これは、Postfix の mynetworksiptables(これらは discourse-setup スクリプトまたはその子スクリプトによって設定されました)によってもさらに複雑化しています。Discourse を実行したい SMTP サーバーを認証なしで使用する正しい設定は何でしょうか?

「いいね!」 1

それは約 20 年前からあまり事実ではなかったと思います。

ファイアウォールの背後にある場合でも、パスワードで保護されていない SMTP サーバーを持つ人はほとんどいないため、あなたの状況では discourse-setup を使用することはできません。

私が行うなら、メールサーバーの SMTP パスワードを設定します。本当にデメリットはほとんどありません。

それをやりたくない場合は、認証に「none」ではなく「」(同様にパスワードとユーザー名も)を使用することを検討してください。

私もそう思います。コンテナ名を試してみてください。両方が同じ Docker ネットワーク上にある必要があると思います。

「いいね!」 2

2019年現在、RHEL/CentOSにおけるPostfixのデフォルト設定では、Postfixはループバックインターフェースのみにバインドし、127.0.0.0/8 以外のSMTPリクエストをすべて破棄します。認証は不要です。Debianについては確信はありませんが、exim も同様のデフォルト設定になっていると想像します。

この問題に直面した他のユーザーによる、フォーラム上の関連トピックがいくつかあります。

Discourse Postfixの両方に対して必要な変更を加えて、RHEL/CentOS上でこれを設定する方法に関するトピックは見当たらないため、ここにドキュメント化します。

これは discourse-setup スクリプトでは不可能のようですが、私はこれを動作させることができました。

まず、Dockerコンテナから見たDockerホストのIPアドレスを特定する必要がありました。127.0.0.1 を使用しても機能しません。なぜなら、Dockerコンテナにとって 127.0.0.1自分自身として認識されるからです。むしろ、Postfix SMTPサーバーを実行しているDockerホストのIPアドレスまたはホスト名を指定する必要があります。また、そのアドレスはDockerコンテナからアクセス可能でなければなりません(例えば、SMTPサーバーをインターネットからアクセス不可にしたい場合、Dockerホストのインターネット向けIPアドレスは使用できません)。

Dockerホスト上で以下のコマンドを実行することで、docker0 インターフェースからDockerホストの関連IPアドレス(172.17.0.1)を抽出しました。

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

次に、Discourseアプリのyamlファイルを編集し、上記の 172.17.0.1 を「DISCOURSE_SMTP_ADDRESS」に設定しました。

[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 を使用しようとしましたが、どうやらこのホスト名はLinuxのDockerユーザーには利用できないようです。

RHEL/CentOSのデフォルトのPostfix設定は127.0.0.1のみにバインドしているため(これは良いことですが)、/etc/postfix/main.cf を変更して docker0 インターフェースにもバインドし、mynetworks グループにそのサブネットを追加する必要があります。これにより、DockerコンテナからのSMTPトラフィックが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を再ビルドすれば、DockerホストのPostfixを介してメールを送信できるようになるはずです。

/var/discourse/launcher rebuild app

これは動作しますが、いくつかの疑問があります。

  1. Dockerホスト(この場合は 172.17.0.1)を指す別の環境変数やホスト名は存在しないでしょうか?

launcher によって「注入」される DISCOURSE_HOST_IP という環境変数があることに気づきました。この DISCOURSE_SMTP_ADDRESS yamlキーを、他のyamlキーと同じ値に設定することは可能でしょうか?例えば以下のようにです。

DISCOURSE_SMTP_ADDRESS: $DISCOURSE_HOST_IP
  1. 一般的に、Dockerホストの 172.17.0.1 というIPアドレスはどの程度安定していますか?RHEL/CentOSシステムでは常にこのIPでしょうか?いつか変わることはあるでしょうか?
「いいね!」 3

@maltfield _instructions について、ありがとうございます。

Debian でも同じ問題に遭遇しました。Discourse 用の別のメールユーザーを作成して、site:465 に接続しログインさせることは可能だとは思いますが、内部からポート 25 に接続する方が、私の意見ではより論理的です。

ちなみに、Debian 10 でリポジトリから docker.io を使用している場合、docker0 は依然として 172.17.0.1/16 です。

もしかすると、@maltfield さんが言っていることを誤解されているのではないでしょうか?

私が覚えている限り(それは20年以上前までさかのぼります)、Linux(/ Unix / BSD / Solaris)システムには SMTP サーバーが実行されており、デフォルトで localhost から受信したあらゆるものを問い質すことなくリレーするように設定されています。これにより、そのマシン上で実行されている他のアプリケーションは、SMTP 設定を自分で気にしたり設定したりする必要がなくなります。

「いいね!」 2

はい、ほとんどの Linux サーバーでは、メール送信に認証は必要ありません(デフォルトで、またはインストールと設定後に不要になります)。また、ローカルネットワーク以外から中継しない場合も不要です。Discourse のデフォルトのインストールスクリプトは、ほとんどのサーバーでは動作しません。これは、特定の Docker ベースのクラウドソリューション向けに設計されています。

RHEL/CentOS 7 を実行する専用ベアメタルサーバーに Discourse をインストールするための完全な詳細な手順は、Open Source Ecology wiki でご覧いただけます。SMTP に関するセクションは以下をご覧ください:

「いいね!」 2

ええ、そんなことについてはほぼいつもあなたの意見を尊重します!ローカルホストで SMTP サーバーを動かしたのはもうかなり昔のことなので、私が何を話しているのか分かっていない可能性が高いでしょう。

私が間違っているというさらなる証拠ですね!:man_shrugging:

素晴らしいですね!

ただし、discourse-setup はシステム管理についてほとんど何も知らない人向けにのみ用意されるものです。SMTP サーバーのインストール方法が分かれば、yml ファイルを編集することもできます。

「いいね!」 3

コンテナが実行されているホストに DNS で取得できる名前がある場合、それを指定するだけで機能します。

DISCOURSE_SMTP_ADDRESS: real.machine.example.com

Postfix は、メールの送信元がローカルであると認識し、そのように処理します。

「いいね!」 1

DISCOURSE_HOSTNAMEDISCOURSE_SMTP_ADDRESS が同じ場合、問題が発生しますか?

Docker ホストで Postfix と Dovecot をセットアップし、TLS 経由で認証済みリクエストを受け入れられるようにしました。サーバー用の有効な証明書がありますが、どのような設定を試しても、Discourse が Docker ホストで実行されている Postfix にメールを正しく送信できません。

ホスト名 (discourse.[myhost].com) を使用すると機能しません(接続すらできません)。Docker ホストの IP アドレス (172.17.0.1) を使用すると、次のエラーが発生します。

hostname "172.17.0.1" does not match the server certificate

明らかに、証明書の作成に使用された FQDN を使用する必要があります。DISCOURSE_SMTP_ENABLE_START_TLSfalse に設定しようとすると、STARTTLS コマンドを発行する必要があると言われます。TLS なしで Postfix を開きたくないので、これは実際には実行可能なオプションとは考えていません。

外部 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サーバーを設定しないのでしょうか!?
または、DockerなしでDiscourseを簡単に使用できるようにしてほしいです!

この問題のために2日間を無駄にしました。

最終的に、Dockerホストで実行されているSMTPとTLSを使用して通信できないという事実を受け入れました(別のホステスト名を使用して証明書を取得しない限り)。これを最終的に機能させるために、Postfixのmain.cfファイルのmynetworks変数に172.17.0.0/16が追加されていることを確認する必要がありました。

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

これにより、Postfixはこのサーバーで実行されている任意のDockerコンテナをネットワークの一部と見なすことができます。

もう1つの変更点は、PostfixをSMTPリレーとして「見知らぬ人」が使用するのを防ぐために、smtpd_sasl_security_optionsnoanonymousに設定されていることを確認することでした。noplaintextオプションがここに設定されていないことを確認してください。そうしないと、PostfixはTLSを使用した認証のみを許可します。

smtpd_sasl_security_options = noanonymous

これらの設定により、app.ymlで次の設定を指定できました。

  DISCOURSE_SMTP_ADDRESS: 172.17.0.1                            # DockerホストのIPアドレス(このコンテナ内から見た場合)
  DISCOURSE_SMTP_PORT: 25
  DISCOURSE_SMTP_USER_NAME: discourse
  DISCOURSE_SMTP_PASSWORD: pa$$word
  DISCOURSE_SMTP_ENABLE_START_TLS: false                        # (オプション、デフォルトはtrue)
  DISCOURSE_SMTP_DOMAIN: discourse.[mydomian].com                # (一部のプロバイダーで必要)
  DISCOURSE_NOTIFICATION_EMAIL: noreply@discourse.[mydomain].com # (通知を送信するアドレス)

SASL認証専用のDockerホストにローカルユーザーアカウントも作成しました。
これらの変更により、コンテナからメールを送信できるようになりましたが、これは最適ではない構成だと感じずにはいられません。理想的には、Dockerホストの目的のホステスト名を使用し、discourse.[mydomain].comへのリクエストが正しい場所にルーティングされるようにする必要があります。

これで、メールが受信トレイ(スパムフォルダではなく)に着陸するように、SPFとDKIMを設定する必要があります。この面倒なプロセスがいつか自動化されることを 本当に 願っています。たとえば、Dockerを使用せずに(cPanelなどで使用できるように)Discourseを設定する方法に関する指示を提供するか、Dockerコンテナに直接デフォルトのSMTP設定を提供するような形でメール設定をより簡単にするかもしれません!

「いいね!」 2

1990年代初頭に戻れば、あなたの望み通りでした。あなたが話していることはすべて機能していました。しかし、スパマーがそれをはるかに複雑にしました。プロセスはさらに困難になるだけなので、多くの複雑な問題を処理してくれるサービスを使用することが推奨されます。

「いいね!」 2

メールの設定が動作してよかったです!

昨日からメールのトラブルシューティングガイドにいくつか更新がありました。もしメールの設定にまだ満足していない場合は、もう一度試してみてはいかがでしょうか!


これは次のようにすることで解決できます。


…単にドメイン名をIPに解決するデフォルトのDNSです。

誤解しないでください。SPFとDKIMの重要性は理解しています。ただ、面倒なだけです。これらの設定がすでに構成されている現在のcPanelサーバーに、これをインストールできればと願うばかりです。

「いいね!」 1

これが足りなかったものです。TLSで動作するようになりました。

DKIMも動作したので、メールがスパムとして扱われなくなるはずです。

「いいね!」 2