Postfix Courier MySQL Quota SpamAssassin Amavis

De Lea Linux
Révision datée du 2 décembre 2006 à 11:52 par Space2d (discussion | contributions) (remplacement du nom de domaine de test)
Aller à la navigation Aller à la recherche

Postfix, Courier Imap & Pop, MySQL et Quota avec filtre AntiSpam et antivirus sous Debian

Par Space2d Page d'origine sur www.espace.fr.to/howto

Le but de cet howto est d'expliquer comment mettre en place un serveur email complet, supportant plusieurs domaines sous Debian GNU/Linux. Celui-ci sera composé des éléments suivants :

  • un serveur smtp : Postfix (avec patch vda supportant la gestion des quotas)
  • un serveur imap/pop : Courier
  • un serveur mysql : MySQL
  • un antivirus : Amavis
  • un filtre antispam : SpamAssassin

Introduction

Au début, j'utilisais le serveur de courier postfix avec la configuration d'origine utilisant l'authentification unix. J'ai eu besoin de servir plusieurs domaines ainsi que des comptes mails virtuels. En effet, l'utilisation des utilisateurs unix n'est pas adaptée à une configuration multidomaine. Désormais, je peux administrer facilement mes domaines et comptes email via l'interface Web PHPMyAdmin. Il est aussi possible de créer une interface spécifique à cette gestion par exemple en utilisant php

Prérequis

Il vous faut un système avec un serveur MySQL installé avec si possible un serveur web et PHPMyAdmin pour faciliter l'administration de la BD. Cette documentation est écrite pour un système Debian GNU/linux

La base de données

Description de la structure

Cette base de données sera structurée dans les 4 tables suivantes :

  • les domaines
    • domaine
    • actif (1 pour oui, 0 pour non)
  • les emails
    • email
    • mot de passe
    • quota
    • accès pop3 (1 pour oui, 0 pour non)
    • accès imap (1 pour oui, 0 pour non)
    • compte email actif (1 pour oui, 0 pour non)
  • les alias
    • email
    • alias (contient une liste d'emails séparés par une virgule vers lesquels seront dirigés les emails reçu par 'email')
    • compte email actif (1 pour oui, 0 pour non)

Creation de la base et de l'utilisateur SQL

Entrez dans l'interface de la base de données :

  • si vous n'avez jamais modifier les utilisateurs de la base, vous puvez acceder à la base de données en tant que root sans mot de passe. Il est conseillé d'ajouter un mot de passe un root pour d'évidente questions de sécurité avec la commande : mysqladmin -u root password votre-mot-de-passe
  • sinon (avec un utilisateur/pwd ayant le droit de modifier la base): mysql -u utilisateur -p

Il faut tout d'abord créer la base de données (ex : postfix) et les tables qu'elle contient.

CREATE DATABASE `postfix`;
USE postfix;

-- 
-- Structure de la table `domain`
-- 
CREATE TABLE `domain` (
  `domain` varchar(255) NOT NULL default '',
  `actif` tinyint(1) NOT NULL default '1',
  PRIMARY KEY  (`domain`)
) ENGINE=MyISAM COMMENT='Postfix Admin - Domaines Virtuels';

-- 
-- Structure de la table `mailbox`
-- 
CREATE TABLE `mailbox` (
  `email` varchar(255) NOT NULL default '',
  `password` varchar(255) NOT NULL default '',
  `quota` int(10) NOT NULL default '0',
  `actif` tinyint(1) NOT NULL default '1',
  `imap` tinyint(1) NOT NULL default '1',
  `pop3` tinyint(1) NOT NULL default '1',
  PRIMARY KEY  (`email`)
) ENGINE=MyISAM COMMENT='Postfix Admin - Boites Emails Virtuelles';

-- 
-- Structure de la table `alias`
-- 
CREATE TABLE `alias` (
  `source` varchar(255) NOT NULL default '',
  `destination` text NOT NULL,
  `actif` tinyint(1) NOT NULL default '1',
  PRIMARY KEY  (`source`)
) ENGINE=MyISAM COMMENT='Postfix Admin - Alias Virtuels';

Ensuite, les différents services doivent accéder à cette base de données. Pour des raisons de sécurité évidentes, il est nécessaire de créer un utilisateur MySQL qui n'a accès qu'en lecture (SELECT) à la base 'postfix'. Pour l'exemple, celui-ci s'appelera 'postfix' avec comme mot de passe 'pass'. Pour le créer, il suffit de taper les commandes suivantes dans la console MySQL :

GRANT SELECT ON `postfix`.* TO 'postfix'@'%'
IDENTIFIED BY 'pass';

Postfix

Installation

Pour l'instant, Postfix ne supporte pas les quotas en natif. Cependant, le patch VDA offre cette possibilité. Pour ne pas recompiler postfix en intégrant le patch VDA, nous allons utiliser le dépot de paquets non-officiel pour Debian : http://debian.home-dn.net Il faut ajouter les lignes suivantes à la liste des dépots de votre serveur dans le fichier /etc/apt/sources.list (vous devez être logué en root pour pouvoir modifier ce fichier) :

#postfix VDA
deb http://debian.home-dn.net/sarge postfix-vda/

Puis il suffit de mettre à jour la liste des paquets et d'intaller les paquets necessaires (en tant que root) :

apt-get update
apt-get install postfix postfix-mysql

L'installateur Debian va demander quel type de configuration vous souhaitez utilisez. Dans notre cas, nous allons choisir "Pas de configuration", afin d'obtenir une configuration vierge.

Configuration

Nous allons configurer le système courier afin que les emails soient conservés dans un seul repertoire : /var/spool/vmail/. Les boites seront rangés (au format maildir) dans un repertoire du type : /var/spool/vmail/virtualdomain/virtualmailbox/

Création de l'utilisateur vmail

Ce repertoire sera accessible en lecture et ecriture par un utilisateur nommé vmail (uid:5000,gid:5000) que nous allons créer ainsi :

groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/spool/vmail/ -m

Fichier de configuration principal

Le fichier /etc/postfix/main.cf définit les paramètres principaux du serveur postfix, notamment les paramètres des domaines virtuels. Le fichier ci-après contient une configuration complète de postfix. Si vous avez déjà un tel fichier et que vous souhaitez seulement ajouter le support des domaines virtuel mysql, il faut copier les directives commençant par virtual_...

# /etc/postfix/main.cf
# Configuration Postfix
# espace.fr.to
#

smtpd_banner = $myhostname ESMTP (Debian/GNU)
biff = no
disable_vrfy_command = yes
smtpd_helo_required = yes

# ajoute le domaine aux emails de la distribution locale
# ainsi vous pourrez envoyer des emails sans @domain.priv
# par la commande sendmail
mydomain = domain.priv 
append_dot_mydomain = yes

# Envoi une alerte de dépassement de délai par email
#delay_warning_time = 4h

myhostname = smtp.domain.priv

# domaine de distribution local
mydestination = localhost, localhost.localdomain

# Mettez ici le relais smtp de votre FAI si vous avez des problèmes de blacklist
# à cause de votre IP
relayhost =

# adresseIP/Masque des réseaux locaux (réseaux autorisés pour l'envoi de courier)
mynetworks = 127.0.0.0/8 192.168.0.0/24
inet_interfaces = all

#restrictions d'accès
# adresses d'expédition
smtpd_sender_restrictions =
        permit_mynetworks,
        reject_unknown_sender_domain, #verifie que le domaine existe
        warn_if_reject reject_unverified_sender

# adresses de destination
smtpd_recipient_restrictions =
        permit_mynetworks,
        reject_unauth_destination,
        reject_unknown_recipient_domain,
        reject_non_fqdn_recipient

# client
smtpd_client_restrictions =
        reject_unknown_client,
        permit_mynetworks

virtual_alias_maps = mysql:/etc/postfix/mysql-virtual_aliases.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual_domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual_mailboxes.cf
virtual_mailbox_base = /var/spool/vmail/
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql-virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = "Desole, la boite email de l'utilisateur est pleine, essayez plus tard."
virtual_overquota_bounce = yes

Fichiers de configuration d'accès à la base de données

Si vous avez un peu lu le fichier précédent, vous avez pu constater que nous faisons appel à des fichiers correspondances (mapping). Ces fichiers fournissent les informations permettant à postfix de récupérer la configuration des domaines et emails virtuels dans la base de données crée précédemment.

Vous devez créer les fichiers suivant dans /etc/postfix/ en remplaçant les paramètres par ceux de votre configuration (par exemple : le champ password).
Attention! Dans le champs host, n'utilisez pas 'localhost'. En effet postfix fonctionne en environnement "chrooté" dans le repertoire (/var/spool/postfix), il ne peut donc pas accéder aux fichiers hors de ce repertoire notamment /var/run/mysqld/mysqld.sock. Hors, si vous utiliser 'localhost', postfix va essayer d'accéder à ce fichier socket. Pour résoudre le problème nous faisons passer la connection par une connection TCP utilisant la boucle locale (lo) en utilisant l'addresse ip 127.0.0.1.

# mysql-virtual_domains.cf
hosts = 127.0.0.1
user = postfix
password = pass
dbname = postfix
select_field = 'virtual'
table = domain
where_field = domain
additional_conditions = AND actif=1
# mysql-virtual_aliases.cf
hosts = 127.0.0.1
user = postfix
password = pass
dbname = postfix
select_field = destination
table = alias
where_field = source
additional_conditions = AND actif=1
# mysql-virtual_mailboxes.cf
hosts = 127.0.0.1
user = postfix
password = pass
dbname = postfix
select_field = CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/')
table = mailbox
where_field = email
additional_conditions = AND actif=1
# mysql-virtual_mailbox_limit_maps.cf
hosts = 127.0.0.1
user = postfix
password = pass
dbname = postfix
select_field = quota
table = mailbox
where_field = email

Ces fichiers doivent être accessibles seulement par root et par postfix. En effet, ils contiennent le mot de passe en clair d'accès à la base de données. Pour cela il suffit de lancer les commandes suivantes qui change le groupe de ces fichiers par "postfix" et affecte les droits d'accès necessaires :

  chgrp postfix /etc/postfix/mysql-virtual_*.cf
  chmod u=rw,g=r,o= /etc/postfix/mysql-virtual_*.cf

Validation de la configuration

Redémarrez postfix /etc/init.d/postfix restart et lancer postfix check afin de verifier que vous n'avez fait aucune erreur.

Courier

Installation

Le serveur Courier est composé de plusieurs éléments:

  • le serveur imap
  • le serveur pop
  • le démon d'authentification (authdaemon) qui utilise le module approprié à la configuration (authmysql)

Pour installer tout ceci :

apt-get install courier-base courier-authdaemon courier-authmysql courier-imap courier-pop

Configuration

Le démon d'authentification

Il faut modifier le fichier /etc/courier/authdaemonrc pour indiquer à authdaemon qu'il doit utiliser le module mysql.

#authmodulelist="authpam"
authmodulelist="authmysql"

Puis il faut configurer le module authmysql en editant le fichier /etc/courier/authmysqlrc ainsi:

MYSQL_SERVER            localhost
MYSQL_USERNAME          postfix
MYSQL_PASSWORD          pass
MYSQL_DATABASE          postfix
MYSQL_USER_TABLE        mailbox

MYSQL_CRYPT_PWFIELD     password
# MYSQL_CLEAR_PWFIELD    clear

MYSQL_UID_FIELD         5000
MYSQL_GID_FIELD         5000

MYSQL_LOGIN_FIELD       email

MYSQL_HOME_FIELD        "/var/spool/vmail/"

MYSQL_MAILDIR_FIELD CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/')

#Ligne à commenter 
# MYSQL_NAME_FIELD       name

MYSQL_QUOTA_FIELD       quota
Veillez à ne pas mettre d'espace en début de ligne. Courier est très suceptible ;)

Validation de la configuration

Relancez les démons que vous venez de configurer :

/etc/init.d/courier-authdaemon restart
/etc/init.d/courier-imap restart
/etc/init.d/courier-pop restart

Test de la configuration

Pour effectuer nos tests, nous allons créer un compte email 'test' ainsi que le domain 'domain.priv' par les requêtes SQL suivantes :

INSERT INTO `domain` (`domain`,`actif`) VALUES ('test',1);
INSERT INTO `mailbox` (`email`,`password`,`quota`,`actif`,`imap`,`pop3`)
       VALUES ('user@domain.priv',ENCRYPT('secret'),0,1,1,1);

Remplissage de la base de données

Pour plus de détail, referez-vous à #BD_structure.

Domaines

Pour chaque domaine, inserez une ligne dans la table 'domain' avec le champs actif à 1.

Boites emails

Pour chaque email, inserez une ligne dans la table 'email' avec le champs actif à 1.

Alias

Grâce à la table 'alias', vous pouvez effectuer plusieurs transferts (source->destination) :

  • d'email à email : alias@domain.priv -> user1@domain.priv
  • d'email à emails : alias@domain.priv -> user1@domain.priv,user1@otherdomain.priv (séparés par une virgule)
  • de tous les emails du domaine qui ne sont pas définis vers un email : @domain.priv -> catchall@domain.priv
  • d'un domain vers un autre : @domain.priv -> @otherdomain.priv

Test Postfix

Nous allons envoyer un email à test@domain.priv via la commande telnet :

~$ telnet 127.0.0.1 25
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 smtp.domain.priv ESMTP (Debian/GNU)
<b>ehlo espace.fr.to</b>
250-smtp.domain.priv
250-PIPELINING
250-SIZE 10240000
250-ETRN
250 8BITMIME
mail from: <test@domain.priv>
250 Ok
rcpt to: <user@domain.priv>
250 Ok
250 Ok
data
354 End data with <CR><LF>.<CR><LF>
Voici le premier mail de test.
.
250 Ok: queued as 8ECC524208
quit
221 Bye
Connection closed by foreign host.

Vous pouvez verifier que tout c'est bien dérouler grâce au fichier de log /var/log/mail.log

postfix/smtpd[2036]: connect from localhost.localdomain[127.0.0.1]
postfix/smtpd[2036]: 8ECC524208: client=localhost.localdomain[127.0.0.1]
postfix/cleanup[2067]: 8ECC524208: message-id=<20060923131054.8ECC524208@smtp.domain.priv>
postfix/qmgr[1876]: 8ECC524208: from=<test@espace.fr.to>, size=377, nrcpt=1 (queue active)
postfix/virtual[2076]: 8ECC524208: to=<user@domain.priv>, relay=virtual, delay=0, \
  status=sent (delivered to maildir)

Si vous trouvez la ligne contenant "status=sent (delivered to maildir)", le mail a bien été reçu. Vérifier alors le contenu du repertoire /var/spool/vmail/ avec la commande find /var/spool/vmail.

/var/spool/vmail/
/var/spool/vmail/domain.priv
/var/spool/vmail/domain.priv/user
/var/spool/vmail/domain.priv/user/tmp
/var/spool/vmail/domain.priv/user/cur
/var/spool/vmail/domain.priv/user/new
/var/spool/vmail/domain.priv/user/new/1159016974.V301I242fe.titan.espace.fr.to
/var/spool/vmail/domain.priv/user/maildirsize

Si celà correpond postfix est bien configuré et fonctionne correctement.

Test Courier

Utlisez votre client de messagerie avec comme utilisateur 'user@domain.priv' et mot de passe 'secret' pour effectuer ce test.

Attention! L'accès imap ou pop echouera si le repertoire de la boite email de l'utilisateur n'existe pas (si vous venez juste d'ajouter l'email dans la base de données). Je vous conseille d'envoyer un email de bienvenue après la création d'une nouvelle boite.

Amavis (facultatif)

Installation

apt-get install amavisd-new clamav clamav-daemon clamav-freshclam lha arj unrar zoo nomarch lzop unzoo bzip2
Les packages lha et unrar font partie du dépot non-free de Sarge.

Lors de l'installation du package clamav-freshclam, debconf va posez 2 questions :

  • Méthode de mise à jour de la base de données des virus :"démon" si vous avez une connexion réseau permanente, "cron" créera une tache cron que vous pourrez modifier à votre convenance.
  • Miroir de la base de données : (choisissez le plus de proche chez vous)
  • Faut-il notifier clamd des mises à jour ? : "Oui"

Configuration

Afin que l'antivirus clamav puisse lire les fichiers crées par amavis, il faut ajouter l'utilisateur clamav au groupe amavis : adduser clamav amavis Ensuite, vous devez modifier le fichier de cofiguration /etc/amavis/amavisd.conf

#ce domaine correspond au domaine local si vous n'avez pas de domaine local utilisez 'localhost'
$mydomain = 'yourdomain.org';

# @bypass_virus_checks_acl = qw( . );  # uncomment to DISABLE anti-virus code
# @bypass_spam_checks_acl  = qw( . );  # uncomment to DISABLE anti-spam code

#amavis doit connaitre les domaines à controler (en effet il controle seulement les mails entrants)
@lookup_sql_dsn = ( [ 'DBI:mysql:postfix;host=127.0.0.1;port=3306', 'postfix', 'pass' ] );
$sql_select_policy =
    'SELECT "Y" as local FROM domains WHERE CONCAT("@",domain) IN (%k) AND actif="1"';

$final_virus_destiny      = D_DISCARD; # (defaults to D_BOUNCE)
$final_banned_destiny     = D_BOUNCE;  # (defaults to D_BOUNCE)
$final_spam_destiny       = D_REJECT;  # (defaults to D_REJECT)
$final_bad_header_destiny = D_PASS;  # (defaults to D_PASS), D_BOUNCE suggested

SpamAssassin (facultatif)

Installation

apt-get install spamassassin libnet-dns-perl libmail-spf-query-perl \
                             libnet-ident-perl libio-socket-ssl-perl libsys-hostname-long-perl \
                             razor pyzor dcc-client

Configuration

Pour améliorer l'analyse des emails par spamassassin, il faut utiliser le démons spamd. Pour cela, modifiez le fichier /etc/default/spamassassin

ENABLED=1

Puis, relancez le démon spamd : /etc/init.d/spamassassin restart Nous allons utiliser amavis pour appeler le filtre spamasssin. La configuration de Amavis est prête à l'utiliser. Il suffit de modifier quelques lignes dans /etc/amavis/amavisd.conf

# @bypass_virus_checks_acl = qw( . );  # uncomment to DISABLE anti-virus code
# @bypass_spam_checks_acl  = qw( . );  # uncomment to DISABLE anti-spam code
#
# Any setting can be changed with a new assignment, so make sure
# you do not unintentionally override these settings further down!
# @bypass_spam_checks_acl  = qw( . );    # No default dependency on spamassassin

$sa_local_tests_only = 0;

$sa_tag_level_deflt = -1000; # note minimal pour ajouter les tags X-Spam... à l'en-tête des emails
$sa_tag2_level_deflt = 3.5;  # note minimal pour ajouter le tag X-Spam-Flag: YES
                             # et modifier l'objet
$sa_kill_level_deflt = 10;   # note à partir de laquelle les mails sont traités comme définis
                             # par la variable $final_spam_destiny (ici ils sont refusés)
$sa_spam_subject_tag = '***SPAM*** '; # chaine ajouté à l'objet de l'email


Copyright

Tête de GNU Vous avez l'autorisation de copier, distribuer et/ou modifier ce document suivant les termes de la GNU Free Documentation License, Version 1.2 ou n'importe quelle version ultérieure publiée par la Free Software Foundation; sans section invariante, sans page de garde, sans entête et sans page finale.

--Space2d 25 sep 2006 à 19:05 (CEST)