Las técnicas de control de spam usadas más frecuentemente pasan por contrastar la autenticidad del remitente a través de algún tipo de comprobación contra el dominio de procedencia del correo electrónico. Lo que se persigue es que si recibo un correo procedente de una cuenta de determinado dominio, el propietario de dicho dominio debería de tener correctamente identificadas cuales son las máquinas autorizadas para enviar correo en su nombre. Recuerda que lo habitual (e indispensable) es identificar las máquinas receptoras del correo (mediante registros MX), pero muchos administradores aún continúan sin identificar de forma alguna a las emisoras a pesar de que tenemos varias opciones para hacerlo. Veamoslas.
Para ilustrar nuestro ejemplo supondremos que tenemos un servidor de correo que actúa como único emisor autorizado y que también funciona como receptor del correo. Su nombre es estafeta.micorreo.net y su IP la 145.255.98.239. Nuestro servidor es un VPS contratado a una empresa de hosting, que es la que nos proporciona la IP, usará postfix sobre una máquina con Debian 7, estará perfectamente configurado y atenderá a dos dominios diferentes (ya hemos hablado también aquí de como hacerlo) llamados midominio.com y midominio.net
La existencia de un registro PTR de resolución inversa para la IP de la máquina que entrega el correo es una de las primeras cosas que valorará de forma positiva un filtro antispam. El problema que vamos a encontrar con esto es que, habitualmente, no podremos crearlo nosotros mismos. Si la IP fija que usa nuestro servidor nos la ha proporcionado nuestro ISP tendremos que pedírle a ellos que creen este registro para nosotros. Si nuestro servidor de correo está alojado en una empresa de hosting se lo solicitaremos a ellos o, tal vez, nos proporcionarán algún mecanismo para que lo hagamos nosotros mismos a través de su panel de configuración. Si tienes la posibilidad de configurarla por ti mismo en un servidor BIND nuestros buenos amigos de systemadmin te dicen aquí como debes de hacerlo, así que no pierdo más el tiempo en ello 😉 .
Para nuestro ejemplo, pediríamos a la empresa de hosting que nos aloja el servidor (yo así lo hice a Gigas, mi empresa actual de hosting que de de alta un registro de resolución inverso para la IP 145.255.98.239 que se resuelva como estafeta.micorreo.net
Para comprobar si lo han hecho correctamente puedes usar nslookup:
nslookup -query=PTR 145.255.98.239
Los registros SPF (Sender Policy Framework o Marco Normativo de Remitentes) constituyen uno de los métodos más comunes y fáciles de implementar para identificar a las máquinas de nuestro dominio autorizadas para enviar correo electrónico. El método es tan sencillo como dar de alta un nuevo registro en la zona de tu dominio donde identifiques a los servidores que autorizas para enviar correo. Originalmente se usaba un registro TXT pero posteriormente se amplió la funcionalidad de las bases de datos DNS añadiendo un nuevo tipo de registros denominado SPF. Hoy en día es recomendable usar ambos métodos por si acaso el servidor que realiza la validación busca aún el tipo de registros antiguo.
La sintaxis de definición de un registro SPF tiene muchas alternativas y puede variar según nuestras necesidades. En esta entrada tienes la especificación completa muy bien explicada y con todo lujo de detalles. Para nuestro ejemplo (un único servidor de correo tanto para envío como para recepción y que coincide con el que aparece en el registro MX) puedes usar los siguientes registros:
@ IN MX 10 estafeta.micorreo.net. @ IN TXT "v=spf1 mx ip4:145.255.98.239 ~all" @ IN SPF "v=spf1 mx ip4:145.255.98.239 ~all"
Puesto que el correo de ambos dominios es gestionado por el mismo servidor debemos repetir esos mismos registros exactamente iguales en las bases de datos de ambas zonas. Y, por supuesto, hacer un reload del servidor bind9 después de hacer los cambios.
Tenemos muchas formas de hacer pruebas si hemos configurado correctamente nuestros resgistros SPF. Una de ellas es usar alguno de los muchos tests online disponibles por ahí. Mis favoritos son estos:
Otra opción es enviar un correo a una cuenta de los grandes proveedores (GMail, Outlook o Yahoo, por ejemplo, comprueban la validez de los registros SPF para valorar si un correo es marcado como SPAM) y observar lo que pone en la cabecera del correo que recibe el destinatario. Ten en cuenta que la validación que hace cada uno de ellos es ligeramente diferente. Por ejemplo, si retiras la partícula ip4 de los registros anteriores Gmail y Yahoo seguirán validando correctamente pero Outlook dejará de hacerlo.
Si, por ejemplo, enviamos un correo a Gmail y no hemos definido aún registros SPF, Google insertará en la cabecera del correo una marca como esta definiéndolo como neutral. Eso quiere decir que no puede determinar si el correo es válido o es spam.
Received-SPF: neutral (google.com: 145.255.98.239 is neither permitted nor denied by best guess record for domain of josemaria@midominio.com) client-ip=145.255.98.239; Authentication-Results: mx.google.com; spf=neutral (google.com: 145.255.98.239 is neither permitted nor denied by best guess record for domain of josemaria@midominio.com) smtp.mail=josemaria@midominio.com
Por el contrario, cuando contemos con unos registros SPF correctos la valoración que Google hará constar anunciará que el correo es correcto (pass):
Received-SPF: pass (google.com: domain of josemaria@midominio.com designates 145.255.98.239 as permitted sender) client-ip=145.255.98.239; Authentication-Results: mx.google.com; spf=pass (google.com: domain of josemaria@midominio.com designates 145.255.98.239 as permitted sender) smtp.mail=josemaria@midominio.com
Si Google recibe un correo de un dominio que usa registros SPF pero el servidor emisor del mismo no está autorizado en estos registros lo marcará como fail o softfail. En el caso de los registros que he puesto como ejemplo lo hará como softfail gracias a la partícula ~all que he especificado (consulta la página de sintaxis que he referenciado antes para entender las diferencias entre ambos).
El tercer tipo de registros que veremos son los DKIM (DomainKeys Identified Mail), un sistema de identificación que usa firmas realizadas con criptografía de clave pública. El método en el que se basa también es sencillo de entender. Nuestro servidor de correo firmará todos sus mensajes salientes mediante su clave privada y esta firma se incluirá en la cabecera del mensaje en una sección llamada «DKIM-Signature».
La clave pública deberá de estar disponible para que quien lo quiera pueda realizar la verificación de la firma. Esto se hace en un registro TXT de nuestro DNS. La implementación de este sistema en nuestros servidores es, sin embargo, bastante más complicada ya que necesitamos generar previamente la pareja de claves, configurar nuestro servidor de correo para que realice la firma de los mensajes y, por último, insertar la clave pública en el registro TXT correspondiente de nuestra zona DNS… Vamos a ver como hacerlo.
En primer lugar instalamos los paquetes necesarios:
apt-get install opendkim opendkim-tools
A continuación creamos un directorio para las claves y archivos de configuración. Podemos, por ejemplo, hacerlo en el directorio /etc. En el crearemos un subdirectorio por cada dominio de correo que usamos y tres ficheros adicionales que luego explicaremos como rellenar:
mkdir /etc/opendkim mkdir /etc/opendkim/midominio.com mkdir /etc/opendkim/midominio.net touch KeyTable touch SigningTable touch TrustedHosts
Vamos ahora a generar las parejas de claves necesarias para que DKIM funcione. Entramos en el directorio que hemos creado para el primer dominio y ejecutamos lo siguiente:
cd /etc/opendkim/midominio.com opendkim-genkey -s mail -d midominio.com
El parametro detrás de la -s es el llamado «selector» y el que va detrás de la -d el dominio para el que generas las claves. La instrucción anterior nos generará un par de ficheros: uno llamado mail.private con la clave privada y otro denominado mail.txt que incluye el registro que, con ligeras modificaciones, tendremos que incluir en nuestra zona DNS y que contiene la clave pública. Fíjate en el contenido en bruto de este fichero:
mail._domainkey IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHBGfg26egqLbX2B1K7HW5NQLKpD/9kOcYsfMzH6fiGo0qtjxAjIAUykoO3GoAqiU7UHgsOv0XU67ONiCMoKrM2IxxL/D0Qt4ePojeqNm55lwk6kSHZDIRAqBCt+r2O4Gc78RVudI4RE17GWnxKzhHEsCG6kHyNb46oYiN1tg3OwIDAQAB" ; ----- DKIM key mail for midominio.com
Y ahora mira lo que yo he incluido en mi DNS:
_domainkey.midominio.com. IN TXT "o=~; r=josemaria@midominio.com" mail._domainkey.midominio.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHBGfg26egqLbX2B1K7HW5NQLKpD/9kOcYsfMzH6fiGo0qtjxAjIAUykoO3GoAqiU7UHgsOv0XU67ONiCMoKrM2IxxL/D0Qt4ePojeqNm55lwk6kSHZDIRAqBCt+r2O4Gc78RVudI4RE17GWnxKzhHEsCG6kHyNb46oYiN1tg3OwIDAQAB" ; ----- DKIM key mail for midominio.com
Como ves, he incluido un primer registro TXT denominado _domainkey.midominio.com. (mail es el selector usado al generar la clave y midominio.com. el dominio) cuyo contenido es la política que usaremos (puedes consultar aquí que significa). El segundo registro es el contenido íntegro del fichero mail.txt al que simplemente le he añadido el dominio correspondiente al final del primer campo.
Esta primera parte ya está lista. Ahora tienes que hacer un reload de las zonas de tu servidor DNS (service bind9 reload) y, por último, podrías probar si tienes correctamente configurado estos registros con esta herramienta.
Tenemos aún que dotar de contenido a los tres ficheros que hemos creado inicialmente en el directorio /etc/opendkim. Los dos primeros sirven para seleccionar la clave privada que se usará para la firma en función del correo del remitente.
El fichero KeyTable contendrá una línea por cada pareja de claves que hemos creado. La sintaxis de cada una de estas líneas con arreglo a como hemos realizado el proceso hasta ahora sería así:
keyid dominio:selector:path_a_la_clave_privada
Nosotros usaremos como keyid el mismo nombre de dominio, así que en nuestro ejemplo quedará así:
midominio.com midominio.com:mail:/etc/opendkim/midominio.com/mail.private midominio.net midominio.net:mail:/etc/opendkim/midominio.net/mail.private
El fichero SigningTable identifica los correos con los keyid del fichero anterior y, por tanto, con la clave privada usada para la firma. La sintaxis de cada línea es esta:
expresion_para_identificar_el_correo keyid
Y en nuestro ejemplo:
*@midominio.com midominio.com *@midominio.net midominio.net
El último de ellos, TrustedHosts, debería de incluir a los servidores autorizados para usar opendkim. Nosotros tenemos sólo uno pero especificaremos todas sus posibles direcciones y/o identificaciones para evitar problemas:
127.0.0.1 145.255.98.239 invernalia.unlugarenelmundo.es
Muy importante: debemos de asegurarnos que el usuario opendkim y sólo él tiene acceso a estos directorios
chown opendkim:opendkim /etc/opendkim/* -R chmod go-rwx /etc/opendkim/* -R
Configuramos ahora /etc/opendkim.conf incluyendo o modificando las siguientes líneas (échale un vistazo con detenimiento porque alguna podría aparecer con otros valores distintos a los que aquí ponemos):
Syslog yes SyslogSuccess yes LogWhy yes UMask 002 OversignHeaders From KeyTable refile:/etc/opendkim/KeyTable SigningTable refile:/etc/opendkim/SigningTable ExternalIgnoreList /etc/opendkim/TrustedHosts InternalHosts /etc/opendkim/TrustedHosts SignatureAlgorithm rsa-sha256 AutoRestart yes UserID opendkim:opendkim Socket inet:8891@localhost Canonicalization relaxed/simple Mode s
En el fichero /etc/postfix/main.cf incluimos las siguientes líneas para instruir a postfix de lo que queremos hacer:
#OpenDKIM milter_default_action = accept milter_protocol = 2 smtpd_milters = inet:localhost:8891 #smtpd_milters = inet:8891@localhost non_smtpd_milters = inet:localhost:8891
Por último, reiniciamos los dos servicios en los que hemos hecho cambios:
service opendkim restart service postfix restart
Puedes comprobar que tu servidor está firmando los mensajes salientes simplemente mirando en la cabecera de los mensajes que hayas enviado (ojo, no vale con mirar esto en la carpeta de enviados de tu cliente de correo: tienes que mirarlo en el buzón de alguién a quién hayas enviado un mensaje 😉 ). Deberías de encontrar una sección como esta:
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=midominio.com; s=mail; t=1393841181; bh=WOdEGJCY/0JhPY8jx68CyFKNQxxdoD1qEPM2Bike+fA=; h=Date:From:Reply-To:To:Subject:From; b=dtHZW0UMlXcKt6c8IY6DS1IVclv7KZTo6IIK0+r/yLWdKet/G9jkvSxmp7MhTeL9t p5Jh87PMKJD0GuRWIJAKx/QLSVAhf9/scXbR7GH9dRPipwxM4lRzaWwxgyCFfKafca SnBJ81jsaKpQgB8sUi2CY4YWt0Y0Vdy7CKCDbpxA=
Además, también puedes mirar los logs de tu servidor postfix (en /var/log/mail.log):
Mar 3 06:22:05 estafeta opendkim[2738]: 4DA1D14206A: DKIM-Signature header added (s=mail, d=midominio.com)
Para saber que la configuración a la que has llegado es correcta, puedes envíar un correo a gmail y comprobar en la cabecera del mensaje recibido que la autenticación a través de DKIM es correcta:
Authentication-Results: mx.google.com; spf=pass (google.com: domain of josemaria@midominio.com designates 145.255.98.239 as permitted sender) smtp.mail=josemaria@midominio.com; dkim=pass header.i=@midominio.com
Como con los SPF, te recomiendo que pruebes también con Yahoo, Outlook y otros proveedores para asegurarte de que has llegado a una configuración correcta.
También te pueden resultar útiles las herramientas de DKIM Core para generación o verificación de tus claves.
Authentication-Results: mta1040.mail.bf1.yahoo.com from=midominio.com; domainkeys=neutral (no sig); from=midominio.com; dkim=pass (ok)
Finalmente, tenemos un mecanismo para realizar una comprobación global de los mecanismos de identificación que nuestro correo es capaz de pasar que consiste en enviar un mail a la dirección check-auth@verifier.port25.com. Como respuesta recibiremos un resumen con los tests de autenticación que pasamos y los que no:
From: auth-results@verifier.port25.com To: josemaria@midominio.com Subject: Authentication Report Message-Id: <1393852132-602016@verifier.port25.com> Precedence: junk (auto_reply) In-Reply-To: <53147EDC.1060808@midominio.com> This message is an automatic response from Port25's authentication verifier service at verifier.port25.com. The service allows email senders to perform a simple check of various sender authentication mechanisms. It is provided free of charge, in the hope that it is useful to the email community. While it is not officially supported, we welcome any feedback you may have at <verifier-feedback@port25.com>. Thank you for using the verifier, The Port25 Solutions, Inc. team ========================================================== Summary of Results ========================================================== SPF check: pass DomainKeys check: neutral DKIM check: pass Sender-ID check: pass SpamAssassin check: ham ========================================================== Details: ========================================================== HELO hostname: estafeta.micorreo.net Source IP: 145.255.98.239 mail-from: josemaria@midominio.com ---------------------------------------------------------- SPF check details: ---------------------------------------------------------- Result: pass ID(s) verified: smtp.mailfrom=josemaria@midominio.com DNS record(s): midominio.com. 86400 IN SPF "v=spf1 mx ip4:145.255.98.239 ~all" midominio.com. 86400 IN MX 10 estafeta.micorreo.net. estafeta.micorreo.net. 14400 IN A 145.255.98.239 ---------------------------------------------------------- DomainKeys check details: ---------------------------------------------------------- Result: neutral (message not signed) ID(s) verified: header.From=josemaria@midominio.com DNS record(s): ---------------------------------------------------------- DKIM check details: ---------------------------------------------------------- Result: pass (matches From: josemaria@midominio.com) ID(s) verified: header.d=midominio.com Canonicalized Headers: date:Mon,'20'03'20'Mar'20'2014'20'14:08:44'20'+0100'0D''0A' from:=?UTF-8?B?Sm9zw6kgTWFyw61hIE1vcmFsZXMgVsOhenF1ZXo=?='20'<josemaria@midominio.com>'0D''0A' reply-to:josemaria@midominio.com'0D''0A' to:josemaria.morales@gmail.com,'20'jmmoralesv@outlook.com,'20'jmmoralesv@yahoo.com,'20'check-auth@verifier.port25.com'0D''0A' subject:prueba'20'desde'20'morales-vazquez'20'a'20'dkim'0D''0A' dkim-signature:v=1;'20'a=rsa-sha256;'20'c=relaxed/simple;'20'd=midominio.com;'20's=mail;'20't=1393852124;'20'bh=bTRBPsyNE9vY+br0wyWV6XaM4bHp8xfOlCzTWRPryRY=;'20'h=Date:From:Reply-To:To:Subject:From;'20'b= Canonicalized Body: xxxx'0D''0A' '0D''0A' --'20''0D''0A' --'20'Jos'C3''A9''20'Mar'C3''AD'a'20'Morales'20'['20'josemaria@midominio.com'20']'0D''0A' ------------'20'Blog:'20'['20'https://blog.unlugarenelmundo.es/'20']'0D''0A' ------------'20'Perfil:'20''20'['20'http://cv.morales-vazquez.es/'20']'0D''0A' DNS record(s): mail._domainkey.midominio.com. 86400 IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHBGfg26egqLbX2B1K7HW5NQLKpD/9kOcYsfMzH6fiGo0qtjxAjIAUykoO3GoAqiU7UHgsOv0XU67ONiCMoKrM2IxxL/D0Qt4ePojeqNm55lwk6kSHZDIRAqBCt+r2O4Gc78RVudI4RE17GWnxKzhHEsCG6kHyNb46oYiN1tg3OwIDAQAB" Public key used for verification: mail._domainkey.midominio.com (1024 bits) NOTE: DKIM checking has been performed based on the latest DKIM specs (RFC 4871 or draft-ietf-dkim-base-10) and verification may fail for older versions. If you are using Port25's PowerMTA, you need to use version 3.2r11 or later to get a compatible version of DKIM. ---------------------------------------------------------- Sender-ID check details: ---------------------------------------------------------- Result: pass ID(s) verified: header.From=josemaria@midominio.com DNS record(s): midominio.com. 86400 IN SPF "v=spf1 mx ip4:145.255.98.239 ~all" midominio.com. 86400 IN MX 10 estafeta.micorreo.net. estafeta.micorreo.net. 14400 IN A 145.255.98.239 ---------------------------------------------------------- SpamAssassin check details: ---------------------------------------------------------- SpamAssassin v3.3.1 (2010-03-16) Result: ham (-2.0 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature