====== 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 **[[spamassassin_private_dnsbl#configure_spamassassin|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 **B**usy ed altre richieste non sono state soddisfatte (lo stato dei child process può essere **I**dle, **S**tarting, **K**illed o **B**usy).
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:
- Test Bayes e network disabilitati
- Test Bayes disabilitati, test network abilitati
- Test Bayes abilitati, test network disabilitati
- 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