viernes, 30 de abril de 2010

FreeBSD 8.X: Spam Gateway



Bueno, ya vieron como levantar un servidor de correo con Dovecot + Postfix. Ahora lo que sigue es proteger a nuestro servidor de spam, virus, etc.

Aqui vamos hacer algo sencillo, lo que le llaman un spam gateway, que su funcion principal es protegernos de los spammers y correos con bichos.

Internet->Postfix->amavisd->clamd->spamassassin->pasa || no pasa

La operacion con mas detalles es que todos los correos de entrada seran recibidos por este servidor, es el que se va a llevar la friega, por que tiene que estar desempaquetando, empaquetando, consultando el DNS y mas cuando hay archivos anexos.

La 1ra operacion o filtro lo hara Postfix, ya que el mismo tiene funciones o filtros que les aplica a cada correo, y es un proceso que se lleva a cabo entre smtp vs smtp, y aqui mucho correo de entrada queda descartado.

Enseguida vamos a ir por una aplicacion que hace algo tan sencillo y tambien bloquea otro monton de spam su nombre es postfix-policyd-weight, existen varias aplicaciones con la misma funcion, pero ya cada quien decide cual usar.

Luego sigue el checado de antivirus con clamavis, seguido de spamassassin ambas operaciones son administradas por amavisd, ya de regreso entran las listas BL y con esto vamos a tener un filtro casi al 100%, ya solo es cuestion de mantener a el dia el servidor y sobre todo spamassassin.

Bien, las aplicaciones que vamos a trabajar son las siguientes:

postfix
postfix-policyd-weight
spamassassin
clamavis
amavisd-new

Mas o menos asi vamos trabar conforme la lista.

Postfix

Vamos viendo la version que estamos trabajando y sobre todo FreeBSD:

OS: 8.2 I386.
Postfix: postfix-2.8.2,1

Otro detalle que me gustaria aclarar es que ambos servidores corren bajo Jails de FreeBSD, osea que estan virtualizados y ninguno posee la loopback interface y tienen un arreglo de disco Raid-1 con Satas.

La configuracion de mi src.conf es la siguiente tanto para el spam como el mail:

WITHOUT_ACCT="yes"
WITHOUT_ACPI="yes"
WITHOUT_AMD="yes"
WITHOUT_APM="yes"
WITHOUT_ASSERT_DEBUG="yes"
WITHOUT_ATM="yes"
WITHOUT_AUDIT="yes"
WITHOUT_AUTHPF="yes"
WITHOUT_BIND="YES"
WITHOUT_BLUETOOTH="yes"
WITHOUT_BOOT="yes"
WITHOUT_CALENDAR="yes"
WITHOUT_CDDL="yes"
WITHOUT_CTM="yes"
WITHOUT_CVS="yes"
WITHOUT_DICT="yes"
WITHOUT_EXAMPLES="yes"
WITHOUT_FLOPPY="YES"
WITHOUT_FORTH="yes"
WITHOUT_FREEBSD_UPDATE="yes"
WITHOUT_GAMES="yes"
WITHOUT_GDB="YES"
WITHOUT_GPIB="yes"
WITHOUT_HTML="yes"
WITHOUT_INET6="yes"
WITHOUT_IPFILTER="yes"
WITHOUT_IPFW="yes"
WITHOUT_IPX="yes"
WITHOUT_JAIL="yes"
WITHOUT_KVM="yes"
WITHOUT_LOCALES="yes"
WITHOUT_LOCATE="yes"
WITHOUT_LPR="yes"
WITHOUT_NCP="yes"
WITHOUT_NDIS="yes"
WITHOUT_NETGRAPH="yes"
WITHOUT_NLS="yes"
WITHOUT_NLS_CATALOGS="yes"
WITHOUT_NS_CACHING="yes"
WITHOUT_PF="yes"
WITHOUT_PMC="yes"
WITHOUT_PPP="yes"
WITHOUT_PROFILE="yes"
WITHOUT_QUOTAS="yes"
WITHOUT_RCMDS="yes"
WITHOUT_RCS="yes"
WITHOUT_RESCUE="yes"
WITHOUT_ROUTED="yes"
WITHOUT_SHAREDOCS="yes"
WITHOUT_SSP="yes"
WITHOUT_SYSINSTALL="yes"
WITHOUT_USB="yes"
WITHOUT_WIRELESS="yes"
WITHOUT_WPA_SUPPLICANT_EAPOL="yes"

Cuando se instala Postfix nos pregunta si deseamos colocar la configuración en /etc, yo no lo acepto en este servidor, si fuera el "mail server" si. Por lo tanto la instalacion se va a:


/usr/local/etc/postfix

Ahora algo que debemos saber es que configuracion nos da Postfix por default? Se supone que casi casi nos da una segura y no un "open-relay" que luego lo vamos a explicar.

Asi esta el archivo main.cf:

postconf -n

command_directory = /usr/local/sbin
config_directory = /usr/local/etc/postfix
daemon_directory = /usr/local/libexec/postfix
data_directory = /var/db/postfix
debug_peer_level = 2
html_directory =
mail_owner = postfix
mailq_path =
manpage_directory =
newaliases_path =
queue_directory = /var/spool/postfix
readme_directory =
sample_directory =
sendmail_path =
setgid_group =
unknown_local_recipient_reject_code = 550

Ahora si desean ver toda la configuracion completa:

postconf

Pero aqui no lo puedo poner porque esta extensa la salida, ustedes en su maquina pueden hacerlo.

Como tenemos 2 servidores:
  • mail-server 192.168.40.2 Correo Saliente
  • spam-server 192.168.40.3 Correo Entrante
Vamos a usar el dominio: example punto com para seguir la tradicion.

Mi DNS apunta a mi spam-server, ya di de alta el registro PTR de mi IP publico a el nombre de mi spam-server, ya que el es quien recibe todo el correo entrante y envia el correo si pasa todos los filtros a el mail-server, si no tiene el PTR muchos servidores de correo no envian ni reciben correo de servidores que no cumplen esta norma.

---------------------------------------------------------------------------------
NOTA:Aqui ya tengo mi servidor de correo operando sin problemas, solo voy a configurar el spam server.
---------------------------------------------------------------------------------

Vamos a empezar con la 1ra configuracion, habran el archivo main.cf de postfix su corazon:

1; Nombre del hostname:

myhostname = spam.example.com

2; Dominio que voy a proporcionar el servicio.

mydomain = example.com

3;Mi origen.

myorigin = $mydomain

5; Las interfaces que el servidor va a usar para recibir la comunicacion: Por lo regular es en todas las que tengamos.

inet_interfaces = all

6; Destinos:

mydestination =

¿Por que en blanco?, como queremos tanta seguridad como sea posible, vamos a deshabilitar el envio local, por ello no damos de alta nuestro dominio aqui, pero vamos a ver mas adelante como habilitar el envio local para recibir mensajes del root del spam-server.

Para habilitar el envio local del root y cuentas de administradores como:
  • postmaster
  • abuse
Deshabilitamos el parametro dejandolo en blanco:

local_recipient_maps =

Ahora si deseo que ciertos usuarios locales puedan recibir correos como los anteriores, vamos hacer uso del parametro este:

virtual_alias_maps = hash:/usr/local/etc/postfix/virtual_alias_maps

Como parametro le damos el archivo en formato binario que se lo indicamos usando la palabra "hash", ahora vamos a crear ese archivo y le agregamos la informacion asi:

postmaster postmaster@example.com
abuse abuse@example.com

Salvamos el archivo en la ruta indicada arriba y crea el formato que nos pide postfix con el comando postmap, asi:

postmap hash:/usr/local/etc/postfix/virtual_alias_maps

Si revisan su directorio van a ver los 2 archivos:

-rw-r--r-- 1 root wheel 141 Apr 14 12:24 virtual_alias_maps
-rw-r--r-- 1 root wheel 65536 Apr 14 12:24 virtual_alias_maps.db

El que tiene extension "db" es el creado con el comand anterior y es el que usa postfix, todos estos archivos son creados usando BDB para esta funcion son excelentes y es mas veloces su acceso que si hicieramos uso de una DB como mysql, por ello se opto por este formato.

Cuando alguien fuera del dominio busque enviar correos a cuentas locales podemos personalizar el mensaje con el parametro:

local_transport

Por default tiene un texto asi:

local_transport = error:local mail delivery not available

Pero pueden poner el texto que gusten como:

local_transport = error:No molestar envio local esta deshabilitado

Con esto el servidor podra enviar correos a las cuentas arriba dadas de alta de lo contrario ni eso podria ser posible.

Ya para rematar debemos eliminar el envio demonio que se encarga de los envios locales, abran el archivo de nombre master.cf y deshabiliten la linea

#local unix - n n - - local

Poniendo un "#" para convertirla a comentario.

7; Datos de nuestra red.

mynetworks = 192.168.40.2/32

Aqui colocamos el IP de nuestro mail-server interno, solo a el vamos a servir, ya que si colocamos nuestro rango de red, ejemplo 192.168.40.0/24 cualquier usuario interno podra usar este servidor como relay y hacer maldades, con este dato descartamos esta posibilidad.

8; Domino que podemos habilitar el relay.

relay_domains = example.com

9; Usuarios validos que pueden recibir correo externo.

relay_recipient_maps = hash:/usr/local/etc/postfix/relay_recipients

Este parametro es una pieza clave que deberan mantener al dia, ya que aqui le indicamos que usuarios del dominio pueden recibir correo, antes de que el spam-server envie el correo a el mail-server revisa este parametro y si la cuenta o "recipient" no esta aqui, rechaza el correo, aqui vamos a eliminar mucho spam, ya que los spammers tienen programas que generan cuentas de usuario aleatoriamente, ya con eso les paramos su kalabaza.

Por lo tanto, como ven de nuevo necesitamos crear ese archivo con los usuarios validos, en mi caso tengo solo 3 y el archivo tiene este formato:

usuario1@example.com OK
usuario2@example.com OK
usuario3@example.com OK

Creamos el archivo en formato BDB:

postmap hash:/usr/local/etc/postfix/relay_recipients

10; Alias

alias_maps = hash:/usr/local/etc/postfix/aliases

De nuevo necesitan crear el archivo con postmap, ya no se los voy a repetir, el archivo esta en blanco aun no hemos hecho uso de el.

11; Alias Databases

alias_database = hash:/usr/local/etc/postfix/aliases

Igual en blanco ya que no hemos hecho uso de el, pero si deben crear el archivo en formato BDB.

12; Banner

smtpd_banner = $myhostname ESMTP $mail_name

Cuando nuestro servidor de correo necesite comunicarse con otro smtp, el RFC pide que nos presentemos usando el HELO y nuestro nombre, este parametro hace eso.

13; Rutas.

sendmail_path = /usr/local/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/local/bin/mailq
setgid_group = maildrop
manpage_directory = /usr/local/man
sample_directory = /usr/local/etc/postfix
readme_directory = /usr/local/share/doc/postfix

14; Habiltando el envio de correo a el mail-server.

transport_maps = hash:/usr/local/etc/postfix/transport

Como pueden observar, necesitamos crear ese archivo con los datos de nuestro mail-server, como sigue:

example.com smtp:[mail.example.com]

Creamos el BDB.

Este ultimo paso es donde le indicamos a nuestro spam-server que envie todos los correos aceptados a este hostname, si no tienen un DNS operable pueden poner el IP si gustan, en mi caso mi DNS esta funcionando sin problemas.

15; Revisamos el sintaxis de postfix.

postix check

Si no hay problema, ya pueden iniciar su servicio y primero que nada buscar sitios publicos donde probar si nuestro servidor no es un "open-relay" que significa que nadie de fuera puede usarlo para enviar correos.

http://www.abuse.net/relay.html

Le dan su IP o nombre del spam-server tal cual lo tiene dado de alta en su DNS y esperen los resultados, van a ver muchas pruebas que le hacen y a el final obtendran un mensaje como este:

Relay test result
All tests performed, no relays accepted.

Pero hagan mas pruebas, existen varios sitios publicos que nos proporcionan este servicio publico.

Tambien revisen su log para que vean lo que postfix logea cuando quieren penetrarlo para openrelay:

May 6 00:09:29 spam postfix/smtpd[3333]: NOQUEUE: reject: RCPT from verify.abuse.net[64.57.183.77]: 554 5.7.1 : Relay access denied; from= to= proto=SMTP helo=
May 6 00:09:32 spam postfix/smtpd[3333]: NOQUEUE: reject: RCPT from verify.abuse.net[64.57.183.77]: 554 5.7.1 : Relay access denied; from= to= proto=SMTP helo=
May 6 00:09:35 spam postfix/smtpd[3333]: NOQUEUE: reject: RCPT from verify.abuse.net[64.57.183.77]: 554 5.7.1 : Relay access denied; from= to= proto=SMTP helo=
May 6 00:09:38 spam postfix/smtpd[3333]: NOQUEUE: reject: RCPT from verify.abuse.net[64.57.183.77]: 554 5.7.1 : Relay access denied; from= to= proto=SMTP helo=

Esto es solo una parte de los logs, familiaricense con ellos, son importantisimos.

Vamos observando como nos queda la configuracion despues de estos primeros cambios:

postconf -n
alias_database = hash:/usr/local/etc/postfix/aliases
alias_maps = hash:/usr/local/etc/postfix/aliases
command_directory = /usr/local/sbin
config_directory = /usr/local/etc/postfix
daemon_directory = /usr/local/libexec/postfix
data_directory = /var/db/postfix
debug_peer_level = 2
html_directory = /usr/local/share/doc/postfix
inet_interfaces = all
local_recipient_maps =
mail_owner = postfix
mailq_path = /usr/local/bin/mailq
manpage_directory = /usr/local/man
mydestination =
mydomain = example.com
myhostname = spam.example.com
mynetworks = 192.168.40.2/32
myorigin = $mydomain
newaliases_path = /usr/bin/newaliases
queue_directory = /var/spool/postfix
readme_directory = /usr/local/share/doc/postfix
relay_domains = example.com
relay_recipient_maps = hash:/usr/local/etc/postfix/relay_recipients
sample_directory = /usr/local/etc/postfix
sendmail_path = /usr/local/sbin/sendmail
setgid_group = maildrop
smtpd_banner = $myhostname ESMTP $mail_name
transport_maps = hash:/usr/local/etc/postfix/transport
unknown_local_recipient_reject_code = 550

Pueden compararla con la primera que mostramos y notaran la diferencia.

Restricciones
1; Helo.

Podemos por regla solicitar a el otro smtp que siempre que trate de entablar comunicacion con nosotros, se presente haciendo uso de su nombre, para ello usamos el parametro:

smtpd_helo_required = yes

Con esto le pedimos que nos mande su hostname, asi dicen los RFC.

Por default postfix no lo pide, pero nosotros si, muchos spammers no les gusta esto y mucho menos obedecer reglas, si asi nos gusta a nosotros ni modo asi va a hacer.

Ahora vean lo que pasa cuando otro smtpd se conecta y es irrespetuoso, vamos a usar un equipo externo para hacer las pruebas, para ver la info en los logs de postfix que en mi caso estan en:

/var/log/maillog

Necesito prender el log de postfix abriendo el archivo de nombre:

master.cf

Y busca la siguiente linea y le agrego el parametro -v, asi quedaria:

smtp inet n - n - - smtpd -v

En este caso es la 1ra.

Aqui si reinicio el servicio.

Ahora, me conecto del otro cliente e intento mandar un correo sin mandar el HELO:

telnet example.com 25
Trying XXX.YYY.ZZZ.WWW...
Connected to example.com (IP-Publica).
Escape character is '^]'.
220 spam.example.com ESMTP Postfix
mail from:
503 5.5.1 Error: send HELO/EHLO first

Esto aparece de lado del otros smtp, ahora vemos los logs de postfix, si va a logear mucho pero aqui estamos aprediendo y no hay como saber leer los logs de cada uno de nuestros servidores de los contrario no somos buenos administradores:

May 9 22:50:53 spam postfix/smtpd[68766]: > mail.example2.com[IP-Publica]: 220 spam.example.com ESMTP Postfix
May 9 22:51:16 spam postfix/smtpd[68766]: < mail.example2.com[IP-Publica]: mail from:
May 9 22:51:16 spam postfix/smtpd[68766]: > mail.example2.com[IP-Publica]: 503 5.5.1 Error: send HELO/EHLO first

Ahi esta nuestra primer restriccion trabajando, asi que funciona.

Panorama de la comunicacion de un correo y lugar donde aplica cada tipo de restriccion, ver siguiente figura:

Figura 1. Ubicacion de restricciones de un correo en postfix.

En base a la figura 1, vamos a seguir este tutorial.

warn_if_reject

Este parametro se creo con el fin de debugear las restricciones, se ponen 1ro que la restriccion y solo nos logea un mensaje como este:

connect from mail.example2.com[IP-publica]
May 9 23:27:29 spam postfix/smtpd[69200]: NOQUEUE: reject_warning:
RCPT from mail.example2.com[IP-publica]: 554 5.7.1
: Client host rejected: Access denied; from=
to= proto=ESMTP helo=

Este pequeño parametro es de gran utilidad, ya que nos avisa si la regla funciona y si la pocision es adecuada y sobre todo que no rechaza el correo es simple informacion en los logs.

warn_if_reject restriccion_deseada

2; Client Restrictions.

Restricciones del cliente, que opciones por default tiene postfix, vamos revisandola:

postconf -d smtpd_client_restrictions
smtpd_client_restrictions =

Ninguna, entonces vamos empezando a ver que nos sirve, aunque aqui se manejan muchas, no todas vamos usar ya que muchas no tiene aplicacion para mi aun.

check_client_access

smtpd_client_restrictions=
warn_if_reject check_client_access hash:/usr/local/etc/postfix/access_clients
permit

Creamos el archivo con un dominio que no deseo aceptar, ejemplo

hotmail.com REJECT

Ya saben es hash, ya saben que tienen que hacer.

reload a postfix, mandamos un correo desde una cuenta de hotmail y vemos log.

connect from snt0-omc3-s32.snt0.hotmail.com[65.55.90.171]
May 9 23:45:21 spam postfix/smtpd[69404]: NOQUEUE: reject:
RCPT from snt0-omc3-s32.snt0.hotmail.com[65.55.90.171]:
554 5.7.1 :
Client host rejected: Access denied;
from= to=
proto=ESMTP helo=
May 9 23:45:21 spam postfix/smtpd[69404]: disconnect
from snt0-omc3-s32.snt0.hotmail.com[65.55.90.171]

Dentro de hotmail recibiran un correo con el subject:

Delivery Status Notification (Failure)‏

Y con el body:

This is an automatically generated Delivery Status Notification.
Delivery to the following recipients failed.
usera-texample.com

Ahora si tiene una cuenta de correo que no sea hotmail, prueben:

connect from mail.otrodominio.com[ippublica]
May 9 23:53:27 spam postfix/smtpd[69410]: 1D55BC16786: client=mail.otrodominio.com[ippublica]
May 9 23:53:27 spam postfix/cleanup[69413]: 1D55BC16786:
message-id=<6101993aafcd9f28f8b610475feca52b.squirrela-twww.otrodominio.com>
May 9 23:53:27 spam postfix/qmgr[69390]: 1D55BC16786:
from=, size=946, nrcpt=1 (queue active)
May 9 23:53:27 spam postfix/smtpd[69410]: disconnect
from mail.otrodominio.com[ippublica]
May 9 23:53:27 spam postfix/smtp[69414]: 1D55BC16786:
to=, relay=mail.example.com[192.168.40.4]:25,
delay=0.09, delays=0.02/0.01/0.02/0.04, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 2DA714E0015)
May 9 23:53:27 spam postfix/qmgr[69390]: 1D55BC16786: removed

Como podran ver rechazo un dominio que es basura desde el 1er filtro segun la figura 1, ahora porque si facebook esta prohibido en su empresa no bloquearlo para no aceptar ninguna invitacion por correo, ya vieron como hacerlo...

NOTA: De los logs voy a quitar "@" y lo voy a remplazar por la palabra a-t, muchos sabran por que.


Ahora veo como queda mi 1er restriccion:

postconf -h smtpd_client_restrictions
check_client_access hash:/usr/local/etc/postfix/access_clients permit

El parametro permit le indica a postfix que si el cliente pasa las reglas anteriores pueden seguir su camino con las demas restricciones si hay.

3; smtpd_recipient_restrictions.

Aqui es donde la mayor parte de las restricciones entran, ya que si revisan la figura 1 en cada nivel postfix tiene filtros, pero segun los expertos aqui es donde van la mayoria. Ahora que es lo hace postfix por default para que nuestro smtpd no sea un "open relay"?,

Vamos primero revisando viendo los parametros por default que nos da esta restriccion:

postconf -d smtpd_recipient_restrictions
smtpd_recipient_restrictions =
permit_mynetworks, reject_unauth_destination

Como podran ver solo existen 2, postfix divide sus restricciones en 2 capas:

nombre_de_restriccion =
----Restricciones que aplica tanto a clientes internos como externos.
permit_mynetworks
----
Restricciones que aplica solo a clientes externos.
permit

Por ello coloca esta restriccion:

reject_unauth_destination

Enseguida de:

permit_mynetworks

Estos dos parametros hacen que nuestro smtp no sea un openrelay y asi viene por default postfix.

El parametro reject_unauth_destination se encarga de eso, verificando que tanto el RCPT TO: su dominio o destinatarios sean de nuestro dominio, de lo contrario son rechazados.

Entonces vamos armando nuestro siguiente filtro y quedaria asi:

smtpd_recipient_restrictions =
permit_mynetworks
reject_unauth_destination
permit

Pongan lo anterior en el archivo main.cf.

4; Exigir que a otros smtp que sigan las reglas del RFC y cuando manden su nombre en el HELO/EHLO venga en forma FQDN.

mail.example.com

De lo contrario sera rechazado, nosotros ponemos las reglas, el parametro usado es:

reject_non_fqdn_hostname

Quedaria asi:

smtpd_recipient_restrictions =
permit_mynetworks
reject_unauth_destination
reject_non_fqdn_hostname
permit

Reload y probamos.

connect from mail.example2.com[pub-ip]
May 12 22:03:33 spam postfix/smtpd[8895]: NOQUEUE: reject_warning:
RCPT from mail.example2.com[pub-ip]:
504 5.5.2 : Helo command rejected: need fully-qualified hostname;
from= to= proto=SMTP helo=
May 12 22:03:33 spam postfix/smtpd[8895]: 4EC1BC16786:
client=mail.example2.com[pub-ip]

5; Ahora vamos a pedirles a otros smtp que usen nombres validos en el hostname usando este parametro:

reject_invalid_hostname

Es parecido a el #4 y util.

Reload y probamos.

6; Hasta aqui hemos atacado el smtp, pero ahora sigue el sender o el "from:", asi como le pedimos a los smtp externos que tengan nombres en forma FQDN, tambien se lo vamos a exigir a los remitentes usando este parametro:

reject_non_fqdn_sender

Y lo vamos a colocar arriba de permit_mynetworks, para que sea a todos, tanto los externos como internos, por si por alguna razon postfix falle no me vaya a causar problemas por error de dedo o de aplicacion, mejor se lo aplico a todos.

Quedaria asi:

smtpd_recipient_restrictions =
reject_non_fqdn_sender
permit_mynetworks
reject_unauth_destination
reject_non_fqdn_hostname
reject_invalid_hostname
permit

Reload y probamos.

connect from mail.example2.com[ip-pub]
May 12 22:31:50 spam postfix/smtpd[9269]: NOQUEUE:
RCPT from mail.example2.com[ip-pub]: 504 5.5.2 :
Sender address rejected: need fully-qualified
address; from= to=
proto=SMTP helo=
May 12 22:31:50 spam postfix/smtpd[9269]:
96E4DC16786: client=mail.example2.com[ip-pub]
May 12 22:31:56 spam postfix/smtpd[9269]:
lost connection after UNKNOWN from mail.example2.com[ip-pub]
May 12 22:31:56 spam postfix/smtpd[9269]:
disconnect from mail.example2.com[ip-pub]

7; Ahora vamos a validar la existencia de los dominios de los otros smtp`s. Con este parametro:

smtpd_recipient_restrictions =
reject_non_fqdn_sender
reject_unknown_sender_domain
permit_mynetworks
reject_unauth_destination
reject_non_fqdn_hostname
reject_invalid_hostname
permit

Reload y probamos.

connect from mail.exmaple2.com[pub-ip]
May 13 06:44:14 spam postfix/smtpd[15311]: NOQUEUE: reject:
RCPT from mail.exmaple2.com[pub-ip]: 450 4.1.8
: Sender address rejected:
Domain not found; from=
to=
proto=SMTP helo=
May 13 06:44:19 spam postfix/smtpd[15311]:
lost connection after RCPT from mail.exmaple2.com[pub-ip]
May 13 06:44:19 spam postfix/smtpd[15311]:
disconnect from mail.exmaple2.com[pub-ip]

Claro que aqui postfix necesita hacer unos queries a el DNS pero no importa vale la pena.

8; Ahora vamos a verficar que el dominio de los destinos existan, ya se que sabemos que no va a pasar, pero para que dejar que la comunicacion sigan procesandose si puede pararla antes mejor, asi me ahorro CPU/memoria/tiempo.

Quedaria asi:

smtpd_recipient_restrictions =
reject_non_fqdn_sender
reject_unknown_sender_domain
reject_unknown_recipient_domain
permit_mynetworks
reject_unauth_destination
reject_non_fqdn_hostname
reject_invalid_hostname
permit

Reload y revisamos logs, les aparecera algo asi:

user@dominio.malo.com>: Recipient address rejected: Domain not found

Hasta aqui hemos creado un grupo de restriciones, las cuales creanme van a bloquar parte de los spammers, pero este es solo la 1er barrera, vamos a seguirle.

10; Validando remitentes.

Ahora vamos a pedirle a postfix que antes de aceptar un correo para un usuario de nuestro dominio lo verifique, para ello tenemos 2 formas, usuarios locales y usuarios del dominio, anteriormente hablamos de los 1eros y configuramos a nuestro smtp para que no acepte nada a cuentas locales, asi que aqui me enfocare a los usuarios del dominio.

El parametro:

relay_recipient_maps = hash:/usr/local/etc/postfix/relay_recipients

Le estamos dando un archivo donde tenemos las cuentas que pueden realmente recibir correos, aqui esta un ejemplo:

user1@example.com OK
user2@example.com OK

Ya saben como deben crear el archivo que requiere postfix, reload y prueban.

connect from mail.example2.com[ip-pub]
May 14 15:35:01 spam postfix/smtpd[32991]: NOQUEUE: reject: RCPT from
mail.example2.com[ip-pub]: 550 5.1.1 :
Recipient address rejected: User unknown in relay
recipient table; from=
to= proto=SMTP helo=
May 14 15:35:08 spam postfix/smtpd[32991]:
lost connection after RCPT from mail.example2.com[ip-pub]
May 14 15:35:08 spam postfix/smtpd[32991]:
disconnect from mail.example2.com[ip-pub]

Se preguntaran, como podre sacar mi lista de usuarios? bueno aqui cada debe saber como tenerla a el dia.

11;Vamos a agregar otros parametros y al ver su nombre ustedes van a saber lo que hacen:

smtpd_recipient_restrictions =
reject_non_fqdn_recipient
reject_non_fqdn_sender
reject_unknown_sender_domain
reject_unknown_recipient_domain
permit_mynetworks
reject_unauth_destination
reject_non_fqdn_hostname
reject_invalid_hostname
permit

Reload y prueban.

12; Envio a multiples destinatarios.

Dice el RFC que uno nunca debe de bloquear el correo de remitentes en esta forma:

<>

Ya que este correo lo usan los mismos smtp para comunicarse, pero muchos spammers abusan y tratan de usarlo para aprovecharse de este atributo y ademas trataran de usarlo para enviar correos a multiples destinatarios, por ello existe este parametro:

reject_multi_recipient_bounce

Su funcion es esa y nuestra configuracion seria asi:

smtpd_recipient_restrictions =
reject_non_fqdn_recipient
reject_non_fqdn_sender
reject_unknown_sender_domain
reject_unknown_recipient_domain
permit_mynetworks
reject_unauth_destination
reject_multi_recipient_bounce
reject_non_fqdn_hostname
reject_invalid_hostname
permit

Reload y prueban.

connect from mail.example2.com[pub-ip]
May 15 22:01:11 spam postfix/smtpd[64455]: 3D706C16E22:
client=mail.example2.com[pub-ip]
May 15 22:01:23 spam postfix/smtpd[64455]:
3D706C16E22: reject: RCPT from mail.example2.com[pub-ip]:
550 5.5.3 : Recipient address rejected:
Multi-recipient bounce; from=<> to=
proto=SMTP helo=
May 15 22:01:28 spam postfix/smtpd[64455]:
lost connection after RCPT from mail.example2.com[pub-ip]
May 15 22:01:28 spam postfix/smtpd[64455]:
disconnect from mail.example2.com[pub-ip]

13; Helo Checks.

Muchos spammers trataran de pasarse de listos y quedran enviar en el HELO/EHLO el nombre de nuestro smtp, por lo tanto vamos deteniendo este detalle creando un archivo con los siguientes caracteres raros:

/^spam\.example\.com$/ REJECT You are not in the server room

# Somebody HELO'ing with our IP address?
/^W\.X\.Y\.Z$/ REJECT You are not my IP
/^\[W.X.Y\.Z\]$/ REJECT You are not my IP
/^[0-9.]+$/ REJECT U are not RFC2821 compliant

Donde W.X.Y.Z es el ip publico de mi spam server, no el interno.

Y dentro de postfix usamos el parametro:

check_helo_access

Asi:

smtpd_recipient_restrictions =
reject_non_fqdn_recipient
reject_non_fqdn_sender
reject_unknown_sender_domain
reject_unknown_recipient_domain
permit_mynetworks
reject_unauth_destination
reject_multi_recipient_bounce
check_helo_access pcre:/usr/local/etc/postfix/helo_checks
reject_non_fqdn_hostname
reject_invalid_hostname
permit

Reload.

Si se dan cuenta, postfix genera un archivo con la extension .pcre de helo_checks.

Ahora revisamos el log:

connect from mail.example2.com[pub-ip]
May 15 22:45:43 spam postfix/smtpd[59312]: NOQUEUE: reject:
RCPT from mail.example2.com[pub-ip]:
554 5.7.1 :
Helo command rejected: You are not in the server room;
from=
to=
proto=SMTP helo=

14; Listras negras de DNS.

Postfix nos permite a nosotros hacer uso de sitios externos para saber si el smtp externo que desea tener comunicacion con nuestro smtp no esta en alguna lista negra. Hay varios parametros y lista de este tipo existen varias, yo en lo particular estoy usando:

http://www.spamhaus.org/index.lasso

Me ha servido mucho y es mucho el spam que me bloquean y no he tenido problemas con ninguno de nuestros clientes en el sentido que este filtro los este bloqueando.

Bien, esta funcion es desgastante en tiempo pero vale la pena, y me refiero a esto porque nuestro smtp tendra que hacer algunos queries a el dns, asi que si ven lentitud vayan pensando en levantar un cache DNS.

Como quedaria my configuracion:

smtpd_recipient_restrictions =
reject_non_fqdn_recipient
reject_non_fqdn_sender
reject_unknown_sender_domain
reject_unknown_recipient_domain
permit_mynetworks
reject_unauth_destination
reject_multi_recipient_bounce
check_helo_access pcre:/usr/local/etc/postfix/helo_checks
reject_non_fqdn_hostname
reject_invalid_hostname
reject_rbl_client zen.spamhaus.org
permit

En mi caso quiero que sea la ultima que se lleve a cabo por lo mismo del tiempo precioso que necesita que son segundos, pero cuando tienes 20 conexiones x segundo ya pesa.

Reload y voy a mostrar un log de cuando este operacion entra en juego:

May 15 23:01:39 spam postfix/smtpd[2968]:
NOQUEUE: reject: RCPT from unknown[PUB-IP]:
554 5.7.1 Service unavailable; Client host
[PUB-IP] blocked using zen.spamhaus.org;
http://www.spamhaus.org/query/bl?ip=PUB-IP;
from= to=
proto=SMTP helo=<456.subnet24-432-789.speedy.telkom.net.id>

15; No permitir usar mi dominio a el remitente.

Ahora vamos a verificar que los smtp no traten de usar mi dominio en sus remitentes, para ello vamos a crear un archivo con estos datos:

example.com 554 No usar mi dominio en tu remitente

Y nuestro configuracion seria asi:

smtpd_recipient_restrictions =
reject_non_fqdn_recipient
reject_non_fqdn_sender
reject_unknown_sender_domain
reject_unknown_recipient_domain
permit_mynetworks
check_sender_access hash:/usr/local/etc/postfix/no_usar_mi_dominio
reject_unauth_destination
reject_multi_recipient_bounce
check_helo_access pcre:/usr/local/etc/postfix/helo_checks
reject_non_fqdn_hostname
reject_invalid_hostname
reject_rbl_client zen.spamhaus.org
permit

Por que ahi? Bien yo quiero que si alguien quiere usar mi dominio en su remitente, no deseo investigar mas ya que ese smtp ha tratado de fingir ser "yo" por lo tanto lo rechazo antes de seguir gastando mi precioso tiempo, CPU, memoria por ello le doy prioridad a esta regla.

Reload y vamos a ver que dice el log:

connect from mail.example2.com[pub-ip]
May 15 23:44:39 spam postfix/smtpd[64295]:
NOQUEUE: reject: RCPT from mail.example2.com[pub-ip]:
554 5.7.1 :
Sender address rejected: No usar mi dominio en tu remitente;
from=
to=
proto=SMTP helo=


16;
Filtros Externos

Ahora vamos hacer uso de programas externos y deseo darles una tecnica que a muchos les parece algo exagerada pero a mi punto de vista la veo muy util, la cual se basa en un funcion de los smtp, la cual funciona asi.

Cuando un smtp se comunica con otro, y este otro esta muy saturado, este ultimo le puede responder a el 1er smtp diciendole que esta muy cargado que espero un poco de tiempo. El rfc tiene contemplado esto.

Asi de simple, pero a que viene esto?

Muchos spaammers les pagan por enviar correos, mientras mas envien mas les pagan o llegan a su cuota, por ello muchos crean su programas para que no obedezcan los RFC de lo contrario serian ejecutables muy grandes y rapidamente detectados.

Y ademas, ellos reciben su paga por enviar y no por confirmar si llego o no, en las palabras anteriores esta la clave.

Para llevar a cabo esta tecnica vamos hacer uso de un programa llamado: Postgrey de este sitio.

http://postgrey.schweikert.ch/

Por ello postfix nos da este parametro:

check_policy_service

Aqui es donde le decimos que haga uso de algo externo.

Lo que hace postgrey es lo siguiente. Cuando un remitente externo(otro smtp) trata de enviarnos por primera vez correos a un destinatario de nuestro dominio, una vez pasado por todas las reglas y llegado a el check_policy_service, postgrey en su bd verifica que haya un par de parametros:

remitente destinatario

Si no hay ninguno, este le retorna el mensaje a el otro smtp que debe esperar, por default postgrey tienen una poliza de 5 minutos, asi que si el otro smtp trata de hacerlo antes postgrey ya lo tiene en su lista de espera y lo vuelve a rechazar hasta que haya pasado ese periodo de gracia.

Una vez que el otro smtp lo intenta en el tiempo especificado ya postgrey le permite el paso por que ya tiene un par de llaves en su bd.

Asi de simple, como les comente anteriormente los spammers no les interesa saber si si correo llego o no, muchos menos detenerse para volver enviar el correo, por ello esta tecnica tambien les va a bloquear un bloque de spam.

Su unico incoveniente es que la 1ra vez que su amigo les envie el correo van a tardar 5 minutos en entrar, pero todos los smtp que siguen las reglas van a respetar nuestras reglas y volver a enviar el correo en el tiempo especificado asi que no van a tener problemas.

Ustedes son los que saben como operar su servidor y que es lo mejor para su compañia asi que si un empleado sale lloron solo tienen que convencer a su jefe la importancia para su compañia de este pequeño truco.

Para ponerlo a trabajar ya solo voy a rc.conf y lo doy de alta:

postgrey_enable="yes"

La bd de datos que usa es BDB, postgrey no es el unico que existen hay muchos, pero para este funcion yo lo elegi a el.

Lo hecho a volar.

Mi configuracion quedaria asi:

smtpd_recipient_restrictions =
reject_non_fqdn_recipient
reject_non_fqdn_sender
reject_unknown_sender_domain
reject_unknown_recipient_domain
permit_mynetworks
check_sender_access hash:/usr/local/etc/postfix/no_usar_mi_dominio
reject_unauth_destination
check_helo_access pcre:/usr/local/etc/postfix/helo_checks
reject_multi_recipient_bounce
reject_non_fqdn_hostname
reject_invalid_hostname
check_policy_service inet:192.168.40.5:10023
reject_rbl_client zen.spamhaus.org
permit

Lo coloco antes del _rbl_client ya que prefiero que los queries externos sea lo ultimo que haga mi spam server.

Reload y van a ver logs como este:

connect from second3.fotuicatan.com[173.246.141.201]
May 16 07:07:39 spam postgrey[18480]: action=greylist, reason=new,
client_name=second3.fotuicatan.com,
client_address=173.246.141.201,
sender=dentalcarea-tfotuicatan.com,
recipient=usera-texample.com
May 16 07:07:40 spam postfix/smtpd[14371]:
NOQUEUE: reject: RCPT from second3.fotuicatan.com
[173.246.141.201]: 450 4.2.0 :
Recipient address rejected: Greylisted, see
http://postgrey.schweikert.ch/help/example.com.html;
from= to=
proto=ESMTP helo=

Clamavis

Ahora vamos a configurar el antivirus open source ClamAV, en este servidor estamos hablando de la version 0.97, y como todo usuario de FreeBSD siempre nos preguntamos y que opciones usamos cuando ejecutemos:

make install clean

Bien aqui pongo las que estoy usando:

Figura 2.

Bien una vez instalado vamos a la configuracion, la instalacion coloca 2 archivos por default en la ruta default: /usr/local/etc/, esto son:

-r--r--r-- 1 root wheel 13986 Mar 23 02:06 clamd.conf.default
-r--r--r-- 1 root wheel 7507 Mar 23 02:06 freshclam.conf.default

Solo compeanos cada a otro archivo sin la extension .default.

Freshclam

Clamav instala 2 servicios:

freshclam clamd.

El 1ro es el encargado de actualizar las firmas del antivirus, asi que este servidor cada cierto tiempo se estara conectado para bajar las firmas mas nuevas.

Su configuracion es la siguiente:

DatabaseDirectory /var/db/clamav
UpdateLogFile /var/log/clamav/freshclam.log
LogFileMaxSize 2M
LogTime yes
LogVerbose yes
LogSyslog yes
PidFile /var/run/clamav/freshclam.pid
DatabaseOwner clamav
AllowSupplementaryGroups yes
DatabaseMirror db.us.clamav.net
DatabaseMirror database.clamav.net
MaxAttempts 5
NotifyClamd /usr/local/etc/clamd.conf

Crear el archivo log si no existe, los demas parametros y comentarios los deje tal cual estan.

El directorio donde se guardan los logs debe tener el siguiente permiso:

drwxr-xr-x 2 clamav clamav 1024 May 17 00:00 clamav

Ahora lo damos de alta en el rc.conf

clamav_freshclam_enable="YES"

Aqui ya lo tenemos listo para proibar.

Clamav

Este programa es el que se encarga de llevar la tarea sucia y revisar nuestros archivos de cosas malas.

Vamos mostrando la configuracion que estoy usando:

LogFile /var/log/clamav/clamd.log
LogFileMaxSize 2M
LogTime yes
LogSyslog yes
LogVerbose yes
ExtendedDetectionInfo yes
PidFile /var/run/clamav/clamd.pid
DatabaseDirectory /var/db/clamav
LocalSocket /var/run/clamav/clamd.sock
FixStaleSocket yes
TCPAddr 192.168.40.5
StreamMaxLength 10M
MaxDirectoryRecursion 20
User clamav
AllowSupplementaryGroups yes
ScanMail yes

Todos los demas parametros los estoy dejando con sus valores por default, aqui solo muestro los que yo uso y eliminando comentarios, ademas tengo habilitado el verbose ya cuando termine de configurar todo lo voy a poner lo mas bajo posible.

FreeBSD crea el usuario y grupo de clamav, ya solo falta agregar el servicio a rc.conf:

clamav_clamd_enable="YES"

Ahora si vamos poniendo ambos en operacion, el1ro es el freshclam y lo ejecutamos a mano, este servicio usa el puerto 80 para bajar sus archivos, asi que su firewall debe permitirle salir por el puerto 80.

freshclam -v

freshclam -v
Current working dir is /var/db/clamav
Max retries == 5
ClamAV update process started at Tue May 17 22:51:02 2011
Using IPv6 aware code
Querying current.cvd.clamav.net
TTL: 422
Software version from DNS: 0.97
main.cvd version from DNS: 53
main.cvd is up to date (version: 53, sigs: 846214, f-level: 53, builder: sven)
daily.cvd version from DNS: 13086
daily.cld is up to date (version: 13086, sigs: 118614, f-level: 60, builder: guitar)
bytecode.cvd version from DNS: 143
bytecode.cld is up to date (version: 143, sigs: 40, f-level: 60, builder: edwin)

Ahora sigue clamd:

/usr/local/etc/rc.d/clamav-clamd start

Starting clamav_clamd.

Vemos el log:

Tue May 17 22:28:26 2011 -> +++ Started at Tue May 17 22:28:26 2011
Tue May 17 22:28:26 2011 -> clamd daemon 0.97 (OS: freebsd8.2, ARCH: i386, CPU: i386)
Tue May 17 22:28:26 2011 -> Running as user clamav (UID 106, GID 106)
Tue May 17 22:28:26 2011 -> Log file size limited to 2097152 bytes.
Tue May 17 22:28:26 2011 -> Reading databases from /var/db/clamav
Tue May 17 22:28:26 2011 -> Not loading PUA signatures.
Tue May 17 22:28:32 2011 -> Loaded 963507 signatures.
Tue May 17 22:28:34 2011 -> LOCAL: Unix socket file /var/run/clamav/clamd.sock
Tue May 17 22:28:34 2011 -> LOCAL: Setting connection queue length to 200
Tue May 17 22:28:34 2011 -> Limits: Global size limit set to 104857600 bytes.
Tue May 17 22:28:34 2011 -> Limits: File size limit set to 26214400 bytes.
Tue May 17 22:28:34 2011 -> Limits: Recursion level limit set to 16.
Tue May 17 22:28:34 2011 -> Limits: Files limit set to 10000.
Tue May 17 22:28:34 2011 -> Limits: Core-dump limit is 4294967295.
Tue May 17 22:28:34 2011 -> Archive support enabled.
Tue May 17 22:28:34 2011 -> Algorithmic detection enabled.
Tue May 17 22:28:34 2011 -> Portable Executable support enabled.
Tue May 17 22:28:34 2011 -> ELF support enabled.
Tue May 17 22:28:34 2011 -> Mail files support enabled.
Tue May 17 22:28:34 2011 -> OLE2 support enabled.
Tue May 17 22:28:34 2011 -> PDF support enabled.
Tue May 17 22:28:34 2011 -> HTML support enabled.
Tue May 17 22:28:34 2011 -> Self checking every 600 seconds.
Tue May 17 22:28:34 2011 -> Listening daemon: PID: 90556
Tue May 17 22:28:34 2011 -> MaxQueue set to: 100
Tue May 17 22:28:34 2011 -> Set stacksize to 1114112

Verificamos:

/usr/local/etc/rc.d/clamav-clamd status
clamav_clamd is running as pid 90556.

Vemos si esta el servicio arriba:

ps -ax | grep clam
90596 ?? IsJ 0:00.00 /usr/local/sbin/clamd

Probamos localmente:

clamscan /usr/local/etc/
/usr/local/etc/screenrc: OK
/usr/local/etc/pkgtools.status-pkg.sh: OK
/usr/local/etc/pkgtools.conf.sample: OK
/usr/local/etc/pkgtools.conf: OK
/usr/local/etc/rarfiles.lst: OK
/usr/local/etc/amavisd.conf-dist: OK
/usr/local/etc/amavisd.conf-sample: OK
/usr/local/etc/amavisd.conf-default: OK
/usr/local/etc/amavisd-custom.conf-dist: OK
/usr/local/etc/amavisd.conf: OK
/usr/local/etc/amavisd-custom.conf: OK
/usr/local/etc/clamd.conf.default: OK
/usr/local/etc/freshclam.conf.default: OK
/usr/local/etc/clamd.conf: OK
/usr/local/etc/freshclam.conf: OK
/usr/local/etc/policyd-weight.conf.sample: OK
/usr/local/etc/my.cnf: OK
/usr/local/etc/nss_ldap.conf.sample: OK
/usr/local/etc/nss_ldap.conf: OK
/usr/local/etc/ldap.conf.dist: OK
/usr/local/etc/policyd-weight.conf: OK
/usr/local/etc/ldap.conf: Symbolic link
/usr/local/etc/portaudit.conf.sample: OK

----------- SCAN SUMMARY -----------
Known viruses: 963507
Engine version: 0.97
Scanned directories: 1
Scanned files: 22
Infected files: 0
Data scanned: 0.59 MB
Data read: 0.33 MB (ratio 1.79:1)
Time: 8.726 sec (0 m 8 s)

Ahora si ejecutamos el demonio de freshclam:

/usr/local/etc/rc.d/clamav-freshclam restart
Starting clamav_freshclam.

Revisamos ambos servicios:

ps -ax | grep clam
90828 ?? IsJ 0:02.74 /usr/local/bin/freshclam --daemon -p /var/run/clamav/freshclam.pid
90850 ?? IsJ 0:00.00 /usr/local/sbin/clamd

Ahora los sockets:

sockstat -4
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
clamav clamd 90850 3 tcp4 192.168.40.5:21989 192.168.40.4:389
clamav freshclam 90828 3 tcp4 192.168.40.5:31452 192.168.40.4:389

Como mi red depende de LDAP, aqui veo que ambos estan teniendo comunicacion eon mi servidor LDAP.

En la configuracion de freshclam viene una parte donde dice que una vez que actualice firmas debe informar a clamd sobre esto, sus logs van a mostrar algo asi:

Tue May 17 22:43:04 2011 -> Current working dir is /var/db/clamav
Tue May 17 22:43:04 2011 -> Max retries == 5
Tue May 17 22:43:04 2011 -> ClamAV update process started at Tue May 17 22:43:04 2011
Tue May 17 22:43:04 2011 -> Using IPv6 aware code
Tue May 17 22:43:04 2011 -> Querying current.cvd.clamav.net
Tue May 17 22:43:04 2011 -> TTL: 900
Tue May 17 22:43:04 2011 -> Software version from DNS: 0.97
Tue May 17 22:43:04 2011 -> main.cvd version from DNS: 53
Tue May 17 22:43:04 2011 -> main.cvd is up to date (version: 53, sigs: 846214, f-level: 53, builder: sven)
Tue May 17 22:43:04 2011 -> daily.cvd version from DNS: 13086
Tue May 17 22:43:04 2011 -> Retrieving http://db.us.clamav.net/daily-13086.cdiff
Tue May 17 22:43:04 2011 -> connect_error: getsockopt(SO_ERROR): fd=6 error=61: Connection refused
Tue May 17 22:43:04 2011 -> Can't connect to port 80 of host db.us.clamav.net (IP: 194.47.250.218)
Tue May 17 22:43:04 2011 -> Trying to download http://db.us.clamav.net/daily-13086.cdiff (IP: 168.143.19.95)
Tue May 17 22:43:04 2011 -> Downloading daily-13086.cdiff [100%]
Tue May 17 22:43:04 2011 -> cdiff_apply: Parsed 21 lines and executed 21 commands
Tue May 17 22:43:05 2011 -> Loading signatures from daily.cld
Tue May 17 22:43:05 2011 -> Properly loaded 118614 signatures from new daily.cld
Tue May 17 22:43:05 2011 -> daily.cld updated (version: 13086, sigs: 118614, f-level: 60, builder: guitar)
Tue May 17 22:43:05 2011 -> bytecode.cvd version from DNS: 143
Tue May 17 22:43:05 2011 -> bytecode.cld is up to date (version: 143, sigs: 40, f-level: 60, builder: edwin)
Tue May 17 22:43:08 2011 -> Database updated (964868 signatures) from db.us.clamav.net (IP: 168.143.19.95)
Tue May 17 22:43:08 2011 -> Clamd successfully notified about the update.

Y la configuracion tambien muestra cada cuanto se va a estar actualizando.

Parece que clamav esta listo para ser usado por amavisd.

SpamAssasin

Viene una pieza angular de este servidor, SA abreviado, es una aplicacion opensource que tiene mucho reconocimiento a nivel mundial, hasta empresas de renombre hacen uso de el.

Amavisd le llama a sa cuando empieza a recibir mensajes de Postfix, sa es un software de autoaprendizaje asi que conforme recibe mensajes va memorizando la comunicacion de cada usuario.

Su configuracion tiene varios achivos en:

/usr/local/etc/mail/spamassassin/

El principal es local.cf




No hay comentarios: