Serveur Postfix avec MySQL et utilisateurs virtuels
Préambule
Postfix est un serveur de mail, c'est à dire que c'est un logiciel qui va gérer l'envoi et la réception de mails. Par défaut, ce dernier fonctionne avec un seul et unique domaine, configuré en général comme étant le nom de la machine, mais cela peut se changer à l'installation. Dans le cadre de ce tutoriel, nous allons voir comment lui adjoindre un serveur MySQL, afin de disposer de plusieurs domaines et plusieurs adresses e-mails différentes.
Installation
La première chose à réaliser, c'est de procéder à l'installation des packages nécessaires :
apt install postfix postfix-mysql mariadb-server mariadb-client
Bien entendu vous remplacez apt par votre gestionnaire de package si vous n'êtes pas sur une distribution Debian ou basée sur Debian.
Pour information : apt et apt-get sont la même chose, il gère l'affichage de la couleur, affiche une barre de progression et évite apt-get pour l'installation et apt-cache pour la recherche de package
Création des tables SQL
Il faut d'abord créer un utilisateur pour la gestion MySQL pour Postfix (souvent appelé mailer ou postfix), et une base de données (souvent postfix).
Ensuite il faut créer les tables SQL :
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)
) ENGINE=INNODB;
CREATE TABLE postfix_relocated (
id int(11) unsigned NOT NULL auto_increment,
email varchar(128) NOT NULL default '',
destination varchar(128) NOT NULL default '',
PRIMARY KEY (id)
) ENGINE=INNODB;
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)
) ENGINE=INNODB;
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)
) ENGINE=INNODB;
CREATE TABLE postfix_users (
id int(11) unsigned NOT NULL auto_increment,
email varchar(128) 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 '2000',
gid int(11) unsigned NOT NULL default '2000',
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),
UNIQUE KEY email (email)
) ENGINE=INNODB;
CREATE TABLE postfix_virtual (
id int(11) unsigned NOT NULL auto_increment,
email varchar(128) NOT NULL default '',
destination varchar(128) NOT NULL default '',
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE postfix_access (
id int(10) unsigned NOT NULL auto_increment,
source varchar(128) NOT NULL default '',
access varchar(128) NOT NULL default '',
type enum('recipient','sender','client') NOT NULL default 'recipient',
PRIMARY KEY (id)
) ENGINE=INNODB;
Pour le champ quota de postfix_users, pensez à le mettre avec une valeur par défaut, si vous souhaitez définir un quota fixe (une taille maximale de la boîte aux lettres) pour toutes les adresses e-mail ; cela vous permettra de ne pas avoir besoin de renseigner cette information. Pour le homedir, c'est pareil, si les mails sont stockés au même répertoire racine, définissez le ici. Dans ce tutoriel nous prendrons : /var/mail/vmail comme dossier racine et donc de base. Pour le champ destination de postfix_virtual, vous pouvez lui mettre : maildrop: comme valeur par défaut, ce qui là aussi évite de devoir le mettre à chaque création.
Configuration de Postfix
Dans le fichier /etc/postfix/main.cf, ajoutez les directives suivantes :
# Pour la redirection
transport_maps = mysql:/etc/postfix/mysql/mysql-transport.cf
virtual_transport = virtual
# Stockage domaine
virtual_mailbox_domains = mysql:/etc/postfix/mysql/mysql-virtual-domains.cf
virtual_alias_maps = mysql:/etc/postfix/mysql/mysql-aliases.cf
virtual_mailbox_base = /var/mail/vmail
# Stockage email
virtual_mailbox_maps = mysql:/etc/postfix/mysql/mysql-virtual-maps.cf
virtual_minimum_uid = 100
virtual_uid_maps = static:2000
virtual_gid_maps = static:2000
# Support du relay
# relay_domains = mysql:/etc/postfix/mysql/mysql-relay-domains.cf
# Support du quota
virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql/mysql_mailbox_limit.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = La boite email de l'utilisateur est pleine, merci d'essayez plus tard.
virtual_overquota_bounce = yes
mysql-aliases.cf
Chaque fichiers pour la configuration MySQL, doit se trouver dans /etc/postfix/mysql. Pensez bien à modifier user et password pour correspondre à votre configuration, idem pour dbname.
user = mailer
password = motdepasse
dbname = postfix
hosts = 127.0.0.1
query = SELECT destination FROM postfix_alias WHERE alias = '%s'
mysql-relocated.cf
user = mailer
password = motdepasse
dbname = postfix
hosts = 127.0.0.1
query = SELECT destination FROM postfix_alias WHERE alias = '%s'
mysql-transport.cf
user = mailer
password = motdepasse
dbname = postfix
hosts = 127.0.0.1
query = SELECT destination FROM postfix_transport where domain = '%s'
mysql-virtual-maps.cf
user = mailer
password = motdepasse
dbname = postfix
hosts = 127.0.0.1
query = SELECT maildir FROM postfix_users where email='%s' and postfix = 'y'
mysql-recipient.cf
user = mailer
password = motdepasse
dbname = postfix
hosts = 127.0.0.1
query = SELECT maildir FROM postfix_users where email='%s' and postfix = 'y'
mysql-sender.cf
user = mailer
password = motdepasse
dbname = postfix
hosts = 127.0.0.1
query = SELECT maildir FROM postfix_users where email='%s' and postfix = 'y'
mysql-client.cf
user = mailer
password = motdepasse
dbname = postfix
hosts = 127.0.0.1
query = SELECT access FROM postfix_access WHERE source = '%s' AND type = 'client'
Appliquez ensuite un chmod 640 sur tous ces fichiers et le groupe postfix à ces derniers.
Créer un utilisateur
La création d'un utilisateur, se fait via l'ajout de lignes dans les différentes tables SQL. Ici, nous gérons deux choses : le domaine associé à l'adresse e-mail (ce qui est après @), et l'adresse e-mail en elle même.
Domaine
Il faut ajouter une ligne dans postfix_virtual_domains, avec le nom du domaine et la valeur maildrop: (d'où le fait de la mettre par défaut, comme ça on n'indique que le nom du domaine pour créer notre ligne).
Adresse
Il faut ajouter une ligne dans postfix_users, avec l'adresse e-mail complète, le champ crypt avec un mot de passe passé via un algorithme de hashage. Pour vos premiers tests, je recommande le MD5 car immédiatement utilisable dans phpmyadmin quand vous allez ajouter votre ligne, par la suite il faudra un algorithme plus sécuritaire comme le SHA512 par exemple. Je vous renvoi sur la documentation de Dovecot car c'est lui qui va gérer l'authentification de l'utilisateur ; vous y trouverez une liste des algos qui sont gérés.
Dans notre ligne, nous devons donc renseigner : email, crypt, name qui est le nom de la personne, homedir (d'où la valeur par défaut), maildir que nous allons voir après (suivi de Maildir/) et quota si on en met un.
Répertoire des mails
Dans notre exemple, nous avons dis que nous allions mettre les mails dans /var/mail/vmail, le dossier vmail correspondant à l'utilisateur vmail (c'est ma configuration ^^). Dedans, nous allons avoir plusieurs sous-répertoire : un par domaine et dedans nous en aurons un par e-mail.
Si je prends l'exemple de ce wiki, nous avons donc : /var/mail/vmail/codedev.fr/contact, ce qui correspond au homedir plus le maildir formé par le domaine indiqué dans postfix_virtual_domains et la première partie de l'adresse e-mail (avant le @). Ici donc j'ai une adresse contact@codedev.fr, ce qui donne un maildir : codedev.fr/contact.
Maintenant que nous avons créée l'adresse e-mail, il nous faut créer le répertoire qui va les contenir, c'est ce qu'on appel un maildir, que l'on crée avec maildirmake :
- maildirmake /var/mail/vmail/domain/user/Maildir
- maildirmake -q quota /var/mail/vmail/domain/user/Maildir
Bien entendu il faut avoir au préalable avoir créer /var/mail/vmail/domain/user avec un mkdir. Pensez à remplacer domain et user par les bonnes informations.
En premier lieu, la première commande va créer l'architecture de répertoires, la seconde va appliquer un quota exprimé en octets (sans cette commande, il n'y a pas de quota). Le quota se termine par un S majuscule (ne me demandez pas pourquoi, c'est comme ça).
Vous pouvez maintenant redémarrer votre serveur Postfix si vous ne l'avez pas fait après avoir créer les fichiers de configuration.
Automatisation possible
Pour ne pas s'embêter, il est possible de réaliser un script shell (par exemple), qui va demander l'adresse e-mail complète à créer, et le quota. Il en extrait le premier élément et dernier élément, donnant donc l'utilisateur et le domaine. Il est possible ensuite de lui faire exécuter une requête SQL via l'outil mysql (il faut le mot de passe de l'utilisateur associé à la base de donnée, donc à mettre en dur dans le script ou à demander à l'exécution pour garantir une certaine sécurité). On peut donc exécuter une requête de sélection pour vérifier que le domaine existe, si la requête renvoi pas de résultat, on exécute une insertion pour créer le domaine, puis une requête pour sélectionner l'utilisateur au cas où il existe déjà ; si aucun retour, on peut exécuter la requête de création de l'utilisateur en fournissant en plus l'information de quota. Enfin, le script peut s'occuper d'exécuter le mkdir nécessaire (-p pour du récursif) puisqu'il connait le domaine et l'utilisateur (et qu'on a fixé l'emplacement du homedir), et exécuter les deux commandes maildirmake.
Cela peut donc permettre de ne pas s'embêter, et d'avoir quelque chose d'automatisé, et qui pourrait être exécuté depuis une interface web. C'est en général d'ailleurs ce que font Google, Yahoo et autres fournisseurs d'adresse e-mail : on crée notre compte depuis leur site, automatiquement derrière un script est exécuté pour créer l'adresse e-mail et le maildir nécessaire au bon endroit.
En PHP, cela peut être fait directement (maildirmake est à exécuté en manuel donc en tan que commande externe, pour les autres commandes y compris les requêtes SQL, PHP sait très bien le faire), ce qui peut permettre d'éviter d'écrire un script supplémentaire : votre interface web peut déjà le faire.
En règle général, tout langage qui sait bossé avec un SGBD, peut automatiser la tâche sans devoir appeler l'outil mysql, et ne devoir appeler en commande externe que le maildirmake ; de quoi ne pas s'embêter d'ailleurs.
Conclusion
Nous avons vu comment installer et configurer Postfix pour nous fournir les mails sur plusieurs adresses ET domaines. Bien que nous avons déjà quelque chose de fonctionnel : on peut envoyer des e-mails via PHP par exemple ou encore l'outil mail en ligne de commande de Linux, on peut aussi en recevoir ; en revanche on ne peut pas consulter pour l'instant, il faut donc procéder à l'installation et configuration de Dovecot qui va le faire pour nous.