Parcheando MailScanner para soportar long_queue_ids y hash_queues de Postfix

Desde la versión 2.9 de Postfix, hay una directiva llamada enable_long_queue_ids, la cual viene deshabilitada por defecto, que da la posibilidad de que los IDs de los mensajes que gestiona Postfix sean más largos que los de por defecto (por ejemplo: 2FEE85E0213 Vs 3zWlWK2Vxgzd8Wj).

Sin dicha opción, cuando un mismo servidor gestiona cientos de miles de mensajes, puede darse el caso de que el ID que se le asigna a un mensaje se repita a lo largo del día (true history). Esto provoca que la gestión de logs pueda dar problemas debido a que un identificador que debería ser único, no lo es y tenemos asociado a él dos FROMs, dos TOs, dos IP origen…etc.

Además, hay otras directivas llamadas hash_queue_depth y hash_queue_names, en las que se pueden definir qué colas van a estar hasheadas, es decir, los mensajes en ellas se guardarán en un árbol de directorios (esto permite los accesos más rápidos a los mensajes, en vez de tener miles en un solo nivel). Por ejemplo:

/var/spool/postfix/hold/A/F/AF12D45
/var/spool/postfix/hold/A/D/AD64212
/var/spool/postfix/hold/3/B/3B123DF

Con los IDs de cola cortos, como en el ejemplo, se van cogiendo secuencialmente caracteres del ID de mensaje (hasta el valor de hash_queue_depth que en el ejemplo sería «2») para ir creando subdirectorios. Con los IDs largos, esto es más complicado, como veremos más adelante.

MailScanner no tenía soporte para IDs de cola largos y las colas hasheadas, por lo que hubo que remangarse (pizza y café, como decimos por la oficina) y ponerse manos a la obra.

Sigue leyendo

Error temporal para Relay Access Denied en Postfix

Quizás, como buen administrador que revisa los logs de vez en cuando (¿verdad?), hayas visto en los de tu servidor de correo que hay bastantes errores de «Relay access denied«. O quizás en las gráficas que los muestran.
Este error se produce, resumiendo mucho, cuando se intenta enviar un mensaje a un servidor que no acepta correos para el dominio destino (por ejemplo, si intentas enviar correo con destino @gmail.com a los servidores de @outlook.com) o cuando no hay autenticación cuando se intenta enviar correo saliente. Centrándonos en el primer caso, no debería darse con una configuración de DNS correcta (el registro MX) y teniendo el dominio configurado en Postfix como destino, pero suele verse (dominios dados ya de baja de la plataforma, registros MX cacheados…etc), sobre todo si hay altas y bajas de dominios a lo largo del tiempo.

Hasta la versión 2.10 de Postfix, la política por defecto era rechazar este tipo de mensajes con un error permanente (errores de tipo 5XX), por lo que los servidores no reintentaban su envío durante varios días hasta que expirasen.
A partir de dicha versión, se añade la directiva smtpd_relay_restrictions que controla las restricciones de relay. Esto se hace, como bien se indica en la página de ayuda de Postfix, debido a que algunas configuraciones permitían el open relay sin saberlo, es decir, haciendo un PERMIT bajo smtpd_recipient_restrictions a una condición muy amplia (por ejemplo, que el FROM o el parámetro del comando HELO fuesen uno determinado). Para evitarlo, se añade la restricción para relay, de tal forma que aparte de las restricciones anteriores y para evitar esos fallos, quién envía hacia o a través de nuestro servidor se controla con:

smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination

Por defecto, podrán enviar a cualquier destino las redes indicadas en la directiva mynetworks y los usuarios autenticados; el resto de destinos no autorizados (dominios no configurados en mydestination, dominios no incluidos en relay_domains…etc), serán rechazados temporalmente. Es ahí donde se provoca que esos correos rechazados por «Relay access denied» lo sean de forma temporal y no permanente. Cambiando el «defer_unauth_destination» por «reject_unauth_destination«, haría que ese comportamiento cambiase y los rechazos fueran definitivos.

Esto evitará reintentos innecesarios (lo ideal es cambiar los MX de los dominios una vez que estemos seguros que el servicio de correo está bien configurado para aceptar sus correos, y no al revés) por parte de los servidores origen, que en caso de ser plataformas grandes, puede ser bastante tráfico.

Bug de Scan Messages en MailScanner

Unas de las cosas que más gustan de MailScanner es la feature de que cada una de las directivas de configuración, en su gran mayoría, pueden ser un archivo de reglas o una llamada a una función. Esto permite que para cada configuración típica de un sistema antispam pueda diferenciarse en base a cuenta origen/destino, IP origen, dominio origen/destino…etc, lo cuál, permite la personalización absoluta del sistema.

Por ejemplo, a la hora de decidir si un mensaje va a ser escaneado o no, en vez de tener un valor de «yes» o «no» para la directiva de configuración que lo controla, que se aplicaría a todos los mensajes, puede hacerse mediante un archivo de reglas externo:

Scan Messages = %rules-dir%/scanmessages.rules

donde se establecerán las reglas que se deseen, por ejemplo:

From: origen@confiable.com no
From: 192.168.1.10 no
From: /^192\.168\.13[4567]\./ no
FromOrTo: default yes

evitando que se escaneen los mensajes de un determinado FROM, de una determinada IP o de un conjunto de IPs que cumplan la expresión regular. Con el resto de mensajes, se hará lo que el «default» diga, en este caso, «yes» (escanearse).

Sigue leyendo

Postfix con DKIM y múltiples dominios

Tras pruebas varias e integraciones con otros sistemas de la plataforma, ya estamos firmando, desde hace unos meses, correos salientes con DKIM (RFC 5585).

¿Y qué es DKIM? Es una idea desarrollada a partir de DomainKeys e IdentifiedMail que
garantiza que un mensaje procede de un determinado sitio. Es usado por grandes proveedores como Yahoo, Gmail, Hotmail…etc.

DKIM usa claves públicas/privadas para certificar el origen de un email a través de DNS. Se crean dos claves, la pública se publica en un registro TXT del DNS del dominio cuyos mensajes se quieren firmar y la privada se usa para crear la firma digital de los mensajes añadiendo el resultado en una cabecera del propio mensaje a enviar.

El servidor destino, consultará la clave pública y chequeará que se corresponde con la clave que ha firmado el mensaje.

Sigue leyendo

Desaparición de mensajes en Postfix

He tenido dudas a la hora de poner un título a este post. El concepto «desaparición» puede que sea algo amarillista, quizás «pérdida de rastro de mensajes» pudiese hacer más justicia a lo que voy a comentar, pero bueno, queda más «Expediente X» el actual ;-)

Todo esto viene debido a que buscando en los logs un determinado mensaje enviado, no se sabía (a priori) qué había pasado con él. Esto es lo que creo (y supongo que todo el mundo cree) que no debe hacer un log, no dejar evidencias de lo que pasa.

Juntar MailScanner con Postfix siempre ha sido muy criticado, sobre todo en la lista de usuarios de Postfix. No hay una interfaz que pase los mensajes recibidos en el demonio smtpd de Postfix a MailScanner, como sucede con otras pasarelas de correo como amavids-new, sino que cuando llegan los mensajes vía SMTP, pasan a la cola hold donde quedan retenidos y MailScanner, con un proceso batch, procede a recogerlos de ahí regularmente para analizarlos.

Sigue leyendo

Greylisting II

Ya hablábamos hace algunos años (¡cómo pasa el tiempo!) sobre Greylisting y la efectividad que tenía al rechazar temporalmente conexiones de ciertas IPs (rangos dinámicos y residenciales). Gracias a esto, todos esos mensajes de spam que envían los bots (que no tienen un sistema de gestión de rechazos (sistema de colas, básicamente) como exige el RFC), son rechazados en primera instancia y no se vuelven a intentar entregar.

Un paso más es combinar esto con la geolocalización de IPs. Gracias a GeoIP, disponemos de una base de datos que guarda el país al que pertenece cada IP de Internet. En Debian por ejemplo, basta hacer:

apt-get install geoip-bin geoip-database

y disponemos ya de un comando que hace la consulta correspondiente:

# geoiplookup 81.12.209.54
GeoIP Country Edition: RO, Romania

¿Y qué podemos hacer con esto? Pues juntarlo con la idea de Greylisting y poder rechazar temporalmente, aparte de las IP dinámicas/residenciales, las conexiones realizadas desde ciertos países que son conocidos por el envío masivo de spam. Podemos sacar un listado de la web de SpamHaus:

Por ejemplo, podemos rechazar temporalmente, las conexiones que tengan como origen IPs de Rumanía, Polonia, China y Brasil. Si decidimos hacer esto, sería conveniente saber si los clientes suelen intercambiar correos con otros usuarios de dichos países, para evaluar el impacto que tendría. No obstante, los servidores legítimos de dichos países, reintentarán el envío del mensaje una vez recibido el rechazo temporal (como exige el RFC), por lo que no habrá problemas de pérdida de correos.

Si lo comentado anteriormente es aplicable para el correo entrante, algo parecido se puede hacer para el correo saliente (el que los clientes nos entregan para hacer relay y entregarlo al destino). Aplicar RBLs sobre los clientes directamente, suele provocar bastantes falsos positivos (con IPs dinámicas sobretodo) así que puede combinarse estas consultas con la geolocalización. La idea podría ser «rechazar los envíos de clientes cuya IP origen esté en una o más RBLs y además el país origen sea poco habitual o sospechoso».

En nuestros servidores de salida, en el día de ayer por ejemplo, estos son algunos de los países al que pertenecen las IPs cuyas conexiones fueron rechazadas por la política anteriormente mencionada:

Vietnam
Rusia
Polonia
Taiwan
Turquía
Rumanía
Kazajistán
Omán

mensajes que no tenían pinta de ser legítimos.

Por tanto, vemos como la combinación de varias herramientas, puede proporcionarnos funcionalidades que podemos aplicar en diferentes ámbitos y de diferentes formas en nuestras plataformas de correo.

Greylisting 2010

En el mes de Mayo del pasado 2010, puse en marcha un nuevo milter en los relays de correo de entrada de Hostalia.
Dicho milter se encarga de hacer greylisting selectivo a determinadas IPs (rangos dinámicos, fundamentalmente) y el resultado ha sido ciertamente, muy efectivo.

En el siguiente gráfico, vemos como el número de mensajes que se procesan por el motor antispam (en este punto, se han pasado ya todas las RBLs y tests SMTP, por lo que son mensajes que pasan a ser procesados por MailScanner y SpamAssassin) da un bajón importante a partir de la puesta en marcha de dicho milter.

Greylisting

Todo esto sin un solo falso positivo :-)

Está claro, como el tiempo ha ido demostrando, que las formas de lucha contra el spam deben pasar por este tipo de soluciones. De hecho, habrá que empezar a probar seriamente PostScreen, una nueva funcionalidad que ya está presente en Postfix (a partir de su versión 2.8) y que permitirá tener una protección por delante del demonio smtpd. Prometo post sobre ello :-)

Whitelisting basado en DNS en Postfix 2.8

En base a un hilo de la lista de de correo postfix-users, Wietse Venema, el creador de Postfix, ha dado soporte a listas blancas basadas en DNS.

Hasta ahora, solo estaba implementado el soporte para RBLs (listas negras) así que cualquier lista blanca de IPs que se quisiese implementar, había que hacerlo con un archivo de texto con el listado de IPs en el propio servidor. Ahora, con esta nueva feature, se puede indicar a Postfix que si la consulta DNS (preguntar por el registro A de la IP a la inversa seguida del dominio, normalmente) para una determinada IP contra una lista blanca basada en DNS, devuelve una IP concreta, pueda evitarse que sigan otros chequeos antispam (como RBLs).

El propio ChangeLog de Postfix 2.8 (versión de desarrollo) ya indica dicha mejora:

20101105

Feature: DNS whitelist support in the Postfix SMTP server.
permit_dnswl_client whitelists a client by IP address, and
permit_rhswl_client whitelists a client by its hostname.
The syntax is the same as reject_rbl_client etc., but the
result is PERMIT instead of REJECT. For safety reasons,
permit_xxx_client are silently ignored when they would
override reject_unauth_destination. The result is
DEFER_IF_REJECT when DNSWL lookup fails. The implementation
is based on a design documented by Noel Jones (August 2010).
File: smtpd/smtpd_check.c.

La documentación también hace referencia a ello.

Eso sí, habrá que esperar algún tiempo hasta que entre en la rama estable actual, la 2.6.

Protección en el kernel de FreeBSD contra DoS a SMTP

En la pasada EuroBSDCon 2009 celebrada en Septiembre, un congreso de los hackers de FreeBSD, hubo una charla cuyo título rezaba «FreeBSD kernel protection measures against SMTP DDoS attacks», por Martin Blapp.

El paper de aquella charla se puede encontrar en:

http://www.ukuug.org/events/eurobsdcon2009/papers/BSDCON09-SMTP-DDoS-Final.pdf

Como el propio título hace suponer, se trata de un módulo (llamado accf_smtp para el kernel de FreeBSD capaz de gestionar las conexiones SMTP entrantes al servidor y prevenir cierto tipo de ataques (comunes entre las botnes). Con dichas conexiones, puede realizar diversas funciones como hacer una pausa antes de entregar el banner del servicio SMTP, rechazar conexiones que no envíen primeramente el comando HELO/EHLO, establecer número máximo de caracteres en parámetros de comandos…etc.

Soy de la opinión de Wietse Venema que comentaba que esas funciones no son para hacerlas en el kernel sino en userland, como ya hacen numerosos servidores de correo electrónico, por lo que en realidad no supone nada nuevo.

Esta idea está basada en el ya existente accf_http, que gestiona las conexiones HTTP entrantes.

Habrá que esperar a ver qué opinan los que puedan probarlo en sus FreeBSDs.