Discussão com outros sites, problema de SMTP: Fim de arquivo alcançado

(para a equipe: isso não tem relação com a assinatura hospedada à qual minha conta também está associada)

Instalei o Discourse em um VPS usando as instruções de Run other websites on the same machine as Discourse, mas com uma diferença: adaptei o app.yml antes da primeira instalação:

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

No YAML, comentei a seção de portas, adicionei - "templates/web.socketed.template.yml" e configurei o hostname + SMTP:

  ## TODO: O nome de domínio ao qual esta instância do Discourse responderá
  ## Obrigatório. O Discourse não funcionará com um IP puro.
  DISCOURSE_HOSTNAME: 'discuss.mydomain.community'

  ## TODO: Lista de e-mails separados por vírgula que serão definidos como administradores e desenvolvedores
  ## no cadastro inicial, exemplo 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'someuser@protonmail.com,anotheruser@otherdomain.io'

  ## TODO: O servidor SMTP usado para validar novas contas e enviar notificações
  # Endereço, nome de usuário e senha do SMTP são obrigatórios
  # AVISO: o caractere '#' na senha do SMTP pode causar problemas!
  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           # (opcional, padrão true)

Em seguida, inicializei e iniciei o aplicativo Discourse:

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

Isso funcionou. Parei o Discourse e configurei o Nginx externo (em /etc/nginx/conf.d/discourse.conf) com a configuração sugerida apenas HTTP (apenas para testes). Consegui acessar http://discuss.mydomain.community.

Parei o Discourse novamente e, com o certbot, atualizei o discourse.conf e agora tenho:

server {
	server_name discuss.mydomain.community;  # <-- altere isso

	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; # gerenciado pelo Certbot
    listen 443 ssl; # gerenciado pelo Certbot
    ssl_certificate /etc/letsencrypt/live/discuss.mydomain.community/fullchain.pem; # gerenciado pelo Certbot
    ssl_certificate_key /etc/letsencrypt/live/discuss.mydomain.community/privkey.pem; # gerenciado pelo Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # gerenciado pelo Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # gerenciado pelo Certbot

}
server {
    if ($host = discuss.mydomain.community) {
        return 301 https://$host$request_uri;
    } # gerenciado pelo Certbot


	listen 80; listen [::]:80;
	server_name discuss.mydomain.community;
    return 404; # gerenciado pelo Certbot
}

Até agora, tudo bem. Consigo acessar o Discourse via HTTPS (mais tarde, quando as coisas não funcionaram, fiz um ./launcher rebuild app, mas isso não fez diferença).

Na tela de «Finalizar instalação», após enviar o formulário de registro, recebo «Enviamos um e-mail de ativação para someuser@protonmail.com» .

Problema: nenhum e-mail chega.

Nenhum e-mail chega na caixa de entrada do administrador. Verifiquei a caixa de entrada de mydomain-no-reply@otherdomain.io e também não há nada.

Nota: O problema inteiro pode ser causado porque o usuário de e-mail está em otherdomain.io e deve residir em mydomain.community. Mas, até onde sei, isso não é um requisito.

Comecei a solucionar o problema e, subsequentemente, testei com as seguintes alterações no app.yml (com um rebuild do app no meio):

  DISCOURSE_SMTP_ENABLE_START_TLS: false

Sem sucesso. Continuando:

## Se você quiser definir o endereço de e-mail «De» para seu primeiro registro, descomente e altere:
  - exec: rails r "SiteSetting.notification_email='mydomain-no-reply@otherdomain.io"

Então, prossegui com Troubleshoot email on a new Discourse install :

  • otherdomain.io tem DKIM e SPF configurados corretamente no DNS
  • Usar telnet do VPS para o provedor SMTP funciona
  • Usar telnet do contêiner Docker (com docker exec e instalação do telnet) também funciona

Executei ./discourse-doctor e duas partes se destacaram (o restante dos resultados estava conforme o esperado):

========================================
Versão do Discourse em discuss.mydomain.community: Discourse 2.6.0.beta2 
Versão do Discourse em localhost: NÃO ENCONTRADO
==================== PROBLEMA DE DNS ====================
Este servidor reporta NÃO ENCONTRADO, mas discuss.mydomain.community reporta Discourse 2.6.0.beta2 .
Isso sugere que você tem um problema de DNS ou que um proxy intermediário é o culpado.
Se você estiver usando Cloudflare ou uma CDN, pode estar configurado incorretamente.
==================== TESTE DE E-MAIL ====================
Para um teste robusto, obtenha um endereço em http://www.mail-tester.com/
Enviando e-mail para REDACTED  . . 
Testando o envio para test-k86jiyqb9@srv1.mail-tester.com usando smtp.myprovider.email:465.
======================================== ERRO ========================================
                                    ERRO INESPERADO

fim do arquivo alcançado

====================================== SOLUÇÃO =======================================
Este não é um erro comum. Não existe solução recomendada!

Por favor, reporte a mensagem de erro exata acima em https://meta.discourse.org/
(E uma solução, se você encontrar uma!)

Tentei duas vezes. Uma vez com o e-mail configurado e outra com um fornecido pelo mail-tester.com. Mesmos resultados. Então, isso não parece bom.

Nota: Aparentemente, o procedimento de instalação do Docker também serve versões beta. Bom saber.

Olhando o log de produção, ele mostra:

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

Esperei um pouco e, em seguida, solicitei via navegador «Reenviar e-mail de notificação». O seguinte foi adicionado ao log de produção:

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

Entrei em contato com meu provedor de hospedagem para ver se o problema estava do lado deles. Eles disseram que, segundo eles, essa configuração deveria funcionar bem, mas que o VPS não causou nenhuma atividade no servidor SMTP.

Então, essa é minha situação atual.. postando no Meta.

Será que o tráfego de saída para o servidor de e-mail está sendo bloqueado? Você consegue fazer telnet até lá? De dentro do container?

Sim, consigo conectar com sucesso ao servidor SMTP usando telnet de dentro do contêiner Docker. No entanto, não consigo enviar um e-mail de teste com o telnet, pois meu provedor não permite isso (fecha a conexão ao receber comandos adicionais).

A solução parecia simples. Embora meu provedor indique a porta acima, fiz um telnet na porta 587 e verifiquei que funcionava. Então, alterei o app.yml, executei um rebuild… e tudo funcionou perfeitamente :smiley:

Antes de ver isso, eu ia recomendar essa mudança.

A porta 465 é SMTP sobre SSL, que está obsoleta.
A porta 587 é a porta MSA (agente de envio de e-mail), na qual o STARTTLS (atualização de uma conexão em texto simples para uma conexão TLS) é normalmente suportada.

Quando você tinha a porta 465 na configuração, o Discourse tentava se comunicar em texto simples com uma porta SSL.

Obrigado, @supermathie, coloquei sua resposta como solução. Explicação clara.

Olá @supermathie

Aparentemente, a porta 465 foi (ou está em processo de ser) revalidada conforme o RFC 8314. Meu provedor de e-mail atual (mailfence.com) parece seguir essa recomendação.

Existe alguma maneira de forçar o TLS na conexão usando a porta 465? Isso deve resolver meu problema, pois verifiquei com swaks que o uso de STARTTLS (–tls) falha, enquanto o uso de --tls-on-connect (–tlsc) funciona perfeitamente dentro do container:

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

Abraços,

Ah, ela está sendo reutilizada para submission sobre TLS, o que faz sentido.

Não no momento. Parece que o ActionMailer suporta isso quando você define :ssl = true em smtp_settings, mas não temos um caminho de código no momento para habilitar isso.

Tenho certeza de que receberíamos com prazer um PR que adicionasse esse suporte.