Ir para o conteudo principal

Configurar DANE/TLSA com Postfix, Bind e Let's Encrypt

Por CaptainDNS
Publicado em 22 de fevereiro de 2026

Diagrama de arquitetura mostrando Postfix, Bind9 e Let's Encrypt conectados por DANE/TLSA
TL;DR
  • DANE/TLSA vincula o certificado TLS do seu servidor de email a um registro DNS assinado por DNSSEC, eliminando a dependência das autoridades certificadoras
  • A combinação recomendada é 3 1 1 (DANE-EE, SPKI, SHA-256): o hash TLSA sobrevive às renovações do Let's Encrypt enquanto a chave privada não mudar
  • O Postfix suporta nativamente a verificação DANE de saída com smtp_dns_support_level = dnssec e smtp_tls_security_level = dane
  • A automação é feita por um deploy-hook do Certbot que regenera o hash TLSA e recarrega a zona Bind9 a cada renovação
  • Verifique sua implantação com dig TLSA, openssl s_client e o inspetor DANE/TLSA CaptainDNS

Você gerencia um servidor de email Postfix e quer proteger suas conexões SMTP contra ataques do tipo downgrade ou man-in-the-middle? DANE (DNS-based Authentication of Named Entities) é a resposta. Ao publicar um registro TLSA na sua zona DNS assinada por DNSSEC, você indica aos servidores remotos qual certificado TLS o seu servidor deve apresentar. Nenhum intermediário, nenhuma autoridade certificadora em quem confiar.

O desafio com o Let's Encrypt é a renovação automática a cada 90 dias. Se o hash TLSA não corresponder mais ao certificado, os servidores que verificam DANE recusarão a conexão. Este tutorial cobre a configuração completa da stack Postfix + Bind9 + Let's Encrypt + DANE, incluindo a automação da renovação para evitar qualquer interrupção.

Este guia é voltado para administradores de sistema Linux que gerenciam um servidor de email self-hosted. Ele pressupõe um conhecimento básico de Postfix, DNS e da linha de comando. Para os fundamentos de DANE e TLSA, consulte nosso guia completo DANE/TLSA (primeiro artigo desta série).

Pré-requisitos

Antes de começar, verifique se você dispõe de:

ComponenteVersão mínimaVerificação
Debian/Ubuntu12+ / 22.04+cat /etc/os-release
Postfix3.4+ (suporte DANE nativo)postconf mail_version
Bind99.18+ (DNSSEC inline-signing)named -v
Certbot2.0+certbot --version
DNSSEC ativoZona assinada + DS no registrardig +dnssec captaindns.com SOA

Se o DNSSEC ainda não estiver ativo na sua zona, este é o pré-requisito. O Bind9 9.18+ suporta inline-signing, que simplifica o gerenciamento. Ative-o antes de continuar.

Portas e acesso à rede

O Postfix utiliza a porta 25 (SMTP) e opcionalmente a 587 (submission). O Let's Encrypt requer a porta 80 ou 443 para o desafio HTTP-01 (ou um desafio DNS-01 se a porta 80 não estiver disponível no servidor de email). Certifique-se de que essas portas estejam abertas no seu firewall.

Arquitetura da stack Postfix, Bind9 e Let's Encrypt com DANE/TLSA

Configurar DNSSEC com Bind9

Se sua zona já está assinada por DNSSEC, pule para a próxima seção. Caso contrário, veja a configuração mínima com Bind9 e inline-signing.

Ativar o inline-signing

No seu arquivo de configuração de zona (/etc/bind/named.conf.local ou equivalente):

zone "captaindns.com" {
    type primary;
    file "/var/lib/bind/captaindns.com.zone";
    dnssec-policy default;
    inline-signing yes;
    key-directory "/var/lib/bind/keys";
};

A diretiva dnssec-policy default gera e gerencia automaticamente as chaves ZSK e KSK. O inline-signing assina a zona em tempo real sem modificar o arquivo fonte.

Publicar o DS no registrar

Após o primeiro carregamento da zona, o Bind9 gera as chaves. Recupere o DS record:

# Listar as chaves geradas
ls /var/lib/bind/keys/

# Extrair o DS record (adaptar o nome do arquivo KSK)
dnssec-dsfromkey /var/lib/bind/keys/Kcaptaindns.com.+013+xxxxx.key

Transmita o DS record ao seu registrar (interface web ou API). A propagação leva de alguns minutos a 48 horas dependendo do registrar.

Verificar a cadeia DNSSEC

dig +dnssec +short captaindns.com SOA
# Deve retornar o SOA com o flag "ad" (Authenticated Data)

dig +dnssec captaindns.com DNSKEY
# Deve retornar as DNSKEY com as assinaturas RRSIG

Gerar o certificado Let's Encrypt

Obter o certificado

# Instalação do Certbot (se ainda não estiver instalado)
apt install certbot

# Obter um certificado para o hostname do servidor de email
certbot certonly --standalone -d mail.captaindns.com

Se a porta 80 já estiver sendo usada por outro serviço, utilize o plugin webroot ou o desafio DNS-01:

# Alternativa com webroot (se Apache/Nginx estiver rodando no servidor)
certbot certonly --webroot -w /var/www/html -d mail.captaindns.com

# Alternativa com desafio DNS (se porta 80 indisponível)
certbot certonly --manual --preferred-challenges dns -d mail.captaindns.com

Configurar o Postfix para usar o certificado

Edite /etc/postfix/main.cf:

# Certificado TLS (recepção - smtpd)
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.captaindns.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.captaindns.com/privkey.pem
smtpd_tls_security_level = may
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

# Verificação DANE de saída (smtp)
smtp_dns_support_level = dnssec
smtp_tls_security_level = dane
smtp_tls_loglevel = 1

Os dois blocos servem funções diferentes: smtpd_tls_* configura o TLS para as conexões de entrada (seu servidor apresenta o certificado), enquanto smtp_tls_* configura o TLS para as conexões de saída (o Postfix verifica o TLSA do destinatário).

Recarregue o Postfix:

postfix reload

Criar o registro TLSA

Escolher os parâmetros TLSA

A combinação recomendada pela RFC 7672 para SMTP é 3 1 1:

CampoValorSignificado
Usage3 (DANE-EE)Verificação direta do certificado do servidor
Selector1 (SPKI)Hash da chave pública (não do certificado inteiro)
Matching type1 (SHA-256)Hash SHA-256

A vantagem do selector SPKI (1): o hash não muda quando você renova o certificado Let's Encrypt, desde que a chave privada permaneça a mesma. Isso é essencial para evitar atualizar o TLSA a cada renovação.

Gerar o hash TLSA

# Extrair o hash SPKI SHA-256 do certificado
openssl x509 -in /etc/letsencrypt/live/mail.captaindns.com/cert.pem \
  -pubkey -noout | \
  openssl pkey -pubin -outform DER | \
  openssl dgst -sha256 -binary | \
  xxd -p -c 64

O resultado é uma string hexadecimal de 64 caracteres, por exemplo:

a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890

Você também pode usar o gerador DANE/TLSA CaptainDNS para gerar o registro sem precisar de comandos.

Adicionar o TLSA na zona Bind9

O nome do registro TLSA segue o formato _port._protocol.hostname. Para a porta 25 (SMTP):

_25._tcp.mail.captaindns.com. IN TLSA 3 1 1 a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890

Adicione essa linha ao seu arquivo de zona, incremente o serial do SOA e recarregue:

# Recarregar a zona (Bind9 assina automaticamente com inline-signing)
rndc reload captaindns.com

Verificar a publicação

# Verificar que o TLSA está publicado e assinado
dig +dnssec _25._tcp.mail.captaindns.com TLSA

# Resultado esperado: o TLSA com as RRSIG

Automatizar a renovação

Esta é a parte crítica. O Let's Encrypt renova o certificado a cada 90 dias. Se você usar DANE-EE com SPKI (3 1 1), o hash não muda enquanto o Certbot reutilizar a mesma chave privada. Mas é preciso garantir isso e prever o caso em que a chave mude.

Estratégia de conservação da chave

Por padrão, o Certbot gera uma nova chave a cada renovação. Para conservar a mesma chave (e portanto o mesmo hash TLSA), adicione a opção --reuse-key:

# Forçar a reutilização da chave privada
certbot certonly --standalone -d mail.captaindns.com --reuse-key

Ou adicione em /etc/letsencrypt/renewal/mail.captaindns.com.conf:

[renewalparams]
reuse_key = True

Deploy-hook para a atualização automática

Mesmo com --reuse-key, é prudente configurar um deploy-hook que verifique o hash e atualize o TLSA se necessário. Crie o script /etc/letsencrypt/renewal-hooks/deploy/update-tlsa.sh:

#!/bin/bash
# Deploy-hook Certbot: atualização TLSA se o hash SPKI mudar

DOMAIN="mail.captaindns.com"
ZONE="captaindns.com"
ZONE_FILE="/var/lib/bind/captaindns.com.zone"
CERT="/etc/letsencrypt/live/$DOMAIN/cert.pem"

# Calcular o novo hash SPKI SHA-256
NEW_HASH=$(openssl x509 -in "$CERT" -pubkey -noout | \
  openssl pkey -pubin -outform DER | \
  openssl dgst -sha256 -binary | \
  xxd -p -c 64)

# Recuperar o hash atual no DNS
CURRENT_HASH=$(dig +short _25._tcp.$DOMAIN TLSA | awk '{print $4}')

if [ "$NEW_HASH" != "$CURRENT_HASH" ]; then
  echo "TLSA hash changed, updating zone..."

  # Substituir o hash no arquivo de zona
  sed -i "s/\(IN TLSA 3 1 1 \)[a-f0-9]\{64\}/\1$NEW_HASH/" "$ZONE_FILE"

  # Incrementar o serial (formato YYYYMMDDNN)
  CURRENT_SERIAL=$(grep -oP '\d{10}' "$ZONE_FILE" | head -1)
  NEW_SERIAL=$((CURRENT_SERIAL + 1))
  sed -i "s/$CURRENT_SERIAL/$NEW_SERIAL/" "$ZONE_FILE"

  # Recarregar a zona
  rndc reload "$ZONE"

  echo "TLSA updated: $NEW_HASH"
else
  echo "TLSA hash unchanged, no update needed."
fi

# Recarregar o Postfix para usar o novo certificado
postfix reload

Torne o script executável:

chmod +x /etc/letsencrypt/renewal-hooks/deploy/update-tlsa.sh

Testar a renovação

# Simular uma renovação (dry-run)
certbot renew --dry-run

# Forçar uma renovação real (para testar o hook)
certbot renew --force-renewal

Fluxo de renovação automática: o Certbot renova o certificado, o deploy-hook verifica o hash SPKI e atualiza o TLSA no Bind9 se necessário

Estratégia de rollover SPKI (troca de chave)

Se você precisar regenerar a chave privada (comprometimento, migração), publique o novo TLSA antes de implantar o novo certificado. A RFC 7671 recomenda um período de dupla publicação:

  1. Gerar a nova chave e calcular seu hash SPKI
  2. Publicar os dois TLSA na zona (antigo + novo)
  3. Aguardar a propagação DNS (2x TTL no mínimo)
  4. Implantar o novo certificado
  5. Remover o TLSA antigo após a propagação
; Duplo TLSA durante a transição
_25._tcp.mail.captaindns.com. IN TLSA 3 1 1 <hash-antigo>
_25._tcp.mail.captaindns.com. IN TLSA 3 1 1 <hash-novo>

Verificar a configuração

Verificação DNS

# Verificar o TLSA
dig +short _25._tcp.mail.captaindns.com TLSA
# Esperado: 3 1 1 <hash-64-chars>

# Verificar DNSSEC
dig +dnssec _25._tcp.mail.captaindns.com TLSA | grep -c "RRSIG"
# Esperado: >= 1

Verificação TLS

# Testar a conexão TLS com verificação TLSA
openssl s_client -connect mail.captaindns.com:25 -starttls smtp \
  -dane_tlsa_domain mail.captaindns.com \
  -dane_tlsa_rrdata "3 1 1 $(dig +short _25._tcp.mail.captaindns.com TLSA | awk '{print $4}')"

O resultado deve exibir Verification: OK e DANE TLSA 3 1 1 matched EE certificate.

Verificação do Postfix de saída

Verifique se o Postfix está verificando corretamente o DANE para os emails de saída:

# Enviar um email de teste e verificar os logs
echo "Test DANE" | mail -s "DANE test" test@gmail.com
grep "Verified TLS connection" /var/log/mail.log | tail -5

Os logs devem mencionar dane no nível de segurança.

Verificação online

Use o verificador de sintaxe DANE/TLSA CaptainDNS para validar a sintaxe do seu registro, e depois o inspetor DANE/TLSA para uma verificação completa incluindo a cadeia DNSSEC.

Plano de ação recomendado

Implantação DANE completa em um servidor de email self-hosted em 6 etapas
  1. Configurar dnssec-policy default e inline-signing yes na zona Bind9. Publicar o DS record no registrar. Verificar a cadeia de confiança com dig +dnssec.

  2. Executar certbot certonly --standalone -d mail.captaindns.com --reuse-key para obter o certificado com conservação da chave privada.

  3. Editar main.cf com os caminhos do certificado (smtpd_tls_*), ativar a verificação DANE de saída (smtp_dns_support_level = dnssec, smtp_tls_security_level = dane).

  4. Gerar o hash SPKI SHA-256 com openssl, adicionar o registro _25._tcp.mail.captaindns.com. IN TLSA 3 1 1 &lt;hash&gt; na zona, recarregar com rndc reload.

  5. Criar o deploy-hook /etc/letsencrypt/renewal-hooks/deploy/update-tlsa.sh que compara os hashes SPKI e atualiza o TLSA se necessário. Testar com certbot renew --force-renewal.

  6. Validar com dig TLSA, openssl s_client -dane_tlsa_domain, os logs do Postfix e o inspetor DANE/TLSA CaptainDNS.

FAQ

Como gerar um registro TLSA para o Let's Encrypt?

Use o comando openssl x509 -in cert.pem -pubkey -noout | openssl pkey -pubin -outform DER | openssl dgst -sha256 -binary | xxd -p -c 64 para extrair o hash SPKI SHA-256. O resultado de 64 caracteres hexadecimais forma os dados do TLSA com os parâmetros 3 1 1.

É necessário atualizar o TLSA a cada renovação do Let's Encrypt?

Não, se você usar --reuse-key com o Certbot e a combinação DANE-EE/SPKI (3 1 1). O hash SPKI depende da chave pública, não do certificado. Enquanto a chave privada permanecer a mesma, o hash não muda. Configure um deploy-hook de verificação por segurança.

Como ativar a verificação DANE no Postfix?

Adicione smtp_dns_support_level = dnssec e smtp_tls_security_level = dane em /etc/postfix/main.cf. O Postfix verificará automaticamente os TLSA dos domínios destinatários via DNSSEC. Se o TLSA estiver ausente ou inválido, o Postfix volta ao TLS oportunista.

O DANE funciona com certificados autoassinados?

Sim. Com DANE-EE (usage 3), o certificado é validado pelo TLSA no DNS, não por uma autoridade certificadora. Um certificado autoassinado com um TLSA correto e uma zona DNSSEC válida é aceito pelos servidores que verificam DANE.

Como testar se o DANE está configurado corretamente?

Três níveis de verificação: 1) dig +dnssec _25._tcp.mail.captaindns.com TLSA para o DNS, 2) openssl s_client -connect mail.captaindns.com:25 -starttls smtp -dane_tlsa_domain para a correspondência certificado/TLSA, 3) o inspetor DANE/TLSA CaptainDNS para um relatório completo incluindo a cadeia DNSSEC.

O Bind é obrigatório ou é possível usar outro servidor DNS?

O Bind9 não é obrigatório. Qualquer servidor DNS com suporte a DNSSEC funciona: NSD, Knot DNS, PowerDNS. Os princípios são idênticos, apenas a sintaxe de configuração muda. O Bind9 é usado neste tutorial por ser o mais difundido em servidores Linux e porque seu inline-signing simplifica o gerenciamento DNSSEC.

O que acontece se o TLSA não corresponder mais ao certificado?

Os servidores que verificam DANE (como o Postfix com dane ou o Gmail) recusarão estabelecer a conexão TLS e voltarão ao modo não criptografado ou rejeitarão a mensagem, dependendo da política. Por isso a dupla publicação TLSA durante as rotações de chave é essencial. Se o seu TLSA estiver dessincronizado, remova-o temporariamente para voltar ao TLS oportunista enquanto corrige.

📚 Guias de DANE/TLSA relacionados

Fontes

Artigos relacionados