Construyendo un Anti-SPAM Gateway. Parte 1 (Postfix)
Hace tiempo que tenía previsto comenzar un artículo donde se tratase la protección contra el SPAM, el cual sufrimos día a día. Después de haber decidido como se estructurará éste, me he decidido por comenzar a escribir y entregarlo en varias partes para dejar lo más claro posible cada uno de los módulos que vamos a ir añadiendo a nuestro Anti-SPAM Gateway e intentar que estos mísmos módulos se puedan aplicar a otros MTAs sin mayor complicaciones.
Estas entregas se van a basar en el MTA de código abierto Postfix, con el cual trabajo desde hace más de 5 años obteniendo buenos resultados y encontrándose bastante extendido en Internet.

La instalación del Anti-SPAM la vamos a realizar en una máquina virtual en la que se ejecuta Linux Debian Lenny 5, la cual debemos dimensionar del siguiente modo:
- 1 vCPU al menos.
- 512 MB RAM para poder soportar el resto de características que se irán añadiendo.
- Dimensionar con suficiente espacio en disco la partición /var, ya que contendrá los logs y la cola de correos.
La instalación de los principales programas la vamos a realizar desde sus fuentes, para así conocer un poco mejor su funcionamiento y la posibilidad de realizar la instalación en otras distribuciones.
Este artículo está enfocado para montar un Gateway, es decir, no almacenará correos en su almacenamiento y no contará con usuarios. Por lo tanto, si deseamos poder tener buzones de correos debemos disponer de un servidor de correo enfocado a dicho cometido. Los pasos que vamos a seguir para conseguir montar esta pasarela de correo son los siguientes:
- Instalación requisitos previos.
- Postfix.
- Obtener fuentes.
- Crear usuario y grupos.
- Compilar e instalar las fuentes.
- Configuración.
- Puesta en marcha.
- Pruebas.
Instalación requisitos previos
Para compilar correctamente Postfix es necesario contar con algunas librerías instaladas en nuestro sistema además de un compilador. Por lo tanto, para preparar el sistema vamos a ejecutar el siguiente comando como usuario root:
apt-get install libdb-dev build-essential ntp ntpdate
Ya tenemos los requisitos necesarios para compilar correctamente posteriormente Postfix. Pero aún falta desinstalar el agente MTA que trae de forma predeterminada Debian, en este caso estamos hablando de Exim 4, ya que de no ser así no se podría arrancar Postfix al estar ocupado ya el servicio SMTP en el puerto 25. Para desinstalar Exim 4 vamos a ejecutar los siguientes comandos como usuario root:
aptitude remove --purge exim4 exim4-base exim4-config exim4-daemon-light bsd-mailx at
update-rc.d -f exim4 remove
Postfix
Una vez cumplidos los requisitos previos, es hora de comenzar con la instalación de nuestro MTA. Esta instalación la vamos a realizar desde las fuentes, obteniendo un mejor rendimiento al estar compilado para un hardware concreto. Una vez hayamos compilado e instalado nuestras fuentes podremos configurar nuestro MTA para que funcione como un Gateway de correo fiable, escalable y de alto rendimiento.
Obtener fuentes
Lo primero que debemos hacer es obtener las últimas fuentes disponibles en su versión estable. Para ello nos tendremos que dirigir a la página de descargas de Postfix y elegir como bien hemos dicho las últimas fuentes estables. Copiamos el enlace de descarga ya que tenemos que bajarlo desde nuestro futuro Anti-SPAM. Para ello una vez copiado el enlace ejecutamos los siguientes comandos como usuario root:
cd /usr/local/src
wget ftp://ftp.inescn.pt/pub/net/mail/postfix/official/postfix-2.7.1.tar.gz
Una vez tenemos ya nuestras fuentes, en estos momentos, la versión 2.7.1, vamos a descomprimir el fichero para obtener su contenido y acceder al directorio que se va a crear. Para todo esto ejecutamos como root los siguientes comandos:
tar xzf postfix-2.7.1.tar.gz
cd postfix-2.7.1
Crear usuario y grupos
Nuestro MTA necesita un usuario con el cual gestionará todo el servicio de correo electrónico, además, si este usuario y los grupos correspondientes no existen, fallará la posterior compilación. Para que esto no ocurra vamos a ejecutar los siguientes comandos como root:
groupadd -g 12345 postfix
groupadd -g 54321 postdrop
useradd -u 12345 -g 12345 -s /bin/false postfix
Compilar e instalar las fuentes
Ya que cumplimos todos los requisitos previos, es hora de realizar la compilación y la instalación. Para realizar dicha tarea ejecutamos el siguiente comando como root:
make && make install
Antes de finalizar la instalación debemos configurar varios parámetros que nos va preguntando, todos estos los dejaremos de forma predeterminada pulsando ENTER en cada una de las opciones.
install_root: /
tempdir: /usr/local/src/postfix-2.7.1
config_directory: /etc/postfix
command_directory: /usr/sbin
daemon_directory: /usr/libexec/postfix
data_directory: /var/lib/postfix
html_directory: no
mail_owner: postfix
mailq_path: /usr/bin/mailq
manpage_directory: /usr/local/man
newaliases_path: /usr/bin/newaliases
queue_directory: /var/spool/postfix
readme_directory: no
sendmail_path: /usr/sbin/sendmail
setgid_group: postdrop
Configuración
Una vez instalado nuestro Postfix, es la hora de realizar la configuración para que funcione como un Gateway o pasarela de correo. Esto nos permitirá más adelante agregar nuevos complementos lo cual aportará ventajas a nuestro Gateway.
Postfix cuenta con dos ficheros de configuración principales, como son el main.cf y master.cf. El fichero main.cf se encarga del control de Postfix con una amplia cantidad de opciones disponibles de configuración. Por lo contrario, el fichero master.cf se encarga de controlar los servicios o procesos que se ejecutan en segundo plano aportando funcionalidad a nuestro Postfix.
Nosotros vamos a comenzar por configurar el fichero main.cf. Nos centraremos únicamente en los parámetros necesarios para conseguir el objetivo que buscamos. Se deseamos conocer todos los parámetros posibles a configurar en fichero fichero podemos visitar su página de ayuda.
Lo primero de todo es realizar una copia de seguridad del fichero main.cf que se ha generado durante la instalación y configurar los parámetros básicos para cualquier instalación Postfix, también aprovechamos para hacer la copia de seguridad del fichero master.cf. Para ello ejecutamos los siguientes comandos como usuario root:
cd /etc/postfix
cp main.cf main.cf.orig
cp master.cf master.cf.orig
Una vez hecha la copia de seguridad, eliminaremos todo el contenido comentado del fichero main.cf, es decir, todo el contenido precedido de #. Editamos el fichero con el comando vi o nano y nos tendremos que quedar con el contenido mostrado a continuación.
Una vez tenemos preparado el fichero main.cf con los parámetros básicos, vamos a comenzar a introducir los parámetros que convertirá nuestro Postfix en un Gateway. En esta primera parte vamos a eliminar la entrega local de correo en el servidor, consiguiendo que sea más difícil comprometer la seguridad del servidor. Para ello como usuario root editamos el fichero e introducimos los siguientes parámetros:
myorigin = example.com # Enviar correo desde esta máquina como "user@example.com"
mydestination =
local_recipient_maps =
local_transport = error:local mail delivery is disabled
En la segunda parte, para corregir problemas técnicos, debemos recibir correos del usuario postmaster@[IP Gateway]. Como extra también vamos añadir abuse@[IP Gateway]. Todos los correos a estas dos cuentas es redireccionado a una dirección o direcciones internas. Para ello agregamos el siguiente parámetro al fichero main.cf:
virtual_alias_maps = hash:/etc/postfix/virtual_alias_maps # Obtiene los datos de un fichero
El parámetro anterior recoge los datos de un fichero llamado virtual_alias_maps que se encuentra en el directorio /etc/postfix. Por lo tanto tenemos que crear este fichero e introducir las redirecciones pertinentes, para ello como usuario root ejecutamos los siguientes comandos:
vi /etc/postfix/virtual_alias_maps # Crea el fichero
postmaster postmaster@example.com
abuse abuse@example.com
postmap /etc/postfix/virtual_alias_maps # Compila el fichero
En la última parte nos queda en el fichero main.cf activar la redirección del correo, para esto introducimos los siguientes parámetros al fichero:
mynetworks = 127.0.0.0/8 RANGO_IP_RED_LOCAL #Agregar redes locales para permitir envío
relay_domains = hash:/etc/postfix/relay_domains # Fichero con dominios aceptados para recibir
parent_domain_matches_subdomains = # No aceptar subdominios
debug_peer_list smtpd_access_maps # No aceptar subdominios
smtpd_recipient_restrictions =
permit_mynetworks # Permitir envío desde las redes declaradas
reject_unauth_destination # Denegar destino no autorizado (declarado en relay_domains)
relay_recipient_maps = hash:/etc/postfix/relay_recipients # Fichero con usuarios receptores
transport_maps = hash:/etc/postfix/transport_maps # Fichero con redirección de dominios
Ahora vamos a crear los ficheros restantes que hemos declarado en algunos parámetros de nuestro main.cf, como son relay_domains (dominios para los que aceptamos recepción), relay_recipients (usuarios para los que aceptamos recepción) y transport_maps (redirección de dominios a servidor final). Para todo esto ejecutamos los siguientes comandos como root:
vi /etc/postfix/relay_domains
example.com OK
example2.com OK
vi /etc/postfix/relay_recipients
user@example.com OK
user2@example.com OK
blog@example2.com OK
vi /etc/postfix/transport_maps
example.com smtp:remoto.example.com
example2.com smtp:remoto.example2.com
Una vez creado los ficheros, tenemos que compilarlo para generar el fichero de base de datos por cada uno de ellos. Para ello como usuario root ejecutamos los siguientes comandos:
postmap /etc/postfix/relay_domains
postmap /etc/postfix/relay_recipients
postmap /etc/postfix/transport_maps
Ya hemos finalizado la configuración del fichero main.cf, ahora vamos a configurar el fichero master.cf para que no entregue correo local, asegurando así el servidor contra posibles fallos de seguridad. Para ello ejecutamos los siguientes comandos como ususario root:
vi /etc/postfix/master.cf
#local unix - n n - - local (comentar esta línea)
Puesta en marcha
Antes de configurar su inicio como servicio, vamos a probar que Postfix arranca y no muestra error alguno. Para ello vamos a arrancar el servicio y posteriormente monitorizar el fichero mail.log. Ejecutamos los siguientes comandos como usuario root:
postfix start
tail -f /var/log/mail.log
Ahora vamos a crear el script de arranque para nuestro Postfix, con ello conseguimos que arranque como servicio durante el inicio del sistema. Ejecutamos los siguientes comandos como root:
vi /etc/init.d/postfix
#!/bin/sh -e
# Start or stop Postfix
#
# LaMont Jones <lamont@debian.org>
# based on sendmail's init.d script
# Modified byPiPo-e2H <pipo@e2h.net>
### BEGIN INIT INFO
# Provides: postfix mail-transport-agent
# Required-Start: $local_fs $remote_fs $syslog $named $network $time
# Required-Stop: $local_fs $remote_fs $syslog $named $network
# Should-Start: postgresql mysql clamav-daemon postgrey spamassassin
# Should-Stop: postgresql mysql clamav-daemon postgrey spamassassin
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop the Postfix Mail Transport Agent
# Description: postfix is a Mail Transport agent
### END INIT INFO
PATH=/bin:/usr/bin:/sbin:/usr/sbin
DAEMON=/usr/sbin/postfix
NAME=Postfix
test -x $DAEMON && test -f /etc/postfix/main.cf || exit 0
. /lib/lsb/init-functions
running() {
queue=$(postconf -h queue_directory 2>/dev/null || echo /var/spool/postfix)
if [ -f ${queue}/pid/master.pid ]; then
pid=$(sed 's/ //g' ${queue}/pid/master.pid)
# what directory does the executable live in. stupid prelink systems.
dir=$(ls -l /proc/$pid/exe 2>/dev/null | sed 's/.* -> //; s/\/[^\/]*$//')
if [ "X$dir" = "X/usr/libexec/postfix" ]; then
echo y
fi
fi
}
case "$1" in
start)
log_daemon_msg "Starting Postfix Mail Transport Agent" postfix
RUNNING=$(running)
if [ -n "$RUNNING" ]; then
log_end_msg 0
else
if start-stop-daemon --start --exec ${DAEMON} -- start; then
log_end_msg 0
else
log_end_msg 1
fi
fi
;;
stop)
RUNNING=$(running)
log_daemon_msg "Stopping Postfix Mail Transport Agent" postfix
if [ -n "$RUNNING" ]; then
if ${DAEMON} stop; then
log_end_msg 0
else
log_end_msg 1
fi
else
log_end_msg 0
fi
;;
restart)
$0 stop
$0 start
;;
force-reload|reload)
log_action_begin_msg "Reloading Postfix configuration"
if ${DAEMON} reload; then
log_action_end_msg 0
else
log_action_end_msg 1
fi
;;
status)
RUNNING=$(running)
if [ -n "$RUNNING" ]; then
log_success_msg "postfix is running"
exit 0
else
log_success_msg "postfix is not running"
exit 3
fi
;;
flush|check|abort)
${DAEMON} $1
;;
*)
log_action_msg "Usage: /etc/init.d/postfix {start|stop|restart|reload|flush|check|abort|force-reload}"
exit 1
;;
esac
exit 0
Ya que tenemos nuestro script de inicio, vamos a darle permisos de ejecución y vamos a configurar sus diferentes niveles de arranque. Para ello ejecutamos los siguientes comandos como root:
chmod +x /etc/init.d/postfix
update-rc.d postfix defaults
Para comprobar que nuestro Postfix arranca podemos ejecutar /etc/init.d/postfix start o también reiniciar la máquina para ver que arranca el servicio sin problemas.
Pruebas
La primera prueba que vamos a realizar es comprobar que podemos acceder al servicio SMTP desde un cliente local. Para ello desde un equipo que no sea el servidor ejecutamos el siguiente comando:
telnet IP_ANTISPAM 25
Nos debe aparecer un mensaje del tipo 220 HOST.DOMINIO ESMTP Postfix, si esto es así quiere decir que nuestro Postfix está ejecutándose correctamente.
La segunda prueba es comprobar que desde un equipo externo a la LAN, esto es importante ya que todos los equipos de la LAN están permitidos a enviar correo a cualquier dominio a través del parámetro permit_mynetworks. Si no podemos hacer la prueba desde el exterior, podemos eliminar la red local en el parámetro mynetworks del fichero main.cf y dejar únicamente 127.0.0.0/8. Sabido esto accedemos nuevamente mediante telnet a nuestro servidor y vamos a enviar un correo a un dominio no declarado en el fichero relay_domains y comprobamos que fallará, para todo esto ejecutamos los siguientes comandos:
telnet IP_ANTISPAM 25
ehlo test.com # Dominio del remitente
mail from:test@test.com # Usuario que remite el correo
rcpt to:test@test2.com # Dominio receptor invalido
Ahora vamos a probar el envío a un dominio aceptado en el fichero relay_domains pero a un usuario no existente en dicho dominio, el cual no está declarado en el fichero relay_recipients. Para ello ejecutamos los siguientes comandos nuevamente en un equipo remoto:
telnet IP_ANTISPAM 25
ehlo test.com # Dominio del remitente
mail from:test@test.com # Usuario que remite el correo
rcpt to:usuario@example.com # Dominio receptor VALIDO, pero usuario invalido
Por último vamos a enviar un correo que conforme todos las opciones correctas, es decir, dominio válido y usuario válido declarado en los ficheros ya conocidos. Para ello ejecutamos los siguientes comandos en un equipo remoto:
telnet IP_ANTISPAM 25
ehlo test.com # Dominio del remitente
mail from:test@test.com # Usuario que remite el correo
rcpt to:user@example.com # Usuario receptor válido en dominio válido
data # Comenzar a escribir el mensaje
esto es un test # Texto del mensaje
. # Finalizar el mensaje
quit # Cerrar la conexión
Si observamos el fichero /var/log/mail.log podremos comprobar el proceso que se va procesando mientras vamos introduciendo los diferentes comandos por la línea de terminal. Para observar este fichero podemos ejecutar el siguiente comando:
tail -f /var/log/mail.log
En los próximos artículos iremos añadiendo nuevas funciones a nuestro Anti-SPAM, dotándolo de fuertes mecanismos de detección de SPAM.























19 julio, 2010 - 18:43
excelente documento che!!
justo estoy implementando un gateway en debian para un Exchange 2003.
esperamos ansioso la parte III
saludos!
19 julio, 2010 - 18:46
Hola Gilgamezh,
Gracias por tu comentario, la tercera parte espero tenerla hoy o mañana y está basada en SPF.
Un saludo.
10 marzo, 2011 - 18:04
Muy interesante el articulo yo tambien lo estoy implementando y me gustaria mucho que publicaras lo de spamm, y se pudieras darme tu direccion de msn o correo para contactarte ,, graciass
10 marzo, 2011 - 18:09
Hola Wenspacay:
Dispones de más artículos sobre funcionalidades adiciones para implementar a Postfix. Para las consultas por favor realízalas a través de los foros.
Un saludo.
29 septiembre, 2011 - 03:54
Muy buen articulo!!!!! Gracias. Una duda más como puedo incorporar mi servidor imap en este gateway para que se conecte a mi servidor interno, trabajo con courier-imap-ssl. Saludos
2 octubre, 2011 - 10:17
Hola Vic:
Gracias por valorar el artículo. Sobre la consulta deberías realizarla en nuestro foros http://blog.e2h.net/foros
Un saludo.