Ir para o conteúdo

Entrega de Email: o Relay SMTP Autenticado

A verificação de email, a recuperação de senha e o cadastro de MFA dependem de uma coisa: que o email crítico de segurança realmente chegue. Provedores de nuvem pública costumam bloquear a porta 25 de saída, então um Keycloak ou aplicação na nuvem não consegue entregar email diretamente. Como solução provisória, a plataforma opera seu próprio relay de saída reforçado em uma infraestrutura sem restrição de saída de email, e todas as aplicações enviam para ele por TLS autenticado.

Provisório por desígnio

Este relay é uma solução transitória deliberada. As aplicações só conhecem "um endpoint de submissão SMTP com credenciais", então ele pode ser trocado depois por um provedor de email transacional apenas alterando configuração — sem mudanças no código das aplicações.

Arquitetura

flowchart LR
    subgraph Cloud["Ambientes de nuvem (porta 25 bloqueada)"]
        KC[Keycloak]
        APP[Aplicações]
    end

    subgraph Relay["Host do relay (saída irrestrita)"]
        SUB["Postfix<br/>submission :587<br/>TLS obrigatório + SASL"]
    end

    MX[Servidores de email dos destinatários]

    KC -- "STARTTLS + login SASL" --> SUB
    APP -- "STARTTLS + login SASL" --> SUB
    SUB -- "entrega direta via MX do destinatário" --> MX

O relay é uma única instância de Postfix com Cyrus SASL, provisionada por um role Ansible que fica desabilitado a menos que um deployment opte por ele. Nada no role cita um cliente: cada chamador é apenas mais uma entrada em uma lista.

Propriedades de segurança

Propriedade Como é imposta
Não é um open relay smtpd_relay_restrictions = permit_sasl_authenticated, reject — não há permit_mynetworks nem fallback aberto. Até uma conexão loopback precisa fazer login
Não é um servidor de email de entrada O listener smtp (porta 25) simples é removido do master.cf; o host expõe apenas o serviço submission na 587
Criptografia obrigatória smtpd_tls_security_level = encrypt — credenciais nunca são aceitas em sessão sem criptografia; SSLv2/3 e TLS 1.0/1.1 estão desabilitados
Acesso anônimo impossível smtpd_sasl_security_options = noanonymous
Identidade por chamador Uma conta SASL por chamador. Toda sessão é atribuível, e uma credencial vazada é revogada removendo essa única conta
Certificado confiável Certificado Let's Encrypt emitido e renovado automaticamente (HTTP-01), com hook de reload que reinicia o Postfix na renovação
Segredos fora dos logs As senhas das contas são tratadas com no_log na automação e nunca ficam no repositório
Rotação segura A criação de contas é create-if-missing; uma rotação é remover → aplicar → adicionar de novo, nunca uma sobrescrita silenciosa

Cadastrando um chamador

Um chamador (por exemplo, um provedor de identidade) precisa de quatro valores: o hostname do relay, a porta 587, STARTTLS e seu próprio usuário/senha. No Keycloak, eles ficam nas configurações de Email do realm:

Campo do Keycloak Valor
Host o hostname público do relay
Port 587
Enable StartTLS ligado
Authentication ligado, com a conta própria do chamador
From um endereço em um domínio que você controla

Adicionar um chamador é uma alteração de uma linha na lista de usuários do relay, seguida de um apply:

fab provide --env deployment --tags smtp_relay[smtp_relay] Install postfix + Cyrus SASL ... ok
[smtp_relay] Deploy main.cf / master.cf ... changed
[smtp_relay] Create missing SASL accounts ... changed
[smtp_relay] Issue Let's Encrypt cert for the relay hostname ... ok
[smtp_relay] Enable and start postfix ... ok

Verificando o relay

Confira a postura de segurança pelo lado de fora e depois envie uma mensagem de verdade.

nc -zv -w 3 mail-relay.example.com 25nc: connect to mail-relay.example.com port 25 (tcp) failed: Connection refused# nada escuta email de entradaopenssl s_client -starttls smtp -connect mail-relay.example.com:587 -brief </dev/null 2>&1 | grep -E "Protocol|Verification"Protocol version: TLSv1.3
Verification: OK
swaks --server mail-relay.example.com --port 587 --tls \ --to [email protected] --from [email protected]<~ 530 5.7.0 Authentication required# a submissão sem autenticação é recusadaswaks --server mail-relay.example.com --port 587 --tls \ --auth LOGIN --auth-user "$SMTP_USER" --auth-password "$SMTP_PASS" \ --to [email protected] --from [email protected]<~ 250 2.0.0 Ok: queued as 4F1C0A2B3D

Checklist de entregabilidade

Um relay só ajuda se os destinatários confiarem no email dele. Mantenha o domínio do remetente alinhado com:

  • SPF — autorize o endereço do relay no registro SPF do domínio.
  • DKIM — assine os emails de saída para o domínio do remetente.
  • DMARC — publique uma política para que os destinatários verifiquem o alinhamento.
  • DNS reverso — o IP do relay deve resolver de volta para o seu hostname.

Emails de segurança são alvo

Emails de verificação e de redefinição são exatamente o que phishers imitam. Mantenha o domínio do From fixo, mantenha os links apontando apenas para o seu host Keycloak e nunca inclua um segredo no corpo da mensagem — os links são assinados e expiram por desígnio (veja Verificação de Email e MFA).