Archive of August 2010
MailScanner, instalación rápida
La filosofía Unix es disponer de pequeñas herramientas que hagan cosas simples, pero que las hagan bien y de forma segura. Uniendo las funcionalidades de las diferentes herramientas podemos conseguir un sistema funcional y con múltiples características donde el único límite es nuestro conocimiento. En los servidores de correos hay 3 elementos indispensables. MTA, AntiSpam y Antivirus. Para cada servicio existe una aplicación, pero hacerlas funcionar en conjunto no suele ser sencillo la primera vez.
MailScanner nos va a ayudar a unir nuestro AntiSpam y Antivirus con el MTA, creando de esta forma un servicio de correo estable y seguro. Este es un pequeño manual que nos guiará en los pasos básicos para tener funcionando Postfix + MailScanner (Spamassassin + Clamav).
Instalación
apt-get install mailscanner clamav unrar zip spamc razor pyzor
Muy complicado…
Configuración
Paramos el servicio de postfix con /etc/init.d/postfix stop. Es importante que postfix corra enjaulado en /var/spool/postfix, si no, habrá que meterlo.
Editamos /etc/postfix/main.cf y añadimos la siguiente línea:
header_checks = regexp:/etc/postfix/header_checks
Dicho fichero debe tener el siguiente contenido:
/^Received:/ HOLD
Su finalidad es sencilla de entender. Con esas líneas le indicamos a postfix que los correos los deje en la cola HOLD. Mailscanner recogerá los correos de la cola, les pasará antivirus y antispam para terminar dejándolos en Incoming, donde postfix terminará de entregarlo.
Dentro de /etc/MailScanner/MailScanner.conf se deben cambiar como mínimos estas líneas:
%report-dir% = /etc/MailScanner/reports/es Run As User = postfix Run As Group = postfix Incoming Queue Dir = /var/spool/postfix/hold Outgoing Queue Dir = /var/spool/postfix/incoming MTA = postfix
Por último enviamos editamos el /etc/default/mailscanner:
run_mailscanner=1
Y ya podemos arrancar mailscanner con /etc/init.d/mailscanner start
¡Importante! Al intentar arrancar mailscanner te dirá que directorios no tiene los permisos correctos. Esto es así porque mailscanner correrá como usuario postfix, por lo tanto todas las carpetas donde sea necesario escribir y eliminar fichero deberán tener como propietario a postfix.
Pruebas
Para enviar un mail que sea detectado como virus debe contener el siguiente texto en el cuerpo:
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
Este será el resultado:
Jan 3 17:36:36 dominioirontec MailScanner[21784]: Virus and Content Scanning: Starting Jan 3 17:37:27 dominioirontec MailScanner[21784]: /var/spool/MailScanner/incoming/21784/ ./9A0989A81D8.80660/msg-21784-1.txt: Eicar-Test-Signature FOUND Jan 3 17:37:27 dominioirontec MailScanner[21784]: Virus Scanning: ClamAV found 1 infections Jan 3 17:37:27 dominioirontec MailScanner[21784]: Infected message 9A0989A81D8.80660 came from 127.0.0.1 Jan 3 17:37:27 dominioirontec MailScanner[21784]: Virus Scanning: Found 1 viruses
De la misma forma, para que sea detectado como Spam debe tener el siguiente texto en el cuerpo:
XJSC4JDBQADN1.NSBN32IDNENGTUBE-STANDARD-ANTI-UBE-TEST-EMAILC.34X
Este será el resultado:
Jan 3 17:55:56 dominioirontec MailScanner[21784]: Spam Checks: Found 1 spam messages
Recetas de Postfix
Algunos trucos y consejos que siempre viene bien tener a mano :)
Habilitar uso de TLS
\# TLS parameters smtpd_tls_cert_file=/etc/postfix/ssl/smtpd.pem smtpd_tls_key_file=/etc/postfix/ssl/smtpd.pem smtpd_tls_CAfile=/etc/postfix/ssl/smtpd.pem smtpd_use_tls=yes smtpd_tls_session_cache_database = btree:${queue_directory}/smtpd_scache smtp_tls_session_cache_database = btree:${queue_directory}/smtp_scache
Para crear el certificado usamos el comando:
openssl req -new -x509 -nodes -out smtpd.pem -keyout smtpd.pem -days 3650
Activar chequeo de listas negras
smtpd_client_restrictions = permit_mynetworks permit_sasl_authenticated \# Activa chequeo de PTR reject_unknown_client \# Seleccionamos las listas negras a usar reject_rbl_client xbl.spamhaus.org reject_rbl_client sbl.spamhaus.org reject_rbl_client list.dsbl.org \# Mensaje de error que se enviará si el emisor se encuentra en listas negras default_rbl_reply = $rbl_code Service unavailable; $rbl_class [$rbl_what] blocked using $rbl_domain.
Es recomendable realizar los chequeos de listas negras en el propio postfix, desactivándolos en el spamassasin. De esta forma evitamos cargar aún más el sistema analizando correos que casi en un 99% serán spam.
Cambiar la dirección del remitente
Se hace mediante los llamados smtp_generic_maps. El cambio únicamente se realizará en la salida de los correos. Se crea el fichero generics:
/etc/postfix/generic: root@localdomain.local otrocorreo@miguelangelnieto.net
Se crea la base de datos a partir del fichero con:
postmap /etc/postfix/generic
Por último se configura main.cf para que use los generic_maps.
smtp_generic_maps = hash:/etc/postfix/generic
Se reinicia postfix y ya debería funcionar. Más información en:
http://www.postfix.org/postconf.5.html#smtp_generic_maps
http://www.postfix.org/generic.5.html
Si queremos también en entrada usaremos las direcciones canónicas que se verán más abajo.
Utilizar distintos relays dependiendo del destino
Se hace mediante los transport. Creamos /etc/postfix/transport con los siguientes datos:
primero@miguelangelnieto.net smtp:[85.112.9.44]:25 segundo@irontec.com smtp:[82.194.75.72]:25 tercero@google.com smtp:gmail.com
Creamos la base de datos con:
postmap /etc/postfix/transport
Configuramos main.cf para que use los transports:
transport_maps = hash:/etc/postfix/transport
Comprobar las direcciones de destino
Con esta solución, postfix comprobará que las direcciones de destino existen realmente. Si no existen rechazará la recepción del correo.
Primero se debe crear un fichero con las direcciones de correo válidas para el sistema. Su sintaxis es la siguiente:
prueba@dominioirontec.local OK prueba2@dominioirontec.local OK admin@dominioirontec.local OK
Dicho fichero, una vez completado, debemos convertirlo en una base de datos con postmap.
En main.cf las opciones son las siguientes:
\# Restricciones de la vida para direcciones externas (para las que se hará relay) relay_recipient_maps = hash:/etc/postfix/valid_recipients \# Restricciones de la vida para direcciones locales (sin relay) local_recipient_maps = hash:/etc/postfix/valid_recipients
Direcciones Canonicas
Una dirección canónica es la dirección de correo electronico con la que se termina enviando un email.
De esta forma, si cuando enviamos un email con la dirección de remitente usuario@dominio y este tiene una dirección canónica luser@hotmail.com, la dirección de remitente se reescribirá por esta última.
Para ello creamos un fichero /etc/postfix/sender_canonical donde se guardan las direcciones canónicas con el siguiente formato:
usuario luser@hotmail.com
Dicho fichero lo postmapeamos y añadimos a /etc/postfix/main.cf:
sender_canonical_maps = hash:/etc/postfix/sender_canonical
Esto también se aplicará a los correos que recibamos.
Maildrop
Programa utilizado para entregar el correo a distintas carpetas según unos filtros definidos. Su fichero de configuración se encuentra en /etc/maildroprc
Para que postfix haga uso de el es necesario configurar main.cf poniendo la siguiente opción:
mailbox_command = /usr/bin/maildrop -d $USER -f $SENDER
En el ejemplo que pegaré a continuación se definen una serie de acciones teniendo en cuenta el las cabeceras o destinatarios del correo.
\# Global maildrop filter file \# Uncomment this line to make maildrop default to ~/Maildir for \# delivery- this is where courier-imap (amongst others) will look. DEFAULT="$HOME/Maildir" \# Si el correo es spam lo movemos \# a la carpeta de spam y lo aprendemos. \if (/^X-Spam-Flag: YES/) { cc "|/usr/bin/sa-learn --spam" to "Maildir/.Spam" } if (/^Delivered-To: ebay@midominio.net/) { cc "|/usr/bin/sa-learn --ham" to "Maildir/.Ebay" } if (/^Delivered-To: curriculum@midominio.net/) { cc "|/usr/bin/sa-learn --ham" to "Maildir/.Curriculum" } \# El resto lo aprendemos como correo NO spam \# y lo dejamos en nuestro INBOX. cc "|/usr/bin/sa-learn --ham" to "Maildir"
Excusas BOFH para Android
Gracias al gran proyecto iniciado por Ivan Mosquera (Irontec) llamado PHP for Android me enteré de la existencia de Scripting Layer for Android, un proyecto que nos permite desarrollar scripts para nuestro sistema móvil favorito. Entre los lenguajes que soporta se encuentran:
- Python
- Sh
- Perl
- Rhino
- Lua
- Ruby
- ...
Mediante unos sencillos scripts es posible acceder a funciones para controlar el TTS, GPS, Bateria, Bluetooth, SMS, etc. Vamos, que en pocas líneas te puedes hacer cositas bastante interesantes. Yo como administrador de sistemas estoy acostumbrado a programar Scripts (y no aplicaciones completas), por lo que esto se convierte en un juguete muy divertido sin necesidad de meterte con el monstruo Java.
La instalación es sencilla. En primer lugar instalamos SL4A:

A continuación desde http://code.google.com/p/android-scripting/downloads/list te puedes instalar los interpretes para alguno de los lenguajes mencionados anteriormente. Para el ejemplo que vamos a ver a continuación usaremos Python:

Y listo, solo nos queda hacer nuestros scripts y subirlos a /sdcard/sl4a/scripts
Yo os pongo un ejemplo, que es simple y facil de entender. Es un script en python que se descarga una lista de excusas BOFH de una URL en concreto y escoge una al azar para mostrartela en pantalla. Siempre viene bien tener a mano estas frases para responder a las típicas preguntas "oyeee, que no me funca el aparatooo". Así que para tenerlo accesible creamos un enlace en el escritorio:

Lo lanzamos y tenemos nuestra excusa:

Aquí el código. Se aceptan críticas y mejoras :P
import android import urllib2 from random import randint droid = android.Android() try: f = urllib2.urlopen("http://pages.cs.wisc.edu/~ballard/bofh/excuses") except urllib2.HTTPError, e: print "ERROR" print e.code exit(1) except urllib2.URLError, e: print "ERROR" print e.reason exit(1) ex = f.read() \# Separamos las frases por los saltos de lineas, convirtiendolo en una lista ex = ex.split("\n") f.close() \# Buscamos el numero de frases que hay (otra forma mas bonita de hacerlo?) c = 0 for i in ex: c = c + 1 \# Cogemos una al azar r = randint(0, c) \# La mostramos droid.dialogCreateAlert("BOFH Excuse", ex.pop(r - 1)) droid.dialogSetPositiveButtonText('Close') droid.dialogShow()







