Intro
Harto de recibir spam y lo que es peor, viruses que Clamav es incapaz de detectar, decidí poner solución, al menos parcia, al tema. Lo peor (o lo mejor, según se mire) del tema es que los correos con virus y spam provenían de direcciones en nuestro dominio, sin que tuviesen su origen en nuestro servidor.
La solución más directa parecía ser implementar un filtro SPF junto con la correspondiente entrada TXT en los DNS del dominio.
Ahora no tengo tiempo para explicar en profundidad el funcionamiento de SPF, pero lo que perseguía es que mi servidor de correo rechazase los correos de remitentes que falseaban el nombre de dominio en la dirección de correo.
Lo primero que hice fue incluir la entrada TXT en el DNS del dominio. La entrada era algo parecido a esto:
"v=spf1 ip4:147.156.xx.xx a:tueresmutonto.ci.uv.es a:mail.mastontotodavia.org a:kalumkalia.uv.es a:patapum.ipv6.uv.es a:postresdeliciosos.uv.es a:postresdeliciosos.ipv6.uv.es -all"
En esa línea indicamos quién está autorizado a enviar correo con nuestra dirección de dominio. Tanto la IP que se indica tras ip4 como las máquinas a las que apuntan los registros tras el ‘a:’ están autorizadas y al resto se lo prohíbe el ‘-all‘
Con eso impedíamos que un servidor preparado para comprobar los registros SPF se tragase los correos de spam o con virus que fuesen enviados en nuestro nombre, pero nosotros nos seguíamos tragando todo.
Filtrando por registros SPF en nuestro servidor
Tradicionalmente el trabajo sucio del parseado de ingentes cantidades de texto lo ha llevado a cabo Perl, un superlenguage de programación en el que hay más de una manera de hacer las cosas (que no se note mucho que le tengo un cariño especial al ser el primer lenguaje de programación web que aprendí allá por el siglo pasado), aunque Python está empezando a ganar terreno y ya existe una herramienta en este lenguaje que realiza el filtrado.
Nosotros seguimos apegados al lenguage de Larry Wall, si, el del camello, así que emplearemos Perl para implementar el filtro.
Como nuestro antiguo servidor de correo era Debian, lo he utilizado como conejo de indias para la instalación y puesto que el nuevo es CentOS, pues hemos aprendido a hacerlo en las dos distribuciones.
Descargando el filtro SPF
Descargamos el filtro (que se llama postfix-policyd-spf-perl) desde launchpad.net, donde lo han movido desde www.openspf.org
La descarga de hace desde el cuadrado verde de la derecha (lo digo porque me perdí un poco en la web hasta que lo encontré).
Luego lo descomprimimos en un directorio temporal y si no existe el directorio /usr/lib/postfix lo creamos y copiamos allí el archivo postfix-policyd-spf-perl
Instalando las dependencias en Debian
El artículo que hemos seguido como guía es ‘How to implement SPF in Postfix’ de HowtoForge.
Puesto que el filtro depende de los módulos de Perl Mail::SPF y NetAddr::IP, habría que instalarlos éstos primero. Debo confesar que solamente necesité instalar el primero, se ve que el segundo venía por defecto en la distribución o que ya lo había instalado, a saber. Entramos en la consola CPAN de Perl:
# perl -MCPAN -e shell
Una vez en la consola CPAN instalamos el módulo:
cpan[1]> install Mail::SPF
El final del resultado de la instalación fué:
Installing /usr/local/bin/spfquery
JMEHNLE/mail-spf/Mail-SPF-v2.9.0.tar.gz
./Build install -- OK
Salimos de la consola de CPAN con:
cpan[1]> q
Instalando las dependencias en CentOS
Empleamos el artículo ‘Centos 6 Postfix Configure SPF Checking‘ de ‘The Noc Cave’ como guía.
Hemos instalado los paquetes perl-Mail-SPF_XS.x86_64 y perl-Sys-Hostname-Long.noarch con el comando:
# yum install perl-Mail-SPF_XS.x86_64 perl-Sys-Hostname-Long.noarch
Sospecho que hace falta instalar el repositorio epel, que ya teníamos instalado y que no voy a explicar aquí como se hace.
Con estos dos paquetes ya tenemos las dependencias cubiertas.
Comprobando que todo está correcto
Un buen paso antes de continuar es comprobar que todo se ha instalado correctamente y no quedan dependencias por satisfacer. Para ello ejecutamos:
# perl /usr/lib/postfix/postfix-policyd-spf-perl
Si no obtenemos ningún mensaje de error es que todo está correcto.
Configurando postfix
Configuramos el filtro en master.cf (/etc/postfix/master.cf), añadiendo la siguiente línea al final del archivo:
policy unix - n n - 0 spawn user=nobody argv=/usr/bin/perl /usr/lib/postfix/postfix-policyd-spf-perl
Fitrando en main.cf (/etc/postfix/mail.cf). Para ello añadimos la entrada:
check_policy_service unix:private/policy
dentro de la sección
smtpd_recipient_restrictions
Añadimos también la línea:
policy_time_limit = 3600s
para evitar que se eternice la consulta al registro SPF del dominio y eso nos bloquee el servidor.
Reiniciamos postfix y se supone que ya tenemos un filtro SPF completamente funcional en nuestro servidor que analiza los registros SPF de los dominios de los remitentes de los correos y los deja pasar o no en función del resultado de la consulta.
Cuando los malos tratan de colarnos un gol enviando un mensaje desde una IP que no está listada en el registro SPF de los DNS del dominio del remitente el sistema se queja con un mensaje del tipo:
550 5.7.1 <Email Address>: Recipient address rejected:
That’s all folks!!!