Rotação de chaves DKIM: runbook operacional (D-7 a D+30)
Por CaptainDNS
Publicado em 19 de maio de 2026

- Definição: a rotação de chaves DKIM consiste em substituir periodicamente o par criptográfico de assinatura DKIM com dois seletores em paralelo, sem interromper o tráfego de e-mail
- Frequência recomendada: 6 a 12 meses em produção padrão, 3 meses em ambiente crítico (banca, setor público)
- Estratégia zero downtime: dois seletores em paralelo, 7 dias antes da comutação, 30 dias após a retirada
- Algoritmos: RSA 2048 mantém-se como o padrão compatível, Ed25519 em double-publish para os MTA modernos
- Armazenamento: chave privada DKIM em KMS (AWS, GCP, Vault), nunca em texto simples num repositório Git
- Automatização: cron a cada 3 a 6 meses, validação pós-rotação através dos relatórios DMARC aggregate
A rotação de chaves DKIM é uma operação recorrente, mas frequentemente subestimada. Os guias dos fornecedores (Microsoft, AWS, SendGrid) descrevem o botão "rotate" sem explicar a janela de sobreposição, o atraso de propagação DNS nem o procedimento de rollback. Este runbook colmata essa lacuna com um cronograma calendarizado D-7 a D+30, scripts openssl testados e as armadilhas reportadas no terreno.
Para a referência geral, consulte o guia completo DKIM. Aqui, o objetivo é operacional: gerar o par, publicar o seletor DKIM, comutar a assinatura, monitorizar o DMARC, retirar o seletor antigo. Público-alvo: administradores de sistemas, DevOps, SRE e equipas de infraestrutura em produção.
Audite os seletores DKIM antes da rotação
Porquê rodar as chaves DKIM?
Três razões operacionais justificam a rotação periódica.
Comprometimento da chave. Uma chave privada DKIM acaba sempre por escapar: backup não cifrado, acesso KMS legacy de um ex-colaborador, fuga de um fornecedor SaaS. A rotação limita a janela de exploração de uma fuga.
Limite criptográfico. A RFC 8301 declarou obsoletas as chaves RSA abaixo de 1024 bits já em 2018 e recomenda RSA 2048 como mínimo. Uma chave RSA 1024 publicada em 2018 é hoje rejeitada pela Google, Yahoo e Microsoft. Rodar regularmente força a substituição dos algoritmos herdados.
Higiene criptográfica. A NIST SP 800-57 Part 1 Rev. 5 recomenda criptoperíodos curtos para as chaves de assinatura: 1 a 2 anos no máximo, mais curtos para os ambientes sensíveis. Sem rotação regular, a primeira rotação forçada transforma-se num pesadelo.
DKIM2, em curso de normalização no IETF, acrescenta uma proteção contra o replay mas não elimina a necessidade de rotação. Ver DKIM2 e a proteção contra o replay.
Estratégia de rotação de chaves DKIM: seletores paralelos em vez de substituição direta
Princípio fundamental da rotação de chaves DKIM: nunca substituir uma chave DKIM por overwrite. Publicar sempre um novo seletor DKIM em paralelo, comutar a assinatura e depois retirar o seletor antigo após um período de tolerância.
Três fatores impõem a coexistência temporária:
- Cache do resolver DNS. O valor TXT de um seletor é colocado em cache durante o TTL (1 a 24 horas). Alguns resolvers ainda servem o valor antigo.
- Retry SMTP. Um MTA destinatário mantém uma mensagem em fila até 5 dias. Se o seletor for retirado demasiado cedo, a reverificação falha.
- Auditoria forense. As equipas de segurança têm de verificar a assinatura de uma mensagem recebida duas semanas antes. Um seletor retirado torna essa verificação impossível.
Convenção de nomenclatura: seletores datados trimestrais. Exemplo: s2026-q1 para janeiro a março de 2026, s2026-q2 para o seguinte. Esta convenção evita colisões com os seletores dos fornecedores (selector1 Microsoft 365, google Google Workspace, mte1 SendGrid). Os dois seletores coexistem durante a janela de sobreposição:
s2025-q4._domainkey.captaindns.com. 3600 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOC..."
s2026-q1._domainkey.captaindns.com. 3600 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOC..."
Duração mínima de sobreposição: 7 dias do lado da propagação, 30 dias do lado da retirada para cobrir os retries SMTP mais longos.
Calendário operacional da rotação de chaves DKIM
Gerar o novo par (ver a secção seguinte), armazenar a chave privada em KMS, publicar a chave pública sob o novo seletor no DNS sem ativar a assinatura do lado do MTA. A janela de 7 dias cobre a propagação DNS e permite uma verificação de integridade antes da comutação.
dig +short TXT s2026-q1._domainkey.captaindns.comO seletor antigo continua a assinar todas as mensagens de saída. Verificar o conteúdo publicado com o DKIM Record Check.
Reconfigurar o MTA para assinar com o novo seletor. A comutação deve ser atómica: evite assinar alternadamente com as duas chaves, o que complica a auditoria DMARC.
No Postfix combinado com OpenDKIM, modifique
KeyTableeSigningTable, depois recarregue. No SES BYODKIM, invoqueaws sesv2 put-email-identity-dkim-signing-attributes. No Microsoft 365, o cmdletRotate-DkimSigningConfiggere a comutação automaticamente.Durante 24 horas, analisar os relatórios DMARC. O campo
auth_results/dkim/selectordeve refletir o novo seletor para 100 % do tráfego legítimo. Qualquer vestígio do seletor antigo indica um fluxo mal reconfigurado. Limiar de alerta: 1 % de tráfego residual sobre o seletor antigo após 48 horas.Agregar os relatórios DMARC dos últimos 7 dias. Se o novo seletor cobrir 100 % do tráfego, passar a D+8. Caso contrário, prolongar a janela e analisar os fluxos residuais (cron jobs internos, aplicações legacy, fornecedor terceiro).
Desativar qualquer possibilidade técnica de assinar com o seletor antigo. O TXT público mantém-se publicado para permitir a verificação das mensagens em fila de retry.
No OpenDKIM, retirar a linha correspondente. No Vault, revogar o lease de leitura da chave antiga para impedir qualquer rollback acidental.
Eliminação definitiva do registo TXT. O prazo de 30 dias cobre os retries SMTP (até 5 dias) e as caches DNS atípicas. Após a eliminação, verificar que
dig +short TXT s2025-q4._domainkey.captaindns.comdevolve uma resposta vazia. Destruir a chave privada correspondente em KMS.
| Dia | Ação | Seletor antigo | Seletor novo |
|---|---|---|---|
| D-7 | Publicar o TXT do novo seletor | Assina e publicado | Publicado (inativo) |
| D+0 | Comutar a assinatura MTA | Publicado | Assina e publicado |
| D+1 | Monitorizar os relatórios DMARC | Publicado | Assina e publicado |
| D+7 | Validar 100 % do tráfego sobre o novo | Publicado | Assina e publicado |
| D+8 | Retirar a assinatura MTA do antigo | Publicado (congelado) | Assina e publicado |
| D+30 | Eliminar o TXT antigo | Eliminado | Assina e publicado |

Gerar o par com openssl
Quatro comandos openssl cobrem a totalidade das necessidades. Todos foram testados com OpenSSL 3.x.
RSA 2048: geração da chave privada.
openssl genrsa -out dkim_private.pem 2048
RSA 2048: extração da chave pública em base64 para o DNS.
openssl rsa -in dkim_private.pem -pubout -outform der | openssl base64 -A
O resultado é o valor a colar na etiqueta p= do registo TXT.
Ed25519: geração da chave privada.
openssl genpkey -algorithm ed25519 -out dkim_ed25519_private.pem
Ed25519: extração da chave pública em base64 (32 bytes).
openssl pkey -in dkim_ed25519_private.pem -pubout -outform der | tail -c 32 | openssl base64
O tail -c 32 é necessário: o openssl emite um cabeçalho ASN.1 de 12 bytes à frente dos 32 bytes efetivos da chave Ed25519, cabeçalho que a RFC 8463 exige retirar para p=.
Tabela comparativa das três opções realistas em 2026:
| Algoritmo | Tamanho chave pública | Tamanho assinatura | Suporte 2026 | Risco TXT split |
|---|---|---|---|---|
| RSA 2048 | ~392 caracteres | 256 bytes | Universal | Baixo (1 cadeia) |
| RSA 4096 | ~736 caracteres | 512 bytes | Universal | Alto (3 cadeias TXT) |
| Ed25519 | ~44 caracteres | 64 bytes | Parcial (Google, Fastmail, MTAs open source) | Nenhum |
Recomendação 2026: RSA 2048 sozinho para a compatibilidade máxima, ou double-publish RSA 2048 mais Ed25519 para beneficiar da assinatura Ed25519 nos recetores compatíveis. Evitar RSA 4096: a chave pública ultrapassa os 255 caracteres e impõe uma divisão TXT em várias cadeias, frágil em cada edição DNS. Para o detalhe comparativo, ver RSA vs Ed25519 para DKIM.
Gestão da chave privada
A chave privada DKIM é um segredo criptográfico do mesmo nível que uma chave TLS. Existem três modelos de armazenamento aceitáveis em produção.
KMS gerido (AWS KMS asymmetric keys, GCP Cloud KMS, Azure Key Vault). A chave é gerada e permanece no HSM. O MTA invoca a API KMS para assinar cada mensagem. A chave privada nunca é exposta na memória da aplicação, a rotação é rastreada por IAM. Desvantagem: 5 a 20 ms de latência por chamada.
HashiCorp Vault Transit. Equivalente self-hosted do KMS gerido. A chave permanece no backend Transit, o MTA assina através da API. Caminho convencional: secret/dkim/captaindns/s2026-q1.
Ficheiro PEM cifrado em repouso. Mínimo aceitável para as pequenas infraestruturas. A chave é armazenada no servidor de envio num volume cifrado (LUKS, encrypted EBS), permissões 0600, propriedade opendkim:opendkim. Implementação através de Ansible Vault, Sealed Secrets do Kubernetes ou SOPS.
Anti-padrões a banir:
- Chave privada incluída no repositório Git, mesmo em branch privado. O Git conserva o histórico para sempre.
- Chave privada passada como variável de ambiente sem cifrar (
DKIM_PRIVATE_KEY=...) num docker-compose ou ficheiro.env. - Chave privada armazenada num secret manager partilhado com contas de serviço desnecessárias (princípio do mínimo privilégio violado).
No momento da rotação, não esquecer de rodar igualmente os acessos KMS. Um ex-colaborador que tenha tido acesso de leitura a secret/dkim/captaindns/s2025-q4 não deve conservar esse acesso mesmo que a chave já não esteja ativa: continua válida para assinar mensagens retroativas.

Automatizar a rotação de chaves DKIM por cron
Uma rotação manual é esquecida nas primeiras férias da equipa. A automatização é indispensável a partir dos 3 a 4 domínios ativos. Dividir o job em 3 etapas idempotentes:
- Generate: produzir o par e armazenar a chave privada em KMS.
- Publish-DNS: invocar a API do fornecedor DNS para acrescentar o TXT.
- Switch-signing: reconfigurar o MTA após a janela D-7.
Esqueleto bash Generate + Publish-DNS no Cloudflare:
#!/bin/bash
set -euo pipefail
SELECTOR="s$(date +%Y-q%q)"
DOMAIN="captaindns.com"
ZONE_ID="${CLOUDFLARE_ZONE_ID}"
# Generate RSA 2048
openssl genrsa -out "dkim_${SELECTOR}.pem" 2048
PUB=$(openssl rsa -in "dkim_${SELECTOR}.pem" -pubout -outform der | openssl base64 -A)
# Store private key in Vault
vault kv put "secret/dkim/${DOMAIN}/${SELECTOR}" private_key=@"dkim_${SELECTOR}.pem"
# Publish DNS via Cloudflare API
curl -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
-H "Content-Type: application/json" \
--data "{\"type\":\"TXT\",\"name\":\"${SELECTOR}._domainkey\",\"content\":\"v=DKIM1; k=rsa; p=${PUB}\",\"ttl\":3600}"
# Verify publication
sleep 30
dig +short TXT "${SELECTOR}._domainkey.${DOMAIN}"
Cron: 0 3 1 */6 * (a cada 6 meses, no 1.º dia do mês às 3h UTC) desencadeia a fase Generate mais Publish-DNS, seguida 7 dias depois por um segundo cron que executa Switch-signing.
Integrações com fornecedores:
- AWS SES BYODKIM: comando
aws sesv2 put-email-identity-dkim-signing-attributescom o parDomainSigningSelectoreDomainSigningPrivateKeycodificado em base64. - Microsoft 365:
Rotate-DkimSigningConfig -Identity captaindns.com -KeySize 2048(Exchange Online PowerShell). A rotação gera um novo seletor do lado da Microsoft mas obriga a publicar o novo CNAME no DNS para ativar a nova chave. - SendGrid: a rotação é gerida através da API
POST /whitelabel/domains/{id}/validateapós acrescentar o novo CNAME junto do fornecedor DNS.
Alerta recomendado: desencadear um alarme se a taxa dkim=fail nos relatórios DMARC aggregate ultrapassar 1 % durante a janela D+0 a D+7. A validação pós-rotação é executada de modo programático através da API DKIM Record Check.

Armadilhas frequentes a evitar
Cinco armadilhas recorrentes aparecem nos tickets de suporte e nos tópicos reddit r/sysadmin.
TTL demasiado longo no seletor antigo. Um TTL de 24 horas impede a propagação rápida de uma correção. Baixar o TTL para 300 segundos 48 horas antes de D+0, depois subi-lo novamente para 3600 segundos após D+7.
Seletor com hífenes mal colocados. Alguns analisadores DKIM estritos rejeitam um seletor que contenha um hífen na primeira ou última posição. Preferir s2026q1 a -s2026-q1-.
DMARC em alinhamento estrito (adkim=s). Uma assinatura d=mail.captaindns.com é rejeitada para um From: contact@captaindns.com. Verificar que o domínio d= da nova chave se mantém idêntico ao da antiga.
Chave pública oculta do lado SaaS. Mailchimp, ActiveCampaign e outros publicam um CNAME em vez de um TXT direto. A rotação é gerida pelo fornecedor: validar que o CNAME aponta para o novo alvo após a rotação declarada.
Etiqueta s= mal configurada. A etiqueta opcional s=email restringe a utilização da chave à assinatura de mensagens eletrónicas. Uma chave publicada com s=* ou sem etiqueta aceita todos os serviços. Para o detalhe, ver a etiqueta s= no registo DKIM.
Exemplo de TXT mal codificado (wrap base64 multilinha com quebra de linha em bruto, rejeitado por alguns resolvers):
s2026-q1._domainkey.captaindns.com. IN TXT ( "v=DKIM1; k=rsa; "
"p=MIIBIjANBgkqhkiG\n"
"9w0BAQEFAAOC..." )
Exemplo correto (cadeia única ou divisão limpa em blocos de 255 caracteres):
s2026-q1._domainkey.captaindns.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
FAQ
FAQ
Com que frequência se deve rodar uma chave DKIM?
6 a 12 meses em produção para uma organização padrão, 3 meses em ambiente crítico (banca, setor público). A RFC 6376 não fixa duração mas a NIST SP 800-57 recomenda criptoperíodos curtos para as chaves de assinatura. Para além dos 18 meses, o risco de fuga (backups, ex-colaboradores, acessos KMS legacy) ultrapassa o custo operacional de uma rotação limpa.
O que fazer se os relatórios DMARC indicarem dkim=fail durante a rotação?
Verificar primeiro que o novo seletor está publicado com dig +short TXT s2026-q1._domainkey.captaindns.com, depois validar a assinatura com um DKIM record checker. Se o seletor antigo foi retirado demasiado cedo, voltar a publicá-lo com o mesmo p= e aguardar 7 dias. As caches dos resolvers (até 24 h) e os retries SMTP (até 5 dias) explicam a maioria das falhas.
É possível rodar uma chave DKIM sem downtime?
Sim, é o único modo operacional aceitável em produção. A estratégia assenta em dois seletores em paralelo: o novo publicado 7 dias antes da comutação, o antigo conservado 30 dias depois. Durante a sobreposição, ambas as assinaturas são válidas. Sem interrupção, sem mensagem rejeitada por dkim=none.
Como rodar num ambiente multi-fornecedor (M365, AWS SES, SendGrid)?
Cada fornecedor gere o respetivo seletor DKIM, pelo que as rotações são independentes mas devem ser coordenadas. Procedimento: 1) listar todos os seletores ativos através de uma auditoria DNS, 2) planear as rotações desfasadas em quinzenas para isolar as fontes de falha, 3) verificar que selector1._domainkey (M365), s2026-q1._domainkey (SES BYODKIM) e s1._domainkey (SendGrid) coexistem sem colisão.
RSA 2048, RSA 4096 ou Ed25519: o que escolher em 2026?
RSA 2048 mantém-se como o padrão compatível. Ed25519 é mais seguro e mais rápido mas exige um double-publish (k=rsa e k=ed25519) porque alguns recetores ainda não o suportam. RSA 4096 produz uma cadeia base64 superior a 255 caracteres que força o split TXT, frágil em cada edição. Recomendação: RSA 2048 sozinho, ou RSA 2048 mais Ed25519 em double-publish para os domínios com elevado tráfego.
Baixe a checklist de implementação
Assistentes podem reutilizar a checklist através dos exports JSON ou CSV abaixo.
Valide a próxima rotação de chaves DKIM: utilize o DKIM Record Check para verificar que o novo seletor DKIM está publicado e que a assinatura DKIM está correta antes e depois da comutação. Renovar uma chave DKIM sem downtime exige disciplina de calendário D-7/D+30 e instrumentação DMARC séria: consulte o guia DMARCbis para equipar a monitorização aggregate (rua). Para antecipar as evoluções do protocolo, ver também DKIM2 e a proteção contra o replay.


