User Tools

Site Tools


doc:appunti:linux:sa:dspam

This is an old revision of the document!


Dspam

Perché usare dspam invece di SpamAssassin?

Il problema è che SpamAssassin impiega molto tempo per analizzare ciascun messaggio di mail. Ad esempio su un Pentium4 3.2 GHz con 2Gb RAM impiega in media 3.43 secondi per messaggio su un campione di 1116 messaggi ricevuti nell'arco di 24 ore.

Questo significa che nei momenti di burst si incappa facilmente nei limiti del MTA, ad esempio Exim smette temporaneamente di ricevere con l'errore SMTP:

421 Too many concurrent SMTP connections: please try again later.

oppure SpamAssassin non riesce ad effettuare il lock su un file utente e genera l'errore:

spamd[1259]: bayes: cannot open bayes databases /home/.spamassassin/bayes_* R/W: lock failed: Interrupted system call

oppure ancora si incappa nell'errore

spamd[7122]: prefork: server reached --max-children setting, consider raising it

Installazione su Debian Lenny

Installati i pacchetti

  • dspam
  • dspam-webfrontend
  • apache2-suexec
  • libapache2-mod-auth-pam

Per far funzionare il frontend web ci vuole l'Apache suexec perché lo script CGI deve essere esguito a nome dell'utente dspam. Il modulo Apache PAM serve a fare l'autenticazione web, necessaria per ovvi motivi di sicurezza e per fornire il nome utente all'interfaccia web.

Il pacchetto libapache2-mod-auth-pam richiede che www-data appartenga al gruppo shadow, in alternativa valutare il pacchetto libapache2-mod-auth-shadow (che non c'è in Lenny, ma è facile farne il backport).

Debian mette il front-end web all'indirizzo http://<host>/dspam/.

Integrazione con Exim4

Configurare TrustedDeliveryAgent in /etc/dspam/dspam.conf:

TrustedDeliveryAgent "/usr/sbin/exim4 -oi"

Aggiungere i seguenti file alla configurazione di Exim4:

/etc/exim4/conf.d/main/00_local

# Allow dspam user to re-enqueue mails setting the protocol to
# spam-scanned (-oMr option) and setting the sender (-f option).
# Setting the sender can be granted also with untrusted_set_sender.
MAIN_TRUSTED_USERS = dspam

/etc/exim4/conf.d/router/550_local_dspam

### router/550_local_dspam
#################################

# Route non-local mail to the dspam filter.
# Dspam will re-queue filtered messages to Exim using the
# "spam-scanned" protocol: we avoid filtering them twice.

dspam_route_check:
  no_verify
  check_local_user
  condition = "${if \
      and {{!eq {$received_protocol}{spam-scanned}} \
           {!eq {$received_protocol}{local}} } \
      {1}{0}}"
  driver = accept
  transport = dspam_check
  headers_add = "X-My-Dspam: scanned by $primary_hostname, $tod_full"
  require_files = /var/spool/dspam:+/usr/bin/dspam


# Feed false negatives and false positives forwarded by
# the users to dspam, for learning.

dspam_route_spam:
  no_verify
  check_local_user
  driver = accept
  local_part_suffix = -spam
  transport = dspam_class_spam

dspam_route_innocent:
  no_verify
  check_local_user
  driver = accept
  local_part_suffix = -nospam
  transport = dspam_class_innocent

Vengono definiti due alias per ogni utente: <login>-spam e <login>-nospam a cui l'utente invierà i falsi negativi e i falsi positivi rispettivamente. Fare attenzione al router definito sopra: non funziona in caso di alias diversi dal login (usati in genere con i domini virtuali).

/etc/exim4/conf.d/transport/40_local_dspam

### transport/40_local_dspam
#################################

# Filter the message with dspam and feed the result to its TrustedDeliveryAgent.
# That will be Exim again, with pass-through arguments -f, -oMr and recipient.
dspam_check:
  driver = pipe
  command = "/usr/bin/dspam --deliver=innocent --user ${lc:$local_part} -f '$sender_address' -oMr spam-scanned -- %u"
  user = dspam
  group = dspam
  return_path_add = false
  # Write the first line of command output to the Exim log.
  log_output = true
  # If command fails, return the command output in the bounce.
  return_fail_output = true
  message_prefix = ""
  message_suffix = ""

# Send false negatives and false positives to dspam for learning.
dspam_class_spam:
  driver = pipe
  command = "/usr/bin/dspam --debug --source=error --class=spam --user ${lc:$local_part}"
  user = dspam
  group = dspam
  return_path_add = false
  log_output = true
  return_fail_output = true
  home_directory = "/var/spool/dspam"
  current_directory = "/var/spool/dspam"
  message_prefix = ""
  message_suffix = ""

dspam_class_innocent:
  driver = pipe
  command = "/usr/bin/dspam --debug --source=error --class=innocent --user ${lc:$local_part}"
  return_path_add = false
  return_fail_output = true
  log_output = true
  home_directory = "/var/spool/dspam"
  current_directory = "/var/spool/dspam"
  user = dspam
  group = dspam
  message_prefix = ""
  message_suffix = ""

Il transport di Exim4 è configurato come driver = pipe, cioè il messaggio viene passato via stdinput al comando dspam, che viene eseguito con lo UID e GID specificati (dspam:dspam). Con questa configurazione dspam passa la mail filtrata nuovamente ad Exim, quindi non ha bisogno dei privilegi di superutente.

Alternativa 1

Con la configurazione vista sopra ciascun messaggio passa per due volte nella mail queue: prima e dopo essere stato filtrato da dspam. Questo consente di processare ulteriormente il messaggio filtrato con gli strumenti di Exim: instradamento verso altri host, espansione del destinatario tramite alias, applicazione di ACL, ecc.

In alternativa si può configurare dspam in modo che provveda direttamente a consegnare la posta nella mailbox, ad esempio avvalendosi di procmail.

FIXME

Alternativa 2

In alternativa all'integrazione con l'MTA, dspam può essere invocato da procmail durante la fase finale della consegna.

FIXME

Configurazione

/etc/dspam/dspam.conf

# DSPAM storage.
Home /var/spool/dspam
StorageDriver /usr/lib/dspam/libhash_drv.so

# Exim4 integration.
TrustedDeliveryAgent "/usr/sbin/exim4 -oi"

# Default filtering: active (user can opt-out).
Opt out

# Daemon configuration.
ServerPort              10024
ServerPass.Relay1       "8d0b79d1f6a3"

# Client configuration.
ClientHost      127.0.0.1
ClientPort      10024
ClientIdent     "8d0b79d1f6a3@Relay1"

Storage

Per default viene usato Hash-Based Driver, una buona alternativa è PostgreSQL. Con l'Hash-Based Driver vengono creati i file con le statistiche per ogni utente in una struttura di directory /var/spool/dspam/data/local/<login>/.

Se lo storage è un PostgreSQL c'è il vantaggio che l'alias per l'invio di spam/nospam può essere unico per tutto il dominio di posta, invece di averne uno per ogni utente.

Demone

In condizioni normali viene invocata un'istanza di dspam per ogni messaggio da filtrare. In alternativa può risultare conveniente attivare una sola istanza daemon di dspam ed eseguire il filtro con l'opzione --client.

Volendo far girare il demone senza i privilegi di superutente bisogna scegliere una porta > 1024, impostando il parametro ServerPort (quella predefinita è la TCP 24). Per consentire ai client di passare al daemon i parametri del comando (viene usato il protocollo proprietario DLMTP) è necessaria una autenticazione client/server, il modo più semplice è impostare il parametro ServerPass.<relay>.

Infine si imposta START=yes in /etc/default/dspam e si avvia il demone con /etc/init.d/dspam start.

Ogni invocazione di dspam dovrà includere l'opzione --client e dovrà trovare nel file di configurazione /etc/dspam/dspam.conf i tre parametri ClientHost, ClientPort e ClientIdent. In caso contrario dspam verrà eseguito silenziosamente in modalità stand-alone. Per il massimo dell'efficienza esiste anche il thin-client dspamc, che include nell'eseguibile solo le funzioni di client.

Quarantena

L'azione predefinita di dspam - quando identifica un messaggio di spam - è metterlo in quarantena, cioè memorizzarlo nel suo storage. Tramite l'interfaccia web l'utente può vedere i messaggi in quarantena, cancellarli oppure farli recapitare normalmente.

Se l'utente decide di recapitare normalmente un messaggio presente in quarantena, questo viene considerato non-spam e va ad istruire il filtro Bayesiano opportunamente. Nella history verrà evidenziato come Retrained.

Se dspam è configurato come filtro nel MTA e viene invocato con l'opzione --deliver=innocent,spam, il messaggio di spam viene recapitato al destinatario senza essere messo nella quarantena. Viene tuttavia aggiunto l'header X-DSPAM-Result: Spam.

Debug

Se si avvia dspam con l'opzione --debug, viene creato il file /var/log/dspam/dspam.debug, oltre al normale dspam.messages.

doc/appunti/linux/sa/dspam.1255041145.txt.gz · Last modified: 2009/10/09 00:32 by niccolo