Filtrado AntiSpam: Postfix, Mailscanner, SpamAssasin (parte I)
En este post voy a explicar como montar un servidor Linux dedicado a filtrar Spam. Uno de los requisitos es que se pueda interponer entre el servidor de correo corporativo e internet sin tener que reconfigurar el servidor corporativo. De esta manera tendremos una appliance de filtrado AntiSpam enchufable en caliente: basta con cambiar el puerto que se publica desde el firewall corportivo a otro equipo y listo!
Vamos a partir de una distro Debian, instalada en cualquier chisme. No es estrictamente necesario que tenga dos tarjetas de red pero es recomendable.
- MTA
Instalamos postfix (apt-get install postfix). Ahora lo configuramos para que haga relay simplemente contra el servidor corporativo, de nuestros dominios y con las primeras restricciones. Para eso, editamos /etc/postfix/main.cf y ponemos:smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
append_dot_mydomain = no
append_at_myorigin = no
myhostname = filter.foo.com
inet_interfaces = all
mynetwork_style = host
relay_host = mailserver.foo.com
header_checks = regexp:/etc/postfix/header_checks
relay_recipient_maps = hash:/etc/postfix/recipients
relay_domains = foo.com, bar.com, foobar.com
Con esto, los emails que reciba este equipo (filter.foo.bar) los reenviará a mailserver.foo.com. Pero tambien, antes de hacer el reenvío hará lo siguiente:- si el destinatario no está incluido en /etc/postfix/recipients, se descarta el mensaje directamente. Más adelante se verá como generar un archivo con los recipientes contra LDAP.
- el archivo /etc/postfix/header_checks contiene esto:
/^Received:/ HOLD
Asi que el mensaje, tal y como se recibe, se coloca en la cola de “retenidos”. A la espera de siguientes pasos. - Procesado de Spam
Ahora, aptgeteamos Mailscanner. Es posible que pida spamassasin y algun antivirus. Mailscanner es una especie de plataforma a la que se le pueden conectar plugins para que hagan diversas tareas sobre los mensajes: antispam, contenido peligroso (XSS), antivirus, phising … etc. En este caso sólo nos interesa el filtrado de spam, asi que, abrimos el archivo /etc/MailScanner/MailScanner.conf y editamos:%org-name% = Corporate-mailfilter
%org-long-name% = Corporate name
%web-site% = www.foo.com
Max Children = 1
Run As User = postfix
Run As Group = postfix
Queue Scan Interval = 6
Incoming Queue Dir = /var/spool/postfix/hold
Outgoing Queue Dir = /var/spool/postfix/incoming
Incoming Work Dir = /var/spool/MailScanner/incoming
Quarantine Dir = /var/spool/MailScanner/quarantine
PID file = /var/run/MailScanner/MailScanner.pid
Restart Every = 14400
MTA = postfixLa mayoría de estas línas son autoexplicativas, pero hay que destacar que mientras el MTA (postfix) sólo comprueba si el destinatario es válido y lo deja en la cola de HOLD, el scanner lee los mensajes cada 6 segundos de la cola HOLD y los deja en INCOMING.
Tambien ajustamos las siguientes opciones del mismo archivo lo siguiente.
Configuración general y banners diversos, cabeceras para distinguir los emails que ya han sido escaneados … etc.
Spam Checks = yes
Mail Header = X-%org-name%-MailScanner:
Spam Header = X-%org-name%-MailScanner-SpamCheck:
Spam Score Header = X-%org-name%-MailScanner-SpamScore:
Envelope From Header = X-%org-name%-MailScanner-From:
Envelope To Header = X-%org-name%-MailScanner-To:
Spam Score Character = s
SpamScore Number Instead Of Stars = no
Hostname = the %org-name% ($HOSTNAME) MailScanner
Listas de spam
Minimum Stars If On Spam List = 0
Spam Modify Subject = yes
Spam Subject Text = {Spam?}
High Scoring Spam Modify Subject = yes
High Scoring Spam Subject Text = {Spam?}
Spam List Definitions = %etc-dir%/spam.lists.conf
Spam List = spamhaus.org
Spam Domain List =
Spam Lists To Reach High Score = 3
Spam List Timeout = 10
Max Spam List Timeouts = 7
Spam List Timeouts History = 10Listas blancas y negras:
Is Definitely Not Spam = %rules-dir%/spam.whitelist.rules
Is Definitely Spam = noDefinimos los umbrales de Spam y HighSpam para SpamAssasin
Use SpamAssassin = yes
Max SpamAssassin Size = 30000
Required SpamAssassin Score = 6
High SpamAssassin Score = 10
SpamAssassin Auto Whitelist = no
SpamAssassin Prefs File = %etc-dir%/spam.assassin.prefs.confVarios timeouts
SpamAssassin Timeout = 75
Max SpamAssassin Timeouts = 10
SpamAssassin Timeouts History = 30
Check SpamAssassin If On Spam List = yes
Spam Score = yes
Rebuild Bayes Every = 86400
Wait During Bayes Rebuild = yesQue hacemos si SpamAssasin detecta que es spam, high scoring spam o ham?
Spam Actions = header "X-custom-header: spam normal" deliver forward low.spam@foo.com
High Scoring Spam Actions = header "X-custom-tag: high score" forward high.spam@foo.com
Non Spam Actions = deliver
Log Spam = yes
Log Non Spam = yesEn este ultimo bloque es donde se definen las acciones a tomar si el email no es spam (se entrega), es spam (se añade cabecera, se entrega una copia a la cuenta low.spam@ y se entrega) o si es spam con alta puntuación (cabecera, copia a high.spam@ y NO se entrega). Además se logan las acciones con syslog, para que luego se puedan extraer estadisticas de maillog.*.
Bien, recapitulando un poco. Hasta ahora tenemos que cuando llega un email y conocemos al destinatario, se pasa a MailScanner en cual, en base a listas blancas/negras y puntuación otorgada por SpamAssasin clasificará el email entre ham (no spam), spam, y high scoring spam. En el primer caso lo entregará al usuario, en el segundo le modificará las cabeceras, subject, hará una copia a una cuenta y lo entregará al destinatario. En el tercer caso no lo entregará al destinatario, pero mandará una copia a otra cuenta de correo, cabeceras, subject.. etc. Pero, como SpamAssasin asigna puntuaciones a los emails?
- SpamAssasin: Aqui es donde entra en juego el último componente: SpamAssasin. Es el encargado de ejecutar el grueso de comprobaciones, expresiones regulares, contenido, probabilidades… etc.Si ya hemos aptgeteado spamassasin, vemos en su archivo de configuración (/etc/MailScanner/spamassasin.prefs.conf):
...
bayes_ignore_header X-Corporate-mailfilter-MailScanner
bayes_ignore_header X-Corporate-mailfilter-MailScanner-SpamCheck
....
Esto es para que no se tenga en cuenta en ninguna comprobación los header que se han añadido en pasos anteriores para redirigir el email.
Y las primeras reglas de ejemplo:
header FRIEND_GREETINGS Subject =~ /you have an E-Card from/i
describe FRIEND_GREETINGS Nasty E-card from FriendGreetings.com
score FRIEND_GREETINGS 100.0
Busca en el header, si el subject del email contiene la expresión, y si es así, le suma 100 puntos. La directiva “describe” es para referenciarla desde en los logs. Vale, mi mensaje tiene +100, ¿es mucho? Pues parece que sí, porque en la configuración de MailScanner habiamos especificado que 6 se considera spam pero se entrega, y 10 se considera spam con alta probabilidad y se descarta.Más reglas sencillas:
uri IE_VULN /%([01][0-9a-f]|7f).*@/i
score IE_VULN 100.0
describe IE_VULN Internet Explorer vulnerabilitySe comprueba si el email contiene un uri que cumpla ese patrón. También suma +100 así que iría a la basura directamente. También se pueden añadir reglas más concretas en /etc/spamassasin/. Cada archivo .cf puede tener un conjunto de reglas relacionadas por temas, aka viagra/cialis, penis, rolex .. Esto ya va a gustos.
Aqui va un fragmento de reglas para viagras y pastillitas:body __DRUGS_ERECTILE11 /(?:\b|\s)_{0,3}[a4\xE0-\xE6@][_\W]{0,3}p[_\W]{0,3}c[_\W]{0,3}[a4\xE0-\xE6@][_\W]{0,3}[l!|1][_\W]{0,3}[i1!|l\xEC-\xEF][_\W]{0,3}s_{0,3}\b/i
meta DRUGS_ERECTILE (__DRUGS_ERECTILE1 || __DRUGS_ERECTILE2 || __DRUGS_ERECTILE3 || __DRUGS_ERECTILE4 || __DRUGS_ERECTILE5 || __DRUGS_ERECTILE6 || __DRUGS_ERECTILE8 || __DRUGS_ERECTILE10 || __DRUGS_ERECTILE11
)
describe DRUGS_ERECTILE Refers to an erectile drug
meta DRUGS_ERECTILE_OBFU ( (__DRUGS_ERECTILE1 &&!__DRUGS_ERECTILE_V) || (__DRUGS_ERECTILE3 && !__DRUGS_ERECTILE_C) ||__DRUGS_ERECTILE2 || (__DRUGS_ERECTILE10 &&!__DRUGS_ERECTILE_V) || (__DRUGS_ERECTILE6 &&!__D
RUGS_ERECTILE_L))
describe DRUGS_ERECTILE_OBFU Obfuscated reference to an erectile drugY otro de rolex baratos:
....
body __SARE_SPEC_GENU_REPL /\bgenuine\b.{1,30}\breplica/i
meta SARE_SPEC_ROLEX_GENREP ( __SARE_SPEC_GENU_REPL && SARE_SPEC_ROLEX )
describe SARE_SPEC_ROLEX_GENREP Genuine Replica Rolex!
score SARE_SPEC_ROLEX_GENREP 1.666
...
Realmente hay gente que se monta cosas raras con expresiones regulares xD
Luego también podemos incluir comprobaciones a servicios externos por DNS, con los que SpamAssasin comprueba si las URIs del contenido de los emails estan en lista negra:uridnsbl URIBL_SBL sbl.spamhaus.org. TXT
body URIBL_SBL eval:check_uridnsbl('URIBL_SBL')
describe URIBL_SBL Contains an URL listed in the SBL blocklist
tflags URIBL_SBL net
Ojo! aquí no se está comprobando si la IP de origen del email está en lista negra. Se comprueba si las URI’s que hay en el contenido del email estan blacklisted. Es mucho más efectivo esto, porque un spammer tenderá a enviarnos hacia los mismos servidores web (las URI’s del contenido) aunque envíe los emails desde IPs distintas.
Por supuesto, podemos excluir algunos dominios de esta comprobación:uridnsbl_skip_domain yahoo.com w3.org msn.com com.com yimg.comAhora entramos a la parte probabilística, porque en /etc/MailScanner/spam.assasin.prefs.conf se definen estos umbrales:
score BAYES_00 -15.0
score BAYES_05 -5.0
score BAYES_95 5.0
score BAYES_99 15.0
Vamos, que si el clasificador bayesiano no da una probabilidad del 97% de que el email es Spam, spamassasin le da +5 a su puntuación. Si nos devuelve una probabilidad del 8% daría +0.0. … etc. Como además de estas comprobaciones, se procesan todas las expresiones regulares de los archivos “.cf”, si el contiene rolex (+1.67) y el clasificador da un 98% (+5), el mensaje queda con +6.67. Con esa puntuación MailScanner le cambia el subject, guarda una copia a low.spam y lo entrega al destinatario.Todo el sistema de puntuación de spamassasin es muy delicado, y cualquier cambio puede suponer que los email dejan de entregarse en gran parte por un puntuación demasiado estricta. Antes de aplicar cambios al sistema de puntuaciones hay que estar muy seguro de las implicaciones que tendrá conociendo el sistema de filtrado al completo.
Cambiar estas lineas
score BAYES_00 -5.0
score BAYES_05 -1.0
score BAYES_95 1.0
score BAYES_99 5.0Por estas otras:
score BAYES_00 -15.0
score BAYES_05 -5.0
score BAYES_95 5.0
score BAYES_99 15.0Supone darle un mayor peso específico al componente Bayesiano del filtro. Al principio de la implantación de este filtro puede convenir tener un bajo peso específico en el Bayesiano porque aunque es muy efectivo, tiene un comportamiento impredecible si no está bien entrenado. Sólo una vez se ha entrenado el Bayesiano con miles de mensajes se le puede dar protagonismo en detrimento de las expresiones regulares normales.
Por todo esto, es muy recomendable hacer un seguimiento de con qué puntaciones se descartan los emails, cuales son las expresiones regulares con más aciertos … etc, para reajustar convenientemente el sistema de filtrado. No siempre hay que tocar las puntuaciones, es más, en la expresiones regulares no es demasiado recomendable, pero si vemos una gran tasa de aciertos con expresiones de rolex, podemos ampliar la colección de archivos “.cf” en ese sentido.
Seguiré en otro post, comentando los puntos donde se integran todos estos componentes, los sripts que hacen falta, como se puede implementar todo esto sin que el usuario note demasiados cortes y como podemos ir ajustando progresivamente el filtro para mantenerlo en forma.
Hasta entonces, dejo unos enlaces:
-
Técnicas AntiSpam
http://en.wikipedia.org/wiki/Anti-spam_techniques_(e-mail)
-
Entrevista a un Spammer
http://www.washingtonpost.com/wp-dyn/content/article/2006/02/14/AR2006021401342.html
-
Greylisting
http://lwn.net/Articles/37536/
-
filtrado bayesiano
http://en.wikipedia.org/wiki/Bayesian_spam_filtering
http://email.about.com/cs/bayesianfilters/a/bayesian_filter.htm
-
Milters
http://www.postfix.org/MILTER_README.html
-
SARE (Spam Assasin Rules Emporium)
http://www.rulesemporium.com/