Dspam

Un article de WindowsLinux.net - Astuces pour Windows et Linux !.

Sommaire

Activer le debug

vi /etc/default/dspam

Il suffit de décommenter la dernière ligne :

# Variables for dspam.
#
# Do not start dspam.
START=yes

# User that runs dspam.
USER=dspam

# Options for dspam.
OPTIONS="--debug"

Le fichier de debug sera alors dans (pour Debian) :

/var/log/dspam/dspam.debug

Déclarer un SPAM

Avec la commande suivante, si vous avez la "bonne signature" du spam :

/usr/bin/dspam --user user@mon-domaine.fr --class=spam --source=error --signature=1,49cbd3c3108754209713687

Afficher les statistiques de dspam

Pour vérifier que le SPAM marqué comme tel par vous soit enfin reconnu comme spam, les statistiques doivent se mettre à jour.

Commande pour afficher les statistiques :

dspam_stats -H user@mon-domaine.fr

WebUI : dspam.cgi

Il arrive que le cgi de dspam retourne une erreur sur l'onglet "Analysis" de votre utilisateur.

L'erreur, dans le log apache peut être la suivante :

Can't use an undefined value as an ARRAY reference at dspam.cgi line 551.

Il suffit de s'envoyer un mail à soi-même pour corriger le problème, ou de patcher dspam.cgi avec les lignes suivantes :

$ svn diff -r30:31
Index: dspam.cgi
===================================================================
--- dspam.cgi   (revision 30)
+++ dspam.cgi   (revision 31)
@@ -532,10 +532,13 @@
    foreach my $period (qw( daily weekly )) {
      my $uc_period=uc($period);
      my $hk="DATA_$uc_period";
-    my %lst=();
+    my %lst=(
+       spam => [],
+       nonspam => [],
+       title   => []
+    );
      foreach my $hr (sort {$a->{idx}$b->{idx}} (values 
%{$Stats{$period}})) {
        foreach my $type (qw( spam nonspam title )) {
-        (exists $lst{$type}) || ($lst{$type}=[]);
          push(@{$lst{$type}},$hr->{$type});
          my $totk="";
          if ($type eq "spam") { $totk="S"; }
@@ -547,9 +550,9 @@
        }
      }
      $DATA{$hk}=join("_",
-               join(",",@{$lst{spam}}),
-               join(",",@{$lst{nonspam}}),
-               join(",",@{$lst{title}}),
+               join(",",@{$lst{spam}}    || [0]),
+               join(",",@{$lst{nonspam}} || [0]),
+               join(",",@{$lst{title}}   || [0]),
         );
    }

Merci à John Peacock sur cette page pour l'information.



Enfin, sous Debian, l'intégralité des répertoires et fichiers contenu dans :

/var/spool/dspam/data

doit appartenir à l'utilisateur et au groupe "dspam".

Erreurs rencontrées

Il est possible de rencontrer une erreur du type :

17080: [03/26/2009 21:31:45] _ds_pref_load: unable to _mysql_drv_getpwnam(user@mon-domaine.fr)

Pour corriger ce bug, il suffit d'ajouter l'adresse "user@mon-domaine.fr" à la bonne base de données et la bonne table de Dspam :


Base de données utilisée : libdspam7drvmysql

Table : dspam_virtual_uids

Action : insérer le nouvel utilisateur de la forme "user@mon-domaine.fr".

Mes "virtual users" n'ont pas de fichiers .stats ou .rstats ! Que faire ?

Le bug provient surement de votre fichier "group" ( /var/spool/dspam/group ). Essayez de démarrer dspam (en activant le debug dans /etc/default/dspam ) sans ce fichier, et testez votre configuration.

Plus d'informations dans la partie nommée 2.1 Configuring groups du fichier README officiel.

Exemple, pour que tous les utilisateurs partagent la même configuration, ce fichier doit contenir :

dspam:shared:*

Vérifiez aussi l'existence de vos utilisateurs dans la base MySQL nommée dspam_virtual_uids de DSPAM : de la forme user@domain.tld (l'ID est unique et automatiquement crée).


Droits & fichiers pour une boite mail (virtual users)

Liste des fichiers et des droits associés, pour que Dspam fonctionne correctement :

# cd /var/spool/dspam/data/domain.tld/user.name/
# ll
total 1,3M
drwxrwx--- 2 dspam dspam 4,0K mai  6 22:47 .
drwxrwx--- 6 dspam dspam 4,0K nov  1  2008 ..
-rw-r--r-- 1 dspam dspam  63K mai  9 03:15 user.name.log
-rw-r--r-- 1 dspam dspam 1,2M mai  9 03:15 user.name.mbox
-rw-r--r-- 1 dspam dspam    6 mai  7 23:32 user.name.mbox.size
-rw-rw---- 1 dspam dspam    0 mai  7 23:32 user.name.mbox.stamp
-rw-r--r-- 1 dspam dspam    0 mai  6 05:07 user.name.retrain.log
-rw-r--r-- 1 dspam dspam   16 mai  6 22:58 user.name.rstats
-rw-rw---- 1 dspam dspam   17 mai  9 03:15 user.name.stats

Un bug a été rencontré : lorsqu'un mail est envoyé à toute adresse mail (exemple@domaine-externe.tld), cette dernière adresse apparaît dans l'interface web (comme mail "administrable").

Il suffit alors d'uiliser opt-in dans dspam.conf, et d'ajouter un fichier nomutilisateur.dspam pour activer le fonctionnement de Dspam pour cette adresse :

# ll /var/spool/dspam/opt-in/
... ... liste des domaines ...
# ll /var/spool/dspam/opt-in/domain.tld/nomutilisateur.dspam
Note : les droits doivent être correctement définis, exemple : dspam.dspam

Scripts

Entrainer automatiquement

Script simple

Ce script s'utilise ainsi, pour du spam :

/path/to/dspam_retrain.sh spam /home/username/imap/domain.com/username/mail/spam

et pour du ham :

/path/to/dspam_retrain.sh ham /home/username/imap/domain.com/username/mail/spam
#!/bin/bash
 
DSPAM_BINARY="/opt/dspam/bin/dspam"
 
case "$1" in
  ham)
	for i in `cat $2 |grep "X-DSPAM-Signature:" |awk {'print $2'}`
	do
		echo "Retrain: $i"
		$DSPAM_BINARY --user dspam --class=innocent --source=error --signature=$i
	done
        ;;
  spam)
	for i in `cat $2 |grep "X-DSPAM-Signature:" |awk {'print $2'}`
	do
		echo "Retrain: $i"
		$DSPAM_BINARY --user dspam --class=spam --source=error --signature=$i
	done
        ;;
  *)
	echo "This utility will retrain your DSPAM for ham or spam emails"
        echo "Usage: $0 {ham|spam} {full path to your ham/spam mailbox/folder}"
        exit 1
esac

Source : http://www.directadmin.com/forum/showthread.php?t=16015


Script plus complet

Basé sur le script décrit sur cette page et disponible initialement par son auteur ici, voici un script qui fonctionne avec GrSoft MailManager, et Roundcube avec le plugin "markasjunk".


Il vous faut un répertoire .Junk (Junk est aussi utilisé par Thunderbird) et .NoJunk, pour chaque adresse mail, afin que ce script fonctionne le plus parfaitement possible. Cependant il peut fonctionner correctement avec l'un ou l'autre, puisqu'il vérifie leur existence avant toute exécution.

#!/bin/sh -
#
# Simple shell script to feed DSpam with errors to retrain
#
#==========================================================
USERPATH=/tmp/dspam.users.tmp
USERLISTPATH=/tmp/dspam.liste.chemin.users
USERMAILS=/tmp/dspam.adresses.users
USERFILE=/tmp/dspam.users
DSPAM=/usr/bin/dspam
MYSQL=/usr/bin/mysql
VIRTUAL_BASE=/home/vmail/
SPAM_VIRTUAL_FOLDER=.Junk
NOSPAM_VIRTUAL_FOLDER=.NoJunk
DBUSER=dbuser
DBPASS=dbpassword
DB=dbmail
DELETESPAM=YES
DELETENOSPAM=NO
 
echo `date` Begin Spam processing
 
# On extrait toute information utile pour créer le chemin pour chaque domaine / utilisateur.
$MYSQL -u $DBUSER -p$DBPASS -e "use $DB; select name,user from virtual_users INNER JOIN virtual_domains ON virtual_users.domain_id = virtual_domains.id;" --skip-column-names > $USERPATH
# On classe les informations dans l'ordre, et on ajoute /Maildir/
while read DOMAINE UTILISATEUR;
do
echo "$DOMAINE/$UTILISATEUR/Maildir/";
done < $USERPATH > $USERLISTPATH
# On cree la liste des utilisateurs, de la forme login@domain.tld
$MYSQL -u $DBUSER -p$DBPASS -e "use $DB; select email from view_users;" --skip-column-names > $USERMAILS
# On fusionne les deux fichiers en un seul, qui sera alors traité par le script écris par info@richard5.net
paste -d "\t" $USERMAILS $USERLISTPATH > $USERFILE
 
# Pour information,
# A partir de ce point, dans $USERFILE, le premier groupe de mot avant la tabulation :
# USER doit etre de la forme : login@domaine.tld
# le second groupe de mot après la tabluation doit etre du type :
# MAILDIR doit etre de la forme : domaine.tld/login/Maildir/
#
 
while read USER MAILDIR
do
  echo `date` Processing $USER in $VIRTUAL_BASE$MAILDIR
  # taking care of false negatives !
  # check if the user has a .Junk folder
  if [ -d $VIRTUAL_BASE$MAILDIR$SPAM_VIRTUAL_FOLDER ]; then
 
    # check both new and cur directories for spam !
    cd $VIRTUAL_BASE$MAILDIR$SPAM_VIRTUAL_FOLDER/new
    for j in *
    do
      # check if the file exists
      if [ -s $j ]; then
        # check if file was already identified as SPAM
        grep "X-DSPAM-Result: Spam" $j 1>/dev/null
        RESULT=$?
        if [ $RESULT = 0 ]; then
          # if wanted, delete the mail.
          if [ $DELETESPAM = "YES" ]; then
            rm -f $j
          fi
        else
          $DSPAM --user $USER --class=spam --source=error < $j
          # if wanted, delete the mail.
          if [ $DELETESPAM = "YES" ]; then
            rm -f $j
          fi
        fi
      fi
    done
    cd $VIRTUAL_BASE$MAILDIR$SPAM_VIRTUAL_FOLDER/cur
    for j in *
    do
      # check if the file exists
      if [ -s $j ]; then
        # check if file was already identified as SPAM
        grep "X-DSPAM-Result: Spam" $j 1>/dev/null
        RESULT=$?
        if [ $RESULT = 0 ]; then
          # if wanted, delete the mail.
          if [ $DELETESPAM = "YES" ]; then
            rm -f $j
          fi
        else
         $DSPAM --user $USER --class=spam --source=error < $j
          # if wanted, delete the mail.
          if [ $DELETESPAM = "YES" ]; then
            rm -f $j
          fi
        fi
      fi
    done
  fi
 
  #taking care of false positives
  echo `date` Processing False Positives as Clean
  # check if the user has a .NotSpam folder
  if [ -d $VIRTUAL_BASE$MAILDIR$NOSPAM_VIRTUAL_FOLDER ]; then
    # check both new and cur directories for nospam !
    cd $VIRTUAL_BASE$MAILDIR$NOSPAM_VIRTUAL_FOLDER/new
    for j in *
    do
      # check if the file exists
      if [ -s $j ]; then
        # check if file was identified as SPAM if not then ignore it !
        grep "X-DSPAM-Result: Spam" $j 1>/dev/null
        RESULT=$?
        if [ $RESULT = 0 ]; then
          $DSPAM --user $USER --class=innocent --source=error < $j
          if [ $DELETENOSPAM = "YES" ]; then
            rm -f $j
          fi
        else
          # not identified as spam, if needed delete the mail.
          if [ $DELETENOSPAM = "YES" ]; then
            rm -f $j
          fi
        fi
      fi
    done
    cd $VIRTUAL_BASE$MAILDIR$NOSPAM_VIRTUAL_FOLDER/cur
    for j in *
    do
      # check if the file exists
      if [ -s $j ]; then
        # check if file was identified as SPAM if not then ignore it !
        grep "X-DSPAM-Result: Spam" $j 1>/dev/null
        RESULT=$?
        if [ $RESULT = 0 ]; then
          $DSPAM --user $USER --class=innocent --source=error < $j
          if [ $DELETENOSPAM = "YES" ]; then
           rm -f $j
          fi
        else
          # not identified as spam, if needed delete the mail.
          if [ $DELETENOSPAM = "YES" ]; then
            rm -f $j
          fi
        fi
      fi
    done
  fi
 
done < $USERFILE
 
# clean up action..
rm -f $USERFILE
rm -f $USERLISTPATH
rm -f $USERMAILS
rm -f $USERPATH
 
echo `date` End AutoSpam processing
echo

Supprimer les messages trop vieux en quarantaine

Source : http://www.convoglio.com/dspam/age.html

Les messages placés en quarantaine peuvent être "oubliés" par les utilisateurs. Le fichier ne cesse alors de prendre de plus en plus de place.

Ce script permet de supprimer automatiquement les messages plus vieux de 14 jours (dans cet exemple).

#!/bin/bash
# age_spam_quarantine - Remove quarantined messages older than a specified number of days.
#    Steve Pellegrin (spellegrin at convoglio dot com)
#
# History:
#    1.0   2005-January-1    Original code
#    1.1   2005-February-3   Works with large, domain or standard
#
# Usage:
#    age_spam_quarantine
 
DAYS=14                                 # Messages left in quarantine older 
                                        # than this many days will be deleted.
DATA=/var/spool/dspam/data/                        # DSpam data directory
ARCHIVEMAIL="/usr/bin/archivemail"      # Path to utility
 
# For each user mailbox...
for mbox in `find ${DATA} -follow -name *mbox`
do
    if [ -s $mbox ]; then
        # Tell archivemail to remove the messages.
        ${ARCHIVEMAIL} --days=${DAYS} --delete --include-flagged --quiet $mbox
    fi;
done

Vous pouvez changer les valeurs DAYS, corriger le chemin DATA, installer archivemail, et tester ce script sans la commande --quiet avant sa mise en place dans un cron.

Voici un exemple de bon fonctionnement :

/var/spool/dspam/data/domain.tld/user/user.mbox:
    deleted 1083 of 1211 message(s) (3.7MB of 4.2MB) in 2.1 seconds

Notification

Il est possible de notifier les utilisateurs dans 3 cas différents :

  • premier lancement
  • premier spam reçus
  • dossier de quarantine rempli

Il faut activer les notifications dans dspam.conf (selon ce post [1] ) :

Notification on

A condition de créer un répertoire "txt" dans /var/spool/dspam (dosser "Home" de Dspam) contenant 3 fichiers (firstrun.txt, firstspam.txt, quarantinefull.txt) avec les droits pour dspam.dspam .

Vous pouvez trouver ces fichiers sur le site officiel de dspam.

Note : Actuellement aucun moyen de faire fonctionner cette option dans le package Debian ...

Optimisation

Une fois par semaine, il est conseillé de nettoyer la base MySQL ainsi (Debian) :

#crontab -e
2 2 * * sun mysql --verbose -uUtilisateurDSPAM -pMotDePasseDSPAM libdspam7drvmysql < /usr/share/doc/libdspam7-drv-mysql/purge-4.1.sql

Une fois par mois, il est conseillé d'optimiser les tables MySQL, vous pouvez utiliser un script similaire à celui-ci :

#!/bin/sh
#
# Optimize the DSPAM mysql database
 
DSPAMCONF=/etc/dspam/dspam.conf
MYSQLCONF=/etc/dspam/dspam.d/mysql.conf
 
if grep -q "^StorageDriver.*mysql_drv.so" $DSPAMCONF; then
  if [ -x /usr/bin/mysql ]; then
    MYSQL_USER="`grep "^MySQLUser" $MYSQLCONF | awk '{print $2}'`"
    MYSQL_PASS="`grep "^MySQLPass" $MYSQLCONF | awk '{print $2}'`"
    MYSQL_DB="`grep "^MySQLDb" $MYSQLCONF | awk '{print $2}'`"
    MYSQL_HOST="`grep "^MySQLServer" $MYSQLCONF | awk '{print $2}'`"
 
    # If host is empty or starting with a / assume it's localhost.
    if [ -z "$MYSQL_HOST" ] || [ "${MYSQL_HOST:0:1}" = "/" ]; then
	echo "OPTIMIZE LOCAL TABLE dspam_preferences, dspam_signature_data, dspam_stats, dspam_token_data, dspam_virtual_uids;" | /usr/bin/mysql --user=$MYSQL_USER --password=$MYSQL_PASS $MYSQL_DB
    else
	if echo "$MYSQL_HOST" | grep "^/" > /dev/null 2>&1 ; then
	    # Assume it's a socket:
	    echo "OPTIMIZE LOCAL TABLE dspam_preferences, dspam_signature_data, dspam_stats, dspam_token_data, dspam_virtual_uids;" | /usr/bin/mysql --user=$MYSQL_USER --password=$MYSQL_PASS $MYSQL_DB
	else
	    echo "OPTIMIZE LOCAL TABLE dspam_preferences, dspam_signature_data, dspam_stats, dspam_token_data, dspam_virtual_uids;" | /usr/bin/mysql --user=$MYSQL_USER --password=$MYSQL_PASS $MYSQL_DB
	fi
    fi
  fi
fi
 
exit 0

Rotation des log

Il est conseillé d'ajouter ce crontab :

dspam_logrotate -a 30 -d /var/spool/dspam/data

MySQL

Il est conseillé de lire le fichier suivant sous Debian : /usr/share/doc/libdspam7-drv-mysql/mysql_drv.txt.gz

Plus spécialement la partie 2. CREATING MYSQL OBJECTS. Divers conseils sont donnés pour les systèmes ayant plus de 32,768 utilisateurs.

Liens

Internes

L'article Apache, et spécifiquement la partie nommée "mod_auth_mysql" utile pour Dspam WebUI.


L'article sur les fichiers .htaccess.

Externes

Configurer DSPAM en relay : http://en.gentoo-wiki.com/wiki/Dspam_relay

Installation avec Postfix : http://dspamwiki.expass.de/Installation/Postfix

Et un exemple intéressant : http://dspamwiki.expass.de/Installation/Postfix/RelayClamExchangeWebUiToActiveDirectory

Autres liens en vrac : https://www.ryxeo.com/Serveur-de-mail-avec-AntiSPAM.html

Un plugin dovecot qui permet d'utiliser un dossier "SPAM" : http://johannes.sipsolutions.net/Projects/dovecot-antispam

Une page d'explications : http://www.kirya.net/articles/setting-up-dspam-as-a-filter-for-postfix-on-debian-etch/

Liens divers :

http://smcv.pseudorandom.co.uk/2009/04/dspam/

Divers scripts

Divers scripts pour Dspam sont disponibles ici : http://www.convoglio.com/dspam/index.html

Add-ons pour clients mails

Rediriger vers spam@domain.tld :

Pour Outlook : http://www.wahlfaelschung.de/dspam-addin/

Pour Thunderbird : http://mailredirect.mozdev.org/

Optimisation

Optimisation, par ajouts d'indexes supplémentaires, pour les très grosses bases :

http://www.howtoforge.com/optimizing_dspam_mysql4.1

Bugs Debian

Ici est disponible la liste des bugs pour ce package Debian.