Firma DKIM para email transaccional — del comando openssl al registro DNS y la verificación final
Por Wilfred Teague · Publicado el 8 de marzo de 2016 · Lectura aproximada 6 min
DKIM es el componente de autenticación más técnico de los tres pilares (SPF, DKIM, DMARC) y donde más equipos se quedan a medias por falta de comprensión clara de los pasos. Este post es una guía práctica end-to-end: generación de claves RSA, publicación correcta en DNS, configuración por proveedor de envío, verificación con herramientas, y rotación periódica como hábito de operación. Sin partes opacas, sin "consulte la documentación de su proveedor".
Qué firma DKIM exactamente
DKIM (DomainKeys Identified Mail, RFC 6376) firma con clave privada un conjunto de cabeceras del email más un hash del cuerpo. La firma se añade como cabecera DKIM-Signature en el mensaje saliente. El receptor extrae esa cabecera, lee qué dominio firmó (d=) y qué selector se usó (s=), busca en DNS la clave pública correspondiente, y verifica matemáticamente que la firma es válida y que las cabeceras y cuerpo firmados no han sido modificados en tránsito.
Una cabecera DKIM-Signature típica se ve así:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=su-empresa.com; s=transactional2026;
h=from:to:subject:date:message-id;
bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
b=hyjLQqg7c8...firma_base64...
Componentes clave: d= es el dominio firmante, s= es el selector (que apunta a un registro DNS específico), h= lista las cabeceras firmadas, bh= es el hash del cuerpo, b= es la firma RSA. El receptor consulta transactional2026._domainkey.su-empresa.com en DNS para obtener la clave pública y verificar.
Generación de claves RSA
La clave DKIM es un par RSA. La práctica actual en 2026 son 2048 bits (1024 es legacy y empieza a fallar con receptores estrictos; 4096 funciona pero algunos resolvers DNS tienen problemas con registros TXT muy grandes y hay que usar split TXT records).
Generar el par con OpenSSL desde la línea de comandos:
# Generar clave privada de 2048 bits
openssl genrsa -out dkim_private.key 2048
# Extraer clave pública en formato PEM
openssl rsa -in dkim_private.key -pubout -out dkim_public.key
# Convertir clave pública a formato DNS (una sola línea sin headers)
cat dkim_public.key | grep -v "^-" | tr -d '\n'
El último comando produce el contenido que va en el registro DNS — la clave pública en base64 sin las líneas -----BEGIN PUBLIC KEY-----. Guardar la clave privada con permisos restrictivos (chmod 600) y backup seguro: si se pierde, hay que generar par nuevo y republicar en DNS.
Publicación en DNS
El registro DNS debe ir en {selector}._domainkey.{dominio} como TXT. Por ejemplo, si el selector es "transactional2026" y el dominio es "su-empresa.com":
transactional2026._domainkey.su-empresa.com. TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxYz9...QAB"
Componentes del valor TXT: v=DKIM1 es la versión obligatoria, k=rsa declara el algoritmo (rsa es default y soportado universalmente; ed25519 está emergiendo pero soporte mixto), p= es la clave pública en base64. Algunos registros incluyen t=s (modo strict, no permite subdominios) o h=sha256 (algoritmo de hash declarado).
Importante sobre el selector: es texto libre que el sender elige. Conviene usar nombres descriptivos que ayuden a futura rotación: 2026q1, transactional, marketing, backup. Algunos proveedores generan selectores automáticos (por ejemplo Mailgun usa k1 por defecto, SendGrid usa s1, s2); no hay problema en usar esos pero documentarlos en interno.
Para verificar que el registro está publicado correctamente:
dig +short TXT transactional2026._domainkey.su-empresa.com
Debería devolver el valor del registro entero. Si devuelve vacío, esperar propagación DNS (puede tardar hasta 24-48h dependiendo del TTL anterior, aunque típicamente minutos en proveedores DNS modernos).
Configuración por tipo de proveedor
La configuración varía según cómo se envía. Tres escenarios típicos cubren la mayoría de casos:
Caso A — relay SMTP de proveedor especializado. El proveedor (Authorize Hosting, SendGrid, Mailgun, Postmark, Amazon SES) gestiona la firma DKIM por defecto pero suele firmar con su propio dominio (d=sendgrid.net, d=mailgun.org). Para alignment correcto con DMARC, hay que configurar custom DKIM: el proveedor da una clave pública específica para el dominio del cliente, el cliente la publica en DNS bajo su propio dominio, el proveedor pasa a firmar con d=su-empresa.com. Este paso es crítico para alignment DMARC.
Caso B — MTA self-hosted (Postfix, Exim, KumoMTA, PowerMTA). El MTA debe configurarse para firmar DKIM. En Postfix, el módulo más común es opendkim: el daemon se ejecuta como milter, intercepta cada mensaje saliente, lee la clave privada del filesystem, calcula la firma, añade la cabecera DKIM-Signature antes de pasar el mensaje al MTA para envío. Configuración típica de opendkim.conf:
Domain su-empresa.com
KeyFile /etc/opendkim/keys/su-empresa.com/transactional2026.private
Selector transactional2026
Mode sv
Canonicalization relaxed/relaxed
SignHeaders From,Reply-To,Subject,Date,To,Cc,Message-ID,MIME-Version,Content-Type
En Exim, la firma se hace mediante el transport. En KumoMTA, vía configuración Lua. PowerMTA tiene su propio módulo. La lógica es la misma — leer clave privada, firmar headers críticos, añadir cabecera DKIM-Signature.
Caso C — multiple senders, varios proveedores. Una empresa típica tiene varios sistemas que envían: transaccional vía relay, marketing vía ESP separado, cold email vía otro relay, monitoring tools (PagerDuty, Datadog) que envían directo, support ticket system, invoicing platform. Cada uno necesita firmar DKIM con un selector propio para que la rotación de uno no afecte a los otros. Pattern típico: transactional._domainkey, marketing._domainkey, support._domainkey, invoicing._domainkey — cada selector apunta a una clave distinta operada por su proveedor respectivo.
Verificación con herramientas
Antes de declarar DKIM "configurado y funcionando", verificar end-to-end. Tres herramientas recomendadas:
mail-tester.com: enviar un email a la dirección que dan, abre un dashboard mostrando si DKIM, SPF y DMARC pasan, más detalles de spam score. Útil como verificación inicial rápida.
dkimcore.org/tools/keycheck.html: introducir dominio y selector, verifica que el registro DNS está publicado correctamente y la clave es válida.
Inspección manual del email recibido: en cualquier cliente de email moderno (Gmail "show original", Outlook view source), buscar las cabeceras Authentication-Results del receptor. Líneas como:
Authentication-Results: mx.google.com;
dkim=pass header.i=@su-empresa.com header.s=transactional2026 header.b=hyjLQqg7;
spf=pass (google.com: domain of bounce@su-empresa.com designates ...) smtp.mailfrom=bounce@su-empresa.com;
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=su-empresa.com
Aquí lo importante es ver dkim=pass y que el dominio firmante (header.i=@su-empresa.com) coincide con el del From visible. Si dice dkim=fail o el dominio firmante es del proveedor (@sendgrid.net), hay que ajustar.
Rotación periódica como hábito
Las claves DKIM deben rotarse periódicamente. La frecuencia recomendada es anual mínimo, semestral mejor. El proceso de rotación sin downtime:
Paso 1: generar nuevo par de claves con selector nuevo (transactional2027q1, por ejemplo, distinto al actual transactional2026).
Paso 2: publicar la clave pública nueva en DNS, dejando el registro antiguo activo. Ahora hay dos selectores publicados simultáneamente.
Paso 3: configurar el proveedor o MTA para empezar a firmar con el selector nuevo. Los emails recientes usan la clave nueva; emails antiguos siguen verificables con la clave antigua.
Paso 4: esperar 7-14 días para que cualquier email en cola o reintento se procese.
Paso 5: eliminar el registro DNS del selector antiguo y archivar la clave privada antigua (no borrar inmediatamente — para troubleshooting de bounces atrasados).
Este proceso protege contra el riesgo de que una clave privada se vea comprometida (incident de seguridad, error operativo, ex-empleado con acceso). Si nunca se rota, una clave comprometida puede usarse indefinidamente para suplantar al dominio.
Errores frecuentes y cómo diagnosticarlos
"DKIM signature did not verify" en logs del receptor: típicamente significa que el cuerpo del mensaje fue modificado en tránsito (algún MTA intermedio reescribió Content-Type o re-encoded el cuerpo) o que la canonicalization configurada en el firmante no es compatible. Probar canonicalization relaxed/relaxed que es la más tolerante a modificaciones menores.
Receptor reporta DKIM key not found: el registro DNS no está publicado, propagación pendiente, o el selector está mal escrito. Verificar con dig directamente desde fuera (no solo desde la red interna que puede tener cache DNS).
DKIM pasa pero DMARC falla: problema de alignment. El dominio firmante (d= de la firma DKIM) no coincide con el dominio del From visible. Solución: configurar custom DKIM en el proveedor para que firme con el dominio del cliente en lugar de su propio dominio.
Múltiples firmas DKIM, una pasa y otra falla: válido y aceptable. DMARC requiere que al menos una firma DKIM con dominio alineado pase. Si el proveedor firma con su dominio (que falla alignment) y también firma con custom DKIM del cliente (que pasa alignment), DMARC pasa correctamente.
DKIM bien configurado es invisible operativamente: emails llegan a inbox, autenticación pasa, métricas son sanas. DKIM mal configurado o ausente es ruido constante: tickets de soporte por emails que no llegan, métricas de deliverability degradadas, exposición a phishing impersonado. La diferencia entre uno y otro es el cuidado en los pasos descritos arriba.
¿Necesita ayuda con infraestructura email seria?
Authorize Hosting opera infraestructura email para equipos que se toman en serio sus envíos desde 2003. Relay SMTP, Email API, PowerMTA gestionado, servidores dedicados y deliverability gestionada con soporte directo en español.