他のウェブサイトとのディスコース、SMTPの問題:End of file reached

(スタッフ向け:これは私のアカウントが関連付けられているホスト型サブスクリプションとは無関係です)

Run other websites on the same machine as Discourse の手順に従って VPS に Discourse をインストールしましたが、以下の点を変更しました:最初のインストール前に app.yml を調整しました。

sudo mkdir /var/discourse
sudo git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
sudo cp samples/standalone.yml containers/app.yml
sudo nano containers/app.yml

YAML ファイルで ports セクションをコメントアウトし、- "templates/web.socketed.template.yml" を追加し、ホスト名と SMTP を設定しました。

  ## TODO: この Discourse インスタンスが応答するドメイン名
  ## 必須。Discourse は IP アドレスのみでは動作しません。
  DISCOURSE_HOSTNAME: 'discuss.mydomain.community'

  ## TODO: 初期登録時に管理者および開発者として登録されるカンマ区切りのメールアドレスのリスト
  ## 例:'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'someuser@protonmail.com,anotheruser@otherdomain.io'

  ## TODO: 新規アカウントの認証と通知送信に使用する SMTP メールサーバー
  # SMTP アドレス、ユーザー名、パスワードは必須
  # 警告:SMTP パスワードに '#' 文字が含まれていると問題が発生する可能性があります!
  DISCOURSE_SMTP_ADDRESS: smtp.myprovider.email
  DISCOURSE_SMTP_PORT: 465
  DISCOURSE_SMTP_USER_NAME: mydomain-no-reply@otherdomain.io
  DISCOURSE_SMTP_PASSWORD: pa$$word
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (オプション、デフォルトは true)

その後、Discourse アプリをブートストラップして起動しました。

sudo ./launcher bootstrap app
sudo ./launcher start app

これは成功しました。Discourse を停止し、推奨される HTTP のみの設定(テスト用)で外部の Nginx(/etc/nginx/conf.d/discourse.conf)を設定しました。http://discuss.mydomain.community にアクセスできました。

Discourse を再度停止し、certbot を使用して discourse.conf をアップグレードしました。現在は以下のようになっています。

server {
	server_name discuss.mydomain.community;  # <-- ここを変更

	location / {
		proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
		proxy_set_header Host $http_host;
		proxy_http_version 1.1;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_set_header X-Real-IP $remote_addr;
	}

    listen [::]:443 ssl ipv6only=on; # Certbot によって管理されています
    listen 443 ssl; # Certbot によって管理されています
    ssl_certificate /etc/letsencrypt/live/discuss.mydomain.community/fullchain.pem; # Certbot によって管理されています
    ssl_certificate_key /etc/letsencrypt/live/discuss.mydomain.community/privkey.pem; # Certbot によって管理されています
    include /etc/letsencrypt/options-ssl-nginx.conf; # Certbot によって管理されています
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Certbot によって管理されています

}
server {
    if ($host = discuss.mydomain.community) {
        return 301 https://$host$request_uri;
    } # Certbot によって管理されています


	listen 80; listen [::]:80;
	server_name discuss.mydomain.community;
    return 404; # Certbot によって管理されています
}

ここまでは順調です。HTTPS で Discourse にアクセスできます(動作しなかったため後で ./launcher rebuild app を実行しましたが、違いはありませんでした)。

登録フォームを送信した後の「インストールの完了」画面で、「someuser@protonmail.com にアクティベーションメールを送信しました」と表示されます。

問題:メールが届きません。

管理者のメール受信トレイにメールが届きません。mydomain-no-reply@otherdomain.io のメールボックスを確認しても、何もありません。

:問題全体が、メールユーザーが otherdomain.io にあり、mydomain.community に存在する必要があるために発生している可能性があります。しかし、私の知る限りこれは要件ではありません。

トラブルシューティングを開始し、その後以下の app.yml の変更(その間に rebuild app を実行)でテストしました。

  DISCOURSE_SMTP_ENABLE_START_TLS: false

成功しませんでした。続けて以下を試しました。

## 最初の登録時の「From」メールアドレスを設定したい場合は、コメントアウトして変更してください:
  - exec: rails r "SiteSetting.notification_email='mydomain-no-reply@otherdomain.io"

その後、Troubleshoot email on a new Discourse install に従って進めました。

  • otherdomain.io の DNS に DKIM と SPF が正しく設定されています
  • VPS から SMTP プロバイダーへの telnet 接続は成功しました
  • Docker コンテナ内(docker exec と telnet のインストールを使用)からの telnet 接続も成功しました

./discourse-doctor を実行したところ、2 つの項目が目立ちました(他の結果は期待通りでした)。

========================================
Discourse version at discuss.mydomain.community: Discourse 2.6.0.beta2 
Discourse version at localhost: NOT FOUND
==================== DNS PROBLEM ====================
This server reports NOT FOUND, but discuss.mydomain.community reports Discourse 2.6.0.beta2 .
This suggests that you have a DNS problem or that an intermediate proxy is to blame.
If you are using Cloudflare, or a CDN, it may be improperly configured.
==================== MAIL TEST ====================
For a robust test, get an address from http://www.mail-tester.com/
Sending mail to REDACTED  . . 
Testing sending to test-k86jiyqb9@srv1.mail-tester.com using smtp.myprovider.email:465.
======================================== ERROR ========================================
                                    UNEXPECTED ERROR

end of file reached

====================================== SOLUTION =======================================
This is not a common error. No recommended solution exists!

Please report the exact error message above to https://meta.discourse.org/
(And a solution, if you find one!)

2 回試しました。1 回は設定済みのメールアドレスで、もう 1 回は mail-tester.com が提供するメールアドレスで試しました。結果は同じでした。これは良くない兆候です。

:どうやら Docker インストール手順ではベータ版も提供されているようです。覚えておいてください。

プロダクションログを見ると、以下のように記録されています。

Started GET "/" for REDACTED-IP at 2020-09-03 06:21:57 +0000
Processing by FinishInstallationController#index as HTML
  Rendering finish_installation/index.html.erb within layouts/finish_installation
  Rendered finish_installation/index.html.erb within layouts/finish_installation (Duration: 3.2ms | Allocations: 356)
  Rendered layouts/_head.html.erb (Duration: 15.7ms | Allocations: 2969)
Completed 200 OK in 323ms (Views: 140.3ms | ActiveRecord: 0.0ms | Allocations: 32137)
Started GET "/finish-installation/register" for REDACTED-IP at 2020-09-03 06:22:01 +0000
Processing by FinishInstallationController#register as HTML
  Rendering finish_installation/register.html.erb within layouts/finish_installation
  Rendered finish_installation/register.html.erb within layouts/finish_installation (Duration: 7.1ms | Allocations: 1607)
  Rendered layouts/_head.html.erb (Duration: 22.3ms | Allocations: 3139)
Completed 200 OK in 107ms (Views: 41.3ms | ActiveRecord: 0.0ms | Allocations: 11760)
Started POST "/finish-installation/register" for REDACTED-IP at 2020-09-03 06:22:22 +0000
Processing by FinishInstallationController#register as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"l1hEEsK/gur5yplJdMIHttZAgYcuzLLkESaAI87IMb88nAFqNwi7l3yJ+3EJBw7leFypVGbH4C5hJl7VnJVYBQ==", "email"=>"someuser@protonmail.com", "username"=>"someusername", "password"=>"[FILTERED]", "commit"=>"Register"}
Redirected to https://discuss.mydomain.community/finish-installation/confirm-email
Completed 302 Found in 48ms (ActiveRecord: 0.0ms | Allocations: 4246)
  Rendering layouts/email_template.html.erb
  Rendered layouts/email_template.html.erb (Duration: 0.2ms | Allocations: 31)
Started GET "/finish-installation/confirm-email" for REDACTED-IP at 2020-09-03 06:22:22 +0000
Processing by FinishInstallationController#confirm_email as HTML
  Rendering finish_installation/confirm_email.html.erb within layouts/finish_installation
  Rendered finish_installation/confirm_email.html.erb within layouts/finish_installation (Duration: 2.3ms | Allocations: 418)
  Rendered layouts/_head.html.erb (Duration: 7.9ms | Allocations: 1612)
Completed 200 OK in 25ms (Views: 22.1ms | ActiveRecord: 0.0ms | Allocations: 4611)
Delivered mail ea8af868-4a2c-4312-85dd-f57061a3cd90@discuss.mydomain.community (60015.9ms)
Job exception: Net::ReadTimeout

少し待ってから、ブラウザから「通知メールを再送」をリクエストしました。プロダクションログに以下が追加されました。

Delivered mail 47ca6f15-cd9e-4c96-a670-6646e2bda585@discuss.mydomain.community (60007.9ms)
Job exception: end of file reached

  Rendering layouts/email_template.html.erb
  Rendered layouts/email_template.html.erb (Duration: 0.2ms | Allocations: 31)
Delivered mail 02367872-af3a-4df4-9a68-4e5e7c5eda60@discuss.mydomain.community (60007.4ms)
Job exception: end of file reached

  Rendering layouts/email_template.html.erb
  Rendered layouts/email_template.html.erb (Duration: 0.2ms | Allocations: 31)
Delivered mail ee9ee1fc-6fd1-4970-89fa-260efe2dd04c@discuss.mydomain.community (60014.1ms)
Job exception: end of file reached

  Rendering layouts/email_template.html.erb
  Rendered layouts/email_template.html.erb (Duration: 0.1ms | Allocations: 31)
Delivered mail 9030f87b-99df-4de2-9a60-2c57f7c752de@discuss.mydomain.community (60007.0ms)
Job exception: end of file reached

  Rendering layouts/email_template.html.erb
  Rendered layouts/email_template.html.erb (Duration: 0.2ms | Allocations: 31)
Started PUT "/finish-installation/resend-email" for REDACTED-IP at 2020-09-03 06:31:22 +0000
Processing by FinishInstallationController#resend_email as HTML
  Parameters: {"authenticity_token"=>"NE21scxxyZz3/DxDkoF8kwi9GXoNKvnstNJdKZjQs7afigDKWcbw4XK/XnvvRHTApqExqUUghybE1oPfyo3aDA=="}
  Rendering finish_installation/resend_email.html.erb within layouts/finish_installation
  Rendered finish_installation/resend_email.html.erb within layouts/finish_installation (Duration: 0.9ms | Allocations: 163)
  Rendered layouts/_head.html.erb (Duration: 2.5ms | Allocations: 269)
Completed 200 OK in 63ms (Views: 6.5ms | ActiveRecord: 0.0ms | Allocations: 6408)
  Rendering layouts/email_template.html.erb
  Rendered layouts/email_template.html.erb (Duration: 0.2ms | Allocations: 31)
Delivered mail 127cc350-3fb0-4ef1-8759-391fb407b1cb@discuss.mydomain.community (60008.0ms)
Job exception: Net::ReadTimeout

Delivered mail d9c70dfd-5a8b-4f4c-bafa-5a540fc8ed4f@discuss.mydomain.community (60010.0ms)
Job exception: end of file reached

  Rendering layouts/email_template.html.erb
  Rendered layouts/email_template.html.erb (Duration: 0.1ms | Allocations: 31)
Delivered mail e9e67ed1-d7b1-4e8a-ba11-30501c6fae89@discuss.mydomain.community (60012.4ms)
Job exception: end of file reached

  Rendering layouts/email_template.html.erb
  Rendered layouts/email_template.html.erb (Duration: 0.2ms | Allocations: 31)
  Rendering layouts/email_template.html.erb
  Rendered layouts/email_template.html.erb (Duration: 0.1ms | Allocations: 31)
Delivered mail 82d0361e-0349-4a1a-928e-dcb16dcffdbc@discuss.mydomain.community (60008.6ms)
Job exception: end of file reached

ホスティングプロバイダーに連絡し、問題が彼らの側にあるかどうかを確認しました。彼らによると、この設定は問題なく動作するはずだが、VPS から SMTP サーバーへの活動は一切検出されなかったとのことです。

これが現在の状況です。Meta に投稿します。

メールサーバーへの送信トラフィックがブロックされている可能性がありますか?そこからtelnetできますか?コンテナ内部からですか?

はい、Docker コンテナ内から telnet を使用して SMTP サーバーに正常に接続できます。ただし、プロバイダーがそれ以降のコマンドを送信すると接続を切断するため、telnet でテストメールを送信することはできません。

解決策はシンプルでした。プロバイダーが上記のポートを示していましたが、587 に telnet 接続すると動作していることがわかりました。そこで app.yml を変更し、再構築を実行したところ、問題なく動作しました :smiley:

これを見る前、私はこの変更を推奨しようとしていました。

ポート 465 は SMTP-over-SSL で、非推奨です。
ポート 587 は MSA ポート(メール送信エージェント)であり、通常、STARTTLS(平文から TLS 接続へのアップグレード)がサポートされています。

設定に 465 を指定していた場合、Discourse は平文で SSL ポートと通信しようとしていました。

@supermathie さん、ありがとうございます。あなたの回答を解決策として採用しました。明確な説明でした。

こんにちは @supermathie

RFC 8314 に従い、ポート465は(廃止から)復活した(または復活の過程にあります)。私の現在のメールプロバイダー(mailfence.com)もこの推奨事項に従っているようです。

ポート465を使用した接続でTLSを強制する方法はありますか?これで問題が解決するはずです。容器内から swaks を使用して確認したところ、STARTTLS (–tls) は失敗しますが、–tls-on-connect (–tlsc) は正常に動作しました:

swaks --to user@example.com --from myuser@mailfence.com --server smtp.mailfence.com:465 --auth LOGIN --tlsc --auth-user myuser@mailfence.com

よろしくお願いいたします。

ああ、TLS 経由の送信用に再利用されているのですね。それは理にかなっています。

現時点ではありません。smtp_settings:ssl = true を設定すると ActionMailer がそれをサポートしている ようですが、現在それを有効にするコードパスはありません。

そのサポートを追加する PR があれば、ぜひ歓迎したいと考えています。