Combattiamo lo spam con sqlgrey

Uno dei principali problemi con cui un amministratore di server deve combattere è lo spam.
Purtroppo il fenomeno dello spam non è in diminuzione, anzi, e per combatterlo dobbiamo attrezzarci armandoci di infinita pazienza: difatti le regole antispam che un SysAdmin può applicare sono molteplici e scegliere quali applicare è un compromesso che non soddisferà mai la totalità degli utenti.

Un filtro molto utile che porta pochi problemi è il greylist. Questo sistema si basa su un principio ancora valido: lo spammer, per monetizzare, deve avere subito riscontro di quante mail sono arrivate a destinazione, pertanto se una consegna fallisce non sarà più ritentata. In maniera totalmente opposta funzionano i server tradizionali: se il server del destinatario ha un problema temporaneo, il mail server mittente riproverà ad inviare l’email successivamente.

Nella pratica, quando un server su cui funzona il greylisting è attivo riceve una email, viene controllata la “tripletta” formata da email mittente/indirizzo IP mittente/email destinatario per vedere se è la prima volta che accade questo evento. Se è la prima volta, l’email viene respinta con un errore temporaneo e la ricezione rimane bloccata per un tempo predefinito (solitamente 1 minuto), altrimenti, se non è la prima volta e se il minuto di blocco dal primo invio è passato, l’email viene accettata.

Se si hanno più mail server in ricezione (MX) è importantissimo che tutti siano configurati con il greylisting, altrimenti il sistema risulta inefficace. Inoltre tutti i server MX devono utilizzare un unico database per memorizzare le triplette, altrimenti si corre il rischio di continuare a respingere le mail.

Una implementazione del greylisting che soddisfa questi requisiti è sqlgrey: difatti questo sistema memorizza le triplette su un database SQL che pertanto può essere condiviso tra i server MX.

Vediamo come configurare il servizio: nella nostra installazione utilizzeremo un server MySQL centralizzato all’indirizzo mysql.dominio.local e un mirror locale del datatabase configurato come slave con la classica replica MySQL in modo da minimizzare il carico di lavoro sul master. Con questa configurazione tutte le query in scrittura andranno sul master, mentre le query in lettura (più numerose e dispendiose) saranno solo locali.

Innanzi tutto modifichiamo il file di configurazione /etc/sqlgrey/sqlgrey.conf:

<strong>/etc/sqlgrey/sqlgrey.conf</strong>
reconnect_delay = 5
max_connect_age = 24
awl_age = 32
group_domain_level = 10
db_type = mysql
db_name = sqlgrey
db_host = mysql.dominio.local
db_port = default
db_user = sqlgrey
db_pass = PasswordSQLgrey
db_cluster = on
read_hosts=localhost
db_cleanup_hostname = localhost
admin_mail = server@domino.local
greymethod = classc

Una cosa importante in questa configurazione è il fatto che abbiamo settato il greymethod a classic: è il metodo più tranquillo, in grado di generare il minor numeri di blocchi.
Difatti questo valore può essere settato a full che memorizza l’ip del mittente, classic che memorizza l’intera classe C (/24) e smart che memorizza l’intera classe C se non riesce a fare il reverse lookup. In pratica, così facendo, saremo certi che se un mittente utilizza più server per la spedizione in round robin, non corra il rischio di rimanere bloccato in un “circolo vizioso”

Quindi creiamo il database sul server MySQL:

# mysql -u root -p
mysql> create database sqlgrey ;
mysql> grant all on sqlgrey.* to sqlgrey@'%' identified by 'PasswordSQLgrey';

e la copia locale:

# mysql -u root -p
mysql> create database sqlgrey ;
mysql> grant all on sqlgrey.* to sqlgrey@'localhost' identified by 'PasswordSQLgrey';

Tralascio la configurazione della replica master/slave: in quest’articolo potete trovare le istruzioni per configurare la replica master/master.

Infine modifichiamo il file /etc/postfix/main.cf aggiungendo la seguente riga:

...
smtpd_recipient_restrictions =
....
check_policy_service inet:127.0.0.1:2501,
...

Il mio consiglio è di utilizzare il greylisting come ultimo controllo, lasciando prima quelli più performanti in modo da evitare inutili query sul database.