MailGateway v2 - Gat2
El objetivo de **Gat** es filtrar el correo no deseado que llega a la empresa sin tener que modificar prácticamente nada al servidor de correo que ya tiene actualmente su empresa.
Escenario
Descripción
En este escenario disponemos de dos partes bien diferenciadas el frontend y el backend, la idea principal es conseguir liberar al servidor principal (backend) de la carga de las tareas de antispam, antivirus y otras complejas configuraciones para garantizar que no se recibe correo no deseado en la empresa. A pesar de que el backend puede estar detras de un firewall para su mejor seguridad no es necesario que esto sea así. Lo que si es importante destacar es que el correo via SMTP siempre irá contra el servidor frontend y el servidor SMTP del backend usará como smtart-host o relay único el frontend. Así aseguramos que todos los correos son examinados por el sistema anti-UCE (unsolicited commercial email).
Estas técnicas son muy útiles porqué a menudo el servidor de backend es un servidor de groupware (exchange, lotus notes, zimbra, etc) o alguna aplicación para gestión de ISPs (plesk, ispconfig, etc) que o queremos sobrecargar con tareas de anti-UCE. Esta solución es indicada para todo aquel sistema que necesite ser escalado en el backend y no quiera tener dependencia de la escalavilidad del sistema anti-UCE para hacer esta escalavilidad, porqué esto aumenta la complejidad del crecimiento inecesariamente.
Componentes
- Servidor SMTP Postfix: encargado de recibir, gestionar y entregar el correo.
- Postfix-Policyd como servidor de greylist, blacklist, whitelist, quotas, etc: encargado de filtrar conexiones ilegítimas y de controlar abusos del servidor.
- DSPAM como servidor anti-spam: el correo aceptado puede no ser no deseado, se aplican filtros estadísticos para intentar descubrirlo.
- Clamav antivirus: servidor antivirus de ficheros adjuntos en correos.
- MySQL servidor de base de datos para DSPAM y Postfix-Policyd: usamos este servidor de BBDD como backend para no tener problemas de escalavilidad.
- Apache+DSPAM WebUI: interface web para información estadística de los correos gestionados por DSPAM y control de correos en cuarentena.
- Módulos a medida para: (programados en python usando twisted)
- SMTP DSPAM learn server: inyecta correos a la BBDD de DSPAM para mejorar su aprendizaje.
- tcp_table:verify_policy: servidor TCP que comprueba si un dominio es local o no.
- tcp_table:transport: servidor TCP que comprueba donde se tiene que entregar un correo.
Ruta del correo
Cuando se recibe una conexión (0) este obviamente llega por SMTP al puerto 25 del servidor del gat, si la conexión es autenticada (1) esta se valida a través de demonio SASLAUTH (1.1) y con el mecanismo de autenticación rIMAP. rIMAP lo que hace es re-enviar las credenciales recibidas en el Postfix contra el servidor IMAP (1.1.1) del servidor de backend. Si la validación de IMAP (1.1.1) es correcta entonces la validación (1) también lo será. Por lo tanto, seguimos adelante con la conexión SMTP.
Llegados al punto (2) via (1.1) o via (2) el procedimiento es e mismo, aunque con matices distintos. O sea, que se trata de validar que el cliente conectado, el remitente del envio, el receptor y el contenido pasán un primer filtro de legitimidad. Este filtro si hay una previa autenticación es mucho más suave y permisivo, por ejemplo, si estas autenticado se permitirá relay al cliente y sinó no.
Los primeros filtros (2.1) a superar son los impuestos por la sentencia smtpd_client_restrictions. Concretamente en este punto controlaremos:
- permit_mynetworks: se considera tráfico legitimo el de nuestras redes locales, definidas en la variable pertinente
- permit_sasl_authenticated: conexiones autenticadas son legítimas
- reject_rbl_client: no aceptamos conexiones de hosts que estan lístas RBL
En el punto (2.2) a nivel de configuración de Postfix corresponde al comando: smtpd_sender_restrictions. Igual que en punto (2.1) se controla: permit_mynetworks y permit_sasl_authenticated. En ambos casos el remitente será aceptado sea cual sea, porqué se permite relay. Las restricciones impuestas son:
- reject_unknown_sender_domain: que el dominio del remitente no se pueda resolver, esto se comprueba conectando al servidor de la tabla TCP: vrfy_domain (2.X.1). O sea, que sólo se aceptan dominios locales. No se pueden mandar emails de dominios que no sean controlados por nuestros servidores.
- reject_non_fqdn_sender: que el dominio del remitente no tenga un registro MX para enviarle correos, esto se comprueba conectando con el servidor de la tabla TCP: transport (2.X.2). El cual indicará cual es el servidor capaz de recibir correos con el dominio indicado.
Finalmente debemos comprobar el destinatario del correo (2.3), el comando de Postfix encargado de definir las restricciones para esta parte es: smtpd_recipient_restrictions. Como en los casos anteriores se tratan a parte los casos: permit_mynetworks y permit_sasl_authenticated. A continuación indicamos que:
- reject_unauth_destination: no se acepta relay si cliente no esta autenticado.
- reject_unverified_recipient: si el destinatario es local, o sea, de alguno de los dominios del backend debe estar verificado, esto va relacionado con los comandos que se especifican fuera de: smtpd_recipient_restrictions.
- address_verify_sender: indicamos remitente que usaremos para saber si el destinatario será aceptado por el SMTP del backend.
- address_verify_local_transport: indicamos dirección y puerto del servidor SMTP del backend.
- reject_unlisted_recipient: funciona en combinación del comando anterior para indicar que el destinatario es válido
- check_policy_service: llama al demonio Postfix-Policyd (2.3.2).
Cuando se ha recibido el comando RCPT no sólo se ejecuta el comando smtpd_recipient_restrictions, sino que también se verficia el dominio y el transporte, o sea, que se conecta a la TCP table vrfy_domain (2.X.1) y transport (2.X.2). Gracias a este último sabemos si el destinatario del correo es una dirección reservada para educar a DSPAM, si es así transport (2.X.2) devolverá un transport que apuntará a SMTP learn spam (2.3.3). En caso de que el transporte sea hacia el servidor de backend (2.3.1) se hará la verificación comentada en address_verify_local_transport.
El servidor SMTP (2.3.3) esta programado con Python y Twisted con la finlidad de ejecutar el comando de sistema DSPAM (2.3.3.1) con los parámetros necesarios para decirle a DSPAM que el correo recibido era:
- Un correo que ha pasado por DSPAM y a pesar de ser HAM fue considerado SPAM. Falso positivo.(ham@…)
- Un correo que ha pasado por DSPAM y a pesar de ser SPAM fue considerado HAM. Falso negativo.(spam@…)
- Un correo que no ha pasado por DSPAM de tipo HAM y que debe servir para aprender que características tienen nuestros correos HAM. (learn-ham@…)
- Un correo que no ha pasado por DSPAM de tipo SPAM y que debe servir para aprender que características tienen nuestros correos SPAM. (learn-spam@…)
El servidor TCP Postfix-Policyd (2.3.2) también debe validar el envio del correo, para hacerlo se apoya con una base de datos MySQL. Los únicos parámetros usables si llamamos al servicio en este punto de la configuración son, ya que todavía no hay otras informaciones como la medida del mensaje ya que este todavía no ha podido ser enviado:
- Whilelist: null sender, email sender, IP, dns name, auto-whitelist
- Blacklist: null sender, email sender, IP, dns name, auto-blacklist, helo,
- Greylist
- Sender throttle: via sasl user, host, quota number of mails, no quota limit for size
- Recipient throttle: recipients limit
Finalmente si todo esto se cumple llegamos al punto (3), aquí el mensaje ya ha sido completamente entregado en el servidor Postfix y hemos informado al cliente que tenemos su correo y lo estamos procesando. En el punto (4) el servidor smtpd (0) envia el correo al servidor LMTP DSPAM (4) que procesará el correo a través de sus filtros anti-spam basados en datos estadísticos del correo. Por otro lado DSPAM (4) enviará los adjuntos del correo al servidor Clamav (4.1) para saber si los adjuntos estan infectados con algún virus.
Es importante destacar que toda la información estadística de DSPAM (4) esta almacenada en una BBDD mysql para asegurar su escalavilidad. En caso de que el correo sea considerado SPAM quedará en cuarentena al servidor, o se reneviará a su destinatario indicando que esta marcado como no deseado. En la cabecera del correo se puede consultar un informe de DSPAM de todos los correos que entran y salen a través del frontend. Por otro lado los correos también tienen una marca al final del mensaje con la palabra DSPAM y un código numérico, este código lo usa DSPAM internamente para reaprender de sus errores si es que a posteriori se le indica que ha comentido alguno.
A la salida de DSPAM (5) el correo puede ser diretamente descartado por haber entrado en cuarentena o seguir su curso normal (6), o sea, siendo reintroducido a Postfix a través de un servidor localhost del mismo sólo disponible para recibir correos re-inyectados desde DSPAM. Cuando un correo llega l punto (6) sigue su habitual (7), o sea, intenta ser entregado (8) a su destino o se descarta definitivamente si esto no es posible.
Si el destino del correo era remoto la entrega será en el servidor que corresponda según las indicaciones de los registros MX del DNS (9.1) y si el correo era local se entregará al servidor backend (9.2).
Servicios
Servidor frontend (Gat)
El único servicio especial que corre en el servidor GatV2 es el learn_spam. Se trata de un simple servidor SMTP que su única función es recibir correos que van a unas direcciones reservadas y educar al servidor dspam para que aprenda sobre correos buenos, malos, falsos positivos y falsos negativos. Este servicio esta en el directorio /opt/learn_dspam. En este directorio a parte del propio servicio hay el fichero de logs (.log), el fichero PID con el ID del proceso del servicio (.pid) y el fichero que se usa para lanzar, parar y saber el estado del demonio (.sh).
El resto de servicios del servidor frontend son:
- postfix (SMTP)
- dspam (sistema anti-spam)
- mysql (base de datos del DSPAM y el policyd)
- apache (UI DSPAM)
- clamav-daemon y clamav-fresh (antivirus)
- saslauthd (autenticación SMTP)
Servidor backend
En este servidor deben correr dos servicios:
- transport: este serivicio sirve para saber cual es el servidor destino donde se debe entregar un correo.
- verify_domain: su finalidad es saber si un dominio es o no local. O sea, si debemos aceptar los correos que van hacia ese dominio.
Ambos demonios se configuran con el fichero config.ini que se encuentra en el mismo directorio que los demonios, por defecto en: /opt/mail-gateway. En este directorio también podemos encontrar el fichero de .pid, el .log y el .sh. El primero sirve para identificar el PID del proceso del servicio, el segundo es el fichero de logs y el tercero sirve para 'iniciar', 'parar' y preguntar el estado del servicio.
Configuración
El único fichero de configuración no estándard de todo el sistema, es el que se usa en el backend para configurar los demonios transport y verify_domain. Para explicar este fichero de configuración se hará a partir del siguiente ejemplo:
; virtual local domains [domains] VIRTUALDOAMINSFILE=/var/qmail/control/virtualdomains ; host per on entrara el correu que te bustia al plesk [transport] TRANSPORT_DEFAULT=[3.3.3.3]:25 ; overload delivery target for some domains [transports] example.com=[1.1.1.1]:25 example2.com=dev.lana2.com:25 ; where to deliver education mail for DSPAM [learn_dspam] ham@example.com=[127.0.0.1]:25001 spam@example.com=[127.0.0.1]:25001 learn_ham@example.com=[127.0.0.1]:25001 learn_spam@example.com=[127.0.0.1]:25001 ;source connections permited [permited_sources] 1.1.1.1=ip 2.2.2.2=ip
La primera parte del fichero, sección [domains] indica donde se encuentra el fichero con el listado de dominios locales, en este caso se refiere a la ruta y a un fichero con el formato de dominios virtuals de qmail concretamente generado por la inerface Plesk. Este fichero tiene el formato:
domain1.com:1 domain2.com:2
Estos son los dominios que seran procesados por el servidor de correo backend como dominios locales, así pues el servidor frontend debe aceptarlos también.
En la sección [transport] se define donde se entregará el correo para los dominios anteriormente mencionados. O sea, en la IP (o hostname) del servidor backend. De esta forma se almacenarán en los buzones de los usuarios. La información de esta sección puede ser sobrecargada por la información de la siguiente sección: [transports], que indica donde debe entregarse el correo para ciertos dominios que pueden o no estar en la lista definida en el fichero de la primera sección. En el contenido de esta sección que nos ocupa, podemos ver que hay una lista de dominios seguida por las IPs y puertos, o hostnames y puertos donde se entregarán los correos para estos dominios. Estos es usado por dominios especiales que deben ser entregados en servidores dedicados. Por ejemplo, en el caso de un ISP estos dominios no descargan el correo del servidor del ISP sinó que el correo se entrega directamente en el servidor de la empresa.
La sección [learn_dspam] se definen una lista de direcciones de correo especiales, la finalidad de las mismas es recibir correos con información para educar a dspam. En caso de modificar estas direcciones también se debe modificar el código del demonio learn_dspam del servidor frotend, concretamente el fichero por defecto esta en /opt/learn_dspam/learn_dspam.tac.py.
Finalmente la sección [permited_sources] tiene un listado de IPs permitidas, o sea, una lista con las IPs que pueden conectarse a los demonios transport y local_domains del servidor de backend.
Monitorización de colas
Escencialmente postfix nos ofrece dos formas para consultar sus colas, por un lado el bien conocido 'mailq' que muestra un listado de mensajes en cola y su estado actual. Para colas relativamente pequeñas es más que suficiente pero para una depuración más profunda es muy recomendable el uso de 'qshape' al que le podremos indicar cuál de las colas que tiene 'postfix' configurado debemos consultar. Es muy útil la agrupación que hace de los correos por dominios ya que hace mucho más usable la herramienta. A pesar de esto su principal problema es el rendimiento.
Tareas de limpieza de BBDD
Escencialmente se usan dos procesos de limpieza de base de datos, uno para DSPAM y otro para policyd. Ambos trabajan con un sistema de limpieza basado en 'round-robin', así pues se borrarán las entradas que hace más tiempo que no se usan de las tablas con el fin de eliminar información que no se este usando.
Si consultamos el crontab podemos ver:
0 0 * * 0 /usr/bin/mysql -u libdspam7-drv-my -ppasswd libdspam7drvmysql < /etc/dspam/purge.sql 0 1 * * 0 /usr/lib/postfix-policyd/cleanup -c /etc/postfix-policyd.conf
que ambos procesos se ejecutan en domingo a las 0h y a la 1h respectivamente de la noche.
Interface WebUI de DSPAM
Actualmente sólo el administrador del sistema es capaz de acceder a esta parte. Aunque el diseño de la herramienta permite trabajar con acceso por usuarios. El problema es que el sistema de autenticación no esta programado para soportarlo.
Pantalla: System Status
Se puede ver una estadística general del sistema, con la actividad de las últimas 24h y la de los últimos dias. El primer recuadro de la parte superior izquiera es el más interesante ya que nos da información sobre cual esta siendo el comportamiento de nuestra herramienta.
Pantalla: User statistics
En esta tabla se observa un listado de las direcciones de correo sobre las que se ha procesado correos en el DSPAM. A continuación se describen los valores mostrados por cada una de las columnas:
- Q.size: medida de la cola de mensajes.
- TP (True Posivite): mensajes considerados SPAM y que realmente lo son.
- TN (True Negative): mensajes deseados, o sea, HAM y que realmente lo son.
- FP (False Positive): mensajes considerados SPAM y que eran HAM. Si salen en este punto quiere decir que DSPAM ha sido re-educado para no volver a equivocarse con esos correos.
- FN (False Negative): mensajes considerados HAM y que realmente eran SPAM. Si salen en este punto quiere decir que DSPAM ha sido re-educado para no volver a equivocarse con esos correos.
- SC
- IC (Inoculotions)
- Mode
- TEFT (train-everything), aprende de todos los mensajes que se procesan. No es un modo muy recomendable para sistemas con mucho tráfico, aunque para estados iniciales es recomendable.
- TOE (train-on-error), cuando un sistema ya ha sido educado con unos 2.500 mensajes HAM este ya puede ponerse en este estado así sólo aprenderá de los errores que vaya cometiendo y nosotros le vayamos informando.
- TUM (train-until-mature), este es un modo hibrido entre los dos modos anteriores.
- NOTRAIN, este modo permite desaprender de los mensajes aprendidos.
- On Spam: que acción se debe tomar si un correo es considerado SPAM:
- Quarantine: poner el correo en cuarentena.
- Tag-subject: añadir una marca en el título del correo
- Header: añadir la cabecera 'X-DSPAM-Result' al correo
- BNR (Bayesian Noise Reduction): usa 2.500 mensajes HAM y provee de una sistema de reducción de ruido para los ataquest de diccionario en los SPAM. Para más información: http://bnr.nuclearelephant.com
- Whitlist: auto-genera una lista blanca automáticamente.
- Sed:
- Sig Loc:
En esta pantalla también se puede pinchar encima de un usuario y entrar a ver el detalle del mismo.
Pantalla: Administration
En esta pantalla podemos configurar cual debe ser el comportamiento general de DSPAM, o el comportamiento de este para un usuario. Básicamente se puede configurar:
- Cuando debe aprender DSPAM
- Como le inyectaremos los correos a DSPAM para que aprenda
- Que hacer cuando DSPAM detecta un correo considerado SPAM
- También podemos activar diversas funcionalidades como el BNR
Pantalla usuario: Performance
Pantalla ideal para ver que tal esta funcionando DSPAM para ese usuario. También sirve para hacernos una idea de su volumen de tráfico de correo.
Pantalla usuario: Preferences
Escencialmente es igual que la pantalla 'Administration' pero esta configuración sólo afectará a este usuario.
Pantalla usuario: Alerts
Sirve para lanzar búsquedas sobre la pantalla de cuarentena.
Pantalla usuario: Quarantine
Listado de correos considerados SPAM y almacenados en cuarentena a la espera de ser recuperados en caso de ser falsos positivos.
Pantalla usuario: Analysis
Muestra de forma gráfica la evolución del tráfico SPAM y HAM de un usuario las últimas 24h y los últimos 14 días.
Pantalla usuario: History
Muestra un histórico de todos los correos procesados para el usuario seleccionado, en caso de haber sido procesado incorrectamente este correo se puede re-educar a DSPAM de una forma muy sencilla y cómoda. Esta pantalla es realmente útil como complemento de los sistema de aprendizaje de DSPAM.
Educar a DSPAM
Para educar a DSPAM hay dos grandes formas de hacerlo, por un lado podemos inyectar correos HAM y SPAM que tengamos guardados de cuando todavía no disponiamos de DSPAM y por otro lado estan los falsos positivos y falsos negativos que pueden generarse por parte de DSPAM.
En el primer de los casos lo que tenemos que hacer re-enviarle el correo a DSPAM:
- Si el correo es SPAM, lo mandamos a learn-dspam@…
- Si el correo es HAM, lo mandamos a learn-ham@…
Si recibimos un correo marcado como HAM o SPAM por parte de DSPAM y este ha sido clasificado erroneamente lo que debemos hacer es:
- Si es un falso positivo, o sea el correo era deseado pero fue marcado como SPAM, lo mandamos a ham@… y el DSPAM será re-educado (retrained)
- Si es un falso negativo, o sea el correo era no deseado pero fue marcado como HAM, lo mandamos a spam@… y el DSPAM será re-educado (retrained)
Los correos que ya han pasado por DSPAM dejan un código en el pie del mensaje o en una cabecera del correo. Este código, se compone de unos símbolos de adminiración, la palabra 'DSPAM' y un código numérico. Esta información es la que usará DSPAM para re-educarse. Ya que buscará en su base de datos y cambiará la consideración que se dió a ese correo.
También es una buena idea darse una vuelta por la pantalla 'History' del usuario en el panel de control web de DSPAM.
FAQ
- Por qué no se soporta SPF?
SPF es un servicio que debería ir ligado al greylist pero postfix-policyd no lo soporta, por lo tanto se debería modificar el plugin para que esta función este soportada. Otra posibilidad sería unirlo a DSPAM para sumar penalizaciones en caso de no cumplir con el registro SPF. IMHO lo mejor sería después de recibir el MAIL FROM, comparar la información SPF y el dominio del email remitente, si este no se cumple le aplicamos una moratoria al estilo greylist. También sería interesante añadir una header al estilo gmail.
