El SPAM es una de las mayores lacras que inundan Internet desde el principio de su creación. Genera cien veces más pérdidas a la sociedad que beneficio a sus creadores y supone el 84% de los emails que recibimos. Y este mal existe, entre otras cosas, porque el sistema de correo electrónico de Internet se diseñó dando por hecho que toda la gente que lo iba a utilizar lo haría de buena fe: craso error.
Pensar que nadie iba a utilizar el correo electrónico para hacer cosas malas hizo que se diseñara, entre otras muchas cosas, sin ningún sistema que garantice a quien los recibe que dichos mensajes no han sido manipulados por el camino o escritos por remitentes falsos.
Por estos motivos, Internet lleva años desarrollando herramientas y sistemas que ayuden a paliar los problemas de diseño que el correo electrónico tiene de base.
DKIM es uno de estos mecanismos, y permite a los destinatarios de un mensaje de correo electrónico saber si un email ha sido realmente enviado por el remitente y no por alguien haciéndose pasar por él (esta práctica se denomina mail spoofing).
Hay distintos sistemas para otorgar un poco más de seguridad al envío de correo electrónico, pero en este artículo me voy a centrar únicamente en explicar qué es DKIM y cómo configurar la implementación open-source de dicho protocolo: OpenDKIM.
Comencemos:
- ¿Qué es DKIM y OpenDKIM?
- Instalación y configuración de OpenDKIM
- Comprobación del sistema
- Referencias
¿Qué es DKIM y OpenDKIM?
Como comentaba al principio, DKIM es un mecanismo a través del cual se intenta evitar la suplantación de identidades a la hora de enviar mensajes de correo electrónico.
DKIM otorga a un servidor de correo la capacidad de firmar los emails que envía, de forma que cuando éstos llegan a su destinatario, este puede comprobar que realmente fueron enviados por dicho servidor y no por otro servidor que estuviera haciéndose pasar por él.
Un correo electrónico (de ahora en adelante: un email) no es más que un paquete de datos que contiene cabeceras (headers) con la fecha de envío, el nombre del remitente, el asunto del mensaje, etc. y un cuerpo (body) que contiene el texto del mensaje. Un ejemplo muy básico de un email sería algo así:
Date: Thu, 12 Oct 2017 04:15:51
Content-type: text/plain
To: destinatario@dominio1.com
From: "Remitente" <remitente@dominio2.com>
Subject: Mensaje urgente
Visita pornohardware.com!
El texto Visita pornohardware.com!
sería el contenido del email (body), y Date
, Content-type
, To
, From
, etc. serían las cabeceras (headers) con la información sobre este.
Cuando este email llega a nuestro correo, la aplicación que usemos para leerlo nos dirá que tenemos un mensaje enviado el dia 12 de octubre de 2017
de parte de un tal "Remitente" <remitente@dominio2.com>
y cuyo asunto es Mensaje urgente
.
¿Pero qué sucedería si alguien nos envía ese mismo mensaje, pero cambiando la cabecera From
?
Date: Thu, 12 Oct 2017 04:15:51
Content-type: text/plain
To: destinatario@dominio1.com
From: "Elon Musk" <elonmusk@spacex.com>
Subject: Mensaje urgente
Visita pornohardware.com!
Lo que sucedería en este caso es que al abrir nuestro cliente de correo creeríamos que el sr. Elon Musk <elonmusk@spacex.com>
nos habría escrito un email.
Esto es porque no se hace ninguna validación sobre si una cabecera ha sido manipulada o sobre si el remitente es realmente quien dice ser. Y cambiar las cabeceras de un email es absolutamente trivial, no tiene ninguna dificultad para cualquiera que tenga unos mínimos conocimientos básicos de informática (y realmente tampoco son necesarios, ya que si no los tienes, existen multitud de programas que te permiten hacerlo a golpe de click).
Es extremadamente fácil manipular el remitente de un email, hasta un niño pequeño, un patán analfabeto o incluso un amante del reggeton podría hacerlo, así que: ¿cómo podemos evitar que nos engañen cuando nos escriben un email?: firmando los emails que enviamos, y asegurándonos de que el destinatario verifica dicha firma cuando los recibe. Y eso es exactamente lo que nos permite hacer DKIM.
Cómo ya expliqué en el artículo Instalación y configuración de un servidor de correo completo en Linux, el flujo común del envío de un email es:
Por defecto, todas las partes implicadas en este proceso (el servidor de correo que envía el email y servidor de correo que lo recibe) asumen que los datos del email son verdaderos, por lo que ninguna de ellas detectaría un email manipulado cuya dirección del remitente se hubiera cambiado para suplantar la identidad del mismo.
Ahí es donde entra DKIM, que permite al servidor de correo que envía el email firmar dicho mensaje con una clave privada, de forma que el servidor de correo que lo recibe puede verificar que la firma es correcta utilizando la correspondiente clave pública (que está disponible en el DNS del dominio que envía el mensaje).
El flujo común del envío de un email con DKIM sería entonces algo así:
Como puedes ver, teóricamente el sistema funciona muy bien... ¿cuál es el problema entonces? ¿porqué a dia de hoy seguimos recibiendo toneladas de emails con spam, virus y demás basura digital? Pues porque desgraciadamente el uso de DKIM es completamente opcional, lo que significa que la inmensa mayoría de los servidores de correo de Internet no lo están usando.
Y al no usarlo, no solo están permitiendo de forma directa que alguien envíe emails haciéndose pasar por los legítimos usuarios de esos servidores, sino que tampoco están verificando que los emails que les llegan a ellos proceden de quien dicen proceder.
Es algo muy parecido a lo que sucede con el sistema SPF (ya escribiré otro artículo sobre este sistema): no servirá de nada hasta que el 100% de los servidores de correo de Internet lo utilicen, pero al menos nos quitaremos un pequeño porcentaje (o grande, según el caso) de emails no deseados.
Vamos entonces a ver cómo se configura OpenDKIM, que como ya dije al principio no es más (ni menos) que la implementación open-source más utilizada del sistema DKIM.
Instalación y configuración de OpenDKIM
Para firmar los emails con OpenDKIM se utiliza el típico esquema de firma de certificados usando un par de claves (pública y privada), comúnmente conocido como criptografía asimétrica. Es el esquema típico que se usa en cientos de aplicaciones y servicios, por lo que no entraré en profundidad en este tema.
Únicamente basta que con tengáis presente que para firmar algo con este sistema se necesitan 2 claves. La clave privada únicamente la tiene la persona que va a firmar el mensaje, y la pública está a disposición de todo el mundo para que puedan utilizarla para validar si el mensaje firmado con la clave privada es correcto. Una explicación muy sencilla (extraída de la página sobre criptografía asimétrica de la Wikipedia) sería esta:
De Dvdrodriguez - Trabajo propio, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=26102947
- David redacta un mensaje
- David firma digitalmente el mensaje con su clave privada
- David envía el mensaje firmado digitalmente a Ana a través de internet, ya sea por correo electrónico, mensajería instantánea o cualquier otro medio
- Ana recibe el mensaje firmado digitalmente y comprueba su autenticidad usando la clave pública de David
- Ana ya puede leer el mensaje con total seguridad de que ha sido David el remitente
En nuestro caso, no será David (la persona que envía el email) quien firme el mensaje, sino que lo hará automáticamente su servidor de correo. Y tampoco será Ana (la persona que recibe el email) quien verifique con la clave pública de David si el mensaje es válido, sino que lo hará también de forma automática su servidor de correo al recibir el mensaje. Es decir, es un proceso transparente para el usuario.
Toda la magia del proceso se hará de forma automática en los respectivos servidores de correo tanto del remitente como del destinatario, sin que estos tengan que preocuparse de nada (como buenos merluzos usuarios).
Lo primero que haremos entonces es instalar los paquetes de OpenDKIM en nuestro servidor SMTP.
Como siempre, si usamos una distribución de Linux decente (como por ejemplo Debian), bastaría con ejecutar:
$ sudo apt-get install opendkim opendkim-tools
Si por el contrario vendimos nuestra alma al Diablo, perdimos una apuesta o estamos realizando algún tipo de penitencia y usamos CentOS, Redhat o similares, podemos instalarlo también de forma sencilla con:
$ sudo yum install opendkim
OpenDKIM se ejecuta en forma de demonio, por lo que antes de iniciar el proceso hay que configurarlo.
El proceso de instalación habrá creado el archivo /etc/opendkim.conf
y el directorio /etc/opendkim
. Es decir, si todo ha ido bien tendréis algo parecido a esto en vuestro servidor:
├─ etc/
│ ├─ opendkim.conf
│ └─ opendkim/
│ ├─ keys/
│ ├─ KeyTable
│ ├─ SigningTable
│ └─ TrustedHosts
No te preocupes si te falta algún archivo, o si en tu caso se llama de otra forma, la instalación puede variar dependiendo de la versión de OpenDKIM, así que una vez que sepas para qué es cada uno de ellos podrás adaptar la instalación a cualquier caso.
- opendkim.conf: Como podrás imaginar, aquí estará la configuración principal del demonio OpenDKIM.
- opendkim/keys/: En este directorio es donde se guardarán las claves privadas con las que OpenDKIM firmará los emails que se envíen desde nuestro servidor.
- opendkim/KeyTable: En este archivo se configuran las claves que vamos a usar para cada dominio que vamos a firmar (es recomendable utilizar una firma diferente para cada dominio).
- opendkim/SigningTable: Este archivo le dice a OpenDKIM cómo debe firmar los mensajes, según el dominio del remitente.
- opendkim/TrustedHosts: Aquí especificamos la lista de dominios en los que confiamos, es decir, los dominios que no vamos a verificar (porque normalmente es nuestro servidor el que los firma).
Empezaremos por el archivo de configuración opendkim.conf
. Hay muchas directivas de configuración disponibles para este archivo, por lo que solo voy a explicar las necesarias para la mayoría de los casos. No obstante, te recomiendo que eches un ojo al archivo /usr/share/doc/opendkim/examples/opendkim.conf.sample.gz
ya que en él se explican la mayoría de ellas (dicho archivo forma parte del paquete de instalación de OpenDKIM para Debian, pero desconozco si en los paquetes de CentOS o RedHat existe también).
Así es como debería estar el archivo de configuración:
Como podéis ver, el archivo es bastante autoexplicativo, pero vamos a ver algunas de las directivas un poco más en detalle:
KeyTable /etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
Estas cuatro directivas se usan para indicar al demonio de OpenDKIM la ruta a los archivos de configuración que vimos antes, donde estableceremos las claves que vamos a usar, los dominios cuyos emails vamos a firmar, etc.
Socket inet:8892@localhost
Aquí especificamos donde estará escuchando el demonio de OpenDKIM (para que nuestro SMTP pueda conectarse a él). Puede escuchar en un socket (local:/path/to/socket
), en una IP y puerto concretos (inet:port@address
) o en un puerto concreto de todos los interfaces de red del servidor (inet:port
).
En este caso concreto estamos configurando OpenDKIM para que escuche en el puerto 8892 del interface de red local (es decir, el servicio únicamente sería accesible desde ese servidor, no desde los demás servidores de nuestra red).
Cuando tengamos el demonio de OpenDKIM y el demonio del SMTP instalado en el mismo servidor, podemos utilizas un socket. En caso de estar en servidores diferentes, tendremos que levantar el demonio en una ip/puerto concreto. No obstante, siempre que sea posible intento evitar el uso de sockets (independientemente de donde tengamos los demonios). Aunque ya digo que esto es personal, podéis configurarlo según vuestras necesidades o preferencias personales.
PidFile /var/run/opendkim/opendkim.pid
Como en la mayoría de los demonios de Linux, hay que indicar un path para el archivo PID.
Como veis no hay ningún misterio, así que no creo que haga falta repasar todas las demás directivas. Vamos entonces a generar en primer lugar nuestro par de claves (pública y privada) para el dominio que vamos a firmar (pueden ser varios, por supuesto).
Por cuestiones de organización, creamos un directorio dentro de /etc/opendkim/keys
por cada uno de los dominios que vayamos a firmar. En nuestro caso vamos a firmar los emails del dominio pornohardware.com
, por lo que crearemos las claves dentro de /etc/opendkim/keys/pornohardware.com
:
$ mkdir /etc/opendkim/keys/pornohardware.com
Ahora generaremos las claves con el comando opendkim-genkey
, especificando algunos parámetros:
-d
o--domain
: El dominio que queremos firmar-D
o--directory
: El directorio donde guardar las claves-s
o--selector
: El nombre que queramos darle a la clave (este es el nombre que tendrá el registro DNS de nuestro dominio donde pondremos la clave pública a disposición de todo el mundo, así que puedes poner el que prefieras)-h
o--hash-algorithms
: Con este parámetro indicamos el algoritmo de cifrado que queremos utilizar para generar las claves. Podemos usar cualquiera, pero según las Recomendaciones de Seguridad para el Correo Electrónico NIST 800-177 (publicadas por el Instituto Nacional de Estándares y Tecnología), es preferible que utilicemos sha256 antes que cualquier otro.-b
o--bits
: La longitud de la clave generada, en bits. Por defecto son 1024, pero de nuevo según las recomendaciones NIST 800-177, es preferible utilizar 2048.
$ sudo opendkim-genkey --domain=pornohardware.com --directory=/etc/opendkim/keys/pornohardware.com --selector=mail --hash-algorithms=sha256 --bits=2048 --verbose
Después de ejecutar ese comando ya tendremos 2 archivos en /etc/opendkim/keys/pornohardware.com
:
mail.private
: La clave privada que usaremos para firmar los emailsmail.txt
: El registro TXT que tendremos que añadir al DNS de nuestro dominio para que los demás servidores puedan disponer de ella para verificar la firma de los emails.
La seguridad nunca está de más, por lo que recomiendo que únicamente el usuario opendkim
pueda acceder a estos archivos:
$ sudo chown opendkim:opendkim /etc/opendkim/keys/pornohardware.com -R
$ sudo chmod 400 /etc/opendkim/keys/pornohardware.com/*
Antes de seguir, vamos a añadir el registro TXT a nuestro dominio con la clave pública. No puedo explicar cómo se hace esto ya que dependerá de donde tengáis vuestro servidor DNS. La mayoría de la gente utiliza como servidor de DNS el propio servicio gratuito que suelen tener la web donde han registrado el dominio, otros usan su propio servidor DNS (bind, por ejemplo). En cualquier caso, tienes el registro TXT que debes añadir en el archivo /etc/opendkim/keys/pornohardware.com/mail.txt
.
Para comprobar que el registro está correctamente publicado en el DNS puedes utilizar el comando dig de esta forma:
$ dig +short -t txt mail._domainkey.pornohardware.com
Si todo ha ido bien, ese comando nos mostrará la clave pública que acabamos de poner en el registro TXT de nuestro dominio, que será algo parecido a esto:
"v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA994Jc/Ws7RYqLWOH2tJsINuOkrj+HektVpXK8zM4/DOcFbgRxQ4cMIvXVD7TtT/7PUezdZSdTeaJ1q/CzETNSh7ZVcRETHa4OQltIDH1p9PlV8WZAfjEiyg4OdzKmt8QBkmm6q3AQC3bffWO1BGiDqgyJtPDt/zd7Ri5KiktsLnTZf3yTW+KbLWeDyUWNR41j4NH/d2Lmht4nEhfNwwRrCKwP3WcWMg8RMXf4HEy4xXpkU+6mKZwl3uspddRSOLIon1GDL8D2bJlnauELuiVexnmUc1uYTh/xZTq2C0VEaB0kD8TnrtwMUDPmSLPLiBt1/qmNhQohjoYjy6OVs/whQIDAQAB"
Ten en cuenta que los cambios que hagamos en el DNS suelen tardar en aplicarse debido a que tienen que propagarse, así que no te preocupes si no aparece nada al ejecutar ese comando... prueba en unos minutos y ya deberías ver el registro TXT de DKIM en tu dominio (en algunos casos los cambios en el DNS pueden llegar a tardar hasta 48 horas en propagarse, aunque no es habitual).
Vamos a suponer que ya se han propagado los cambios en el DNS correctamente, así que vamos a continuar.
Editamos el archivo /etc/opendkim/KeyTable
para configurar nuestro dominio con las claves que acabamos de generar. La sintaxis de este archivo es muy sencilla:
La primera parte indica el registro TXT del DNS que contendrá la clave pública (En nuestro caso será mail._domainkey.pornohardware.com
, formado por el selector
que utilizamos al generar las claves, seguido de _domainkey_
y de nuestro dominio).
Después el dominio, el selector y la ruta de la clave privada que acabamos de generar (las tres cosas separadas entre si por :
).
Se pueden añadir tantos dominios como queramos, uno por linea.
El siguiente archivo es SigningTable
, en cual tendrá un aspecto similar a esto:
Al igual que antes, podemos configurar más de un dominio, indicando uno en cada linea.
Y por último el archivo TrustedHosts
, que será parecido a esto:
Ahora que hemos acabado de configurar OpenDKIM, levantamos el servicio y nos aseguramos de que se levante solo cada vez que se inicie el servidor:
$ sudo service opendkim start
$ sudo systemctl enable opendkim
Y si todo ha ido bien, tendremos el servicio de OpenDKIM corriendo en nuestro servidor.
Podemos comprobar si todo está correctamente configurado con el comando opendkim-testkey
:
$ sudo opendkim-testkey -d pornohardware.com -k /etc/opendkim/keys/pornohardware.com/mail.private -s mail -vvv -x /etc/opendkim.conf
opendkim-testkey: key loaded from /etc/opendkim/keys/pornohardware.com/mail.private
opendkim-testkey: checking key 'mail._domainkey.pornohardware.com'
opendkim-testkey: key OK
No te preocupes si también aparece un mensaje que dice opendkim-testkey: key not secure
. Si no tienes DNSSEC configurado en tu DNS, es normal que aparezca. Es solo una recomendación, un warning, por lo que puedes continuar en cualquier caso (ya configurarás DNSSEC otro dia).
Por defecto OpenDKIM utiliza el mismo log que el resto de servicios de correo, por lo que para buscar posibles problemas, información sobre nuestro proceso, etc. podéis ver el archivo /var/log/mail.log
si estais usando Debian/Ubuntu, y /var/log/maillog
si usáis CentOS/RedHat.
Y ahora que tenemos nuestro servicio de OpenDKIM levantado y funcionando, solo nos queda configurar nuestro servidor de correo MTA para que lo utilice.
- Si utilizáis Postfix, tenéis que añadir éstas líneas a su archivo de configuración
/etc/postfix/main.cf
:
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8892
non_smtpd_milters = $smtpd_milters
- Si utilizáis Sendmail, tenéis que añadir estas líneas a vuestro
/etc/mail/sendmail.mc
:
INPUT_MAIL_FILTER(`opendkim', `S=inet:8892@localhost')
define(`confINPUT_MAIL_FILTERS', `opendkim')
En cualquiera de los dos casos, una vez modificada la configuración y reiniciado el servicio corespondiente (Postfix o Sendmail) ya debería estar todo listo.
Comprobación del sistema
Aparte de la comprobación que hicimos antes con el comando opendkim-testkey
, existen varios servicios online gratuitos para verificar que vuestro servidor de OpenDKIM envía los emails correctamente firmados.
Uno de los más completos es https://www.mail-tester.com, donde os darán una dirección a la que debéis enviar un email. La web analizará dicho email y en unos pocos minutos os enviará un informe sobre dicho email y sus correspondientes comprobaciones de DKIM, SPF, etc:
Si únicamente queréis comprobar si vuestra clave pública esta correctamente configurada y se encuentra disponible para todo el mundo, en otra parte de esa misma web teneis la herramienta para hacerlo: https://www.mail-tester.com/spf-dkim-check
Aquí debéis indicar el nombre de vuestro dominio y el nombre del selector que hemos asignado a nuestras claves, y os dirá si el registro TXT está correctamente configurado.
Aparte de esta web, existen otras con funcionalidades similares que también nos ayudarán a validar nuestro recién instalado servidor OpenDKIM:
Y por supuesto también podéis hacer una prueba manual, simplemente enviándoos un email a cualquier otra cuenta que tengáis y mirando sus cabeceras en busca de la información de OpenDKIM. Por ejemplo, si me envío un email a mi mismo y una vez recibido miro el código fuente de dicho email, debería ver algo similar a esto:
Así que por favor, si tienes algún servidor de correo a tu cargo, firma tus mensajes con OpenDKIM. No solo estarás ayudando a tus usuarios a recibir menos spam, sino a todos los posibles destinatarios que alguna vez pudieran llegar a recibir algún email procedente de cualquier dominio de correo que gestione tu servidor.
Como siempre, espero que el artículo os haya resultado de utilidad! Y por supuesto, no dudéis en distribuirlo y compartirlo con todo el mundo (pero por favor, cita siempre la fuente original de éste artículo).
Alaaaaaaaaaaaaaaaaaaaaaaa!