Configuration messagerie sur Debian Testing
Document version 1.2


Retour à la page d'accueil

Table des matières


1 Introduction

1.1 Dans quel cas appliquer cette configuration

1.2 En quoi consiste cette configuration

Fonction Programme
Délivrement dans les bases courrier locales procmail - c'est la situation par défaut
MTA & MSA - gestionnaire de mail sendmail
Récupération depuis un serveur (POP3 ou IMAP) fetchmail
Anti-SPAM SpamAssassin

Noms de domaine de messagerie
Comme votre Linux est supposé ne pas avoir de nom public, un problème se pose : quel nom de domaine de messagerie utiliser en local ?
Il faut utiliser un nom privé (qui n'existe pas sur Internet). Ainsi ma machine s'appelle maison-1.claix.perouses.fr, et le domaine de messagerie est le même, maison-1.claix.perouses.fr. Par défaut si vous n'avez configuré aucun nom, le nom est localhost.localdomain, qui ne pose pas de problème.

Pour que les emails puissent sortir vers Internet avec les bonnes informations (notamment, une adresse d'émetteur connue sur Internet, et non pas privée), le nom de l'émetteur devra être translaté depuis l'adresse locale vers une adresse email réelle, connue sur Internet.
C'est pourquoi "genericstable" est configuré dans sendmail.

1.3 Pourquoi appliquer cette configuration

  1. Votre messagerie est autonome : les emails internes (émis par et à destination d'utilisateurs locaux) ne quittent pas la machine.
  2. L'interface utilisateur (KMail, evolution, ...) et le système de messagerie sont séparés.
  3. Les programmes de mail évolués comme KMail ou Evolution bénéficient d'une interface très agréable, mais ils atteignent vite leurs limites pour gérer les tâches de bas niveau.
    Lorsque la récupération des emails est interrompue, KMail recommence à zéro... et récupère les mêmes messages une deuxième fois, et ainsi de suite, jusqu'à ce que la totalité des messages soit récupérée avec succès, en une seule connexion.
    Avec fetchmail, ce type d'inconvénient n'existe pas. Fetchmail mémorise les messages récupérés, et n'en récupère jamais un plusieurs fois, même en cas d'interruption.
  4. Un programme en ligne de commande tel que "mail" fonctionne parfaitement, qu'il soit utilisé en envoi d'email ou pour consulter les emails reçus.
    C'est une conséquence naturelle du fait que le système est configuré pour la messagerie.
    Même si vous ne vous servez jamais de "mail" pour gérer votre correspondance, ce point n'est pas négligeable : l'envoi d'emails depuis des scripts est facilité.

2 Configuration

2.1 Paramètres système

Avant de configurer la messagerie elle-même, il faut s'assurer que le nom du système est convenablement défini, car la messagerie y est étroitement liée.
Fichiers à considérer :

Fichier Fonction
/etc/hostname Nom de la machine
/etc/hosts Correspondance entre noms et adresses IP, utile si le nom d'hôte est privé
/etc/host.conf Rien à modifier ici si le contenu est standard
/etc/mailname Nom de la machine pour la messagerie, identique par défaut à /etc/hostname

Fichier /etc/hostname

maison-1.perouses.claix.fr

Fichier /etc/hosts
L'intérêt de la ligne 192.168.1.2 est de ne pas avoir un avertissement de sendmail au démarrage (exécution d'un gethostbyaddr).
Évidemment si votre adresse IP est dynamique (connexion par modem, DHCP avec votre boîtier ADSL, ...), cette ligne est inutile.

# 127.0.0.1	localhost.localdomain	localhost	maison
127.0.0.1	maison-1.perouses.claix.fr	localhost.perouses.claix.fr	maison-1	localhost
192.168.1.2	maison-1.perouses.claix.fr	localhost.perouses.claix.fr	maison-1	localhost

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

Fichier /etc/host.conf (anciennes versions)

order hosts,bind
multi on

Fichier /etc/host.conf (versions récentes)

multi on

Fichier /etc/mailname
Ce fichier doit contenir le nom local du système tel que vu dans la messagerie. Il est pris en compte lors de la première configuration de sendmail.
Comme le nom de domaine est identique au nom de la machine, ce fichier est identique à /etc/hostname.

maison-1.perouses.claix.fr

2.2 Configuration de Sendmail

Le paquetage à installer est sendmail. sendmail-doc apporte de la documentation utile, je conseille de l'installer également. Attention, installer sendmail nécessite d'enlever exim.
Exemple d'un dpkg-query pour vérifier les paquetages installés :

sebastien@maison-1:~$ dpkg-query -l "sendmail*"
Souhait=inconnU/Installé/suppRimé/Purgé/H=à garder
| État=Non/Installé/fichier-Config/dépaqUeté/échec-conFig/H=semi-installé
|/ Err?=(aucune)/H=à garder/besoin Réinstallation/X=les deux (État,Err: majuscule=mauvais)
||/ Nom                                 Version                             Description
+++-===================================-===================================-======================================================================================
ii  sendmail                            8.13.7-2                            powerful, efficient, and scalable Mail Transport Agent
ii  sendmail-base                       8.13.7-2                            powerful, efficient, and scalable Mail Transport Agent
ii  sendmail-bin                        8.13.7-2                            powerful, efficient, and scalable Mail Transport Agent
ii  sendmail-cf                         8.13.7-2                            powerful, efficient, and scalable Mail Transport Agent
ii  sendmail-doc                        8.13.7-2                            powerful, efficient, and scalable Mail Transport Agent
un  sendmail-tls                        <néant>                             (aucune description n'est disponible)
sebastien@maison-1:~$

Fichier /etc/aliases
Ligne permettant de rediriger vers l'utilisateur de votre choix, les emails adressés à root - login_name est à remplacer par votre nom de login :

root: login_name

	Exemple

[...]
postmaster: root
root: sebastien
[...]
mailer-daemon: postmaster
[...]

Fichier /etc/mail/sendmail.mc
- Mettre les lignes commençant par MAILER à la fin, pour éviter que sendmail ne proteste lors de la compilation .mc -> .cf.
- A la ligne MASQUERADE_AS, préciser le nom de la machine, tel qu'indiqué dans /etc/mailname. En principe c'est déjà fait.
- Toujours dans /etc/mail/sendmail.mc, ajouter le paragraphe ci-dessous, avant les lignes MAILER.

Remarques

  1. Le fait d'écrire le SMART_HOST entre crochets [] indique à sendmail de résoudre le nom en type A (serveur) au lieu de type MX (Mail eXchanger).
    Avec de nombreux fournisseurs c'est équivalent, toutefois j'ai constaté qu'avec club-internet, l'absence de crochets provoque la résolution vers un serveur différent, qui refuse tout relais vers Internet.
  2. La ligne contenant SMART_HOST peut être commentée, auquel cas les envois sont faits "directement vers le domaine cible", sans passer par un relais du fournisseur d'accès.
  3. accept_unresolvable_domains et accept_unqualified_senders permettent d'être plus souple sur la réception. Notamment, si les emails sont récupérés par fetchmail, cela évite d'avoir des emails dont l'émetteur est incorrect qui traînent sur le compte POP3 par exemple. En effet fetchmail efface un message seulement après l'avoir envoyé avec succès au mailer local. En principe le fournisseur d'accès fait également des contrôles, mais j'ai eu ce cas pour un SPAM reçu, alors que le domaine émetteur n'existait plus.
  4. confTO_QUEUEWARN et confTO_QUEUERETURN règlent les délais d'avertissement et d'envoi d'erreur. Par défaut elles sont de 4h et 5 jours, pour un ordinateur personnel il vaut mieux avoir des durées beaucoup plus petites. Personnellement je mets respectivement 10 et 30 minutes.
  5. L'option nocanonify permet de router avec succès les emails locaux même si le lien Internet est indisponible - sans cette option, tout envoi d'email même local provoque la résolution du domaine de l'émetteur par le DNS. Cette option rend le système de messagerie de la machine indépendant de la connectivité Internet pour gérer les emails locaux.
    D'après le document /usr/share/doc/sendmail/cf.README.gz, la ligne define(`confBIND_OPTS', `-DNSRCH -DEFNAMES') fait la même chose.
    Attention, sur un lien Internet non permanent, l'absence d'option nocanonify n'est pas un problème, car le fichier /etc/resolv.conf est modifié en fonction des connexions établies (il est vide en l'absence de connexion), et cela modifie le comportement de sendmail.
dnl # Added by me
FEATURE(`nocanonify')dnl
FEATURE(`genericstable')dnl
GENERICS_DOMAIN(`maison-1.perouses.claix.fr')dnl
define(`SMART_HOST', `[mail.club-internet.fr]')dnl
define(`confTO_QUEUERETURN', `30m')dnl
define(`confTO_QUEUEWARN', `10m')dnl
FEATURE(`accept_unresolvable_domains')dnl
FEATURE(`accept_unqualified_senders')dnl

A noter que les lignes :

include(`/etc/mail/m4/dialup.m4')dnl
include(`/etc/mail/m4/provider.m4')dnl

sont inutiles. Leur présence dépend des choix faits lors de la configuration de la messagerie, au tout début de l'installation de Debian.
Il faut les commenter ce qui donne :

dnl # include(`/etc/mail/m4/dialup.m4')dnl
dnl # include(`/etc/mail/m4/provider.m4')dnl

Avec ces modifications, la fin de sendmail.mc doit ressembler à cela :

[...]
dnl #
dnl # If you're on a dialup link, you should enable this - so sendmail
dnl # will not bring up the link (it will queue mail for later)
dnl define(`confCON_EXPENSIVE',`True')dnl
dnl #
dnl # Dialup/LAN connection overrides
dnl #
dnl # include(`/etc/mail/m4/dialup.m4')dnl
dnl # include(`/etc/mail/m4/provider.m4')dnl
dnl #

dnl # Masquerading options
FEATURE(`always_add_domain')dnl
MASQUERADE_AS(`maison-1.perouses.claix.fr')dnl
FEATURE(`allmasquerade')dnl
FEATURE(`masquerade_envelope')dnl

dnl # Added by me
FEATURE(`nocanonify')dnl
FEATURE(`genericstable')dnl
GENERICS_DOMAIN(`maison-1.perouses.claix.fr')dnl
define(`SMART_HOST', `[mail.club-internet.fr]')dnl
define(`confTO_QUEUERETURN', `30m')dnl
define(`confTO_QUEUEWARN', `10m')dnl
FEATURE(`accept_unresolvable_domains')dnl
FEATURE(`accept_unqualified_senders')dnl

dnl # Default Mailer setup
MAILER_DEFINITIONS
MAILER(`local')dnl
MAILER(`smtp')dnl

Si vous êtes connecté à Internet par modem et que le lien met du temps à s'établir, il faut demander à sendmail d'attendre avant de renoncer. Cela dépend de la manière dont vous ouvrez le lien Internet. L'option est dial_delay, 1 minute est une bonne durée. Dans ce cas, ligne à ajouter au fichier /etc/mail/sendmail.mc :

define(`confDIAL_DELAY', `60s')dnl

Fichier /etc/mail/submit.mc
- Ajouter ces lignes pour avoir un comportement identique entre le MSA (port 587) et le MTA (port 25).
Le comportement du MSA est défini par submit.mc, le comportement du MTA est défini par sendmail.mc.

[...]
define(`confTO_QUEUERETURN', `30m')dnl
define(`confTO_QUEUEWARN', `10m')dnl

Fichier /etc/mail/genericstable
- Créer le fichier /etc/mail/genericstable (alias d'émetteurs).
Droits = 644, propriétaire = root.smmsp.

Remarque

On peut définir le même alias pour le super-utilisateur, mais je préfère "aliasser" mon nom uniquement - je n'ai pas de cas où un email émis par root doit quitter ma machine.

# /etc/mail/genericstable
login_name	Internet_email_address
[...]

	Exemple

# /etc/mail/genericstable
sebastien	sebastien.millet1@club-internet.fr

Compilation des fichiers .mc et mise à jour des tables (.db)
- Aller dans /etc/mail et exécuter make :

cd /etc/mail
make

Cela crée le fichier /etc/mail/genericstable.db. Pour mettre à jour ce fichier en particulier sans exécuter "make", utiliser makemap (utilitaire fourni avec sendmail) ainsi :

cd /etc/mail
makemap hash genericstable < genericstable

Il semble que make doive être exécuté deux fois de suite pour que le fichier genericstable.db soit créé.

Fichier /etc/mail/sendmail.conf
Ici se trouvent les paramètres de sendmail en tant que service (à la mode Debian), notamment la période de parcours des queues de messages. Personnellement je les mets à 5 minutes chacune.

Il faut également contrôler que les démons sont exécutés dans le mode qui vous convient. Mais encore ? Par défaut, le MTA (port 25) fonctionne en mode démon, alors que le MSP (port 587) fonctionne avec "cron". Dans ce cas le MSP n'est pas un démon au sens système du terme, c'est un processus à exécution unique qui est lancé régulièrement par cron. Cela revient au même, mais personnellement, je préfère que les deux processus soient de véritables démons. Pourquoi ?
Est-ce que j'en pose, moi, des questions ? Je préfère, c'est tout. Qu'on se le dise.
En bref, il faut s'assurer que les valeurs de QUEUE_MODE et MSP_MODE sont "daemon" et non pas "none" ou "cron".
Dans l'extrait ci-dessous, QUEUE_MODE est à la bonne valeur car plus haut dans le fichier, la variable DAEMON_MODE est définie à "Daemon".

Lignes après modification :

[...]
QUEUE_MODE="${DAEMON_MODE}";
[...]
QUEUE_INTERVAL="5m";
[...]
MSP_MODE="daemon";
[...]
MSP_INTERVAL="5m";
[...]

Redémarrage de sendmail
Une fois la configuration modifiée, et make exécuté, lancer :

/etc/init.d sendmail reload

Re-configuration complète de sendmail
Si le type de fonctionnement de sendmail change - modification du mode d'exécution du démon ou du queue runner, par exemple exécution par CRON au lieu de queue runner "démon" (autonome) - il faut exécuter la commande :

sendmailconf (anciennes versions)
	ou
sendmailconfig (versions plus récentes)

2.3 Configuration de Fetchmail

Le paquetage à installer est fetchmail. Exemple d'un dpkg-query pour vérifier le paquetage installé :

sebastien@maison-1:~$ dpkg-query -l fetchmail
Souhait=inconnU/Installé/suppRimé/Purgé/H=à garder
| État=Non/Installé/fichier-Config/dépaqUeté/échec-conFig/H=semi-installé
|/ Err?=(aucune)/H=à garder/besoin Réinstallation/X=les deux (État,Err: majuscule=mauvais)
||/ Nom                                 Version                             Description
+++-===================================-===================================-======================================================================================
ii  fetchmail                           6.3.4-3                             SSL enabled POP3, APOP, IMAP mail gatherer/forwarder
sebastien@maison-1:~$

2.3.1 Cas avec une connexion Internet permanente

Avec l'ADSL la connexion est le plus souvent permanente (activée au démarrage), et le plus simple est de lancer fetchmail en tant que démon système, lors du démarrage. Cela suppose de l'activer en tant que service, et de créer un fichier /etc/fetchmailrc.

Activation de fetchmail en tant que service
- Installer le paquetage Debian rcconf. Ce programme est une interface au programme update-rc.d, qui permet de régler les services démarrés automatiquement en fonction du runlevel.
Exemple d'un dpkg-query pour vérifier le paquetage installé :

sebastien@maison-1:~$ dpkg-query -l rcconf
Souhait=inconnU/Installé/suppRimé/Purgé/H=à garder
| État=Non/Installé/fichier-Config/dépaqUeté/échec-conFig/H=semi-installé
|/ Err?=(aucune)/H=à garder/besoin Réinstallation/X=les deux (État,Err: majuscule=mauvais)
||/ Nom                                 Version                             Description
+++-===================================-===================================-======================================================================================
ii  rcconf                              1.19                                Debian Runlevel configuration tool
sebastien@maison-1:~$

- Une fois installé, invoquer rcconf avec la commande... rcconf, tout simplement.
- Dans l'interface de rcconf, cocher fetchmail.

Activer le démon fetchmail au démarrage en modifiant le fichier /etc/default/fetchmail.
Contenu du fichier après modification :

# This file will be used to declare some vars for fetchmail

# Declare here if we want to start fetchmail. 'yes' or 'no'
START_DAEMON=yes

Configuration du service fetchmail
Créer le fichier /etc/fetchmailrc avec des lignes "poll" pour chaque compte à récupérer localement.
Droits = 600, propriétaire = fetchmail.root.
Les droits sont très restreints car ce fichier contient toutes les informations (nom, mot de passe) pour récupérer les emails sur les serveurs.

Remarques

  1. Par défaut fetchmail enverra sa sortie vers le log (de type "mail" => fichiers /var/log/mail.*).
    Ainsi la commande set syslog est facultative. Qui plus est elle pourrait empêcher de programmer un contrôle automatique de fetchmail avec CRON, voir plus loin.
  2. L'option fetchlimit est facultative, elle permet de lisser un peu la réception au retour de vacances... ;-)
  3. La ligne set daemon 300 provoque un réveil du démon toutes les 5 minutes.
  4. Il serait logique de faire envoyer par fetchmail les emails au MSA, port 587. Mais fetchmail (version 6.3.4+NTLM+SDPS+SSL+NLS) semble ignorer les paramètres tels que smtphost localhost/587 ou bien smtphost localhost/submission.
  5. Plutôt que d'invoquer sendmail en loopback, il est possible de l'invoquer directement. Cela permet de désactiver le démon sendmail à l'écoute des ports 25 et 587, et de ne laisser qu'un queue runner sur le système - seulement si vous êtes parano.
  6. Auparavant, l'option flush était sensée éviter que des emails déjà récupérés, mais non supprimés pour une raison quelconque (par exemple lors d'une déconnexion du serveur intempestive), ne restassent indéfiniment sur le serveur - c'est le comportement de fetchmail par défaut !
    Finalement suite à des tests effectués, il semble que cette option soit à éviter. Depuis la version 1.2 de ce document, l'option flush n'est plus utilisée.
    En revanche l'option fetchall a été ajoutée, pour éviter de laisser des emails indéfiniment sur le serveur POP3. Avec cette option il y a un risque de télécharger un même email plusieurs fois.

Bref. Exemple avec mon fichier /etc/fetchmailrc :

# /etc/fetchmailrc

# General settings
set daemon 300

# Poll commands
poll pop.free.fr protocol pop3 uidl user sebastien.millet password mypwd fetchlimit 100 is sebastien here
poll pop.libertysurf.fr protocol pop3 uidl user smil0014_1_lsurf password myotherpwd fetchlimit 100 is sebastien here
poll pop3.club-internet.fr protocol pop3 uidl user sebastien.millet1 password yetanotherpwd fetchlimit 100 is sebastien here

Exemple d'une ligne "poll" avec exécution de sendmail à la place d'une connection TCP locale :

poll pop.free.fr protocol pop3 user sebastien.millet password guessit fetchlimit 30 mda "/usr/sbin/sendmail -i -f %F %T" fetchall is sebastien here

Test régulier de l'état des boîtes aux lettres sur les serveurs
Ce lancement d'un fetchmail de test à intervalle régulier contrôle s'il reste des emails bloqués sur un compte.
Par exemple, si l'émetteur a une mauvaise syntaxe, fetchmail échouera à chaque envoi vers le mailer local, et laissera le message indéfiniment sur le serveur.
La solution est d'exécuter fetchmail en mode "check" (option -c) avec CRON, en lui donnant /etc/fetchmailrc comme fichier de configuration, et en envoyant sa sortie dans un mail.
Attention, si ce fichier contient la ligne "set syslog", l'exécution de fetchmail, bien que de type "non démon" dans ce cas (puisque lancement par cron), enverra la sortie vers le LOG au lieu de la sortie standard. Cela provoquera l'envoi d'emails... vides !
Plus haut on a activé les options accept_unresolvable_domains et accept_unqualified_senders afin de diminuer le risque d'être confronté à des emails jamais enlevés des serveurs.

- Se loguer en tant qu'utilisateur fetchmail - comme c'est un pseudo-utilisateur sans mot de passe, se loguer en tant que root et exécuter su - fetchmail.
- Éditer la crontab de l'utilisateur fetchmail avec la commande crontab -e
- Saisir le contenu ci-dessous.

Remarques

  1. On n'utilise pas le mécanisme d'envoi de mail par défaut de CRON, afin de définir le sujet de l'email à notre convenance.
  2. Dans l'exemple ci-dessous, l'exécution est faite chaque jour à 21:30.
  3. Le "\" devant le "%" évite la collision avec CRON qui interprète ce caractère.
  4. Dans mon cas, POSTMASTER est redirigé vers root, qui est redirigé vers sebastien. Ainsi j'aurais pu mettre directement sebastien comme destinataire.
  5. L'option --pidfile n'apporte pas grand chose, je l'ai ajoutée pour faire joli. Et alors ?
  6. Si le lien Internet est indisponible au moment de l'exécution de cette tâche, un fichier vide est émis.
# m h  dom mon dow   command
MAILTO=""
30 21 * * *	/usr/bin/fetchmail -c -f /etc/fetchmailrc --pidfile /var/run/fetchmail/fetchmail-check.pid | mail -s"Statut messagerie `date +\%D`" POSTMASTER

Avec cette programmation dans CRON, je reçois chaque jour à 21:30 un email comme celui-ci :

Statut messagerie 06/15/06
(fetchmail@maison-1.perouses.claix.fr, Thu Jun 15 21:30:09 2006)

fetchmail: Aucun message pour sebastien.millet dans pop.free.fr
fetchmail: Aucun message pour smil0014_1_lsurf dans pop.libertysurf.fr
fetchmail: Aucun message pour sebastien.millet1 dans pop3.club-internet.fr

2.3.2 Cas avec une connexion Internet non permanente

C'est en général le cas avec les connexions RTC (par modem, à travers la ligne téléphonique standard).
Fetchmail doit être démarré/arrêté soit manuellement (par script), soit au moment de la connexion/déconnexion du lien avec le fournisseur d'accès.

Avant de se préoccuper de démarrer/arrêter Fetchmail, il faut d'abord le configurer. Contrairement au fichier /etc/fetchmailrc décrit plus haut, ici le fichier de configuration est spécifique à l'utilisateur qui actionne Fetchmail, ce qui change légèrement le contenu.

Exemple de fichier ~/fetchmailrc
Remarquez qu'on ne précise plus ici l'utilisateur auquel envoyer les emails - si nécessaire, on démarrera fetchmail avec un sudo pour définir explicitement le propriétaire du processus.
De plus on a enlevé la commande set daemon, car on précisera la période de réveil du démon en paramètre de la ligne de commande qui lance fetchmail.

# /home/sebastien/.fetchmailrc
poll pop.free.fr protocol pop3 user sebastien.millet password mypwd fetchlimit 30

Solutions possibles pour démarrer/arrêter Fetchmail

  1. A la main, par un script.
  2. Dans les pre et post job du programme d'ouverture de la connexion (kppp par exemple).
    Cette solution est la plus simple, mais on perd le cloisonnement entre le système et l'interface utilisateur.
  3. Pre et post job de l'interface réseau, ppp en général. C'est ma méthode préférée - 100% automatique et c'est *le* bon endroit pour placer ce code.
2.3.2.1 Démarrer/arrêter Fetchmail à la main, par un script

Remarquez que les noms des scripts ne contiennent pas le mot "fetchmail" intégralement, pour éviter que la commande pgrep ne renvoie le PID du script d'arrêt de fetchmail, ce qui le rendrait inutilisable.
Ces scripts sont minimalistes et un peu sales, des scripts plus élaborés permettent de contrôler de manière parfaitement fiable l'arrêt/redémarrage d'un programme donné. A améliorer donc...

Script de démarrage - start_fetchm

#!/bin/sh
#
# /home/sebastien/scripts/start_fetchm
#
# Start fetchmail daemon with:
#   Retrieval every minute
#   Output to syslog
#

# FIXME : il faudrait ici vérifier si fetchmail n'est pas déjà lancé.

/usr/bin/fetchmail -d 60 --syslog
sleep 1
FPID=`pgrep -u sebastien fetchmail`
if [ "$FPID" = "" ]; then
	echo ERROR: failed to start fetchmail.
else
	echo Fetchmail running with pid $FPID.
fi

echo "Press [ENTER] key."
read

Script d'arrêt - stop_fetchm

#!/bin/sh
#
# /home/sebastien/scripts/stop_fetchm
#
# Stop fetchmail daemon
#

FPID=`pgrep -u sebastien fetchmail`
if [ "$FPID" = "" ]; then
	echo ERROR: no fetchmail process currently running.
else
	kill $FPID
	sleep 1
	FPID=`pgrep -u sebastien fetchmail`
	if [ "$FPID" = "" ]; then
		echo Fetchmail stopped successfully.
	else
		echo ERROR: failed to stop fetchmail.
	fi
fi

echo "Press [ENTER] key."
read
2.3.2.2 Démarrer/arrêter Fetchmail dans les pre et post job du programme d'ouverture de la connexion

Exemple avec kppp

Dans les paramètres du compte de kppp, page Exécution, champ Après la connexion, écrire la commande suivante :

/usr/bin/sudo -H -u sebastien /usr/bin/fetchmail -d 60 --syslog

Dans le champ Avant la déconnexion, écrire :

kill `pgrep -u login_name fetchmail`

Ces scripts supposent que kppp fait un SUID root et lance les scripts en tant que root. Cela rend nécessaire l'invocation de fetchmail par sudo. Du coup root doit être autorisé à faire le sudo en question. Tout cela est un peu gruiiik.
Pour éviter de passer par sudo lorsque l'utilisateur qui invoque le script n'est pas le bon, vous pouvez aussi préciser à la fin des lignes poll l'utilisateur local (is login_name here), et démarrer fetchmail avec l'option -f pour indiquer quel fichier de configuration utiliser.
Enfin, une dernière solution pour éviter sudo est d'utiliser su -c.
sudo est configuré dans /etc/sudoers, semble-t-il aussi dans /etc/pam.d/sudo, mais par défaut ce dernier fichier ne contient aucun test.
La commande visudo est recommandée pour éditer /etc/sudoers.
su est configuré dans /etc/pam.d/su.
Naturellement, cela est vrai seulement si vous avez installé PAM, cf. Remarque au sujet de PAM, dans le document Trucs et Astuces sur Debian Testing (janvier - février 2007)

2.3.2.3 Démarrer/arrêter Fetchmail dans les pre et post job de l'interface réseau

On suppose ici que l'interface réseau est ppp, ce qui correspond à un modem sur une ligne téléphonique standard.
Pour d'autres interfaces l'emplacement sera différent de /etc/ppp/ip-{up,down}.d, mais le principe sera le même.

Démarrage de fetchmail
Créer le fichier /etc/ppp/ip-up.d/90login_name ci-dessous.
Droits = 755, propriétaire = root.root.

Remarque : le sudo peut être évité, cf. plus haut.

#!/bin/sh
#
# /etc/ppp/ip-up.d/90sebastien
# Script to launch retrieval of new mails for sebastien account
# Needs sebastien' .fetchmailrc file (/home/sebastien/.fetchmailrc).

/usr/bin/sudo -H -u sebastien /usr/bin/fetchmail -d 60 --syslog

Arrêt de fetchmail
Créer le fichier /etc/ppp/ip-down.d/90login_name ci-dessous.
Droits = 755, propriétaire = root.root.

#!/bin/sh
#
# /etc/ppp/ip-down.d/90sebastien
# Script to stop fetchmail of sebastien

kill `pgrep -u sebastien fetchmail`

Attention
Le paquetage fetchmail installe des fichiers dans /etc/ppp/ip-up.d/ et /etc/ppp/ip-down.d/, de nom fetchmail, lorsqu'il est activé en tant que service. Si c'est le cas, il faut faire attention à ce qu'il n'y ait pas de contradiction entre votre script et celui-là. Comme ces scripts font un peu la même chose, a priori, il est illogique qu'ils existent au même moment.
Cela étant s'il y a besoin d'un code spécifique pour intervenir sur le démarrage/arrêt de fetchmail, il faut dans la mesure du possible créer un fichier spécifique plutôt que de modifier /etc/ppp/ip-{up, down}.d/fetchmail. En effet ces fichiers font partie du paquetage fetchmail, et s'ils sont modifiés, apt vous demandera quoi faire à chaque migration de fetchmail (à vérifier).

2.4 Configuration de SpamAssassin

2.4.1 Installation de SpamAssassin

Le paquetage à installer est spamassassin. Exemple d'un dpkg-query pour vérifier le paquetage installé :

sebastien@maison-1:~$ dpkg-query -l spamassassin
Souhait=inconnU/Installé/suppRimé/Purgé/H=à garder
| État=Non/Installé/fichier-Config/dépaqUeté/échec-conFig/H=semi-installé
|/ Err?=(aucune)/H=à garder/besoin Réinstallation/X=les deux (État,Err: majuscule=mauvais)
||/ Nom                                 Version                             Description
+++-===================================-===================================-======================================================================================
ii  spamassassin                        3.1.1-1                             Perl-based spam filter using text analysis
sebastien@maison-1:~$

2.4.2 Lancement de SpamAssassin au démarrage

SpamAssassin peut être utilisé de deux façons : avec la commande spamassassin, ou bien avec la commande spamc, qui travaille en duo avec le démon spamd. La première méthode a l'avantage de la simplicité - pas de démon à démarrer - la deuxième est plus performante.
L'URL http://svn.apache.org/repos/asf/spamassassin/branches/3.1/spamd/README donne des mesures faites pour comparer la performance de spamassassin et spamc/spamd, en version 3.1.x. La différence est impressionnante.
C'est la deuxième méthode (spamc/spamd) que nous employons ici.
Par défaut SpamAssassin utilise une base de données (dans ~/.spamassassin) par utilisateur. Il est possible de le configurer pour avoir une seule base partagée par tous, mais les droits sur le répertoire contenant la base sont délicats à définir. MySQL permet de contourner la difficulté.
Ici nous utilisons SpamAssassin avec une base par utilisateur.

Pour lancer SpamAssassin au démarrage, faire appel à rcconf (cf. plus haut) pour cocher spamassassin. Ensuite modifier le fichier /etc/default/spamassassin.
Extrait de ce fichier, après modification :

[...]
ENABLED=1
[...]

2.4.3 Appel de SpamAssassin juste avant le délivrement des messages

Pour passer les mails de moins de 512 Ko à SpamAssassin, avant délivrement à l'utilisateur, créer le fichier .procmailrc approprié dans la racine de son répertoire personnel.
Plus loin, est également donné un exemple de fichier permettant de différencier, avec l'aide de procmail, les SPAMs certains ("SPAM-score" >= 10 par ex.) et probables.
Fichier ~/.procmailrc à créer :

# Run Procmail as user
DROPPRIV=yes

:0 fw
	* < 512000
	| /usr/bin/spamc

2.4.4 Configuration de SpamAssassin

Fichier Configuration Exemple
/etc/default/spamassassin Démon spamd
Uniquement si utilisation de spamc/spamd, cf. 2.4.2
Nombre de threads, priorité du processus (nice)
/etc/mail/spamassassin/local.cf Réglage du filtrage Ajout de *SPAM* au sujet, définition des scores pour certaines règles
~/.spamassassin/user_prefs Réglage du filtrage par utilisateur Idem que /etc/mail/spamassassin/local.cf, mais par utilisateur

Mon fichier /etc/default/spamassassin

# /etc/default/spamassassin
# Duncan Findlay

# WARNING: please read README.spamd before using.
# There may be security risks.

# Change to one to enable spamd
ENABLED=1

# Options
# See man spamd for possible options. The -d option is automatically added.

# SpamAssassin uses a preforking model, so be careful! You need to
# make sure --max-children is not set to anything higher than 5,
# unless you know what you're doing.

OPTIONS="--create-prefs --max-children 20 --helper-home-dir"

# Pid file
# Where should spamd write its PID to file? If you use the -u or
# --username option above, this needs to be writable by that user.
# Otherwise, the init script will not be able to shut spamd down.
PIDFILE="/var/run/spamd.pid"

# Set nice level of spamd
#NICE="--nicelevel 15"

Mon fichier /etc/mail/spamassassin/local.cf

# This is the right place to customize your installation of SpamAssassin.
#
# See 'perldoc Mail::SpamAssassin::Conf' for details of what can be
# tweaked.
#
# Only a small subset of options are listed below
#
###########################################################################

#   Add *****SPAM***** to the Subject header of spam e-mails
#
# rewrite_header Subject *****SPAM*****


#   Save spam messages as a message/rfc822 MIME attachment instead of
#   modifying the original message (0: off, 2: use text/plain instead)
#
# report_safe 1


#   Set which networks or hosts are considered 'trusted' by your mail
#   server (i.e. not spammers)
#
# trusted_networks 212.17.35.


#   Set file-locking method (flock is not safe over NFS, but is faster)
#
# lock_method flock


#   Set the threshold at which a message is considered spam (default: 5.0)
#
required_score 4.0


#   Use Bayesian classifier (default: 1)
#
use_bayes 1


#   Bayesian classifier auto-learning (default: 1)
#
bayes_auto_learn 1


#   Set headers which may provide inappropriate cues to the Bayesian
#   classifier
#
bayes_ignore_header X-Bogosity
bayes_ignore_header X-Spam-Flag
bayes_ignore_header X-Spam-Status
bayes_ignore_header X-Spam-Level
bayes_ignore_header X-Spam-HighScore

Mon fichier /home/sebastien/.spamassassin/user_prefs

# SpamAssassin user preferences file.  See 'perldoc Mail::SpamAssassin::Conf'
# for details of what can be tweaked.
###########################################################################

# Whitelist and blacklist addresses are now file-glob-style patterns, so
# "friend@somewhere.com", "*@isp.com", or "*.domain.net" will all work.
# whitelist_from	someone@somewhere.com

# Add your own customised scores for some tests below.  The default scores are
# read from the installed spamassassin rules files, but you can override them
# here.  To see the list of tests and their default scores, go to
# http://spamassassin.apache.org/tests.html .
#
# score SYMBOLIC_TEST_NAME n.nn

# Speakers of Asian languages, like Chinese, Japanese and Korean, will almost
# definitely want to uncomment the following lines.  They will switch off some
# rules that detect 8-bit characters, which commonly trigger on mails using CJK
# character sets, or that assume a western-style charset is in use. 
# 
# score HTML_COMMENT_8BITS	0
# score UPPERCASE_25_50		0
# score UPPERCASE_50_75		0
# score UPPERCASE_75_100	0
# score OBSCURED_EMAIL          0

# Speakers of any language that uses non-English, accented characters may wish
# to uncomment the following lines.   They turn off rules that fire on
# misformatted messages generated by common mail apps in contravention of the
# email RFCs.

# score SUBJ_ILLEGAL_CHARS      0

score BAYES_99	4.0

bayes_expiry_max_db_size	500000

bayes_min_ham_num	100
bayes_min_spam_num	150

Problème avec SpamAssassin sur Testing 2007 (janvier - mars)
SpamAssassin ne se connecte pas au réseau.

Il manque le module PERL Net::DNS::Resolver, cela est visible en activant le debug DNS (-D dns ajouté aux options de spamd). Dans le log on trouve cette ligne :
[...] spamd[...]: dns: is Net::DNS::Resolver available? no
Pour corriger cela, installer le paquetage libnet-dns-perl.

2.4.5 Entraînement de SpamAssassin

Pour être efficace, l'algorithme baysien (BAYES) doit être nourri avec des emails légitimes (HAMs), et avec des pourriels (SPAMs). Avec cette base d'emails des deux types, l'algorithme calcule une probabilité pour qu'un email examiné soit du SPAM, en fonction de la "distance" aux HAMs et aux SPAMs. L'algorithme est fort complexe.
La commande sa-learn entraîne SpamAssassin. sa-learn --ham pour nourrir la base avec des emails légitimes, sa-learn --spam pour nourrir la base avec des SPAMs.
sa-learn peut être employé de deux manières.

  1. Filtres
    Les programmes de Mail évolués (KMail, evolution, ...) permettent de créer des filtres pour appliquer une commande donnée aux messages sélectionnés. Conseil : mieux vaut les premières fois envoyer le résultat de la commande dans un fichier journal (log), pour s'assurer que le filtre fait son travail. C'est énervant de découvrir au bout de 1 mois que l'apprentissage ne se fait pas, à cause d'un problème de droits sur le fichier des tokens (~/.spamassassin/bayes_toks). C'est du vécu ;-).
  2. Ligne de commande - script
    Vous pouvez demander à sa-learn de lire directement votre base courrier.
    sa-learn reconnaît les formats mbox et mbx ainsi que les formats "un fichier par email" tels que Maildir, cf. plus loin.
2.4.5.1 Entraînement de SpamAssassin avec des filtres

Ci-dessous, commande sa-learn lancée par le filtre "Apprends HAM", créé dans KMail.

echo "Learning HAM..." >> ~/sa-learn.debug ; /usr/bin/sa-learn --ham >> ~/sa-learn.debug 2>&1

L'option -D (debug) produit une grande quantité d'informations (non utilisée ici).
Après application du filtre à un ensemble d'emails, le fichier ~/sa-learn.debug contient le journal de sa-learn.
La redirection en mode ajout (">>") permet de conserver tous les résultats, même si le filtre est appliqué à plusieurs emails simultanément.
Pour l'apprentissage des SPAMs, remplacer --ham par --spam.

2.4.5.2 Entraînement de SpamAssassin en ligne de commande

Les commandes à exécuter dépendent du format de base courrier. Il existe de nombreux formats, et il n'est pas toujours facile de s'y retrouver. L'URL http://www.washington.edu/imap/documentation/formats.txt.html est datée (1999) mais donne des informations intéressantes sur les formats existants.

Passons à un aperçu rapide (et non exhaustif) des formats que l'on rencontre.

Formats de base courrier

Exemple de script

Le script ci-dessous envoie quasiment toute la base courrier à sa-learn.
Les SPAMs doivent se trouver dans n'importe quel fichier ou sous-répertoire de ~/Mail/spam*, les HAMs pris en compte sont n'importe où ailleurs, à l'exception de quelques dossiers spéciaux tels que Envoyés (sent), brouillons (drafts), etc., qui sont ignorés.

#!/bin/sh
#
# ~/scripts/sal
#
# Learn SPAM and HAM emails of my email account, of type MAILDIR.
#
# This script assumes SPAM emails are located in any spam* folder (under $MAILDIR)
# And it will consider all other folders except drafts, outbox, sent-mail and trash, as a
# HAM email source.
# Therefore any folder other than the above will be taken as a HAM reference, *INCLUDING THE inbox FOLDER*.
# Names given above are case insensitive (egrep is invoked with -i option).
# The root ($MAILDIR itself) is ignored.
# Only directories ending by /cur are processed.
#
# Previous version did not manage directories containing space characters correctly.
# Now it works fine.
#

MAILDIR="$HOME/Mail"

# Remove comments below if you wish to sync your database before proceeding.
# echo "Syncing database..."
# sa-learn --sync

cd $MAILDIR

echo "Learning SPAM emails..."
find . -type d | egrep -i "^\.\/\.?spam.*\/cur$" | while read d; do
	echo SPAM:$d
	sa-learn --showdots --spam "$d"
done

echo "Learning HAM emails..."
find . -type d | egrep -iv "^\.(\/(drafts|outbox|sent-mail|trash|\.?spam[^/]*)(\/|$)|$)" | egrep "/cur$" | while read d; do
	echo HAM:$d
	sa-learn --showdots --ham "$d"
done

echo "Press [ENTER] key."
read

2.4.6 Différencier plusieurs types de SPAM avec procmail

Avec SpamAssassin, lorsqu'un SPAM est détecté, le champ X-Spam-Level contient un nombre d'étoiles égal au score. Cela va permettre à procmail de déclencher des actions à partir d'un certain nombre d'étoiles.
Ci-dessous, un fichier ~/.procmailrc pour ajouter "X-Spam-HighScore : YES" aux en-têtes des emails quand le "SPAM-score" est supérieur ou égal à 10.

# Run Procmail as user
DROPPRIVS=yes

# Limit above which to add "X-Spam-HighScore: YES" header to emails
# Replace 10 by any suitable value.
STARS=`s=""; for ((i=1; $i<=10; i++)); do s="\*"$s; done; echo $s`

:0 fw
	* < 512000
	| /usr/bin/spamc

:0 fHh
	* $^X-Spam-Level *: *$STARS
	| formail -A"X-Spam-HighScore: YES"

Il pourrait sembler plus simple d'utiliser une expression telle que "* ^X-Spam-Level *: *\*{10,}" pour détecter dix étoiles et plus (la virgule précédant l'accolade fermante est optionnelle, je vous laisse deviner pourquoi), mais ça ne fonctionne pas ! Idem pour l'espace entourant le ":", que l'on devrait plutôt écrire [[:space:]], mais ça ne fonctionne pas non plus.
Si la méthode choisie vous défrise (elle est peu performante), vous pouvez remplacer la ligne

	* $^X-Spam-Level *: *$STARS
par
	* ^X-Spam-Level *: *\*\*\*\*\*\*\*\*\*\*

et bien sûr supprimer la ligne

STARS=`s=""; for ((i=1; $i<=10; i++)); do s="\*"$s; done; echo $s`

Remarquez que l'on a enlevé le $ qui précède l'expression. Il permet la substitution de $STARS en sa valeur.
Il ne reste plus qu'à différencier les emails possédant l'en-tête X-Spam-HighScore: YES, en les classant dans un dossier spam-highscore par exemple. Cette opération nécessite un filtre, cf. 2.5 Programme de mail (GUI)

Fichier ~/.procmailrc pour supprimer les emails dont le score est supérieur ou égal à 10.
* Attention *
Cet exemple est à utiliser avec précaution, une erreur dans le test et des emails légitimes pourraient être supprimés.

# Run Procmail as user
DROPPRIVS=yes

# Limit above which to add "X-Spam-HighScore: YES" header to emails
# Replace 10 by any suitable value.
STARS=`s=""; for ((i=1; $i<=10; i++)); do s="\*"$s; done; echo $s`

:0 fw
	* < 512000
	| /usr/bin/spamc

:0 fHh
	* $^X-Spam-Level *: *$STARS
	/dev/null

Pour plus de sécurité, vous pouvez aussi ajouter un test vérifiant que l'email a bien été détecté comme étant du SPAM - si par erreur le test comptant les étoiles de X-Spam-Level se révèle toujours "VRAI", seuls les SPAMs seront supprimés. Fichier :

# Run Procmail as user
DROPPRIVS=yes

# Limit above which to add "X-Spam-HighScore: YES" header to emails
# Replace 10 by any suitable value.
STARS=`s=""; for ((i=1; $i<=10; i++)); do s="\*"$s; done; echo $s`

:0 fw
	* < 512000
	| /usr/bin/spamc

:0 fHh
	* $^X-Spam-Level *: *$STARS
	* ^X-Spam-Flag *: *YES
	/dev/null

2.4.7 Étudier les SPAMs

Script sa-stats.pl

L'URL http://wiki.apache.org/spamassassin/StatsAndAnalyzers, accessible depuis la FAQ du site SpamAssassin, lien de nom StatsAndAnalyzers, donne de nombreux scripts d'analyse. En général, ils analysent les journaux (logs) du démon spamd.
Ce sont souvent des usines à gaz, adaptées à des serveurs traitant des volumes importants d'emails.
Pour un particulier, le script sa-stats.pl est simple et rapide. Attention, il en existe deux :

  1. Le script mentionné comme faisant partie du paquetage SpamAssassin (mais il n'en fait pas partie sur ma distribution Debian Etch), accessible à l'URL http://spamassassin.apache.org/full/3.1.x/dist/tools/sa-stats.pl (pour SpamAssassin version 3.1.x).
    Ce script indique, heure par heure, le nombre de SPAMs reçus. Pour un particulier, il n'est pas très intéressant.
  2. Le script "Dallas Engelken's version", accessible depuis la page StatsAndAnalyzers du site de SpamAssassin (FAQ), URL du script http://www.rulesemporium.com/programs/sa-stats.txt (enregistrer la cible sous le nom sa-stats.pl).
    Ce script indique quelles règles interviennent dans l'identification de SPAM et de HAM, en les affichant par nombre d'occurrences décroissant.

C'est le deuxième script ("Dallas Engelken") que nous allons employer.
Dans les exemples ci-dessous, nous supposons que les journaux se trouvent dans /var/log/mail.log*, et que logrotate les gzip régulièrement - c'est la configuration par défaut. Enfin, le script sa-stats.pl se situe dans le répertoire courant.

	Analyse le journal en cours
./sa-stats.pl -f mail.log

	Analyse tous les journaux disponibles
zcat /var/log/mail.log.*.gz > ~/tmplog
cat /var/log/mail.log.0 /var/log/mail.log >> ~/tmplog
./sa-stats.pl -l ~ -f tmplog

	Exemple avec résultat - analyse d'anciens journaux
maison-1:~# zcat /var/log/mail.log.*.gz > ~/tmplog
maison-1:~# ./sa-stats.pl -n 5 -l ~ -f tmplog
Email:     5016  Autolearn:  3104  AvgScore:  21.84  AvgScanTime:  3.03 sec
Spam:      4643  Autolearn:  3035  AvgScore:  23.50  AvgScanTime:  3.14 sec
Ham:        373  Autolearn:    69  AvgScore:   1.20  AvgScanTime:  1.62 sec

Time Spent Running SA:         4.22 hours
Time Spent Processing Spam:    4.05 hours
Time Spent Processing Ham:     0.17 hours

TOP SPAM RULES FIRED
----------------------------------------------------------------------
RANK    RULE NAME                       COUNT  %OFMAIL %OFSPAM  %OFHAM
----------------------------------------------------------------------
   1    HTML_MESSAGE                     3296    69.56   70.99   51.74
   2    RCVD_IN_XBL                      2366    47.19   50.96    0.27
   3    DNS_FROM_RFC_ABUSE               2237    46.35   48.18   23.59
   4    SUBJ_ILLEGAL_CHARS               2125    42.36   45.77    0.00
   5    MIME_HTML_ONLY                   1935    40.25   41.68   22.52
----------------------------------------------------------------------

TOP HAM RULES FIRED
----------------------------------------------------------------------
RANK    RULE NAME                       COUNT  %OFMAIL %OFSPAM  %OFHAM
----------------------------------------------------------------------
   1    HTML_MESSAGE                      193    69.56   70.99   51.74
   2    AWL                               130     4.65    2.22   34.85
   3    DNS_FROM_RFC_ABUSE                 88    46.35   48.18   23.59
   4    MIME_HTML_ONLY                     84    40.25   41.68   22.52
   5    ALL_TRUSTED                        47     0.96    0.02   12.60
----------------------------------------------------------------------


maison-1:~#

	Autre exemple avec résultats - uniquement journaux récents
maison-1:~# cat /var/log/mail.log.0 /var/log/mail.log > ~/tmplog
maison-1:~# ./sa-stats.pl -n 5 -l ~ -f tmplog
Email:     1805  Autolearn:  1198  AvgScore:  24.56  AvgScanTime:  5.26 sec
Spam:      1733  Autolearn:  1153  AvgScore:  25.63  AvgScanTime:  5.25 sec
Ham:         72  Autolearn:    45  AvgScore:  -1.29  AvgScanTime:  5.46 sec

Time Spent Running SA:         2.64 hours
Time Spent Processing Spam:    2.53 hours
Time Spent Processing Ham:     0.11 hours

TOP SPAM RULES FIRED
----------------------------------------------------------------------
RANK    RULE NAME                       COUNT  %OFMAIL %OFSPAM  %OFHAM
----------------------------------------------------------------------
   1    BAYES_99                         1683    93.63   97.11    9.72
   2    HTML_MESSAGE                     1147    64.71   66.19   29.17
   3    RCVD_IN_XBL                      1019    56.45   58.80    0.00
   4    DNS_FROM_RFC_ABUSE                891    49.70   51.41    8.33
   5    MIME_HTML_ONLY                    837    46.98   48.30   15.28
----------------------------------------------------------------------

TOP HAM RULES FIRED
----------------------------------------------------------------------
RANK    RULE NAME                       COUNT  %OFMAIL %OFSPAM  %OFHAM
----------------------------------------------------------------------
   1    BAYES_00                           57     3.16    0.00   79.17
   2    AWL                                54     4.54    1.62   75.00
   3    ALL_TRUSTED                        35     1.99    0.06   48.61
   4    HTML_MESSAGE                       21    64.71   66.19   29.17
   5    NO_REAL_NAME                       12    11.19   10.96   16.67
----------------------------------------------------------------------


maison-1:~#

On voit dans ces deux exemples que l'apprentissage baysien (règles BAYES_nn) et l'auto-whitelist (AWL) monte en puissance avec le temps.
L'URL http://spamassassin.apache.org/tests.html décrit tous les tests effectués par SpamAssassin, par défaut.

Quel score BAYES en général ?

Exécuter la commande

egrep "spamd.*result:.*\<bayes=" /var/log/mail.log | sed 's/.*bayes=\([0-9.e-]\+\).*/\1/' | sed 's/.*e-.*/0/' | sort -nr | cat -n
	Ou bien, pour parcourir les LOGs gzippés
zcat /var/log/mail.log.*.gz | egrep "spamd.*result:.*\<bayes=" | sed 's/.*bayes=\([0-9.e-]\+\).*/\1/' | sed 's/.*e-.*/0/' | sort -nr | cat -n

J'ai pu voir avec cette commande que la plupart des SPAMs avaient un score proche de 1, ce qui confirme la pertinence du test baysien. Cela nous amène logiquement à la rubrique suivante.

SpamAssassin en mode local

Puisque BAYES et AWL font tout, autant aller jusqu'au bout de la logique et demander à SpamAssassin de ne plus faire appel aux tests réseau (RBL, razor, etc.) pour examiner un email. Les règles habituelles, ainsi que l'apprentissage BAYES, devraient suffire.
Lorsque le démon SpamAssassin (spamd) est invoqué avec l'option -L, aucune connexion réseau n'est faite. Pour passer ce paramètre au démon démarré en tant que service, modifier le fichier /etc/default/spamassassin. Remplacer la ligne
OPTIONS="--create-prefs --max-children 20 --helper-home-dir"
par
OPTIONS="--create-prefs --max-children 20 --helper-home-dir -L"

Ensuite, il est préférable de configurer l'affectation des scores en conséquence, dans le fichier /etc/mail/spamassassin/local.cf.
Dans l'exemple qui suit les scores sont tels qu'à partir de bayes=95%, un email est d'office classé SPAM, et à partir de bayes=80%, il suffit d'un rien pour le passer en SPAM.

[...]
required_score		4

# Il m'arrive de recevoir des emails en hongrois ou en anglais
ok_languages fr hu en

score BAYES_00	-4.0
score BAYES_05	-2.0
score BAYES_20	-1.0
score BAYES_40	-0.5
score BAYES_50	0.001
score BAYES_60	1.5
score BAYES_80	3.9
score BAYES_95	4.1
score BAYES_99	5.0
[...]

L'absence de test réseau diminue la précision, et j'obtiens plus de faux négatifs (SPAMs non identifiés), de manière significative.
La durée moyenne de test d'un email par spamd passe de 3,50 secondes à 0,77 secondes, avec un lien ADSL d'environ 1Mbps.
Le test baysien demeure efficace car je reçois des dizaines de SPAMs par jour. Pour un volume plus faible (quelques SPAMs par jour), je suppose que le test baysien est moins pertinent - c'est une hypothèse.
J'ai quand même remis en route les tests réseau, pour un meilleur taux de détection, et en particulier, une meilleure identification des SPAMs certains (score >= 10), que je n'examine pas. Mais configurer SpamAssassin pour une utilisation "isolée" est utile si la connexion Internet est poussive.

2.5 Programme de mail (GUI)

Configuration du programme de Mail (KMail, evolution, etc.)

Réception d'emails
Indiquer un compte de type "boîte aux lettres locale", dont le dépôt se trouve typiquement dans /var/spool/mail/login_utilisateur.
Pour la méthode de verrouillage, j'ai choisi FCNTL car... ça marche !

procmail peut être configuré (dans ~/.procmailrc) pour délivrer les emails directement au bon endroit, ~/Mail par exemple. De plus si l'on en croit certains commentaires disponibles sur Internet, le format employé dans /var/spool/mail, qui stocke les emails dans un seul fichier par utilisateur, est mauvais en termes de sécurité.
Personnellement je préfère laisser le programme de Mail (KMail) gérer lui-même ~/Mail, et ne pas laisser procmail mettre ses pattes dedans. Donc je laisse la configuration par défaut, et les emails passent par /var/spool/mail.

Envoi d'emails
Vous pouvez soit invoquer directement sendmail, soit faire l'envoi à sendmail par le MSA (mailer local, sur le port 587).

Solution 1
Indiquer un envoi de type "sendmail". Attention, dans ce cas sendmail ajoutera un X-Authentication-Warning dans les en-têtes de chaque email émis, du fait de l'option -f utilisée par le programme à l'invocation de sendmail (pour définir l'émetteur de l'email).
Pour éviter cet avertissement, ajouter le nom des utilisateurs susceptibles d'invoquer sendmail directement dans le fichier /etc/mail/trusted-users.

Solution 2
Indiquer un envoi SMTP sur le serveur "localhost" (ou le nom d'hôte, ou encore 127.0.0.1, c'est la même chose), port 587. Le port 25 (MTA) fonctionne également mais le MSA est là pour ça.

Classement automatique dans le dossier spam
Pour envoyer dans le dossier spam tous les emails détectés comme SPAM, créer un filtre avec le critère :

X-Spam-Flag=YES
Action : classer dans le dossier spam.

3 Aller plus loin

3.1 Débogage

3.1.1 Logs messagerie

Le fonctionnement du système de log est paramétré dans /etc/syslog.conf.
Sendmail (sur Debian) est configuré par défaut pour renseigner les fichiers
/var/log/mail.info, /var/log/mail.log, /var/log/mail.warn et /var/log/mail.err.
mail.log et mail.info sont identiques.
Pour suivre ce qui se passe dans la messagerie, exécuter en tant que root :

tail -f /var/log/mail.log
	ou
tail -f /var/log/mail.log | egrep -i sendmail\\\[[0-9]+\\\]
	ou bien
tail -f /var/log/mail.log | egrep -i sm-mta\\\[[0-9]+\\\]
	ou encore
tail -f /var/log/mail.log | egrep -i "(sendmail|sm-mta)\[[0-9]+\]"
	et pour finir, une recherche dans plusieurs fichiers simultanément
tail -f /var/log/mail.{log,err,warn} | egrep -i "(sendmail|sm-mta)\[[0-9]+\]"

Faire de même pour suivre Fetchmail et SpamAssassin, en recherchant les occurrences de fetchmail et spamd, respectivement.
Pour tout loguer dans /var/log/mail.log indistinctement, modifier /etc/syslog.conf ainsi :

[...]
mail.*				-/var/log/mail.log
[...]
# mail.info			-/var/log/mail.info
# mail.warn			-/var/log/mail.warn
# mail.err			/var/log/mail.err
[...]

3.1.2 Tests avec le programme "mail"

Pour envoyer un email depuis la ligne de commande, en tant qu'utilisateur standard (on ne sait jamais ; peut-être que certains problèmes apparaissent uniquement en l'absence des privilèges root), exécuter la commande mail -v destinataire.
Entrer le sujet, puis écrire le corps du message - terminer par un saut de ligne, un point, un saut de ligne. L'option -v affiche les informations de débogage de sendmail. L'envoi doit fonctionner aussi bien pour un utilisateur local que distant.
Dans l'exemple ci-dessous, l'envoi à POSTMASTER provoque le délivrement à l'utilisateur local sebastien, car POSTMASTER est redirigé vers root, lequel est redirigé vers sebastien.

mail -v sebastien
	ou bien
mail -v machin@zedomaine.fr

	Exemple

sebastien@maison-1:~$ mail -v POSTMASTER
Subject: Test 20060808141506
Ceci est un email de test
.
Cc:
POSTMASTER... Connecting to [127.0.0.1] port 587 via relay...
220 maison-1.perouses.claix.fr ESMTP Sendmail 8.13.7/8.13.7/Debian-2; Mon, 14 Aug 2006 15:06:37 +0200; (No UCE/UBE) logging access from: maison-1.perouses.claix.fr(OK)-maison-1.perouses.claix.fr [127.0.0.1]
>>> EHLO maison-1.perouses.claix.fr
250-maison-1.perouses.claix.fr Hello maison-1.perouses.claix.fr [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-EXPN
250-VERB
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH DIGEST-MD5 CRAM-MD5
250-DELIVERBY
250 HELP
>>> VERB
250 2.0.0 Verbose mode
>>> MAIL From:<sebastien@maison-1.perouses.claix.fr> SIZE=71 AUTH=sebastien@maison-1.perouses.claix.fr
250 2.1.0 <sebastien@maison-1.perouses.claix.fr>... Sender ok
>>> RCPT To:<POSTMASTER@maison-1.perouses.claix.fr>
>>> DATA
050 <POSTMASTER@maison-1.perouses.claix.fr>... aliased to root
050 root... aliased to sebastien
250 2.1.5 <POSTMASTER@maison-1.perouses.claix.fr>... Recipient ok
354 Enter mail, end with "." on a line by itself
>>> .
050 sebastien... Connecting to local...
050 sebastien... Sent
250 2.0.0 k7ED6bhO013213 Message accepted for delivery
POSTMASTER... Sent (k7ED6bhO013213 Message accepted for delivery)
Closing connection to [127.0.0.1]
>>> QUIT
221 2.0.0 maison-1.perouses.claix.fr closing connection
sebastien@maison-1:~$

Si un email a été délivré en local, se loguer en tant qu'utilisateur qui en est destinataire, et exécuter mail sans option.

Important
Un envoi interne - émis depuis la machine, vers un utilisateur de la machine - est traité directement en local, sans jamais quitter la machine - il ne passe pas par le fournisseur d'accès. En l'absence de toute connectivité Internet, le routage local fonctionnera quand même.

3.1.3 Démon sendmail

Un telnet en local sur le port 25 démontre la disponibilité du démon sendmail. Mais cela n'indique pas les paramètres de sendmail (périodicité du queue runner). Pour savoir quelle est la période du queue runner, le plus simple est de regarder dans le log.

egrep -i "(sendmail|sm-mta)\[[0-9]+\].*starting" /var/log/mail.log | tail -n 1
	
	Ensuite, vérifier que l'exécutable dont le PID est donné entre crochets [],
	est bien présent dans la liste des processus :

ps -elf ww | grep numéro_pid

	Exemple

maison-1:~# egrep -i "(sendmail|sm-mta)\[[0-9]+\].*starting" /var/log/mail.log | tail -n 1
Aug 13 10:25:14 maison-1 sm-mta[4241]: starting daemon (8.13.7): SMTP+queueing@00:05:00
maison-1:~# ps -elf ww | grep 4241
5 S root      4241     1  0  76   0 -  2118 -      10:25 ?          0:00 sendmail: MTA: accepting connections  
0 R root      7520  7040  0  75   0 -   546 -      10:59 pts/1      0:00 grep 4241
maison-1:~# telnet maison-1 25
Trying 127.0.0.1...
Connected to maison-1.perouses.claix.fr.
Escape character is '^]'.
220 maison-1.perouses.claix.fr ESMTP Sendmail 8.13.7/8.13.7/Debian-2; Sun, 13 Aug 2006 10:59:40 +0200; (No UCE/UBE) logging access from: maison-1.perouses.claix.fr(OK)-maison-1.perouses.claix.fr [127.0.0.1]
ehlo world
250-maison-1.perouses.claix.fr Hello maison-1.perouses.claix.fr [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-EXPN
250-VERB
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH DIGEST-MD5 CRAM-MD5
250-DELIVERBY
250 HELP
quit
221 2.0.0 maison-1.perouses.claix.fr closing connection
Connection closed by foreign host.
maison-1:~# telnet maison-1 587
Trying 127.0.0.1...
Connected to maison-1.perouses.claix.fr.
Escape character is '^]'.
220 maison-1.perouses.claix.fr ESMTP Sendmail 8.13.7/8.13.7/Debian-2; Sun, 13 Aug 2006 10:59:51 +0200; (No UCE/UBE) logging access from: maison-1.perouses.claix.fr(OK)-maison-1.perouses.claix.fr [127.0.0.1]
ehlo world
250-maison-1.perouses.claix.fr Hello maison-1.perouses.claix.fr [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-EXPN
250-VERB
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH DIGEST-MD5 CRAM-MD5
250-DELIVERBY
250 HELP
quit
221 2.0.0 maison-1.perouses.claix.fr closing connection
Connection closed by foreign host.
maison-1:~#             

3.1.4 Files d'attente de sendmail

Par défaut les emails en attente dans sendmail se trouvent dans /var/spool/mqueue-client et /var/spool/mqueue, ce pour le MSA (port 587 et appel de l'exécutable sendmail) et le MTA (port 25), respectivement. Pour afficher ces queues, exécuter la commande mailq en tant que root, ou bien en tant qu'utilisateur appartenant au groupe wheel.
Exemple :

sebastien@maison-1:~$ mailq
MSP Queue status...
                /var/spool/mqueue-client (1 request)
-----Q-ID----- --Size-- -----Q-Time----- ------------Sender/Recipient-----------
k7DIfR2u014729*      17 Sun Aug 13 20:41 sebastien
                 (reply: read error from [127.0.0.1])
                                         postmaster
                Total requests: 1
MTA Queue status...
/var/spool/mqueue is empty
                Total requests: 0
sebastien@maison-1:~$	

Remarque

Pour avoir un email dans la file d'attente, j'ai commenté la ligne FEATURE(`nocanonify')dnl dans le fichier /etc/mail/sendmail.mc, puis provoqué la recompilation de sendmail.mc en sendmail.cf avec la commande make, ensuite redémarré le démon sendmail avec la commande /etc/init.d/sendmail restart, puis j'ai déconnecté physiquement mon câble Ethernet, et enfin, je me suis envoyé un email avec la commande mail -v sebastien. Voilà, c'est tout !
Suite à cela, j'ai reçu au bout de 10 minutes un avertissement, et au bout de 30 minutes, un message d'erreur, émis par
Mail Delivery Subsystem <MAILER-DAEMON@maison-1.perouses.claix.fr> .

3.2 Documentation

Syslog
man syslog.conf Configuration des logs système dans /etc/syslog.conf
Procmail
man procmail Aide de procmail
man procmailrc Configuration de procmail avec ~/.procmailrc
man procmailex Exemples de configuration de procmail avec ~/.procmailrc
http://www.procmail.org Page d'accueil de procmail
Sendmail
sendmail, sendmail-doc Noms des paquetages sendmail
/usr/sbin/sendmail -bt -d0.1 < /dev/null Indique la version de sendmail et ses options de compilation
/usr/share/doc/sendmail/cf.README.gz Configuration de sendmail. C'est de loin le plus utile
/usr/share/doc/sendmail/op/op.* Documentation générale de sendmail
http://www.sendmail.org Page d'accueil de sendmail
SpamAssassin
spamassassin Nom du paquetage SpamAssassin
/usr/sbin/spamd -h Indique la version du démon (spamd) de SpamAssassin
spamc -V Indique la version de la partie client (spamc) de SpamAssassin
sa-learn -V Indique la version de la commande d'apprentissage de SpamAssassin
man Mail::Spamassassin::Conf Configuration des fichiers /etc/mail/spamassassin/local.cf et ~/.spamassassin/user_prefs, très utile
man spamassassin Aide générale de SpamAssassin
http://www.spamassassin.org Page d'accueil de SpamAssassin
http://spamassassin.apache.org/tests_3_1_x.html Scores assignés aux tests effectués
Fetchmail
fetchmail Nom du paquetage fetchmail
fetchmail -V Indique la version de fetchmail et, si ~/.fetchmailrc existe, affiche le détail des récupérations de courrier qui seraient effectuées si fetchmail avait été invoqué sans le paramètre -V
man fetchmail Documentation générale sur fetchmail
http://fetchmail.berlios.de Page d'accueil de fetchmail

4 Journal des changements

1.2

  1. Correction d'une référence erronée au fichier /etc/submit.mc (=> /etc/mail/submit.mc).
  2. Correction de quelques erreurs mineures dans la rédaction HTML.
  3. Modification du titre du document. Encore !
  4. Enlèvement de l'option flush de la configuration de fetchmail.
  5. Mises à jour mineures dans la configuration de SpamAssassin - required_score 4.0 au lieu de 5.0 et score BAYES_99 4.0 dans user_prefs.
  6. Enlèvement de l'option -f de spamc, qui n'existe plus.
  7. Ajout de l'option uidl à fetchmail pour ne pas laisser des messages déjà vus indéfiniment sur le serveur.
  8. Noms de fichiers mis en forme avec <code>nom_fichier</code>
  9. sendmailconf remplacé par sendmailconfig.
  10. Mise à jour contenu fichier /etc/host.conf.
  11. Ajout des options bayes_min_ham_num et bayes_min_spam_num à SpamAssassin.
  12. Ajout de l'option bayes_expiry_max_db_size à SpamAssassin

1.1

  1. Correction du script d'apprentissage de SpamAssassin.
    - Fonctionne désormais avec les noms de dossier contenant des espaces.
    - Fonctionne avec les sous-dossiers.
    - Ignore les dossiers ne se terminant pas par /cur.
  2. Ajout d'une rubrique pour déterminer la nature du SPAM reçu avec sa-stats.pl.
  3. Ajout d'explications sur les formats de base courrier, et ajout d'une partie sur l'apprentissage avec des filtres.
  4. Ajout d'explications et d'un tableau dans le paragraphe 2.4.4 (configuration SpamAssassin).
  5. Modification du titre du document.

1.0

  1. Création du document