DKIM (DomainKeys Identified Mail) permite que tu servidor de correo firme cada mensaje saliente con una clave privada. Los servidores que lo reciben obtienen la clave pública correspondiente de tu DNS y comprueban la firma, lo que demuestra que el mensaje procede realmente de tu dominio y no se ha modificado por el camino. Gmail, Outlook y Yahoo esperan DKIM, y es imprescindible para que una política DMARC funcione. En este tutorial instalarás OpenDKIM en Ubuntu 24.04, lo conectarás con Postfix, publicarás la clave pública en DNS y comprobarás que tus mensajes superan la verificación.
Requisitos previos
Para seguir este tutorial necesitas:
- Un servidor con Ubuntu 24.04 LTS y una instalación de Postfix que ya envíe correo, por ejemplo un VPS de CubePath.
- Un usuario no root con privilegios
sudo. - Un dominio que controles, con acceso a su zona DNS. Esta guía usa
your_domaincomo dominio de envío; sustitúyelo en todas partes por el tuyo. - Un buzón externo que puedas leer (Gmail u Outlook sirven) para comprobar el resultado.
Paso 1: Instalar OpenDKIM
OpenDKIM funciona como un milter: un demonio independiente al que Postfix entrega cada mensaje antes de enviarlo. Instala el demonio y sus herramientas:
sudo apt update
sudo apt install opendkim opendkim-tools
El paquete opendkim proporciona el servicio y el archivo /etc/opendkim.conf. El paquete opendkim-tools incluye opendkim-genkey y opendkim-testkey, que usarás en los pasos siguientes. Comprueba que el servicio se ha instalado:
systemctl status opendkim --no-pager
● opendkim.service - OpenDKIM Milter
Loaded: loaded (/usr/lib/systemd/system/opendkim.service; enabled; preset: enabled)
Active: active (running)
Paso 2: Generar el par de claves DKIM
Una clave DKIM se identifica por un selector, una etiqueta corta que forma parte del nombre DNS donde se publica la clave pública (selector._domainkey.your_domain). Usar una fecha como selector, por ejemplo 202609, facilita rotar la clave más adelante: publicas un selector nuevo, cambias a él y eliminas el antiguo.
Ubuntu incluye /etc/dkimkeys, un directorio propiedad del usuario opendkim con permisos 700, pensado para las claves privadas. Genera ahí una clave de 2048 bits:
sudo opendkim-genkey -b 2048 -d your_domain -s 202609 -D /etc/dkimkeys
Esto crea dos archivos:
/etc/dkimkeys/202609.private: la clave privada con la que firma OpenDKIM./etc/dkimkeys/202609.txt: la clave pública, ya con formato de registro DNS.
La clave privada solo debe poder leerla el usuario opendkim; de lo contrario, el servicio se niega a usarla:
sudo chown opendkim:opendkim /etc/dkimkeys/202609.private
sudo chmod 600 /etc/dkimkeys/202609.private
sudo ls -l /etc/dkimkeys
-rw------- 1 opendkim opendkim 1704 Sep 25 10:12 202609.private
-rw------- 1 root root 502 Sep 25 10:12 202609.txt
Nota2048 bits es el tamaño recomendado. Las claves de 1024 bits se consideran débiles, y las de 4096 bits generan registros DNS demasiado largos para muchos proveedores de DNS.
Paso 3: Configurar OpenDKIM
Abre el archivo de configuración principal:
sudo nano /etc/opendkim.conf
El archivo por defecto de Ubuntu ya trae valores razonables (Canonicalization relaxed/simple, OversignHeaders From, UserID opendkim). Tienes que indicarle para qué dominio firmar, qué clave usar y dónde escuchar a Postfix. Busca las líneas comentadas Domain, Selector y KeyFile y la línea Socket, y cámbialas para que queden así:
Domain your_domain
Selector 202609
KeyFile /etc/dkimkeys/202609.private
Socket inet:8891@localhost
Asegúrate de que solo queda una línea Socket sin comentar. Un socket TCP en localhost es la opción más sencilla en Ubuntu, porque Postfix ejecuta su servidor SMTP en un chroot dentro de /var/spool/postfix y no puede alcanzar el socket Unix por defecto en /run/opendkim.
Si no se define Mode, OpenDKIM firma y verifica. Firma los mensajes enviados desde 127.0.0.1 (el valor por defecto de InternalHosts) y los de clientes que se autenticaron con SMTP AUTH, lo que cubre el correo enviado por un webmail en el mismo servidor y por los usuarios que envían por el puerto 587. El correo que llega de otros servidores solo se verifica.
Reinicia OpenDKIM y comprueba que escucha en el puerto 8891:
sudo systemctl restart opendkim
sudo ss -ltnp | grep 8891
LISTEN 0 4096 127.0.0.1:8891 0.0.0.0:* users:(("opendkim",pid=4121,fd=3))
Si el servicio no arranca, consulta el motivo en el journal con sudo journalctl -u opendkim -n 30. Las causas habituales son una ruta de clave incorrecta o permisos erróneos en la clave privada.
Paso 4: Conectar Postfix con OpenDKIM
Postfix tiene que pasar cada mensaje al milter. Abre su configuración principal:
sudo nano /etc/postfix/main.cf
Añade estas líneas al final del archivo:
# Firma DKIM con OpenDKIM
milter_default_action = accept
smtpd_milters = inet:localhost:8891
non_smtpd_milters = $smtpd_milters
smtpd_miltersse aplica al correo que llega por SMTP, incluido el de los usuarios autenticados.non_smtpd_miltersse aplica al correo enviado localmente con el comandosendmail, por ejemplo desde PHP o cron.milter_default_action = acceptmantiene el flujo de correo si OpenDKIM está caído: los mensajes salen sin firmar en lugar de rechazarse.
Si smtpd_milters ya tiene un valor (por ejemplo, de un filtro antispam), añade OpenDKIM a esa línea separado por una coma en lugar de crear una segunda.
Comprueba la configuración y recarga Postfix:
sudo postfix check
sudo systemctl reload postfix
postfix check no muestra nada si la configuración es válida.
Paso 5: Publicar la clave pública en DNS
Muestra el registro DNS que ha preparado opendkim-genkey:
sudo cat /etc/dkimkeys/202609.txt
202609._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3n..."
"...Q2hwIDAQAB" ) ; ----- DKIM key 202609 for your_domain
En tu proveedor de DNS, crea un registro TXT con estos valores:
| Campo | Valor |
|---|---|
| Tipo | TXT |
| Nombre / Host | 202609._domainkey (algunos paneles necesitan el nombre completo 202609._domainkey.your_domain) |
| Valor | v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkq...IDAQAB |
El archivo divide la clave en varias cadenas entre comillas porque una cadena DNS está limitada a 255 caracteres. La mayoría de los paneles DNS esperan un único valor continuo: une las partes entre comillas, sin las comillas, los paréntesis ni el comentario. Si gestionas tú mismo un archivo de zona de BIND, puedes pegar el registro tal cual.
Espera unos minutos y consulta el registro:
dig +short TXT 202609._domainkey.your_domain
"v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3n..." "...Q2hwIDAQAB"
La respuesta puede llegar dividida en varias cadenas. Es normal: los receptores las unen.
Ahora deja que OpenDKIM compare la clave publicada con tu clave privada:
sudo opendkim-testkey -d your_domain -s 202609 -k /etc/dkimkeys/202609.private -vvv
opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: key loaded from /etc/dkimkeys/202609.private
opendkim-testkey: checking key '202609._domainkey.your_domain'
opendkim-testkey: key not secure
opendkim-testkey: key OK
key OK significa que el registro DNS coincide. key not secure solo indica que tu zona no está firmada con DNSSEC y no afecta a DKIM.
Paso 6: Probar un mensaje firmado
Envía un mensaje desde el servidor a un buzón externo que puedas leer. Sustituye las direcciones por las tuyas:
printf 'From: admin@your_domain\nTo: [email protected]\nSubject: Prueba DKIM\n\nEste mensaje debería ir firmado.\n' | sudo sendmail -f admin@your_domain [email protected]
Busca en el log la línea de firma:
sudo journalctl -u opendkim -n 20 --no-pager | grep "DKIM-Signature"
Sep 25 10:31:07 mail opendkim[4121]: 4cKx2N1QzXz9sWb: DKIM-Signature field added (s=202609, d=your_domain)
Abre el mensaje en el buzón de destino y consulta el código fuente original (en Gmail: menú de tres puntos y luego Mostrar original). Los resultados de autenticación deberían incluir:
dkim=pass header.i=@your_domain header.s=202609
Firmar el correo de varios dominios
Las directivas Domain, Selector y KeyFile cubren un solo dominio. Para firmar varios, genera una clave por dominio y usa tablas de búsqueda. Genera la clave del segundo dominio en su propio directorio:
sudo mkdir -p /etc/dkimkeys/example.net
sudo opendkim-genkey -b 2048 -d example.net -s 202609 -D /etc/dkimkeys/example.net
sudo chown -R opendkim:opendkim /etc/dkimkeys/example.net
sudo chmod 600 /etc/dkimkeys/example.net/202609.private
El directorio /etc/opendkim no existe por defecto; créalo antes de editar los archivos:
sudo mkdir /etc/opendkim
Crea la tabla de claves, que asocia un nombre de clave con un dominio, un selector y un archivo de clave privada:
sudo nano /etc/opendkim/key.table
202609._domainkey.your_domain your_domain:202609:/etc/dkimkeys/202609.private
202609._domainkey.example.net example.net:202609:/etc/dkimkeys/example.net/202609.private
Crea la tabla de firmas, que asocia las direcciones de remitente con una clave:
sudo nano /etc/opendkim/signing.table
*@your_domain 202609._domainkey.your_domain
*@example.net 202609._domainkey.example.net
Después, en /etc/opendkim.conf, comenta las líneas Domain, Selector y KeyFile y añade:
KeyTable /etc/opendkim/key.table
SigningTable refile:/etc/opendkim/signing.table
El prefijo refile: permite usar comodines como *@example.net en la tabla de firmas. Reinicia OpenDKIM, publica el registro TXT de cada dominio y compruébalos uno a uno con opendkim-testkey.
Solución de problemas
- No aparece ninguna línea
DKIM-Signature field addeden el log. Postfix no está pasando el mensaje a OpenDKIM, o OpenDKIM considera externo al remitente. Comprueba quepostconf smtpd_milters non_smtpd_miltersmuestrainet:localhost:8891y que el dominio delFromcoincide exactamente con el valor deDomain. dkim=fail (bad signature)en el receptor. El mensaje se modificó después de firmarlo, a menudo por una lista de correo o un servicio de reenvío, o el registro DNS tiene una errata. Vuelve a ejecutaropendkim-testkeyy compara el valorp=publicado con/etc/dkimkeys/202609.txt.opendkim-testkey: record not found. El registro no existe, aún se está propagando o se creó como202609._domainkey.your_domain.your_domainporque el panel añadió el dominio dos veces. Consúltalo condigy corrige el nombre.- OpenDKIM no arranca con
can't load key. La clave privada no pertenece aopendkimo la pueden leer otros usuarios. Vuelve a aplicar elchowny elchmod 600del paso 2.
Conclusión
Tu servidor firma ahora el correo saliente con una clave DKIM de 2048 bits, la clave pública está publicada en DNS y los receptores informan de dkim=pass. DKIM por sí solo no indica a los receptores qué hacer con el correo sin firmar, así que el siguiente paso es publicar los registros SPF y DMARC de tu dominio. Planifica también rotar la clave una o dos veces al año: genera un selector nuevo, publícalo, cambia Selector y KeyFile y elimina el registro antiguo una semana después.
