====== 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