Nuova pagina di appunti dedicata a SpamAssassin, basata sull'esperienza con SpamAssassin 3.2.4 su Debian Lenny.
Si è deciso di chiamare SpamAssassin non come filtro del programma di posta (Exim), ma come filtro sulla consegna in mailbox tramite procmail(1)
. Questo consente una migliore personalizzazione del sistema antispam per ogni singolo utente.
Come di consueto si installa la versione daemon (più performante) spamd e il relativo client spamc.
Come verificare cosa funziona e cosa no. Grazie a spamassassin –help
oppure a man spamassassin-run
si scopre il comando:
spamassassin --lint -D
che visualizza tanti messaggi di debug relativi al set di regole, riportando errori di sintassi ecc.
Per testare il funzionamento del filtro su un messaggio si esegue semplicemente:
cat messaggio_spam.txt | spamc | less
È possibile avere un rapporto dettagliato dell'analisi con i punteggi ottenuti dalle singole regole con il comando:
spamassassin -t < messaggio.txt
La scansione non passa per spamd
, ma lancia un'istanza di spamassassin per la singola esecuzione. La configurazione usata dovrebbe essere quella di sistema in /etc/spamassassin
. Utile ad esempio per testare delle variazioni sui punteggi assegnati tramite regole inserite in /etc/spamassassin/local.cf
.
Di norma non è possibile aggiungere delle regole personalizzate nella user_prefs
di un utente. Ci sono motivi di sicurezza e di performance. Solo in casi eccezionali vale la pena di intervenire sul parametro allow_user_rules
.
In alternativa si può cambiare il punteggio assegnato ad una regole, per fare tutti i necessari esperimenti. Ad esempio la regola DRUG_ED_SILD
scatta se il testo del messaggio contiene la parola sildenafil, possiamo dare un punteggio diverso con:
score DRUG_ED_SILD 10.8
Un messaggio contenente un link blacklisted non viene intercettato dalle regole URIBL_*, scopriamo perché. Anzitutto vediamo quali test vengono effettuati:
cat messaggio_spam.txt | spamc -y AWL,BAYES_00
Hanno dato risultati solo i test Auto-whitelist e Bayesian spam probability, mancano i risultati dei test URIBL_*.
Quando i test URIBL_ danno dei risultati si ha un output di questo tipo:
cat messaggio_spam.txt | spamc -y RDNS_NONE,SPF_PASS,URIBL_AB_SURBL,URIBL_BLACK,URIBL_JP_SURBL, URIBL_OB_SURBL,URIBL_SBL,URIBL_SC_SURBL,URIBL_WS_SURBL
e anche un dump delle richieste DNS originate dal server può rivelare se i test vengono effettuati:
tcpdump -i eth1 -n 'port 53' ... > 206.222.12.226.53: 62184% [1au] A? 26.16.57.88.plus.bondedsender.org. (62) ... > 209.67.211.202.53: 41563% [1au] TXT? 26.16.57.88.bl.spamcop.net. (55) ... > 217.23.130.99.53: 26316% [1au] TXT? 26.16.57.88.list.dsbl.org. (54)
Invece di passare per spamc/spamd proviamo a passare direttamente per spamassassin, si scopre che in questo caso i test URIBL vengono fatti:
cat messaggio_spam.txt | spamassassin | less
Riavviando il demone spamd il problema si risolve, quindi esiste qualche condizione (insufficienza di RAM?) che avvelena il demone senza ucciderlo del tutto, rendendolo quasi del tutto inefficace.
Volendo mettere alcuni mittenti in whitelist è possibile fare quanto segue:
/etc/spamassassin/local.cf
, che contenga: include whitelist_from
/etc/spamassassin/whitelist_from
che contiene righe del tipo whitelist_from nome@dominio.org whitelist_from *@dominio.org whitelist_from *.dominio.org
Riavviare spamassassin.
Si possono aggiungere delle regole personalizzate direttamente in /etc/spamassassin/local.cf
oppure in un file incluso da esso con la direttiva include
.
Ecco una semplice regola che controlla la presenza di un determinato header Sender:
ed assegna un punteggio negativo (diminuendo cioè la possibilità che sia identificarlo come SPAM):
header LOCAL_SENDER_GOOGLE_CALENDAR Sender =~ /calendar-notification\@google\.com/ describe LOCAL_SENDER_GOOGLE_CALENDAR Sender is Google Calendar score LOCAL_SENDER_GOOGLE_CALENDAR -2.8
Fare attenzione alla stringa dopo il segno =~
, si tratta di un'espressione regolare racchiusa tra slash. Alcuni caratteri come il punto e il simbolo @ devono essere preceduti da backslash perché sono simboli speciali nelle espressioni regolari.
Un altro esempio per penalizzare certi top level domain particolarmente utilizzati dagli spammer:
header LOCAL_FROM_SPAMMER_TLD From =~ /@[a-z0-9\-\.]+\.(cam|top|xyz)/i describe LOCAL_FROM_SPAMMER_TLD Domain originates a lot of spam score LOCAL_FROM_SPAMMER_TLD 4.0
Vedere anche il paragrafo come utilizzare una blacklist DNS con SpamAssassin.
È possibile impostare forzatamente un punteggio SPAM molto alto (+100) o molto basso (-100) per un particolare indirizzo email nel proprio database $HOME/.spamassassin/auto-whitelist
:
spamassassin --add-addr-to-blacklist='spammer@spam.net' spamassassin --add-addr-to-whitelist='niccolo@rigacci.org'
Per togliere l'indirizzo dal database si usa:
spamassassin --remove-addr-from-whitelist='niccolo@rigacci.org'
Qualche volta si trova nel file di log il messaggio di warning:
spamd[8175]: prefork: server reached --max-children setting, consider raising it spamd[874]: bayes: cannot open bayes databases /home/.../.spamassassin/bayes_* R/W: lock failed: Interrupted system call spamd[8175]: prefork: server reached --max-children setting, consider raising it
Debian mette in /etc/default/spamassassin
l'opzione –max-children 5
e sconsiglia di modificarla. Per capire in quali circostanze avviene il problema eseguiamo il comando:
grep "prefork: child state" /var/log/syslog | less Jan 20 16:08:28 spamd[7122]: prefork: child states: II Jan 20 16:09:31 spamd[7122]: prefork: child states: II Jan 20 16:10:45 spamd[7122]: prefork: child states: II Jan 20 16:10:50 spamd[7122]: prefork: child states: BB Jan 20 16:10:50 spamd[7122]: prefork: child states: BBB Jan 20 16:10:50 spamd[7122]: prefork: child states: BBBB Jan 20 16:10:50 spamd[7122]: prefork: child states: BBBIB Jan 20 16:10:54 spamd[7122]: prefork: child states: BBBBB Jan 20 16:10:58 spamd[7122]: prefork: child states: BBBBB Jan 20 16:11:02 spamd[7122]: prefork: child states: BBBBB Jan 20 16:11:03 spamd[7122]: prefork: child states: BBBBB Jan 20 16:11:06 spamd[7122]: prefork: child states: BBBBB Jan 20 16:11:06 spamd[7122]: prefork: child states: BBBBI Jan 20 16:11:08 spamd[7122]: prefork: child states: BBIBI Jan 20 16:11:08 spamd[7122]: prefork: child states: IBIBI Jan 20 16:11:08 spamd[7122]: prefork: child states: IBIB Jan 20 16:11:09 spamd[7122]: prefork: child states: IBII Jan 20 16:11:09 spamd[7122]: prefork: child states: IBI Jan 20 16:11:10 spamd[7122]: prefork: child states: III Jan 20 16:11:10 spamd[7122]: prefork: child states: II Jan 20 16:12:59 spamd[7122]: prefork: child states: II Jan 20 16:13:10 spamd[7122]: prefork: child states: II
Come si vede si è verificato un burst di mail durato circa 20 secondi durante il quale i 5 processi figli erano Busy ed altre richieste non sono state soddisfatte (lo stato dei child process può essere Idle, Starting, Killed o Busy).
A seconda dei casi si può aumentare il numero dei processi figli oppure renderli più veloci. Ad esempio l'accesso alle preferenze dell'utente contenute in $HOME/.spamassassin/
probabilmente non è concorrente e blocca i processi successivi. Forse spostare le preferenze in un database potrebbe migliorare le prestazioni.
In una installazione Debian (es. 9 Stretch) i file che definiscono il punteggio SPAM sono in /var/lib/spamassassin/*/updates_spamassassin_org/, ad esempio nel file 50_scores.cf.
Una regola che assegna punteggio SPAM può includere 4 punteggio distinti, esempio:
score SUBJ_ALL_CAPS 0.518 1.625 1.197 1.506
I 4 valori sono rispettivamente per queste condizioni:
In generale viene applicato il punteggio del quarto caso: tutti i test abilitati.
Per attivare i test Bayes bisogna includere nel file di configurazione use_bayes 1.
I test network sono disabilitati se il demone spamd viene avviato con l'opzione -L
oppure --local
.
Con il seguente script dovrebbe essere possibile verificare il punteggio associato per ciascun test:
#!/bin/sh TESTS="$1" if [ -z "$TESTS" ]; then echo "Usage: $(basename $0) [rule1,rule2,...]" exit 1 fi cat << EOF === Punteggio SpamAssassin === * Test Bayes e network disabilitati * Test Bayes disabilitati, test network abilitati * Test Bayes abilitati, test network disabilitati * >>> Test Bayes e network abilitati EOF TESTS="$(echo "$TESTS" | sed 's/,/ /g')" for TEST in $TESTS; do find /var/lib/spamassassin/ -name "*scores.cf" | while read file; do SCORE="$(egrep "^score\s+${TEST}\b" "$file")" if [ -n "$SCORE" ]; then #echo "$SCORE" RULE="$(echo "$SCORE" | awk '{print $2}')" SCORE1="$(echo "$SCORE" | awk '{print $3}')" SCORE2="$(echo "$SCORE" | awk '{print $4}')" SCORE3="$(echo "$SCORE" | awk '{print $5}')" SCORE4="$(echo "$SCORE" | awk '{print $6}')" printf '%-25s %7.2f %7.2f %7.2f %7.2f\n' "$RULE" "$SCORE1" "$SCORE2" "$SCORE3" "$SCORE4" fi done done
Ecco un esempio di utilizzo:
./spamassassin-score-print HELO_NO_DOMAIN,HTML_MESSAGE,NICE_REPLY_A,RDNS_NONE,SPF_FAIL === Punteggio SpamAssassin === * Test Bayes e network disabilitati * Test Bayes disabilitati, test network abilitati * Test Bayes abilitati, test network disabilitati * >>> Test Bayes e network abilitati HELO_NO_DOMAIN 0.00 4.40 0.00 4.40 HTML_MESSAGE 0.00 0.00 0.00 0.00 NICE_REPLY_A -0.25 -0.00 -0.25 -0.00 RDNS_NONE 2.40 1.27 1.23 0.79 SPF_FAIL 0.00 0.92 0.00 0.00
Per impostazione predefinita il client spamc tenta di connettersi al demone Spamassassin usando il nome localhost, che potrebbe tradursi nell'indirizzo IPv6 ::1, se il demone non è in ascolto su quel socket si ottiene l'errore:
spamc[16810]: connect to spamd on ::1 failed, retrying (#1 of 3): Connection refused
Per forzare (system-wide) l'utilizzo di IPv4 si può creare /etc/spamassassin/spamc.conf
mettendo:
-d 127.0.0.1