DSPAM s'installe au niveau du serveur de mail, c'est donc particulièrement intéressant pour celles et ceux qui ne sont pas encore passés à des logiciels de gestion de courriels évolués tels que Mozilla Thunderbird (ou que vous ne voulez pas télécharger 300 mails dont 298 spams si vous avez une petite connexion internet par exemple).

Bien entendu ces avantages peuvent-être remis en questions néanmoins sur le fond et à l'instant où j'écris cet article cette information est vérifiable :) Pourquoi je dis ça ? tout simplement parcequ'il est possible qu'un développeur génial soit en train d'optimiser spamassassin en ce moment même :)

Remarque à propos du choix de la configuration exposée dans cet article: la connexion entre postfix et dspam peut se faire de plein de manières différentes, j'ai opté pour une configuration particulière et elle me convient. Vous pourrez cependant trouver bien d'autres exemples sur le net.

Postfix

La configuration de postfix est décrite ci-dessous. Il est intéressant de noter que dspam sera lancé en mode serveur et que la communication entre postfix et dspam sera faite via un socket (solution optimale au niveau des performances). Tous les mails qui arrivent pour la première fois sur le serveur sont passés dans la règle écrite dans le fichier dspam_filter_access et lorsque vous voulez apprendre à dspam que le mail que vous venez de recevoir est un spam il suffit de lui faire suivre ce mail à l'adresse utilisateur+spam@domaine.extension. Cette réécriture est possible grâce à l'utilisation de recipient_delimiter=+ et aux règles transport qui fait appel ensuite à la règle dspam-retrain de master.cf ... Un petit schéma pour expliquer comment le mail voyage dans postfix permettrait de mieux comprendre ce qui se passe :)

  • /etc/postfix/main.cf
myhostname = mail.ryxeo.fr
myorigin = /etc/mailname
mydestination = ryxeo.fr, mail.ryxeo.fr, localhost
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

virtual_maps = hash:/etc/postfix/virtual
transport_maps = pcre:/etc/postfix/transport

#dspam
dspam_destination_recipient_limit = 1
smtpd_client_restrictions =
       permit_mynetworks,
       check_client_access pcre:/etc/postfix/dspam_filter_access
local_recipient_maps = proxy:unix:passwd.byname $alias_maps $virtual_maps $transport_maps
  • /etc/postfix/master.cf

On a ajouté deux règles supplémentaires: l'une pour le traitement de tous les mails qui arrivent et l'autre pour la gestion des mails qu'on redonne à manger à dspam en lui expliquant si c'est du spam ou du non spam (ham). Notez que nous utilisons des pipe pour faire cette opération.

#dspam
smtp      inet  n       -       n       -       -       smtpd
dspam   unix    -       n       n       -       10      pipe
  flags=Rhq user=dspam argv=/usr/bin/dspamc --client --deliver=innocent,spam --user ${user} -i -f $sender -- $recipient

dspam-retrain   unix    -       n       n       -       10      pipe
  flags=Ru user=dspam argv=/usr/bin/dspam-retrain $nexthop ${sender} ${recipient}
  • /etc/postfix/transport

La gestion du transport en fonction du contenu de l'adresse email, l'expression régulière pourrait-être améliorée pour avoir par exemple /.*\+spam@.*/ au lieu de la recherche du mot "spam" ... je vous laisse améliorer tout ça par vous-même !

/.*spam.*/              dspam-retrain:spam
/.*ham.*/               dspam-retrain:innocent
  • /etc/postfix/virtual

C'est le fichier dans lequel on fait correspondre le nom du compte unix qui correspond à l'adresse email. Comme ryxeo.fr est dans mydestination je n'ai pas besoin de donner des adresses contenant ce domaine sous peine d'avoir une erreur de postfix.

eric.seigne             erics
olivier.cortes          olive
guillaume.masson        guillaume

Recréer ensuite le fichier DB associé avec la commande « sudo postmap /etc/postfix/virtual ».

  • /etc/postfix/dspam_filter_access
#ce qui est envoye a blablabla+spam@domaine passe direct a la suite
/^.*(spam|ham)@.*$/ OK

#on filtre tout le reste
/^.*$/   FILTER dspam:dspam

DSPAM

Si vous n'avez pas mysql, installez-le au préalable, avec son interface d'admin : "sudo apt-get install mysql-server apache2 phpmyadmin" Connectez-vous sur PHPmyAdmin et mettez un mot de passe administrateur (utilisateur "root" sur la machine "localhost").

Installer les paquets de dspam (sur Ubuntu par exemple) : "sudo apt-get install dspam libdspam7-drv-mysql". Le paquet libdspam7-drv-mysql vous demandera le mot de passe administrateur MySQL que vous avez entré précédement ; vous pouvez laisser tous les autres paramètres sans les modifier, le paquet va créer la base de données et l'utilisateur automatiquement.

Puis il faut adapter les fichiers de configuration:

  • /etc/default/dspam
START=yes

# Options for dspam.
#OPTIONS="--debug"
  • /etc/dspam/default.prefs

Le fichier de configuration des préférences par défaut de dspam, je vous propose de lire la documentation de dspam pour chaque entrée, je n'ai pas vraiment la place de tout détailler ici.

# Training Mode: TEFT, TOE, TUM, NOTRAIN
trainingMode=TEFT

# Spam Action: quarantine, tag
spamAction=tag

# Spam Subject: the text to be prepended onto the subject line of tagged spams
spamSubject=[SPAM]

# Bayesian Noise Reduction: on/off
enableBNR=on

# Automatic Whitelisting: on/off
enableWhitelist=on

# Statistical Sedation: 0-10
statisticalSedation=5

# Signature Location: message, headers, attachment
signatureLocation=headers

# Whitelist Threshold: the minimum number of innocent hits from a recipient to
# be automatically whitelisted. Do not set this value too low!
whitelistThreshold=10

# showFactors: when set to on, the determining factors for each message will
# be added to a X-DSPAM-Factors message header.
showFactors=on

# optIn/optOut: Depending on the opt mode set, you can also use one of these.
optIn=off
optOut=on
  • /etc/dspam/dspam.conf

Le fichier de configuration principal de dspam ... n'oubliez pas d'activer le pilote de stockage mysql si vous voulez l'utiliser !

StorageDriver /usr/lib/dspam/libmysql_drv.so
TrustedDeliveryAgent "/usr/sbin/sendmail"
UntrustedDeliveryAgent "/usr/bin/procmail -d %u"
QuarantineAgent        "/usr/bin/procmail -d spam"
EnablePlusedDetail     on
#Debug *
#DebugOpt process spam fp
#vérifier que Feature sbph est bien en commentaire, sinon on a
#un warning dans les logs mais c'est une erreur réelle qui plante
#toute la chaîne
Feature tb=5
ImprobabilityDrive on
Preference "spamAction=tag"
Preference "signatureLocation=headers" # 'message' or 'headers'
Preference "spamSubject=[SPAM]"
TrainPristine on
ParseToHeaders on
ChangeModeOnParse on
ChangeUserOnParse on
ServerQueueSize        32
ServerPID              /var/run/dspam.pid
ServerMode dspam
ServerPass.Relay1      "secret"
ServerParameters       "--deliver=innocent -d %u"
ServerDomainSocketPath  "/tmp/dspam.sock"
ClientHost     /tmp/dspam.sock
ClientIdent    "secret@Relay1"
  • webfrontend.conf
# Default DSPAM enviroment
$CONFIG{'DSPAM_HOME'}   = "/var/spool/dspam";
$CONFIG{'DSPAM_BIN'}    = "/usr/bin";
$CONFIG{'DSPAM'}        = $CONFIG{'DSPAM_BIN'} . "/dspam";
$CONFIG{'DSPAM_STATS'}  = $CONFIG{'DSPAM_BIN'} . "/dspam_stats";
$CONFIG{'DSPAM_ARGS'}   = "--deliver=innocent --class=innocent " .
                          "--source=error --user %CURRENT_USER% -d %u";
$CONFIG{'TEMPLATES'}    = "/usr/share/dspam/upstream-templates/";       # Location of HTML templates
$CONFIG{'ALL_PROCS'}    = "ps auxw";            # use ps -deaf for Solaris
$CONFIG{'MAIL_QUEUE'}   = "mailq | grep '^[0-9,A-F]' | wc -l";

$CONFIG{'WEB_ROOT'}     = "./"; # URL location of included htdocs/ files

# Default DSPAM display
$CONFIG{'HISTORY_SIZE'} = 799;          # Number of items in history
$CONFIG{'HISTORY_PER_PAGE'} = 100;
$CONFIG{'MAX_COL_LEN'}  = 50;           # Max chars in list columns
$CONFIG{'SORT_DEFAULT'} = "Date";       # Show quarantine by "Date" or "Rating"
$CONFIG{'3D_GRAPHS'}    = 1;
$CONFIG{'LOCAL_DOMAIN'} = "localhost";

# Add customized settings below
$CONFIG{'LOCAL_DOMAIN'} = "ryxeo.com";

$ENV{'PATH'} = "$ENV{'PATH'}:$CONFIG{'DSPAM_BIN'}";

# Autodetect filesystem layout and preference options
$CONFIG{'AUTODETECT'} = 1;

# Or, if you're running dspam.cgi as untrusted, it won't be able to auto-detect
# so you will need to specify some features manually:
#$CONFIG{'AUTODETECT'} = 0;
#$CONFIG{'LARGE_SCALE'} = 0;
$CONFIG{'DOMAIN_SCALE'} = 1;
$CONFIG{'PREFERENCES_EXTENSION'} = 0;

$CONFIG{'DSPAM_CGI'} = "dspam.cgi";

# Configuration was successful
1;
  • /etc/dspam/dspam.d/mysql.conf
# -- MySQL --

#
# Storage driver settings: Specific to a particular storage driver. Uncomment
# the configuration specific to your installation, if applicable.
#
MySQLServer       /var/run/mysqld/mysqld.sock
#MySQLPort         3306
MySQLUser         libdspam7-drv-my
MySQLPass         hackmeplease
MySQLDb           libdspam7drvmysql
#MySQLCompress          false

# Use this if you have the 4.1 quote bug (see doc/mysql.txt)
# mysql-server-4.1 version => 4.1.15-1 doesn't have this bug.
# This bug doesn't apply to debian mysql server, it is already fixed in the
# mysql packages.
#MySQLSupressQuote      on

# If you're running DSPAM in client/server (daemon) mode, uncomment the
# setting below to override the default connection cache size (the number
# of connections the server pools between all clients). The connection cache
# represents the maximum number of database connections *available* and should
# be set based on the maximum number of concurrent connections you're likely
# to have. Each connection may be used by only one thread at a time, so all
# other threads _will block_ until another connection becomes available.
#
MySQLConnectionCache    10

# If you're using vpopmail or some other type of virtual setup and wish to
# change the table dspam uses to perform username/uid lookups, you can over-
# ride it below

#MySQLVirtualTable          dspam_virtual_uids
#MySQLVirtualUIDField       uid
#MySQLVirtualUsernameField  username

# UIDInSignature: MySQL supports the insertion of the user id into the DSPAM
# signature. This allows you to create one single spam or fp alias
# (pointing to some arbitrary user), and the uid in the signature will
# switch to the correct user. Result: you need only one spam alias

#MySQLUIDInSignature    on

Script /usr/bin/dspam-retrain

J'ai modifié le script "usine" proposé sur le site web de DSPAM pour l'adapter à ma configuration et y ajouter également des points de debug histoire de savoir exactement ce que ça fait lorsque nous sommes en situation d'installation et de configuration.

#! /usr/bin/perl

# Get arguments
$class  = $ARGV[0] || die; shift;
$sender = $ARGV[0] || die; shift;
$recip  = $ARGV[0] || die; shift;

#open(LOG, ">>/tmp/eric_ryxeo_debug.log");
#$t = localtime;
#print LOG "TEST ERIC $t \n\n";
#print LOG " ->class: $class\n ->sender: $sender\n ->recip: $recip\n";

if ($recip =~ /^(.*)\+(spam|ham).*/) {
    # username is part of the recipient
    $user = $1;
#    print LOG "user from recip $recip / $user\n";
} elsif ($sender =~ /^(.*)@/) {
    # username is in the sender
    $user = $1;
#    print LOG "user from sender $sender / $user\n";
}
 else {
    print "Can't determine user [$recip]\n";
    exit 75;                    # EX_TEMPFAIL
}


# Pull out DSPAM signatures and send them to the dspam program
while (<>) {
#    print LOG "readline:$_";
    if ( (! $subj) && (/^Subject: /) ) {
        $subj = $_;
#       print LOG "sub found: $subj\n";
    }
    if ( /(X-DSPAM-Signature: .*)/ ) {
        open(F, "|/usr/bin/dspamc --client --source=error --class=$class --user $user ");
        print F "$subj\n$1\n";
        close(F);
#        print LOG "BEEEEEEP: seconde\n";
#        print LOG "PROCESS SPAM LEARN: $subj, pipe mail to /usr/bin/dspamc --client --source=error --class=$class --user $user\n";
    }
}
#close(LOG);

Une fois le script créé, il faut le rendre exécutable avec la commande « sudo chmod a+x /usr/bin/dspam-retrain ».

Et ensuite

Maintenant que tout est installé c'est l'horreur: "ça ne marche pas, c'est nul" ... c'est ce que vous allez forcément entendre de la part de vos utilisateurs ! Pas de panique, c'est normal. DSPAM ne filtre rien tant que vous ne lui avez pas appris ce qui est bon et mauvais. Expliquez donc à vos utilisateurs de faire suivre le spam non filtré à l'adresse email+spam@domaine.ext et au bout de quelques jours ou semaine tout ira mieux.

Un coup de pouce, une base de spam à apprendre

Allez, voici une astuce que j'utilise pour éviter trop de problèmes: je collecte des spams sur ce serveur nouvellement installé et je les fais apprendre à dspam pour chaque utilisateur histoire qu'il soit un peu efficace dès le début, c'est motivant pour les usagers.

cat /tmp/spam_viagra | /usr/bin/dspamc --client --source=error --class=spam --user erics
cat /tmp/spam_enlargepenis | /usr/bin/dspamc --client --source=error --class=spam --user erics
etc.

Et comme tout administrateur unix qui se respecte, je pose tous mes spams-type dans /tmp/spams/ et je lance la moulinette suivante:

for usager in erics olive guillaume
do
 for spam in /tmp/spams/*
 do
  cat $spam | /usr/bin/dspamc --client --source=error --class=spam --user $usager
 done
done

À voir, pour la suite ...

Je vous propose de donner un petit coup d'oeil sur les choses suivantes:

Éric