Greylist e SPF con Exim e Postfix


Home Page | Commenti | Articoli | Faq | Documenti | Ricerca | Archivio | Storie dalla Sala Macchine | Contribuire | Login/Register

Al giorno d'oggi penso che non esista piu' nessun utente di Internet che non riceva la sua dose quotidiana di Spam+Virus. Esistono molti sistemi per riconoscere questi messaggi ed evitare di infettarsi la macchina (vedi SpamAssassin e ClamAV). Molti Provider offrono gia' un sistema di filtraggio di Spam e Virus. Chi invece ha il suo Server personale oppure lavora presso un Provider, deve cercare di difendersi da solo.

Per questi ultimi e' dedicato questo articolo. Infatti, sebbene si possa decidere di lasciare le E-Mail con Spam e/o Virus sul Server, si consuma banda in ogni caso (per riceverle).

Un buon modo per risparmiare la banda (che si paga!!) e' di bloccare sul nascere lo Spam e i Virus.

In questo ci aiutano le GreyList e il SPF!

Questo articolo spiega cosa sono questi due sistemi e come implementarli con Postfix ed Exim. Suppongo proprio che anche QMail offra questa possibilita', ma non conosco questo programma. Se invece usate Sendmail, il mio consiglio e' di passare ad un altro MTA al piu' presto...

DISCLAIMER:

Tutto quanto ho scritto in quest'articolo e' basato sulla mia esperienza personale e lavorativa. NULLA garantisce che anche voi riusciate a ottenere gli stessi risultati. Sebbene possa darvi qualche raro consiglio via E-Mail quando tenterete di usare questi sistemi, NON sono a vostra completa disposizione come consulente. Ho gia' abbastanza da fare con il MailCluster del Provider dove lavoro e NON ho tempo da dedicare anche a voi... NON mi potete ritenere altresi' responsabile di eventuali danni e/o perdite di E-Mail dovute all'utilizzo di questi sistemi!

Tutti conoscono le WhiteList (IP o indirizzi che vengono sempre accettati) e le Blacklist (IP o indirizzi che vengono sempre rifiutati). E' un inizio per difendersi dallo Spam, purtroppo ha il grande svantaggio di dover essere configurato e mantenuto MANUALMENTE! Inoltre questi sistemi ben poco possono nel caso che il mittente venga falsificato.

L'idea delle GreyList si basa su un concetto totalmente diverso, automatico e, per giunta, molto semplice!

In pratica: ogni MailServer che sia degno di tal nome mette le sue E-Mails in una coda, poi tenta di spedirle. Se ci riesce le cancella dalla coda, se non ci riesce, riprova fino al raggiungimento di un TimeOut (default: 5 Giorni). Gli Spammer, per contro, vista la mole enorme di messaggi che inviano (e visto che spesso usano PC-Zombie) NON hanno una coda. Il che vuol dire che, se il MailServer con il quale parlano rifiuta (anche temporaneamente!) l'E-Mail, NON ritentano di spedirla, come invece farebbe un qualsiasi MTA.

Quindi cosa fara' un MailServer che vuole proteggersi dallo Spam con questa tecnologia? Semplice: appena arriva un'E-Mail manda un "450 temporary reject". Quando poi l'E-Mail arriva di nuovo (dopo qualche minuto) la riconosce e la accetta. In questo modo viene filtrata una percentuale impressionante di Spam e Virus (sul mio Server personale, circa il 97%!! Ovviamente non do' nessuna garanzia che anche voi riuscirete a raggiungere questi risultati...).

A questo punto, la domanda e': come faccio ad identificare un'E-Mail per sapere se ha gia' provato ad essere spedita o meno?

Ci si basa su 3 elementi: E-Mail del mittente, E-Mail del destinatario e IP del mittente. Se questa tripla di elementi e' gia' conosciuta (si guarda in un DB!), allora la si accetta, se non e' conosciuta, si ritorna un "temporary reject".

Si puo' poi (e si fa cosi', normalmente!) configurare il sistema per rifiutare (sempre temporaneamente!!) le E-Mail per X secondi (normalmente e' 5 minuti). Cosi', se uno Spammer riprova subito a rispedire quell'E-Mail, non ci riuscira'. Se invece un Server riprova dopo quegli X secondi, tutto andra' in porto.

Addendum
Purtroppo anche le Greylist, come tutte le cose belle, ha un difetto, non tragico, ma pur sempre un difetto... Nel caso in cui il Server al quale voi SPEDITE un'E-Mail faccia un controllo sul VOSTRO Server (alcuni MTA son cosi' configurati in modo da controllare l'esistenza di un certo account sul Server dal quale ricevono l'E-Mail...) anche questo controllo viene messo in Greylist.

Lo scenario e' quindi il seguente:

  1. Il vostro Server A parla con il Server B per spedirgli un'E-Mail
  2. Il Server B vuole verificare che il vostro Server A effettivamente gestisca il dominio specificato in "MAIL FROM" e apre una sessione con il Server A, mandando "HELO", "MAIL FROM " e "RCPT TO "
  3. Il vostro Server A, se ancora non conosce quella tripla di indirizzi, manda il "Temporary failure"
  4. Il Server B NON e' riuscito a verificare il mittente della vostra E-Mail (che tentate di spediregli!) e la rifiuta...

Ovviamente, se ritentate DOPO il periodo da voi indicato per il Greylisting, la tripla sara' conosciuta e il Server B riuscira' a verificare il mittente...

L'alternativa, visto che la maggioranza dei programmi, in caso di verifica, cerca di controllare l'esistenza dell'account e' di disattivare l'uso delle Greylist per questo account.

SPF, ossia Sender Policy Framework e' un sistema per identificare esattamente i Servers che sono autorizzati a spedire le E-Mail per un certo dominio.
Normalmente, nelle informazioni del DNS di un dominio, esiste almeno un record MX (Mail-Exchange), ossia il Server che deve essere usato per mandare E-Mail a quel dominio.

SPF implementa l'altra direzione, ossia dice: "guarda che le E-Mail per il dominio xyz.de arriveranno da questi Servers! Non accettare E-Mail @xyz.de da altri!!".

Visto che, ovviamente, non e' possibile (almeno in breve tempo) rivoluzionare completamente lo standard del DNS per aggiungere un nuovo campo, si e' deciso di sfruttare il record TXT che consente di scrivere un testo a piacere.

Secondo una sintassi abbastanza semplice (dettagli su http://www.openspf.org) si scrive in un record TXT quali Servers sono abilitati a mandare E-Mails. Per esempio, se si interroga mydomain.de configurato per offrire informazioni di SPF, otterremo quanto segue (ovvio che mydomain.de e' del tutto inventato per scopi dimostrativi!!):

[lucabert@lucabert lucabert]$ dig +short -t txt mydomain.de 
"v=spf1 a mx -all"

Questa riga contiene le informazioni per l'SPF. Tradotto in linguaggio umano significa:

Avrei anche potuto scrivere un ulteriore campo (mx:<server>) per dire da quali (altri) Servers possono venire spedite le E-Mails.

Sul sito di OpenSPF c'e' un ottimo Wizard per ottenere le informazioni da scrivere nel proprio DNS, con tanto di istruzioni per vari programmi, quindi non sprechero' altro tempo per descrivere il sistema.

Il punto, comunque, e' che il MailServer che riceve l'E-Mail diciamo da test@mydomain.de (per fare un esempio) potra' verificare se l'IP dal quale arriva l'E-Mail e' tra quelli che io (come "dnsmaster") ho autorizzato per spedire le mie E-Mails. Se non e' cosi', puo' tranquillamente rifiutare l'E-Mail e chiudere la porta in faccia allo Spammer.

Addendum
Purtroppo, anche l'SPF ha un difetto: nel momento in cui si ha una casella di posta che rimbalza le mail ad un'altro indirizzo (un forward in pratica), e il server del mittente (non necessariamente il nostro) offre le informazioni dell'SPF e si verifica quanto segue:

  1. la mail viene spedita dal mittente e ricevuta dal vostro server
  2. la mail viene rigirata all'indirizzo di destinazione, mantenendo pero' mittente e destinatario
  3. il server che riceve la mail controlla le informazioni del mittente, che non e' il nostro server e, visto che proviene da ip diverso la rifiuta.

Il problema si verifica sia che il nostro server faccia il controllo SPF o meno, basta avere un forward attivo. Che io sappia esistono solo due modi per risolvere il problema:

  1. Non rimbalzare la mail
  2. Riscrivere il mittente prima di forwardare la posta

Vediamo ora come possiamo implementare il meccanismo delle Greylist usando Postfix.

Postfix adotta un sistema di Plugin per gestire vari meccanismi non direttamente implementati nel sistema. Questo si traduce in una riga modificata nel file main.cf e un paio di aggiunte in master.cf.

Per prima cosa, pero', e' necessario scaricare un programma che gestisca il sistema. Come semplicita' e prestazioni, io mi sono trovato bene con GPS (http://mimo.gn.apc.org/gps). Scaricatelo e compilatelo (e' in C), poi seguite le istruzioni per creare il DB. Un esempio di file di configurazione e' il seguente:

mode=normal
dbtype=
db_host=
db_username=
db_password=
db_dbname=
timeout=300
wl_recipient=dbcached
wl_network=db
wl_sender=off
wl_pattern=dbcached

La prima volta che si usa GPS occorre mettere "mode=init" al posto di "normal" in modo da fargli creare automaticamente le tabelle che gli servono. Poi e' possibile ristabilire "normal".

Ora e' necessario dire a Postfix come deve fare per trattare le E-Mail in arrivo. Nel file main.cf occorre modificare la riga con smtpd_recipient_restrictions e aggiungere:

smtpd_recipient_restrictions = , check_policy_service unix:private/greypolicy

Ovviamente, questa policy dev'essere messa DOPO l'accept per gli utenti che si sono autentificati, altrimenti verrebbero anche loro rifiutati... Quindi, in master.cf si aggiunge quanto segue:

greypolicy  unix  -       n       n       -       -       spawn
      user=nobody argv=/usr/local/bin/gps /etc/gps.conf

Ovviamente, con i Path per GPS e il suo file di configurazione che avete nel vostro sistema.

Riavviate Postfix (o fare un reload della configurazione), et voila'! Il vostro MailServer ora gestisce le GreyList! Per fare una prova, potete usare telnet sulla porta 25. Dovreste vedere qualcosa di simile:

[lucabert@lucabert lucabert]$ telnet mail.mydomain.de smtp
Trying XX.YY.ZZ.KK...
Connected to mail.mydomain.de (XX.YY.ZZ.KK).
Escape character is '^]'.
220 mail.mydomain.de ESMTP
helo smtp
250 mail.mydomain.de Hello smtp [X1.Y1.Z1.K1]
mail from: pippo@hotmail.com
250 OK
rcpt to: test@mydomain.de
450 : Recipient address rejected
quit
221 mail.mydomain.de closing connection
Connection closed by foreign host.

Se provate dopo 5 minuti (cosi' ho scritto in gps.conf) otterrete dopo rcpt un bellissimo accepted! Per mantenere il DB abbastanza pulito, occorre mettere nel crontab i programmi che effettuano la pulizia del DB (uno script in PERL). E' tutto molto ben descritto nel ReadMe di GPS!

attenzione:
Queste istruzioni sono valide per Exim a partire dalla versione 4.50!! NON ho la piu' pallida idea se funzionino con le versioni precedenti!!

Con Exim e' forse lievemente piu' complicato, ma sicuramente e' possibile gestire il sistema in maniera molto piu' flessibile (e' ben per questo che ho deciso di passare da Postfix ad Exim...). Per prima cosa e' necessario scaricare un programma che gestisca le GreyList. Uno molto usato lo si trova (in due parti!) a questi indirizzi: http://users.aber.ac.uk/auj/spam/Greylist.pm.txt http://users.aber.ac.uk/auj/spam/exim_sockd.pl.txt

Una versione leggermente modificata da me, in modo che il programma venga lanciato come demone, la si puo' trovare nella sezione Download del mio sito http://www.lucabert.de/myProgram/listPrograms.php?lang=it

Una volta scompattato il file da qualche parte e messo i giusti valori in Greylist.pm per l'accesso al DB, potete copiare i due files in /usr/local/bin Scrivete uno start-stop-script per il vostro sistema e fate in modo che venga avviato all'accensione della macchina (con il parametro --daemon). Create il DB secondo lo schema contenuto in Greylist.pm e, infine, lanciate il programma!

A questo punto occorre dire ad Exim che deve appoggiarsi a questo programma per gestire le Greylist.

Nel vostro file configure aggiungete queste righe (DOPO la sezione che accetta le E-mail dall'utente che si e' autentificato!!!):

NOTA: il codice qui' riportato ha le parti "set" e "message" su piu' righe per questioni di leggibilita'.


  # Greylisting
  warn    domains        = +local_domains
          recipients     = !/etc/exim/nogreylist
          set              acl_m3 = ${readsocket{/var/run/greylistd.sock} \
                           {GREYLIST ${lc:$sender_address} \
                           ${lc:$local_part@$domain} \
                           $sender_host_address}{3s}{\n}{0}}

  warn    domains        = +local_domains
          recipients     = /etc/exim/nogreylist
          set              acl_m3 = 0

  defer   domains        = +local_domains
          condition      = ${if eq {$acl_m3}{0}{0}{1}}
          message        = Greylisted for ${if < {$acl_m3}{119} \
                           {${eval:$acl_m3/60} minutes}{$acl_m3 seconds}}. \
                           \nYour mail system should automatically try \
                           again later.

          log_message    = Greylisted $acl_m3

In questo modo TUTTI gli utenti del vostro sistema useranno le Greylist, eccetto i Recipient (ALIAS!!! Non Account!!) contenuti nel file /etc/exim/nogreylist che, ovviamente, deve contenere meno indirizzi possibile. Il mio, per esempio, e' VUOTO e tale rimarra'!

Riavviate Exim e fate la stessa prova che ho descritto con Exim. A parte i messaggi lievemente diversi, il risultato sara' identico!

Il programma che avete scaricato e lanciato comprende anche un paio di opzioni per tenere pulito il DB.

E' opportuno mettere in crontab almeno una volta al giorno la pulizia del DB. Nella versione da me modificata, questo lo si ottiene lanciando il comando "/usr/local/bin/greylistd.pl --cleanup". Altrimenti dovete scrivervi voi qualcosa che usa la funzione cleanup offerta da Greylist.pm

Greylist.pm consente anche di "dimenticare" un IP (funzione forget, accessibile con la mia versione modificata tramite l'opzione --forget). Questo si rivela utile nel caso che un Server che normalmente funziona bene, improvvisamente venga crackato e tenti di spedire Spam. Ammetto che non penso che questa funzione verra' usata molto...

Come detto precedentemente, Postfix gestisce i vari Addons come plugin. Anche per le SPF e' quindi necessario usare un nuovo Plugin.

Con Postfix (almeno nella versione 2.2.8) e' gia' fornito un programma che fa al caso nostro. Nei sorgenti, si cerchi nella directory examples/smtpd-policy e si trovera' il file spf.pl

Occorre installare il modulo Mail::SPF::Query che si trova in CPAN o in http://spf.pobox.com/downloads.html e modificare leggermente il file secondo quanto scritto proprio nelle prime righe. Copiate poi questo file dove vi pare.

A questo punto, modificate il vostro main.cf come segue:

smtpd_recipient_restrictions = , check_policy_service unix:private/spfpolicy

Anche in questo caso, questa policy dev'essere DOPO l'accept per gli utenti che si sono autentificati! Nel caso usiate anche le Greylist, e' meglio mettere questa policy PRIMA di quella delle Greylist, cosi' mandare la richiesta di Greylisting solo nel caso in cui il mittente sia autorizzato dall'SPF.

Quindi aggiungete in master.cf le seguenti righe:

spfpolicy   unix -      n       n       -       -       spawn
      user=nobody argv=/usr/bin/perl /opt/postfix/libexec/spf.pl

ovviamente con il path corretto!

Riavviate Postfix ed il sistema e' pronto! A questo punto, un tentativo di falsificazione di mittente verra' riconosciuto (se il mittente "vero" ha messo le informazioni di SPF nel DNS) e rifiutato.

Attenzione:
Queste istruzioni sono valide per Exim a partire dalla versione 4.50!! NON ho la piu' pallida idea se funzionino con le versioni precedenti!!

Con Exim la cosa e' ancora piu' semplice. Occorre pero' ricompilare Exim per usare le SPF. Per prima cosa installate le libspf2 (con un vostro package manager o scaricandole da http://www.libspf2.org/). Poi, nel file Local/Makefile di Exim, aggiungete le seguenti righe:

EXPERIMENTAL_SPF=yes
CFLAGS  += -I/usr/include
LDFLAGS += -L/usr/lib -lspf2

Ovviamente con i path corretti.

Ricompilate Exim e installate la nuova versione. A questo punto, nel file configure aggiungete le seguenti righe (sempre DOPO la sezione che accetta le E-mail dall'utente che si e' autentificato!!!):

  deny   message         = [SPF] $sender_host_address is not allowed to send mail from $sender_address_domain
         domains         = +local_domains
         log_message     = SPF check failed.
         spf             = fail

Riavviate Exim ed il gioco e' fatto!

Per fare un esempio, ecco cosa succede quando si tenta di mandare un'E-Mail spacciandosi per qualcun'altro, per esempio @gmx.de (che implementa il SPF). Ovviamente faccio questa prova da un IP che NON e' tra quelli autorizzati da GMX...

[lucabert@lucabert lucabert]$ telnet mail.mydomain.de smtp
Trying XX.YY.ZZ.KK...
Connected to mail.mydomain.de (XX.YY.ZZ.KK).
Escape character is '^]'.
220 mail.mydomain.de ESMTP Exim 4.60 Thu, 26 Jan 2006 11:55:24 +0100
helo smtp
250 mail.mydomain.de Hello smtp [X1.Y1.Z1.K1]
mail from: pippo@gmx.de
250 OK
rcpt to: test@mydomain.de
550 [SPF] 213.174.32.254 is not allowed to send mail from gmx.de
quit
221 mail.mydomain.de closing connection
Connection closed by foreign host.

Sebbene le GreyList e il SPF consentano di ridurre drasticamente lo Spam, il buon amministratore di sistema NON DEVE MAI abbassare la guardia.

Per quanto SPF sia sicuro e difficilmente aggirabile, prima o poi gli Spammer troveranno il modo di aggirare le GreyList (semplicemente implementando una coda...).

Un buon controllo sulle E-Mail che vengono effettivamente ricevute, per esempio con SpamAssassin e ClamAV (o un altro antivirus), e' SEMPRE SICURAMENTE un'OTTIMA idea!

Ultimamente ho cominciato a ricevere Spam da IP e indirizzi E-Mail teoricamente inaccettabili, tipo E-Mail @verizon.net o @gmail.com da IP sicuramente NON appartenenti alle loro reti.

Dopo un rapido controllo ho potuto notare che il problema e' originato dalla stupidita' degli amministratori di Verizon e di GMail. Questi elementi hanno scritto quanto segue:

verizon.net text "v=spf1 ip4:206.46.232.0/24 ip4:206.46.170.0/24
ip4:206.46.252.0/24 ip4:206.46.128.33 ip4:206.46.128.101 ip4:209.84.13.21
ip4:209.84.13.20 ?all"

GMail ha un record simile e anche AOL (anche se, finora, non ho ricevuto Spam simile da AOL) e suppongo che non siano i soli... In pratica, hanno dato una lista abbastanza dettagliata di Servers e reti dai quali accettare le connessioni e poi hanno messo quel "?all" alla fine che significa, in linguaggio umano, "se pero' le connessioni arrivano da altri IP, ignora quanto ti ho detto e accetta l'E-Mail".

Ovviamente gli Spammer non si sono lasciati sfuggire l'occasione e hanno cominciato a spedire E-Mail falsificate da indirizzi @verizon.net e @gmail.com (o @googlemail.com), approfittando del fatto che i Servers che fanno il controllo SPF avrebbero accettato le loro E-Mails.

Dopo un breve studio del problema, ho gia' individuato la soluzione che NON e' bella, ma e' almeno funzionale.

In pratica, libspf2 nel caso di un'E-Mail che arriva da un IP non compreso nella lista dei Server e il cui dominio usi "?all", ritorna "neutral" al posto di "pass". A questo punto basta far reagire l'MTA anche al neutral, almeno per alcuni domini e il problema e' tamponato. Ovviamente, cosi' facendo si rischia anche di bloccare E-Mail valide spedite da altri Servers non compresi nella lista SPF del dominio del mittente... Occorre scegliere cosa fare in base alla propria esperienza. Se ancora non vi capitano Spam da questi indirizzi, non fate niente o implementate il sistema il maniera profilattica senza pero' inserire nessun dominio nella lista di questo controllo aggiuntivo.

Nel caso del Provider presso il quale lavoro non potevamo far finta di niente visto che, mediamente, ricevevamo 25.000 E-Mail al giorno da questi Spammers...

Exim

Con Exim e' abbastanza semplice ovviare al problema. Basta aggiungere questa sezione dopo quella gia' descritta prima per l'SPF:

  deny   spf             = neutral
         sender_domains  = /etc/exim/fakespf
         domains         = +local_domains
         recipients      = !/etc/exim/alwaysreceive
         message         = [SPF] $sender_host_address is not allowed to send \
                           mail from $sender_address_domain
         log_message     = SPF check failed.

Potete notare questi due files (/etc/exim/fakespf e /etc/exim/alwaysreceive). Il primo contiene la lista dei domini da sottoporre a questo controllo aggiuntivo, il secondo la lista degli Alias che potranno comunque ricevere E-Mail che, secondo il controllo, andrebbero rifiutate. Tipicamente, alwaysreceive contiene l'indirizzo del postmaster cosi' che i mittenti "reali" possano comunicarvi che state bloccandogli invii legittimi. Il mio fakespf, attualmente, contiene i seguenti domini:

verizon.net
googlemail.com
gmail.com
aol.com

Tutto qui!

Postfix

ATTENZIONE: questa parte NON e' basata sulla mia esperienza personale in quanto ora uso Exim come MTA. DOVREBBE funzionare, ma non do' nessuna garanzia!!

Per Postfix la cosa si fa un po' piu' complicata visto che non e' possibile agire su nessuna configurazione. In questo caso occorre patchare il programmino PERL che fa il controllo. Un sistema molto incompleto e' l'aggiungere la seguente riga nella funzione sender_permitted_from in modo da bloccare anche i neutral:

  elsif ($result eq "neutral")  { return "REJECT " . ($smtp_comment ||
$header_comment); }

Ovviamente in questo caso non c'e' nessuna lista di esclusione. Tutte le E-Mail che avranno un neutral verranno bloccate. Prima o poi mi mettero' a scrivere una buona patch per questo programma in modo da avere tutte le possibilita' offerte da Exim. Non ci vuole molto, solo un po' di tempo che, ora come ora, mi manca. Se qualcuno vuole scriverla, ben venga! :)


I commenti sono aggiunti quando e soprattutto se ho il tempo di guardarli e dopo aver eliminato le cagate, spam, tentativi di phishing et similia. Quindi non trattenete il respiro.

1 messaggio this document does not accept new posts
Alessandro Porcu Di Alessandro Porcu - postato il 23/12/2010 04:55

Articolo interessantissimo, e visto che il mio serverino ha deciso che non vuole arrivare alla fine dell'anno, e in quello nuovo mi faro' sicuramente anche il server di posta, queste informazioni mi veranno certamente molto utili.

--
Alessandro Porcu


Precedente Successivo

Luca Bertoncello ha lavorato come responsabile del MailCluster per un Internet Service Provider in Dresden (Germania), specializzandosi nella configurazione di Exim, SpamAssassin e Clam e nella gestione di Clusters basati su Heartbeat e DRBD.
Attualmente lavora per una ditta che gestisce campagne pubblicitarie su Internet (no, non e' uno spammer :D) come programmatore e sistemista.
E' completamente paranoico... :)
Maggiori informazioni sul suo sito: http://www.lucabert.de/

Volete contribuire? Leggete come!.
 
 

Il presente sito e' frutto del sudore della mia fronte (e delle mie dita), se siete interessati a ripubblicare uno degli articoli, documenti o qualunque altra cosa presente in questo sito per cortesia datemene comunicazione (o all'autore dell'articolo se non sono io), cosi' il giorno che faccio delle aggiunte potro' avvisarvi e magari mandarvi il testo aggiornato.


Questo sito era composto con VIM, ora e' composto con VIM ed il famosissimo CMS FdT.

Questo sito non e' ottimizzato per la visione con nessun browser particolare, ne' richiede l'uso di font particolari o risoluzioni speciali. Siete liberi di vederlo come vi pare e piace, o come disse qualcuno: "Finalmente uno dei POCHI siti che ancora funzionano con IE5 dentro Windows 3.1".

Web Interoperability Pleadge Support This Project
Powered By Gort