User Tools

Site Tools


doc:appunti:linux:sa:spamassassin

SpamAssassin

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.

Troubleshooting

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.

Custom rules

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

Problema con URIBL

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.

whitelist_from

Volendo mettere alcuni mittenti in whitelist è possibile fare quanto segue:

  • Aggiungere una riga a /etc/spamassassin/local.cf, che contenga:
    include whitelist_from
  • Creare il file /etc/spamassassin/whitelist_from che contiene righe del tipo
    whitelist_from nome@dominio.org
    whitelist_from *@dominio.org
    whitelist_from *.dominio.org

Riavviare spamassassin.

Regole personalizzate

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.

AutoWhitelist

È 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'

server reached --max-children setting

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.

Punteggio SPAM

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:

  1. Test Bayes e network disabilitati
  2. Test Bayes disabilitati, test network abilitati
  3. Test Bayes abilitati, test network disabilitati
  4. Test Bayes e network abilitati

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.

Verifica punteggio

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

Client spamc e IPv6

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
doc/appunti/linux/sa/spamassassin.txt · Last modified: 2021/07/08 12:19 by niccolo