Servidor de Correo – Casillas y usuarios virtuales

Control de SPAM

Control de SPAM

El filtro de spam se hace en dos etapas:

  1. El spam es identificado al ingreso al sistema.
  2. El spam es entregado en una carpeta dedicada en la cuenta del usuario.

Estas etapas son cosas separadas. Spamassassin identifica y etiqueta al spam mientras que el plugin Sieve de Dovecot permite colocarlo automáticamente en la carpeta spam del usuario. Primero identificaremos el spam.

Verificar la aceptación de correo

Agregamos un nuevo conjunto de verificaciones a /etc/postfix/main.cf para reducir la cantidad de correo que acepta el sistema

### Para descartar correo mal formado
smtpd_helo_required = yes
strict_rfc821_envelopes = yes
disable_vrfy_command = yes
unknown_address_reject_code = 554
unknown_hostname_reject_code = 554
unknown_client_reject_code = 554
smtpd_helo_restrictions =
 permit_mynetworks,
 reject_invalid_hostname,
## Al modificar sender_checks, el archivo debe ser regenerado
## usando postmap <archivo>, para generar una Berkeley DB
 regexp:/etc/postfix/helo.regexp,
 permit
smtpd_recipient_restrictions =
 check_client_access hash:/etc/postfix/helo_client_exceptions,
 check_sender_access hash:/etc/postfix/sender_checks,
 reject_invalid_hostname,
## Puede provocar problemas con Auth SMTP
 reject_non_fqdn_hostname,
##################################
 reject_non_fqdn_sender,
 reject_non_fqdn_recipient,
 reject_unknown_sender_domain,
 reject_unknown_recipient_domain,
 permit_mynetworks,
 reject_unauth_destination,
## Agregamos excepciones RBL, al hacer cambios el archivo debe ser regenerado usando
## postmap <archivo>, para generar una Berkeley DB
 check_client_access hash:/etc/postfix/rbl_client_exceptions,
 reject_rbl_client cbl.abuseat.org,
 reject_rbl_client sbl-xbl.spamhaus.org,
 reject_rbl_client bl.spamcop.net,
 reject_rhsbl_sender dsn.rfc-ignorant.org
 permit

Ahora necesitamos crear dos archivos:
El primero /etc/postfix/helo.regexp que contendrá:

/^subdominio\.host\.com$/ 550 No uses mi nombre de host
/^xxx\.yyy\.zzz\.xxx$/ 550 No uses mi dirección IP
/^\[xxx\.yyy\.zzz\.xxx\]$/ 550 No uses mi dirección IP
/^[0-9.]+$/ 550 Tu software no cumple con RFC 2821
/^[0-9]+(\.[0-9]+){3}$/ 550 Tu software no cumple con RFC 2821

Esto por sí solo hará que los spammers que intentan enviar el comando helo y hacerse pasar por el servidor que recibe el correo por IP o por nombre de host, así como rechazar algunos de los correos que no cumplen con la RFC 2821.
Luego necesitamos crear /etc/postfix/helo_client_exceptions

# Estas direcciones IP pueden evitar los controles fqdn
# Algún comentario para identificar el IP de abajo
www.xxx.yyy.zzz OK

Este archivo es necesario en caso un servidor de correo que se comporta mal no puede enviar el helo correcto y tienes que permitir que se acepte el correo de esa fuente. Cosas como dispositivos independientes, cámaras de CCTV son pobres en el cumplimiento de las normas, por lo que podría tener que hacer una excepción para esto.
Antes de que cualquier cambio en este archivo sea utilizable, hay que ejecutar

# postmap /etc/postfix/helo_client_exceptions

Esto creará un archivo llamado /etc/postfix/helo_client_exceptions.db
Más adelante tenemos /etc/postfix/sender_checks que permite evitar varios controles FQDN y habilitar un remitente determinado. Esto resulta particularmente útil cuando si una empresa tiene un midominio.edu.ar para trabajar pero el correo funcionar en interno.midominio.edu.ar y no hay configuración DNS para interno.midominio.edu.ar, estos es genial para la seguridad pero los DNS externos desconocen la existencia de tal estructura interna y, a consecuencia de ello, postfix rechazará interno.midominio.edu.ar.

usuario@midominio.edu.ar REJECT
usuario@interno.midominio.edu.ar OK

Una vez modificado el archivo es necesario crear una Berkely DB usando:

# postmap /etc/postfix/sender_checks

Luego tenemos las verificaciones RBL. Existen muchos sitios dedicados a ello (en el ejemplo hay 4) que brindan listas actualizadas constantemente con IPs y nombres de host que los spammers utilizan para enviar correo. Cada IP que intenta enviar correo a nuestro servidor de correo será verificado contra esas listas y si la IP no está listada en las RBLs, el servidor aceptará el correo. Eventualmente los servidores pueden aparecer listados y removerlos puede demorar 24 horas luego de un brote de spam de modo que siempre es bueno contar con una manera de evitar los controles.
Para hacerlo creamos un archivo llamado /etc/postfix/rbl_client_exceptions

## Algún comentario
www.xxx.yyy.zzz OK

Una vez más será necesario generar la Berkeley DB

postmap /etc/postfix/rbl_client_exceptions

Postgrey

Se podría agregar postgrey como capa adicional de filtrado, lo cual no es para nada complejo. Solo se instala el servicio

# apt -y install postgrey

y agregamos a smtpd_recipient_restrictions

check_policy_service inet:127.0.0.1:10023

La configuración de postgrey se almacena en /etc/default/postgrey. Allí se puede modificar, por ejemplo, el retraso impuesto a la entrega de los correos.

check_policy_service inet:127.0.0.1:10023 --delay=60

Reduciría la demora a un minuto. El valor predeterminado es de cinco.
Las restricciones smtpd son fáciles de comprender, mientras no surja un NO de manera explícita a un mensaje determinado, éste seguirá avanzando en la lista de verificaciones.

Instalar Spamassassin

# apt-get install spamassassin spamc

Creamos un usuario para spamc. Se trata de la mitad cliente de la pareja spamc/spamd. Debería ser usado en lugar de “spamassassin” en scripts para procesar el correo. Leerá el correo desde STDIN, y lo pondrá en la cola de su conexión a spamd, luego leer el resultado y lo imprime a STDOUT. Spamc tiene un impacto muy bajo en el rendimiento, por lo que debería ser mucho más rápida su carga comparado con el programa spamassassin completo.”

# adduser spamd --disabled-login

Basta con presionar enter ante cada pregunta.
Habilitamos el inicio de Spamassassin en cada arranque:

# systemctl enable spamassassin.service

Editamos /etc/default/spamassassin

OPTIONS="--create-prefs --max-children 5 --username spamd --helper-home-dir /home/spamd/ -s /home/spamd/spamd.log"
# Habilita la actualización automática de las reglas de Spamassassin cada noche.
CRON=1

Luego editamos /etc/spamassassin/local.cf para establecer las reglas de SPAM:

rewrite_header Subject ***** SPAM _SCORE_ *****
# Muestra el mensaje spam original en lugar de un mensaje
# que contenga al correo con spam como adjunto.
report_safe 0
required_score 5.0
use_bayes 1
bayes_auto_learn 1
skip_rbl_checks 0
use_dcc 0
use_pyzor 0

Iniciamos el filtro de spam:

# systemctl start spamassassin

Le indicamos a Postfix que tenemos activo un filtro de contenido. En
/etc/postfix/master.cf
encontrar la linea

smtp inet n - - - - smtpd

y directamente debajo agregamos:

 -o content_filter=spamassassin

En este caso la linea que comienza con -o debe tener uno o más espacios en blanco al comienzo. De no ser así, al recargar la configuración Postfix ‘dirá’: “/usr/sbin/postconf: fatal: invalid type field”. Nuevamente, incontables horas de diversión.
Ya que postfix enviará el recipiente a spamc, necesitamos indicarle a postfix que entregue el correo a cada usuario de separadamente. Agregamos la siguiente linea a /etc/postfix/main.cf

spamassassin_destination_recipient_limit = 1

Necesitamos indicar a Postfix que encamine el correo a spamd. Para ello, al final de
/etc/postfix/master.cf
agregamos:

spamassassin unix - n n - - pipe
 user=spamd argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}

Nuevamente hay que tener en cuenta el espacio al comienzo de la segunda linea.

# systemctl restart spamassassin
# postfix reload

En este punto es necesario enviar un correo de prueba hacia y desde nuestra cuenta en Roundcube para cerciorarnos que aún funciona.
Si no fuera así, removemos las últimas entradas de /etc/postfix/master.cf, reiniciamos Postfix e intentamos nuevamente. Verificamos no haber ingresado algo mal y que al reiniciar Postfix no arroja ningún error. Solamente vamos a continuar si el envío y la recepción funcionan.

Probando el filtro de spam

Enviamos un correo a nuestro recipiente con el GTUBE. Es el EICAR para los filtros de spam: es una cadena especial de caracteres que los filtros de spam reconocen como tal para propósito de pruebas. Más en: http://spamassassin.apache.org/gtube/
Así que enviamos un correo con esta cadena en el cuerpo del mensaje:

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

Al ingresar a Roundcube el mensaje debería estar etiquetado como *****SPAM*****. Un mensaje sin esta cadena no debería contener esa alerta.
Abrimos el mensaje etiquetado como *****SPAM***** y vamos a “Mostrar código”.
Deberíamos ver algo así:

X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on servidor
X-Spam-Flag: YES
X-Spam-Level: **************************************************
X-Spam-Status: Yes, score=1001.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID,
DKIM_VALID_AU,FREEMAIL_FROM,GTUBE,PYZOR_CHECK,RCVD_IN_MSPIKE_H2,
SPF_PASS autolearn=no autolearn_force=no version=3.4.2
X-Spam-Report:
* 1000 GTUBE BODY: Generic Test for Unsolicited Bulk Email

Mover automáticamente el spam a la carpeta Basura

Esto es en realidad parte de algo más grande, llamado sistema de filtrado de correo. Usando filtros (también llamados reglas) podemos aplicar acciones a correo usando lógica, por ejemplo mover correo que está etiquetado como spam a la carpeta Basura.

Suscribir automáticamente usuarios a las carpetas especiales IMAP

En primer lugar necesitamos asegurarnos que el cliente IMAP está suscripto a la carpeta a la que el spam será movido.
Al abrir Roundcube vemos que solo existen dos carpetas: Entrada y Enviados. Apuntamos a subscribir automáticamente los usuarios a varias carpetas IMAP especiales de modo que siempre estén allí. En /etc/dovecot/dovecot.conf agregamos:

namespace inbox {
 mailbox Drafts {
 special_use = \Drafts
 auto = subscribe
 }
 mailbox Junk {
 special_use = \Junk
 auto = subscribe
 }
 mailbox Trash {
 special_use = \Trash
 auto = subscribe
 }
 #mailbox Archive {
 # special_use = \Archive
 # auto = subscribe
 }
 mailbox Sent {
 special_use = \Sent
 auto = subscribe
 }
 #mailbox "Sent Messages" {
 # special_use = \Sent
 #}
}

A las carpetas comentadas Roundcube no las reconoce, pero puede ser que algún otro MUA sí lo haga.
Luego

# dovecot reload

y volvemos a entrar a Roundcube ya que las carpetas especiales son creadas al ingresar.

Sieve

Dovecot cuenta con un plugin llamado Managesieve que permite definir reglas de filtrado en el servidor IMAP, de modo que todos los clientes veran lo mismo independientemente de la plataforma.
Para habilitarlo, en /etc/dovecot/dovecot.conf agregamos:

protocol lmtp {
 mail_plugins = $mail_plugins sieve
 postmaster_address = administrador@midominio.edu.ar
}
plugin {
 sieve = file:~/sieve;active=~/.dovecot.sieve
}

Luego reiniciamos dovecot

# systemctl restart dovecot

Probamos la conexión

# telnet localhost 4190

Deberíamos obtener algo así

Connected to localhost.
Escape character is '^]'.
"IMPLEMENTATION" "Dovecot Pigeonhole"
"SIEVE" "fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date ihave"
"NOTIFY" "mailto"
"SASL" "PLAIN LOGIN"
"VERSION" "1.0"
OK "Dovecot ready."

lo cual significa que Sieve está funcionando. Hay que presionar Enter tres veces para salir.
Si surgen inconvenientes, es necesario verificar la configuración, reiniciar Dovecot y volver a intentar.

# doveconf -n

puede ayudar a comprobar errores de tipeo y cosas por el estilo.
Es posible crear reglas sieve predeterminadas. Esto tiene una enorme contra: tan pronto como el usuario crea sus propias reglas (por ejemplo, define una respuesta automática para cuando no está en la oficina) las reglas predeterminadas ya no son tenidas en cuenta aún luego de eliminar la regla personal.

Definir regla de spam de manera global

Vamos a definir una regla de spam global que moverá el spam automáticamente a la carpeta Basura del usuario.

sieve_default = /etc/dovecot/sieve/spamfilter.sieve

Esta carpeta y archivo son arbitrarios pero me parecieron lógicos.
Creamos la carpeta:

# mkdir /etc/dovecot/sieve

Cambiamos permisos ya que de no hacerlo dovecot se va a quejar.

# chown dovecot:dovecot /etc/dovecot/sieve/ -R

En /etc/dovecot/sieve/spamfilter.sieve

require ["fileinto"];
if header :contains "X-Spam-Flag" "YES" {
 fileinto "Junk";
}

Esta regla verifica un encabezado llamado ‘X-Spam-Flag’. Si contiene YES el mensaje es almacenado en la carpeta Basura.
Recargamos Dovecot y enviamos un mensaje con la cadena GTUBE para verificar si funciona.

Eliminar spam automáticamente luego de 30 días

Usando doveadm podemos eliminar automáticamente todo el correo en la carpeta Basura más antiguo que cierto tiempo, por ejemplo 30 días.
Doveadm es es la utilidad de administración de Dovecot. Con man doveadm se puede consulta por mayor información sobre la utilidad. Otra lectura relevante para este caso: man doveadm-search y man doveadm-search-query.
Digamos que queremos buscar todos los documentos en todas las bandejas de entrada de más de cuatro horas de antigüedad:

# doveadm search -A mailbox Inbox savedbefore 4h
administrador@midominio.edu.ar 74b4db2757f9f05661350000595b2a1f 1
administrador@midominio.edu.ar 74b4db2757f9f05661350000595b2a1f 2

-A significa revisar todas las casillas, no solo la especificada.
No queremos buscar solo la Bandeja de entrada y queremos correo de más de 30 días:

# doveadm search -A mailbox Junk savedbefore 30d
administrador@midominio.edu.ar 4adeeb2ca5c1ca565c3b000038e0142a 1
administrador@midominio.edu.ar 4adeeb2ca5c1ca565c3b000038e0142a 2
administrador@midominio.edu.ar 4adeeb2ca5c1ca565c3b000038e0142a 3

Para más información sobre el formato de consulta.

$ man doveadm-search-query

Pero no queremos buscar solamente sino eliminar esos correos. (Usamos search primero para verificar que obtenemos los resultados que estábamos esperando.)

# doveadm expunge -A mailbox Junk savedbefore 30d

Como seguramente no vamos a querer correr esto manualmente todos los días. Lo programamos:

# crontab -e

Agregamos esta línea:

@hourly /usr/bin/doveadm expunge -A mailbox Junk savedbefore 30d

En caso que no querramos recibir un aviso por correo sobre la salida de esta programación la cambiamos a

@hourly /usr/bin/doveadm expunge -A mailbox Junk savedbefore 30d > /dev/null 2>&1

Lo anterior ejecutará el comando cada hora. Cambiarlo a

@daily /usr/bin/doveadm expunge -A mailbox Junk savedbefore 30d > /dev/null 2>&1

hará que se ejecute cada día

Revisar la cola de correo de Postfix

Cuando un correo electrónico no se envía, termina en una de las dos colas dentro de Postfix: pending (pendiente) y deferred (diferido).
La cola de pendientes incluye todos los mensajes que has enviado a Postfix que aún no han sido enviados y entregados al servidor del destinatario. La cola de correo diferido contiene todos los mensajes que han fallado y se necesita reintentar enviarlos (fallo temporal).
Postfix intentará reenviar los mensajes de la cola diferida a intervalos establecidos. Esto está configurado a 5 minutos de manera predeterminada, pero este proceso es totalmente configurable.
Introduciendo cualquiera de los siguientes comandos, puedes inspeccionar y gestionar tus colas de mensajes de Postfix con facilidad.