Postfix Mysql

De NCad Wiki
Aller à la navigation Aller à la recherche

.:[ Serveur de Messagerie ]:.

Installation >> Postfix avec MySQL

Filtrage anti-spam : Anti-Spam SpamAssassin | Anti-Virus Clamav


Filtrage anti-virus : Plateforme de filtrage Amavis >> Amavis avec MySQL


Plus de fonctions : Ajouter un Disclaimer | Signature DKIM | Mailman | Maildrop


Clients de messagerie : Configurer Thundirbird | Configurer Roundcube


Pour aller plus loin : Commandes messagerie | DNSBL | MX Backup

Prérequis

Vue schématique de l'installation

Avant de lire les instructions qui vont suivre, il est recommandé de lire la page consacrée à Postfix où au moins les annexes qui reprennent le fichier de configuration /etc/postfix/main.cf finale et qui va servir de base pour cette page.

Afin de faciliter la gestion du serveur de mail ou encore d'automatiser certaine tâche et de développer des fonctionnalités pour les utilisateurs finaux, il est possible de coupler le serveur mail à une base de données Mysql.

Les fonctions de cette bases seront les suivantes :

  • assurer l'authentification des utilisateurs;
  • stocker les comptes mails;
  • établir une table de correspondance login / adresse émetteur autorisée.



Ainsi, Mysql va agir sur 4 services :

  • le service SMTP assuré par Postfix (quota, alias, émetteurs autorisés, ...);
  • l'authentification SMTP via sasl;
  • l'authentification IMAP et la localisation du répertoire mail de l'utilisateur;
  • l'authentification POP3 et la localisation du répertoire mail de l'utilisateur.



Vous devez disposer d'un serveur Mysql fonctionnel. Dans cet article le serveur mysql et le serveur mail sont hébergés sur une même machine. Si ce n'est pas le cas de votre configuration, pensez à changer la valeur du hosts.

Installation

  • Pour fonctionner avec une base de données MySQL, il faut installer les paquets postfix-mysql, libsasl2-modules-sql (module saslauthd), courier-authlib-mysql (modules courier POP/IMAP) et libpam-mysql (module pam):

sudo apt-get install postfix-mysql libsasl2-modules-sql courier-authlib-mysql libpam-mysql

Création de la base de données

  • Création de l'utilisateur mysql postfix avec le mot de passe motdepassebasemysqlpourpostfix et sa base de données nommée postfix avec les droits nécessaires.

CREATE USER 'postfix'@'%' IDENTIFIED BY 'motdepassebasemysqlpourpostfix';
GRANT USAGE ON * . * TO 'postfix'@'%' IDENTIFIED BY 'motdepassebasemysqlpourpostfix' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
CREATE DATABASE IF NOT EXISTS `postfix` ;
GRANT ALL PRIVILEGES ON `postfix` . * TO 'postfix'@'%';

Authentification

Module Saslauthd

  • Postfix utilise le module saslauthd pour l'authentification des utilisateurs qui est basée sur pam. Voici le contenu du fichier de configration /etc/pam.d/smtp :
auth       required     pam_mysql.so user=postfix passwd=motdepassebasemysqlpourpostfix host=10.0.0.47 db=postfix table=postfix_users usercolumn=username passwdcolumn=clear crypt=0
account    sufficient   pam_mysql.so user=postfix passwd=motdepassebasemysqlpourpostfix host=10.0.0.47 db=postfix table=postfix_users usercolumn=username passwdcolumn=clear crypt=0

Si le fichier existe déjà, remplacer-le.

  • Redémarrer le service saslauthd :

sudo service saslauthd restart

Module authdaemonrc pour POP / IMAP

  • Pour activer l'authentification mysql, dans le fichier /etc/courier/authdaemonrc remplacer :
authmodulelist="authpam"
  • Par :
authmodulelist="authmysql"
  • Créer le fichier de connexion à la base de données mysql /etc/courier/authmysqlrc :
MYSQL_SERVER            10.0.0.47
MYSQL_USERNAME          postfix
MYSQL_PASSWORD          motdepassebasemysqlpourpostfix
MYSQL_PORT              0
MYSQL_OPT               0
MYSQL_DATABASE          postfix
MYSQL_USER_TABLE        postfix_users
MYSQL_CRYPT_PWFIELD     crypt
MYSQL_CLEAR_PWFIELD     clear
MYSQL_UID_FIELD         5000
MYSQL_GID_FIELD         5000
MYSQL_LOGIN_FIELD       CONCAT(username,'@',domain)
MYSQL_HOME_FIELD        "/var/mail/vmail"
MYSQL_NAME_FIELD        name
MYSQL_MAILDIR_FIELD     maildir
MYSQL_QUOTA_FIELD       concat(quota,'S')
  • On redémarre le service courier-authdaemon :

sudo service courier-authdaemon restart

Configuration de Postfix

Général

  • Pour activer les utilisateurs virtuels et interroger les bases de données adéquates, il faut ajouter les lignes suivantes dans le fichier de configuration /etc/postfix/main.cf de Postfix après la ligne broken_sasl_auth_clients = yes:
virtual_mailbox_base = / 
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-aliases.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-domains.cf
virtual_minimum_uid = 5000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_transport = virtual
transport_maps = mysql:/etc/postfix/mysql-virtual-transport.cf 

Ici, nous indiquons à Postfix où se trouve la liste des boîtes mails hébergées virtual_mailbox_maps ainsi que l'utilisateurs UNIX qui a les permissions nécessaires pour accéder aux dossiers et fichiers de ces boîtes mails.

Les noms de domaine contenus dans cette table ne devront pas apparaître dans le paramètre mydestination du fichier de configuration /etc/postfix/main.cf de Postfix.

Fichiers de configurations

  • Le fichier de configuration /etc/postfix/mysql-virtual-maps.cf qui permet de récupérer la liste des utilisateurs virtuels de Postfix :
user = postfix
password = motdepassebasemysqlpourpostfix
dbname = postfix
hosts = 10.0.0.47
query = SELECT maildir FROM postfix_users where CONCAT(username,'@',domain)='%s' and postfix = 'Y'
  • Le fichier de configuration /etc/postfix/mysql-virtual-domains.cf permet de vérifier les domaines locaux de Postfix :
user = postfix
password = motdepassebasemysqlpourpostfix
dbname = postfix
hosts = 10.0.0.47
query = SELECT destination FROM postfix_virtual_domains WHERE domain = '%s'
  • Le fichier de configuration /etc/postfix/mysql-virtual-aliases.cf permet de configurer les alias / redirections mails de chaque utilisateur :
user = postfix
password = motdepassebasemysqlpourpostfix
dbname = postfix
hosts = 10.0.0.47
query = SELECT destination FROM postfix_alias WHERE alias = '%s'
  • Le fichier de configuration /etc/postfix/mysql-virtual-transport.cf permet de connaître le transport utilisé par chaque domaines locaux ou relayés :
user = postfix
password = motdepassebasemysqlpourpostfix
dbname = postfix
hosts = 10.0.0.47
query = SELECT destination FROM postfix_transport where domain = '%s'
  • Le fichier de configuration /etc/postfix/mysql-virtual-relay.cf permet d'identifier les noms de domaine pour lesquels Postfix devra relayer les messages entrants vers un serveur tierce :
user = postfix
password = motdepassebasemysqlpourpostfix
dbname = postfix
hosts = 10.0.0.47
query = SELECT domain FROM postfix_virtual_domains WHERE domain = '%s' and destination = 'relay'

Comptes mails et utilisateurs

Utilisateur générique vmail

  • Les messages des utilisateurs virtuels seront stockés dans le dossier /var/mail/vmail qui sera crée spécialement à cet effet. On créera aussi l'utilisateur et le groupe vmail qui pourront accéder à ce dossier et ses sous-dossiers.

groupadd vmail -g 5000
useradd vmail -u 5000 -g 5000
mkdir /var/mail/vmail
chown vmail:vmail /var/mail/vmail
chmod 700 /var/mail/vmail

Création des tables

  • Maintenant, il faut créer la table contenant les utilisateurs virtuels de Postfix :
CREATE TABLE postfix_users (
 id int(11) unsigned NOT NULL auto_increment,
 username varchar(64) NOT NULL default ,
 domain varchar(64) NOT NULL default ,
 clear varchar(128) NOT NULL default ,
 crypt varchar(128) NOT NULL default ,
 name tinytext NOT NULL,
 uid int(11) unsigned NOT NULL default '5000',
 gid int(11) unsigned NOT NULL default '5000',
 homedir tinytext NOT NULL,
 maildir tinytext NOT NULL,
 quota tinytext NOT NULL,
 access enum('Y','N') NOT NULL default 'Y',
 postfix enum('Y','N') NOT NULL default 'Y',
 disablepop3 char(1) NOT NULL default '0',
 disableimap char(1) NOT NULL default '0',
 disablewebmail char(1) NOT NULL default '0',
 sharedgroup varchar(128) NOT NULL default '0',
 smtpaccess enum('Y','N') NOT NULL default 'Y',
 PRIMARY KEY (id)
)
  • Celle contenant les noms de domaine locaux :
CREATE TABLE postfix_virtual_domains (
 id int(11) unsigned NOT NULL auto_increment,
 domain varchar(128) NOT NULL default ,
 destination varchar(128) NOT NULL default ,
 PRIMARY KEY (id),
 UNIQUE KEY domain (domain)
)
  • Une table qui va répertorier la liste des alias / redirections mails :
CREATE TABLE postfix_alias (
  id int(11) unsigned NOT NULL auto_increment,
  alias varchar(128) NOT NULL default ,
  destination varchar(128) NOT NULL default ,
  PRIMARY KEY (id)
)
  • Ainsi que le transport utilisé :
CREATE TABLE postfix_transport (
  id int(11) unsigned NOT NULL auto_increment,
  domain varchar(128) NOT NULL default ,
  destination varchar(128) NOT NULL default ,
  PRIMARY KEY (id),
  UNIQUE KEY domain (domain)
)

Création d'un utilisateur

  • Nous allons ajouter l'utilisateur cacheln avec le mot de passe cacheln et pour adresse mail cacheln@mail.glx dans la table mysql postfix_users :
INSERT INTO `courriel`.`postfix_users` (
 `id` ,
 `username` ,
 `domain` ,
 `clear` ,
 `crypt` ,
 `name` ,
 `uid` ,
 `gid` ,
 `maildir` ,
 `quota` ,
 `access` ,
 `postfix` ,
 `disablepop3` ,
 `disableimap` ,
 `disablewebmail` ,
 `sharedgroup` ,
 `smtpaccess`
)
VALUES (
 NULL , 'cacheln', 'mail.glx', 'cacheln', , 'Nicolas CACHELOU', '5000', '5000', '/var/mail/vmail/mail.glx/cacheln/', '10000000', 'Y', 'Y', '0', '0', '0', '0', 'Y'
);
  • Nous définissons également une entrée dans la table postfix_virtual_domains pour indiquer à Postfix qu'il héberge les mails pour le domaine mail.glx.
INSERT INTO  `postfix`.`postfix_virtual_domains` (
 `id` ,
 `domain` ,
 `destination`
)
VALUES (
 NULL ,  'mail.glx',  'virtual'
);
  • Nous allons créer le répertoire mail de l'utilisateur :

mkdir -p /var/mail/vmail/mail.glx/
maildirmake /var/mail/vmail/mail.glx/cacheln
chown vmail:vmail /var/mail/vmail -R
chmod 700 /var/mail/vmail -R

Test de validation du serveur

  • Nous pouvons maintenant vérifier le bon fonctionnement de l'authentification sur les services POP/IMAP et SMTP. Pour rappel, l'identifiant du compte est cacheln@mail.glx et son mot de passe est cacheln.

Test du serveur SMTP

  • Nous pouvons vérifier le bon fonctionnement du serveur SMTP en s'y connectant avec les identifiants du compte qui ont été ajoutés à la table postfix_users puis en nous envoyant à nous même un courriel :

telnet 127.0.0.1 25
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 alice.lan ESMTP Postfix
AUTH LOGIN Y2FjaGVsbkBtYWlsLmdseA==
334 UGFzc3dvcmQ6
Y2FjaGVsbg==
235 2.7.0 Authentication successful
mail from:<cacheln@mail.glx>
250 2.1.0 Ok
rcpt to:<cacheln@mail.glx>
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
test
.
250 2.0.0 Ok: queued as 0279C461C69
quit
221 2.0.0 Bye
Connection closed by foreign host.

  • L'authentification a bien fonctionné. Le mail a apparemment été envoyé. Nous allons rechercher sa trace dans le fichier de log /var/log/mail.log pour le message 0279C461C69 :

cat /var/log/mail.log
Feb 4 02:36:46 alice postfix/smtpd[10873]: 0279C461C69: client=localhost[127.0.0.1], sasl_method=LOGIN, sasl_username=cacheln@mail.glx
Feb 4 02:36:51 alice postfix/cleanup[10880]: 0279C461C69: message-id=<20140204013646.0279C461C69@alice.lan>
Feb 4 02:36:51 alice postfix/qmgr[10799]: 0279C461C69: from=<cacheln@mail.glx>, size=293, nrcpt=1 (queue active)
Feb 4 02:36:51 alice postfix/virtual[10881]: 0279C461C69: to=<cacheln@mail.glx>, relay=virtual, delay=15, delays=15/0.03/0/0.05, dsn=2.0.0, status=sent (delivered to maildir)
Feb 4 02:36:51 alice postfix/qmgr[10799]: 0279C461C69: removed

Le message a bien été délivré.

Restriction émetteur / sender

Si vous avez mis en place un contrôle de l'adresse de l'émetteur en fonction de son login (c.f Postfix#Restriction_.C3.A9metteur.2Fsender, cette partie est donc obligatoire. Le cas échant, le SMTP refusera d'envoyer les mails des utilisateurs locaux.

Création de la table

  • Création de la table postfix_senders :
CREATE TABLE postfix_senders (
 id int(11) unsigned NOT NULL auto_increment,
 username varchar(64) NOT NULL default ,
 email varchar(128) NOT NULL default ,
 PRIMARY KEY (id)
)

Cette table liste les adresses mails autorisées à être présentées en fonction du login (username) de l'utilisateur.

  • Pour que l'utilisateur cacheln puisse envoyer des mails via le smtp en utilisant son adresse mail cacheln@mail.glx, nous allons insérer l'enregistrement suivant :
INSERT INTO `courriel`.`postfix_senders` (
 `id` ,
 `username` ,
 `email`
)
VALUES (
 NULL , 'cacheln', 'cacheln@mail.glx'
);

Configuration de Postfix

  • Dans le fichier /etc/postfix/main.cf, remplacer :
smtpd_sender_login_maps =hash:/etc/postfix/sender_login
  • Par :
smtpd_sender_login_maps = mysql:/etc/postfix/mysql-virtual-senders.cf

Fichier de configuration

  • Créer le fichier de configuration /etc/postfix/mysql-virtual-senders.cf qui permettra d'interroger la table des adresses d'émetteurs autorisés :
user = postfix
password = motdepassebasemysqlpourpostfix
dbname = postfix
hosts = 10.0.0.47
query = SELECT email FROM postfix_senders where username='%s'

Gestion des quotas

  • Les quotas permettent de limiter la taille maximale d'une boîte mail. Si c'est le cas, les nouveaux messages seront refusés et l'émetteur en sera informé dans le retour du code d'erreur du serveur.

Par défaut, Postfix ne supporte pas la gestion des quotas. Pour lui greffer cette fonctionnalité, il faudra lui appliquer un patch spécifique.

Création de la table

  • Le module utilise la valeur du champs quota sans la table postfix_users de chaque utilisateur.

Configuration de Postfix

  • Dans le fichier de configuration /etc/postfix/main.cf on ajoutera les lignes suivantes :
virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql-virtual-quotas.cf
virtual_mailbox_limit_inbox = no
virtual_mailbox_limit_override = yes
virtual_maildir_extended = yes
virtual_overquota_bounce = no
#virtual_maildir_limit_message_maps = hash:/etc/postfix/limit_messages
virtual_maildir_limit_message = "La boîte mail de votre destinataire est actuellement pleine. Votre message n'a pu lui être remis. Veuillez réessayer ultérieurement."
#virtual_maildir_suffix = "Maildir/"
virtual_trash_count = no
virtual_trash_name = ".Trash"
virtual_maildir_filter = no
#virtual_maildir_filter_maps = hash:/etc/postfix/vfilter

Fichier de configuration

  • Créer le fichier de configuration /etc/postfix/mysql-virtual-quotas.cf qui permettra d'interroger la table des quotas pour chaque utilisateurs :
user = postfix
password = motdepassebasemysqlpourpostfix
hosts = 10.0.0.47
dbname = postfix
query = SELECT quota FROM postfix_users where username='%s'

Validation

  • Pour vérifier l'application des quotas, nous allons abaisser le quota de la boîte mail de cacheln@mail.glx à 10 Ko :
UPDATE  `courriel`.`postfix_users` SET  `quota` =  '10' WHERE  `postfix_users`.`username` ='cacheln';
  • Ensuite, nous allons envoyé un mail à cette boîte, dans notre cas depuis la boîte cachelp@mail.glx. Voici le message reçus par cachelp@mail.glx :
This is the mail system at host alice.lan.

I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.

For further assistance, please send mail to postmaster.

If you do so, please include this problem report. You can
delete your own text from the attached returned message.

                  The mail system

<cacheln@mail.glx>: maildir delivery failed: "La bo??te mail de votre
   destinataire est actuellement pleine. Votre message n'a pu lui ??tre remis.
   Veuillez r??essayer ult??rieurement."
  • Au niveau des logs de Postfix voici ce que l'on obtient :
Feb  9 03:01:13 alice postfix/smtpd[26670]: F0E34462194: client=unknown[10.0.0.50]
Feb  9 03:01:14 alice postfix/cleanup[26674]: F0E34462194: message-id=<52F6E167.808@mail.glx>
Feb  9 03:01:14 alice postfix/qmgr[26550]: F0E34462194: from=<cachelp@mail.glx>, size=519,
 nrcpt=1 (queue active)
Feb  9 03:01:14 alice postfix/virtual[26682]: F0E34462194: to=<cacheln@mail.glx>,
 relay=virtual, delay=0.3, delays=0.23/0.01/0/0.06, dsn=5.2.2, status=bounced (maildir
 delivery failed: "La bo??te mail de votre destinataire est actuellement pleine. Votre
 message n'a pu lui ??tre remis. Veuillez r??essayer ult??rieurement.")
Feb  9 03:01:14 alice postfix/cleanup[26674]: 287BD462197: message-id=
 <20140209020114.287BD462197@alice.lan>
Feb  9 03:01:14 alice postfix/bounce[26684]: F0E34462194: sender non-delivery notification:
 287BD462197
Feb  9 03:01:14 alice postfix/qmgr[26550]: 287BD462197: from=<>, size=2512, nrcpt=1 (queue
 active)
Feb  9 03:01:14 alice postfix/virtual[26682]: 287BD462197: to=<cachelp@mail.glx>,
 relay=virtual, delay=0.07, delays=0.03/0/0/0.04, dsn=2.0.0, status=sent (delivered to maildir)

Nous remarquons en rouge l'erreur de quota détectée lors de la remise du mail dans la boîte de l'usager. Dès que l'erreur est détectée, Postfix envoi à l'émetteur une notification d'échec de remise en indiquant le message d'erreur configuré dans le paramètre virtual_maildir_limit_message.

Gestion des Alias

  • Jusqu'à présent, nous avons vu qu'une boîte mail est définit par deux éléments :
    • une adresse de messagerie qui, dans notre cas est de la forme <login>@mail.glx;
    • un répertoire de stockage situé dans le dossier /home/<login>/Maildir/.
  • Néanmoins, il est possible d'ajouter une ou plusieurs adresses supplémentaires pointant vers notre boîte mail principal. Ces adresses supplémentaire sont appelé alias. Par exemple, on peut créer l'alias nicolas.cachelou@mail.glx pour la boîte mail cacheln@mail.glx. Ainsi, tous les mails reçus sur nicolas.cachelou@mail.glx seront en faites stockés dans la boîte cacheln@mail.glx.
  • Les alias sont sauvegardés dans la table postfix_alias. Cette table comporte deux champs important : alias qui comportera l'adresse de notre alias et destination qui comportera l'adresse vers laquelle pointera l'alias.
  • Nous souhaitons créer l'alias nicolas.cachelou@mail.glx pour le compte mail cacheln@mail.glx. Voici l'enregistrement Sql que nous allons ajouter :
INSERT INTO `courriel`.`postfix_alias` (
 `id` ,
 `alias` ,
 `destination`
)
 VALUES (
 NULL , 'nicolas.cachelou@mail.glx', 'cacheln@mail.glx'
);
  • Maintenant, envoyons un mail à nicolas.cachelou@mail.glx et observons les logs dans /var/log/mail.log :
Feb 16 12:46:25 alice postfix/smtpd[2702]: connect from oxtrode.net.ncad.fr[10.0.0.51]
Feb 16 12:46:25 alice postfix/smtpd[2702]: 6C8D42E2A7D: client=oxtrode.net.ncad.fr[10.0.0.51]
Feb 16 12:46:25 alice postfix/cleanup[2707]: 6C8D42E2A7D: message-id=<5300A511.1080707@mail.glx>
Feb 16 12:46:25 alice postfix/qmgr[1114]: 6C8D42E2A7D: from=<cachelp@mail.glx>, size=552, nrcpt=1 (queue active)
Feb 16 12:46:25 alice postfix/smtpd[2702]: disconnect from oxtrode.net.ncad.fr[10.0.0.51]
Feb 16 12:46:25 alice postfix/virtual[2709]: 6C8D42E2A7D: to=<cacheln@mail.glx>, orig_to=<nicolas.cachelou@mail.glx>,
  relay=virtual, delay=0.25, delays=0.13/0.04/0/0.08, dsn=2.0.0, status=sent (delivered to maildir)
Feb 16 12:46:25 alice postfix/qmgr[1114]: 6C8D42E2A7D: removed

Le mail parvient bien à cacheln@mail.glx. Nous observons la présence des champs to=<> et orig_to=<> qui permettent de distinguer l'alias de la destination réelle.

Gestion des Répondeurs

Un message automatique peut être retourner à l'émetteur pour toute réception d'un mail. Cette fonction vacation appelée aussi Message d'absence ou répondeur permet de notifier l'émetteur en cas d'absence du destinataire ou pour acquitter la bonne réception de son mail.

Installation

  • Installation du module vacation et des dépendances :

sudo apt-get install vacation libmail-sendmail-perl libdbd-pg-perl libemail-valid-perl libmime-perl libmime-charset-perl libmime-encwords-perl libdbd-mysql-perl

  • Création de l'utilisateur vacation :

sudo useradd -m vacation -s /bin/nologin -c "Utilisateur vacation"

  • Le programme vacation.pl est issue de la solution PostfixAdmin :

mkdir /var/spool/vacation
cd /var/spool/vacation
wget www.linuxmail.info/files/vacation.pl
chown postfix:vacation /var/spool/vacation -R
chmod 750 /var/spool/vacation -R

  • Dans le fichier /var/spool/vacation/vacation.pl, on va adapter les lignes suivantes selon les paramètres de connexion à la base de données :
our $db_type = 'mysql';
our $db_host = '10.0.0.47';
our $db_username = 'postfix';
our $db_password = 'motdepassebasemysqlpourpostfix';
our $db_name     = 'postfix';
our $test_mode   = 0;

Création des tables

  • Ensuite on créée les deux tables permettant au programme de gérer les messages d'absence depuis la base de données précédemment définie :
CREATE TABLE `vacation` (
 `email` varchar(255) NOT NULL,
 `subject` varchar(255) character set utf8 NOT NULL,
 `body` text character set utf8 NOT NULL,
 `cache` text NOT NULL,
 `domain` varchar(255) NOT NULL,
 `created` datetime NOT NULL default '0000-00-00 00:00:00',
 `active` tinyint(1) NOT NULL default '1',
 PRIMARY KEY  (`email`),
 KEY `email` (`email`)
)

CREATE TABLE `vacation_notification` (
 `on_vacation` varchar(255) character set latin1 NOT NULL,
 `notified` varchar(255) character set latin1 NOT NULL,
 `notified_at` timestamp NOT NULL default CURRENT_TIMESTAMP,
 PRIMARY KEY  (`on_vacation`,`notified`)
)

Définition de la règle de transport

  • L'appel de la route vacation se fera par tout courriel étant reçu sur le domaine fictif vacation.mail.glx. Pour cela, nous allons définir une règle de transport pour ce nom de domaine dans la table postfix_transport :
INSERT INTO `courriel`.`postfix_transport` (
  `id` ,
  `domain` ,
  `destination`
)
  VALUES (
  NULL , 'vacation.mail.glx', 'vacation'
);
  • Nous allons également configurer le fichier hosts du serveur pour faire pointer en local le domaine fictif vacation.lan. Pour cela, éditer le fichier /etc/hosts puis y ajouter la ligne suivante :
127.0.0.1       vacation.mail.glx

Configuration de Postfix

  • Ajout de la route vers le répondeur vacation dans le fichier /etc/postfix/master.cf :
vacation   unix  -      n       n       -       -       pipe
 flags=Rq user=vacation argv=/var/spool/vacation/vacation.pl ${recipient} ${original_recipient}
  • Création du fichier /etc/postfix/vacation.conf avec les lignes suivantes (à adapter selon les paramètres de connexion à la base de données):
$db_type = 'mysql';
$db_host = '10.0.0.47';
$db_username = 'postfix';
$db_password = 'motdepassebasemysqlpourpostfix';
$db_name     = 'postfix';
  • Redémarrer Postfix pour appliquer les nouveaux paramètres :

sudo service postfix restart

Restreindre les services courier

  • Il est possible de limiter l'accès aux services POP3 / IMAP selon les utilisateurs. Pour cela, la table postfix_users dispose de deux colonnes :
    • disablepop3 pour limiter l'utilisation du service POP3 (0 : activé - 1 : désactivé);
    • disableimap pour limiter l'utilisation du service IMAP (0 : activé - 1 : désactivé).

Configuration de courier-authdaemon

  • Éditer le fichier de configuration /etc/courier/authmysqlrc puis ajouter à la fin du fichier la ligne suivante :
MYSQL_AUXOPTIONS_FIELD  CONCAT("disableimap=",disableimap,",disablepop3=",disablepop3,",disablewebmail=",disablewebmail,",sharedgroup=",sharedgroup)
  • Redémarrer le service courier-authdaemon pour appliquer les changements :

service courier-authdaemon restart

Blocage de IMAP

  • Nous souhaitons bloquer l'accès au serveur IMAP pour l'utilisateur cacheln. Pour cela, nous allons mettre à jour la valeur du champs disableimap pour l'enregistrement de l'utilisateur cacheln dans la table postfix_users :
UPDATE `postfix_users` SET `disableimap` = '1' WHERE `postfix_users`.`id` = '2' AND `postfix_users`.`postfix` = 'Y' LIMIT 1 
  • Maintenant, essayons de nous connecter au serveur IMAP avec le compte cacheln@mail.glx :

telnet 10.0.0.44 143
Trying 10.0.0.44...
Connected to 10.0.0.44.
Escape character is '^]'.
¤ OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION
STARTTLS] Courier-IMAP ready. Copyright 1998-2011 Double Precision, Inc. See COPYING for distribution information.
01 LOGIN cacheln@mail.glx cacheln
01 OK LOGIN Ok.
* BYE IMAP access disabled for this account.
Connection closed by foreign host.

Le serveur nous indique que nos identifiants sont correctes mais que IMAP a été désactivé pour notre compte.

Blocage de POP3

  • Nous souhaitons bloquer l'accès au serveur POP3 pour l'utilisateur cacheln. Pour cela, nous allons mettre à jour la valeur du champs disablepop3 pour l'enregistrement de l'utilisateur cacheln dans la table postfix_users :
UPDATE `courriel`.`postfix_users` SET `disablepop3` = '1' WHERE `postfix_users`.`id` =2;
  • Maintenant, essayons de nous connecter au serveur POP3 avec le compte cacheln@mail.glx :

telnet 10.0.0.44 110
Trying 10.0.0.44...
Connected to 10.0.0.44.
Escape character is '^]'.
+OK Hello there.
user cacheln@mail.glx
+OK Password required.
pass cacheln
-ERR POP3 access disabled for this account.
Connection closed by foreign host.

Sécurité

  • D'après la configuration étudiée ci-dessus, les mots de passe des utilisateurs transitent en clair entre le serveur Postfix' et la base de données Mysql. Si ces deux services sont hébergés sur des machines différentes, la faille de sécurité est d'autant plus dangereuse.


  • La base de données Mysql peut stocker les mot de passe en les cryptant. Lors de l'authentification, c'est le mot de passe crypté qui est comparé et non le mot de passe en clair. Ainsi, que le mot de passe soit récupéré lors de la phase d'authentification ou directement dans la base de données, cela n'a plus d'importance : le mot de passe est crypté et donc illisible par un humain.


  • Notre table postfix_users contient deux colonnes :
    • clear : pour le mot de passe stocké en claire (configuration actuelle);
    • crypt : pour le mot de passe stocké après avoir été crypté (configuration étudié par la suite).


  • Il faudra également spécifié à pam la méthode de cryptage souhaitée.

Cryptage du mot de passe

Configuration de pam pour Postfix

  • Éditer le fichier de configuration /etc/pam.d/pam et remplacer :
auth       required     pam_mysql.so user=postfix passwd=motdepassebasemysqlpourpostfix host=10.0.0.47 db=postfix table=postfix_users usercolumn=username passwdcolumn=clear crypt=0
account    sufficient   pam_mysql.so user=postfix passwd=motdepassebasemysqlpourpostfix host=10.0.0.47 db=postfix table=postfix_users usercolumn=username passwdcolumn=clear crypt=0
  • Par :
auth       required     pam_mysql.so user=postfix passwd=motdepassebasemysqlpourpostfix host=10.0.0.47 db=postfix table=postfix_users usercolumn=username passwdcolumn=crypt crypt=1
account    sufficient   pam_mysql.so user=postfix passwd=motdepassebasemysqlpourpostfix host=10.0.0.47 db=postfix table=postfix_users usercolumn=username passwdcolumn=crypt crypt=1
  • Appliquer les paramètre en redémarrant le service d'authentification saslauthd :

sudo service saslauthd restart

Configuration de authdaemon pour POP3 / IMAP

  • Éditer le fichier de configuration /etc/courier/authmysqlrc et commenter la ligne :
#MYSQL_CLEAR_PWFIELD = clear
  • Puis décommenter la ligne :
MYSQL_CRYPT_PWFIELD = crypt
  • Appliquer les paramètre en redémarrant le service d'authentification courier-authdaemon :

service courier-authdaemon restart

Mise à jour du mot de passe

  • Nous allons mettre à jour le mot de passe de notre utilisateur cacheln dans la base de données pour utiliser la méthode de cryptage ENCRYPT :
UPDATE `courriel`.`postfix_users` SET `clear` = , `crypt` = ENCRYPT( 'cacheln' ) WHERE `postfix_users`.`id` =2;

Vérification

  • On valide le login -u cacheln et le mot de passe -p cacheln avec la commande testsaslauthd :

testsaslauthd -u cacheln -p cacheln -f /var/spool/postfix/var/run/saslauthd/mux -s smtp

  • Visualisation d'une trame échangée entre le serveur Postfix et celui de la base de données MySQL sans cryptage :
Trame échangée entre le serveur SMTP Postfix et le serveur MySQL distant avant configuration

Le mot de passe apparaît en clair sur cette capture !

  • Visualisation d'une trame échangée entre le serveur Postfix et celui de la base de données MySQL avec cryptage ENCRYPT() :
Trame échangée entre le serveur SMTP Postfix et le serveur MySQL distant après configuration

Le mot de passe apparaît en crypté sur cette capture !

Ces modifications affectent aussi bien Postfix que POP3 et IMAP.

Chiffrement des échanges POP3/IMAP et Mysql

Il est conseillé de chiffrer les données si POP3/IMAP et MySQL sont installés sur deux machines différentes.

Prérequis

  • Il est nécessaire de disposer d'un serveur MySQL avec le chiffrement SSL d'activé. Si ce n'est pas le cas, se reporter à la documentation MySQL#SSL pour de plus amples informations. À l'issue de la lecture de ce document, il sera nécessaire de récupérer les fichiers ca.key, ca.crt et ca.pem issues du Certificat d'Autorité.

Certificat client

  • Le matériel de chiffrement sera stocké dans le répertoire /etc/courier/ssl :

mkdir -p /etc/courier/ssl
cd /etc/courier/ssl

  • On procède à la génération de la clé privée :

sudo openssl genrsa -out client.key 2048

  • On génère un fichier de demande de signature de certificat :

sudo openssl req -new -key client.key -out client.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
- - - - -
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:Paris
Locality Name (eg, city) []:Paris
Organization Name (eg, company) [Internet Widgits Pty Ltd]:NCad Network
Organizational Unit Name (eg, section) []:Intranet Goulouxiou
Common Name (e.g. server FQDN or YOUR name) []:10.0.0.44
Email Address []:tech@ncad.fr

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:N'importe quoi.
An optional company name []:NCad Network

  • On signe notre certificat à l'aide du certificat auto-signé de notre autorité de certification (qui sont identiques à ceux utilisés pour la signature du certificat du serveur MySQL) :

openssl x509 -req -in client.csr -days 365 -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
Signature ok
subject=/C=FR/ST=Paris/L=Paris/O=NCad Network/OU=Intranet
Goulouxiou/CN=10.0.0.44/emailAddress=tech@ncad.fr
Getting CA Private Key


client.crt >> client.pem
client.key >> client.pem

Configuration pour authdaemon

  • On configure courier-authdaemon pour utiliser le certificat généré. Pour cela, on édite le fichier /etc/courier/authmysqlrc et on y ajoute les lignes suivantes :
MYSQL_SSL_KEY      /etc/courier/ssl/client.key
MYSQL_SSL_CERT     /etc/courier/ssl/client.pem
MYSQL_SSL_CACERT   /etc/courier/ssl/ca.pem
MYSQL_SSL_CAPATH   /etc/courier/ssl/ca.pem
MYSQL_SSL_CIPHERS  ALL:!DES
  • On applique les modifications en redémarrant le service courier-authdaemon :

sudo service courier-authdaemon restart

Vérification

  • Bien que les méthodes vues précédemment permettent de ne plus voir le mot de passe qui transite en claire, il est quand même possible de voir le reste de la conversation entre les serveurs de courier et celui de la base de données. Pour sécuriser ces échanges, la méthode la plus sûre reste le chiffrement via SSL.
  • Visualisation d'une trame échangée entre le serveur Postfix et celui de la base de données MySQL sans ssl :
COURIER AUTH Clear.png

Les échanges apparaissent en clair sur cette capture !

  • Visualisation d'une trame échangée entre le serveur Postfix et celui de la base de données MySQL avec ssl :
COURIER AUTH Ssl.png

Les échanges apparaissent chiffrés sur cette capture !

Analyse de logs

Réception des mails

  • Nous sommes dans le cas d'une configuration avec des utilisateurs virtuels stockés dans une base de données MySQL. Voici comment transite le message reçu par Postfix :
Réception d'un mail
  • Maintenant, voici les logs relevés dans /var/log/mail.log :
Feb  7 13:30:04 alice postfix/smtpd[2443]: B19554618DE: client=geocoucou.net.ncad.fr[10.0.0.49]
Feb  7 13:30:04 alice postfix/cleanup[2450]: B19554618DE: message-id=<efd138995d0f22b61fe2ceb9cb007360@ncad.me>
Feb  7 13:30:04 alice postfix/qmgr[2441]: B19554618DE: from=<nicolas.cachelou@ncad.me>, size=1568, nrcpt=1 (queue active)
Feb  7 13:30:04 alice postfix/virtual[2451]: B19554618DE: to=<cacheln@mail.glx>, relay=virtual, delay=0.12, delays=0.06/0.01/0/0.05, dsn=2.0.0, status=sent (delivered to maildir)

Liens