Conectando a um servidor SMTP em localhost:25 sem autenticação?

Quais são as configurações corretas passadas para ./discourse-setup para conectar a um servidor SMTP em localhost:25 sem autenticação?

Fico muito surpreso que isso não seja suportado OOTB (fora da caixa); é a configuração padrão na maioria das instalações Linux.

Meu servidor executa o Postfix localmente; ele não é acessível pela Internet. Funciona bem, por exemplo, ao executar o comando mail. Encontrei alguns guias não oficiais na Internet sugerindo alterações em /var/discourse/containers/app.yml, e finalmente consegui instalá-lo e iniciá-lo com as seguintes configurações:

  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

Observe que, se eu omitir as variáveis DISCOURSE_SMTP_USER_NAME ou DISCOURSE_SMTP_PASSWORD, o script de instalação reclama dizendo que elas são obrigatórias (bug?).

Agora, quando clico no botão “Reenviar E-mail de Ativação” na interface web do Discourse, esta entrada aparece no arquivo de log (/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

…Mas meu tipo de autenticação é ‘none’. Qual deve ser a configuração correta para nenhuma autenticação?

EDIT: Além disso, alguém pode me enviar o link para a documentação que define todas as possíveis variáveis “DISCOURSE_SMTP_*” e todos os seus valores válidos?

EDIT2: Isso está se provando muito mais difícil do que deveria. Acredito que ‘localhost’ esteja sendo resolvido dentro do contêiner Docker para o próprio contêiner Docker do Discourse (app) — e não para o host Docker que está executando meu servidor SMTP Postfix. Isso é ainda mais complicado pelas configurações de mynetworks do Postfix e iptables (que foram configurados pelo script discourse-setup ou seus scripts filhos). Qual é a configuração correta aqui para fazer com que o Discourse use apenas o servidor SMTP no qual pretendo executar o Discourse, sem autenticação SMTP?

Acho que isso não tem sido muito verdade há cerca de 20 anos.

Você não pode usar o discourse-setup para situações como a sua, pois poucas pessoas têm servidores SMTP sem proteção por senha, mesmo atrás de um firewall.

O que eu faria seria configurar senhas SMTP para o meu servidor de e-mail. Realmente não há muita desvantagem nisso.

Se você não quiser fazer isso, acho que, em vez de “none” para autenticação, você deve usar “” (e o mesmo para senha e nome de usuário).

Acho que sim. Você pode tentar usar o nome do contêiner. Acredito que você precise verificar se ambos estão na mesma rede Docker.

Em 2019, essa é a configuração padrão do Postfix no RHEL/CentOS. O Postfix se vincula apenas à interface de loopback e rejeita todas as solicitações SMTP que não se originam de 127.0.0.0/8. Nenhuma autenticação é necessária. Não tenho certeza sobre o Debian, mas imagino que o exim tenha uma configuração padrão semelhante.

Alguns tópicos relevantes nestes fóruns de outros usuários que enfrentaram esse problema:

Parece não haver um tópico sobre como configurar isso no RHEL/CentOS com as alterações necessárias tanto no Discourse quanto no Postfix, então estou documentando isso aqui.

Isso não parece ser possível com o script discourse-setup, mas consegui fazer funcionar.

Primeiro, precisei descobrir o endereço IP do host Docker conforme visto pelo contêiner Docker. Usar 127.0.0.1 não funcionará porque o contêiner Docker verá 127.0.0.1 como ele mesmo. Em vez disso, precisamos especificar o endereço IP ou o nome de host do host Docker que está executando o servidor SMTP do Postfix, e que seja acessível pelo contêiner Docker (portanto, não o endereço IP público do seu host Docker, caso deseje que seu servidor SMTP não seja acessível pela Internet, por exemplo).

Extraí o endereço IP relevante do host Docker (172.17.0.1) da interface docker0 executando o seguinte no host Docker:

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

Em seguida, editei o arquivo YAML do meu aplicativo Discourse, definindo “DISCOURSE_SMTP_ADDRESS” para 172.17.0.1 conforme acima.

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

Observe que primeiro tentei usar o nome de host interno do Docker host.docker.internal para isso, mas aparentemente esse nome de host não está disponível para usuários do Docker no Linux.

Como a configuração padrão do Postfix no RHEL/CentOS se vincula apenas a 127.0.0.1 (o que é bom), você precisará alterar /etc/postfix/main.cf para que ele também se vincule à interface docker0 e adicionar essa sub-rede ao grupo mynetworks, de modo que o tráfego SMTP vindo dos contêineres Docker seja aceito pelo 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]$ 

Após essas alterações, reconstrua o Discourse e ele deverá agora ser capaz de enviar e-mails através do Postfix do seu host Docker.

/var/discourse/launcher rebuild app

Embora isso funcione, tenho algumas perguntas:

  1. Existe alguma outra variável de ambiente ou nome de host que já aponte para o host Docker (172.17.0.1 neste caso)?

Notei que há uma variável de ambiente DISCOURSE_HOST_IP “injetada” pelo launcher. É possível definir a chave YAML DISCOURSE_SMTP_ADDRESS com o mesmo valor que a outra chave YAML, algo assim?

DISCOURSE_SMTP_ADDRESS: $DISCOURSE_HOST_IP
  1. Em geral, quão durável é o IP 172.17.0.1 do host Docker? É sempre esse IP em sistemas RHEL/CentOS? Ele algum dia mudará para mim?

@maltfield Só queria agradecer pelas instruções.

Encontrei o mesmo problema no Debian… Poderia criar um usuário de e-mail separado para o Discourse, suponho, e fazê-lo conectar e fazer login no site:465, mas conectar à porta 25 de dentro é mais lógico, na minha opinião.

E, a propósito, no Debian 10 com o docker.io dos repositórios, o docker0 ainda é 172.17.0.1/16.

Talvez você esteja mal interpretando o que @maltfield está dizendo?

Desde que me conheço por gente (o que vai além de 20 anos), sistemas Linux ( / Unix / BSD / Solaris) possuem um servidor SMTP em execução, configurado por padrão para aceitar relatar qualquer coisa recebida do localhost sem fazer perguntas. Isso dispensa qualquer outro aplicativo rodando naquela máquina de ter que se preocupar e configurar as configurações SMTP por conta própria.

Sim, a maioria dos servidores Linux não exige autenticação para enviar e-mails (seja por padrão ou após a instalação e configuração). Também não é necessário se eles não fizerem retransmissão de nenhum lugar além da rede local. Os scripts de instalação padrão do Discourse não funcionarão na maioria dos servidores. Eles foram projetados para um conjunto restrito de soluções em nuvem baseadas em Docker.

Você pode ler minhas instruções completas e abrangentes para instalar o Discourse em um servidor dedicado e baremetal executando RHEL/CentOS 7 na wiki da Open Source Ecology. Observe a seção sobre SMTP aqui:

Bem, quase sempre sigo sua opinião sobre esses assuntos! Acredito que faz bastante tempo que não executo um servidor SMTP no localhost, então é bem provável que eu não saiba do que estou falando.

Mais uma prova de que estou errado! :man_shrugging:

Legal!

Mas o discourse-setup é destinado apenas a quem praticamente não conhece administração de sistemas. Se você sabe como instalar um servidor SMTP, consegue editar um arquivo yml.

Se o host onde o contêiner está em execução tiver um nome acessível via DNS, basta especificá-lo:

DISCOURSE_SMTP_ADDRESS: real.machine.example.com

O Postfix ainda verá que a origem do e-mail é local e o tratará dessa forma.

Se o DISCOURSE_HOSTNAME e o DISCOURSE_SMTP_ADDRESS forem os mesmos, isso causará problemas?

Configurei o Postfix e o Dovecot no host Docker para aceitar requisições autenticadas via TLS. Tenho certificados válidos para o meu servidor, mas qualquer que seja a configuração que eu tente, não consigo fazer o Discourse enviar e-mails corretamente para o Postfix rodando no host Docker.

Se eu usar o nome do host (discourse.[myhost].com), não funciona (nem sequer conecta). Se eu usar o endereço IP do host Docker (172.17.0.1), recebo

hostname "172.17.0.1" does not match the server certificate

Claramente, preciso usar o FQDN que foi usado para criar os certificados. Se eu tentar definir DISCOURSE_SMTP_ENABLE_START_TLS como false, ele diz que preciso emitir um comando start TLS. Eu realmente não quero abrir o Postfix sem TLS, então não vejo isso como uma opção viável de qualquer forma.

Usar um relay SMTP externo também não é uma opção porque não quero pagar mais apenas para garantir que os e-mails não acabem nas pastas de spam/lixo eletrônico das pessoas.

Tenho que dizer, eu tenho apenas um entendimento rudimentar de redes Docker, um entendimento ainda menor de configuração de um servidor SMTP Postfix com Dovecot para autenticação, mas não sou um completo novato, mas conseguir essa configuração de forma segura e protegida está se mostrando extremamente difícil.

@maltfield Li seu artigo sobre Open Source Ecology, mas não quero usar sem autenticação pela porta 25. A universidade onde trabalho tem protocolos muito rigorosos sobre o uso de comunicação não criptografada e não autenticada (mesmo dentro de uma configuração de rede local como esta). Eles estão muito preocupados que isso possa ser abusado por um aluno descontente.

Então, eu suspeitei que havia algo estranho em usar o mesmo nome de host para o servidor Discourse e o servidor SMTP.

Investigações adicionais revelam que o contêiner Docker adiciona a seguinte entrada ao arquivo hosts:

172.17.0.2	discourse.[mydomain].com discourse

Portanto, qualquer tentativa de usar o mesmo nome de host para o contêiner em execução e o host Docker fará com que todas as solicitações emitidas do contêiner vão para o próprio contêiner e não para o host Docker.

Que fiasco! Por que o Discourse não fornece um servidor SMTP configurado padrão no contêiner!?
OU torna mais fácil usar o Discourse sem Docker!

Dois dias da minha vida perdidos por causa desse problema.

No final, aceito o fato de que não posso usar TLS para me comunicar com o SMTP em execução no host Docker (sem obter certificados usando um nome de host diferente). Para que isso finalmente funcione, tive que garantir que 172.17.0.0/16 fosse adicionado à variável mynetworks no arquivo main.cf do Postfix:

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

Isso permite que o Postfix considere qualquer contêiner Docker em execução neste servidor como parte da rede.

Outra alteração que tive que fazer foi garantir que smtpd_sasl_security_options fosse definido como noanonymous para evitar que “estranhos” usassem o Postfix como um retransmissor SMTP. Certifique-se de que a opção noplaintext não esteja definida aqui, caso contrário, o Postfix permitirá a autenticação apenas via TLS.

smtpd_sasl_security_options = noanonymous

Com essas configurações, pude especificar as seguintes configurações em app.yml:

  DISCOURSE_SMTP_ADDRESS: 172.17.0.1                            # Endereço IP do host Docker (conforme visto de dentro deste contêiner)
  DISCOURSE_SMTP_PORT: 25
  DISCOURSE_SMTP_USER_NAME: discourse
  DISCOURSE_SMTP_PASSWORD: pa$$word
  DISCOURSE_SMTP_ENABLE_START_TLS: false                         # (opcional, padrão true)
  DISCOURSE_SMTP_DOMAIN: discourse.[meudominio].com                # (exigido por alguns provedores)
  DISCOURSE_NOTIFICATION_EMAIL: noreply@discourse.[meudominio].com # (endereço para enviar notificações)

Também criei uma conta de usuário local no host Docker apenas para fins de autenticação SASL.
Com essas alterações, finalmente consegui enviar e-mails do contêiner, mas não posso deixar de sentir que esta é uma configuração subótima. Idealmente, deveria ser possível usar o nome de host desejado para o host Docker e ter as solicitações para discourse.[meudominio].com indo para o lugar certo.

Agora preciso configurar SPF e DKIM para que os e-mails cheguem às caixas de entrada das pessoas (em vez de suas pastas de spam). Espero realmente que um dia esse processo doloroso seja mais automatizado. Talvez fornecer algumas instruções sobre como configurar o Discourse sem usar Docker (para que possa ser usado com cPanel, por exemplo…) ou tornar a configuração de e-mail menos dolorosa, fornecendo algum tipo de configuração SMTP padrão diretamente no contêiner Docker!

Se você voltar ao início dos anos 1990, era como você deseja. As coisas sobre as quais você está falando simplesmente funcionavam. Mas os spammers fizeram com que tudo se tornasse muito mais complicado. O processo só se tornará mais difícil, e é por isso que a recomendação é usar algum serviço que lide com muitas das complicações para você.

Fico feliz que sua configuração de e-mail esteja funcionando!

Houve algumas atualizações no guia de solução de problemas de e-mail desde ontem. Se você ainda não está satisfeito com sua configuração de e-mail, talvez valha a pena tentar novamente!


Pode ser resolvido usando:


… apenas resolução DNS padrão do nome de domínio para IP.

Não me entenda mal. Entendo a importância do SPF e do DKIM. É apenas irritante. Eu só queria que isso pudesse ser instalado em nossos servidores cPanel atuais, onde essas coisas já estão configuradas.

Era isso que estava faltando. Está funcionando agora com TLS.

Também fiz o DKIM funcionar, então os e-mails não devem mais ir para spam.