Configurar email de entrada para entrega direta em sites hospedados por você com Mail-Receiver

Olá! Tenho um problema estranho em que configurei isso seguindo o guia, e funciona muito bem! No entanto, algo deu errado com o e-mail de saída, que eu pensei que não seria afetado por nada disso. O Sidekiq apresenta o seguinte erro para cada e-mail tentado (todos presos na lista de Retentativas) desde que ativei o mail-receiver:

Jobs::HandledExceptionWrapper: Wrapped OpenSSL::SSL::SSLError: SSL_read: unexpected eof while reading

Minha pesquisa me leva a acreditar que isso está relacionado ao TLS de alguma forma. Eu descomentei as linhas relacionadas ao TLS no arquivo .yml, mas comentá-las novamente também não resolveu o problema. Tentei as instruções no guia para resolver conflitos do Postfix, mas aparentemente não tenho Postfix? (O diretório /etc/postfix no guia não existe na minha instância, nem ele reconhece o postfix como um serviço.) E de acordo com os resultados do netstat, apenas o docker-proxy está usando a porta 25.

Estamos usando o Gmail como serviço SMTP de saída e, na verdade, estávamos usando o Gmail para a pesquisa POP3 de entrada antes disso. Eu excluí vários registros MX apontando para o Google, mas o guia disse para fazer isso.

Este é o meu mail-receiver.yml, com certos detalhes omitidos, é claro:

## este é o template do container do receptor de e-mail
##
## Após fazer alterações neste arquivo, VOCÊ DEVE reconstruir
## /var/discourse/launcher rebuild mail-receiver
##
## TENHA MUITO CUIDADO AO EDITAR!
## ARQUIVOS YAML SÃO SUPER SUPER SENSÍVEIS A ERROS DE ESPAÇAMENTO OU ALINHAMENTO!
## visite http://www.yamllint.com/ para validar este arquivo conforme necessário

base_image: discourse/mail-receiver:release
update_pups: false

expose:
  - "25:25"   # SMTP

env:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8

  ## Para onde o e-mail para o seu fórum deve ser enviado. Em geral, é perfeitamente aceitável
  ## usar o mesmo domínio do fórum aqui.
  MAIL_DOMAIN: discourse.[mydomain].org
# descomente estas (e o volume abaixo!) para suportar TLS
  POSTCONF_smtpd_tls_key_file:  /letsencrypt/discourse.[mydomain].org/discourse.[mydomain].org.key
  POSTCONF_smtpd_tls_cert_file:  /letsencrypt/discourse.[mydomain].org/fullchain.cer
  POSTCONF_smtpd_tls_security_level: may


  ## A URL base para esta instância do Discourse.
  ## Esta será a URL do seu site Discourse. Por exemplo,
  ## https://discourse.example.com. Se você estiver executando uma configuração de subpasta,
  ## certifique-se de levá-la em consideração (ou seja, https://example.com/forum).
DISCOURSE_BASE_URL: 'https://discourse.[mydomain].org'

  ## A chave API principal do seu fórum Discourse. Você pode obtê-la na
  ## aba \"API\" do seu painel de administração.
  DISCOURSE_API_KEY: [myapikey]

  ## O nome de usuário a ser usado para processar e-mails de entrada. A menos que você tenha
  ## renomeado o usuário `system`, você deve deixar isso como está.
  DISCOURSE_API_USERNAME: system

volumes:
  - volume:
      host: /var/discourse/shared/mail-receiver/postfix-spool
      guest: /var/spool/postfix
# descomente para suportar TLS
  - volume:
      host: /var/discourse/shared/standalone/letsencrypt
      guest: /letsencrypt

A tecnologia de e-mail está um pouco fora da minha especialidade, então agradeço qualquer conselho, mesmo que seja para apontar que perdi algo estúpido ao configurar isso. Obrigado!

1 curtida

Como você pensou, não tem nada a ver com o receptor do pescoço. O host pelo qual você está enviando e-mails tem um certificado SSL quebrado.

Bem, eu descobri depois de muita solução de problemas. O problema provavelmente surgiu do fato de que o domínio em que hospedamos nossa instância do Discourse não é o mesmo que o domínio em que nossos registros MX estavam. Assim que superei essa confusão, tudo se encaixou.

É definitivamente meu próprio erro estúpido, mas o guia contribuiu um pouco para minha confusão com isto:

Não está muito claro que as duas entradas forum.example.com não precisam ser idênticas, e no meu caso elas precisavam ser diferentes. Talvez as pessoas que usam este guia devam ter experiência suficiente para saber disso, mas eu não tinha. Então estou deixando isso aqui para qualquer outra pessoa que possa encontrar um problema semelhante. Aprendi algumas coisas sobre DNS que eu não sabia, então esta foi uma boa experiência de aprendizado, e tudo está funcionando muito bem agora. :slight_smile:

Bem, falei cedo demais. O e-mail de saída funciona bem, as respostas de entrada parecem funcionar bem, mas o envio para o endereço de e-mail de uma categoria está falhando silenciosamente. Copiei e colei o endereço diretamente das configurações em um novo e-mail, então sei que não há erros de digitação.

Os logs do meu mail-receiver basicamente têm três tipos de entradas. A bem-sucedida, que foi uma resposta por e-mail a uma postagem existente, se parece com isto:

Sep 20 16:59:44 discourse-mail-receiver postfix/smtpd[277]: connect from server168-1.web-hosting.com[68.65.122.144]
Sep 20 16:59:45 discourse-mail-receiver postfix/smtpd[277]: NOQUEUE: reject: RCPT from server168-1.web-hosting.com[68.65.122.144]: 454 4.7.1 <[category]@discourse.[domain].org>: Relay access denied; from=<ryan@[redacted].com> to=<[category]@discourse.[domain].org> proto=ESMTP helo=<server168-1.web-hosting.com>
<22>Sep 20 16:59:45 policyd-spf[288]: : prepend Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=[redacted]; helo=server168-1.web-hosting.com; envelope-from=ryan@[redacted].com; receiver=discourse.[domain].org Sep 20 16:59:45 discourse-mail-receiver postfix/cleanup[281]: 4CCED114200: message-id=<20240920165945.4CCED114200@discourse-mail-receiver.localdomain>
Sep 20 16:59:45 discourse-mail-receiver postfix/smtpd[277]: disconnect from server168-1.web-hosting.com[68.65.122.144] ehlo=1 starttls=0/1 mail=1 rcpt=0/1 data=0/1 quit=1 commands=3/6

Além disso, há dois tipos de (o que presumo serem) erros, cada um se repetindo bastante. O primeiro se parece com:

Sep 20 17:00:23 discourse-mail-receiver postfix/qmgr[124]: 5D162FC26D: from=<double-bounce@discourse-mail-receiver.localdomain>, size=960, nrcpt=1 (queue active)

E o outro:

Sep 20 17:00:23 discourse-mail-receiver postfix/error[293]: 8DC3BFC141: to=<postmaster@discourse-mail-receiver.localdomain>, orig_to=<postmaster>, relay=none, delay=126622, delays=126622/0.05/0/0, dsn=4.4.3, status=deferred (delivery temporarily suspended: Host or domain name not found. Name service error for name=discourse-mail-receiver.localdomain type=MX: Host not found, try again)

E aqui está como meu mailq se parece, apenas entradas como esta repetidas sem parar:

3D07BFC23D      960 Fri Sep 20 06:42:23  double-bounce@discourse-mail-receiver.localdomain
(delivery temporarily suspended: Host or domain name not found. Name service error for name=discourse-mail-receiver.localdomain type=MX: Host not found, try again)
                                         postmaster@discourse-mail-receiver.localdomain

Parte disso parece ter a ver com e-mails que o Discourse envia, que então são devolvidos por algum motivo. O mail-receiver tem alguma funcionalidade para processar esses bounces, ou eles ficarão na mailq para sempre?

Em segundo lugar, por que as respostas funcionam, mas o envio direto de e-mail para uma categoria não funciona? Obrigado novamente pela sua ajuda e paciência. :slight_smile:

[quote=“Ryan Hyer, post:514, topic:49487, username:Ryan_Hyer”]O bem-sucedido, que foi uma resposta por e-mail a uma postagem existente, se parece com isto:

...
454 4.7.1 <[category]@discourse.[domain].org>: Relay access denied;
...

[/quote]

Essas parecem ser as entradas de log para falha em um endereço de categoria, em vez de sucesso ao responder a uma postagem.

[quote=“Ryan Hyer, post:514, topic:49487, username:Ryan_Hyer”]Em segundo lugar, por que as respostas funcionam, mas o envio de e-mails diretamente para uma categoria não funciona?
[/quote]

Não tenho 100% de certeza, mas acho que relay access denied sugere que discourse.[domain].org provavelmente não é o domínio usado para MAIL_DOMAIN em mail-receiver.yml. Possivelmente, o endereço de resposta é permitido por outros meios.

Sei que o que é usado em MAIL_DOMAIN acaba em pelo menos um lugar em um arquivo de configuração do postfix, então alterá-lo provavelmente requer a reconstrução do contêiner. Você alterou MAIL_DOMAIN e, se sim, executou ./launcher rebuild mail-receiver depois?

2 curtidas

[Desculpe por acidentalmente pressionar Enter prematuramente antes de terminar minha postagem anterior]

Ainda estou quebrando a cabeça com este problema. Mas tenho uma nova ideia sobre qual pode ser o problema. Estou trabalhando com dois domínios, vamos chamá-los de [domain1] e [domain2]. Meu relay SMTP do Gmail está hospedado em [domain1]. Minha instância do Discourse, bem como meu mail-receiver, está hospedada em [domain2].

Como defino a configuração reply-by-email-address no Discourse para forçar um endereço de resposta em [domain2], quando o e-mail está sendo enviado de [domain1]? Recebo o erro SSL EOF mencionado acima ao tentar fazer isso. Presumo que haja alguma artimanha de autenticação DNS ou algo que estou perdendo.

Parece que finalmente descobri isso. Para que o endereço ‘reply-to’ esteja em um domínio diferente do relay SMTP, precisei flexibilizar algumas configurações no Google Workspace. Tudo parece estar funcionando como pretendido em ambas as direções.

1 curtida

Uma última pergunta. Mesmo que tudo funcione corretamente agora, ainda tenho um monte de entradas antigas no meu mailq. Provavelmente são e-mails que foram gerados com as configurações erradas e, portanto, ficarão presos no limbo para sempre. Prefiro simplesmente excluí-los e seguir em frente. Então, como eu limpo o mailq?

Post um pouco antigo, mas talvez a razão mais comum para o erro SSL EOF seja um conflito entre versões do OpenSSL: v1.1.1f vs v3. Atualizar o antigo 1.1.1f será a solução. E a má notícia é que, por exemplo, o Ubuntu 20.x não pode usar um mais novo, então todo o Ubuntu precisa ser atualizado.

1 curtida

Estou no fim da linha com isso, depois de passar horas. Não consigo superar esse erro do Launcher, mesmo que os nomes dos meus arquivos de configuração estejam todos em minúsculas.

“ERRO: O nome da configuração não deve conter caracteres maiúsculos, espaços ou caracteres especiais. Corrija o nome da configuração e execute novamente ./launcher.”

ao executar

./launcher rebuild mail-receiver

ou

./launcher bootstrap mail-receiver

ou

./launcher start mail-receiver

Posso ver isso aqui no código do launcher

Grrrrrrrrrr – Por favor, ajude!

Tentei tudo no post vinculado acima relacionado a locale, e tudo o que pude encontrar em outro lugar.

./launcher rebuild app — todos estão funcionando bem!

Tenho uma pista possível: isso começou a acontecer imediatamente depois que eu acidentalmente ativei o CapsLock (mas capitalizei apenas 2 das letras) ao nomear o arquivo de configuração, o que eu imediatamente desativei o CapsLock e reditei as 2 letras antes mesmo de salvá-lo.

É difícil imaginar como esse breve erro de digitação/correção poderia ter causado isso, mas talvez as maiúsculas estejam presas em um buffer em algum lugar, ou ???

Está muito acima do meu conhecimento, mas fico surpreso que a mensagem de erro não exiba a variável $config :thinking:
Com certeza ajudaria na depuração.

1 curtida

Obrigado @Canapin! - é isso que estou tentando configurar:

https://www.perplexity.ai/search/provide-the-code-lJcI4BrFQ2auuD42ehYFwA

Você pode copiar e colar todo o conteúdo da sua linha de comando?

Do seu ./launcher start mail-receiver até a mensagem de erro, bem como o nome exato do arquivo .yml?

Se eu renomear o arquivo de configuração para Mail-receiver.yml, ./launcher start Mail-receiver irá gerar

ERROR: Config name 'Mail-receiver' must not contain upper case characters, spaces or special characters. Correct config name and rerun ./launcher.

Aqui a mensagem de erro contém o nome do arquivo.

Além disso, se você executar ./launcher start aaa, ele não encontrará nenhum arquivo correspondente e listará os disponíveis. Ele apenas os seleciona da pasta, então não há mágica aqui, mas talvez ele gere algo interessante :person_shrugging:

ERROR: containers/aaa.yml does not exist or is not readable.

Available configs ( app, mail-receiver )

Valeu mesmo – consegui resolver e está funcionando.

Qual foi o problema no final? Pode ajudar outros :slight_smile:

Não houve problema, foi realmente apenas uma curva de aprendizado para entender como os vários componentes do servidor interagem para rotear domínios e e-mails. Eu nunca tinha me aprofundado em aprender sobre postfix antes. Foi divertido e aprendi muito.

A receita que finalmente cheguei é usar um mail-receiver.yml (um contêiner docker) emparelhado a cada instância do Discourse, todos compartilhando a porta 25 usando o recurso de transporte no postfix para lidar com o roteamento.

2 curtidas

Em meu servidor dedicado (rodando Ubuntu 22.04, com Postfix instalado) uso um mail-receiver.yml separado associado a cada instância do Discourse onde habilitei o recurso de postagem por e-mail.

Essa configuração cria um contêiner separado para cada instância do Discourse em meu servidor (ao lado do contêiner app típico) que recebe e processa os e-mails para sua instância correspondente do Discourse.

E-mails de entrada para todos os fóruns do Discourse no servidor são recebidos pelo Postfix através da porta 25 padrão, onde o arquivo de configuração principal do Postfix usa um “transport map” para “retransmitir” cada e-mail para seu fórum Discourse pretendido, analisando o nome do domínio no endereço “To:” do e-mail.

Portanto, além das instruções deste Tópico, eu…

  1. modifiquei o arquivo de configuração do postfix existente em: /etc/postfix/main.cf

  2. então, adicionei o arquivo correspondente postfix transport map em: /etc/postfix/transport

  1. por último, adicionei os arquivos correspondentes para criar o contêiner de e-mail para cada um dos fóruns:
    /var/discourse/containers/mail-receiver-domain1.yml
    /var/discourse/containers/mail-receiver-domain2.yml
    /var/discourse/containers/mail-receiver-domain3.yml
    /var/discourse/containers/mail-receiver-domain4.yml
    /var/discourse/containers/mail-receiver-domain5.yml

3 curtidas

Não há DISCOURSE_MAIL_ENDPOINT em mail-receiver.yml, e também há DISCOURSE_BASE_URL para alterar.

2 curtidas

Eu uso um serviço de encaminhamento de e-mail que suporta o encaminhamento de e-mails em formato JSON para um webhook.

Esta é uma opção para entrega direta de e-mail?

1 curtida