Adrien's log

Yet Another Note Pad

Serveur de mails perso

by adrien on 30 janvier 2011

Quand on a un site web, il est plus professionnel que le contact entre les visiteurs et le webmaster se fasse via une adresse en @lesiteenquestion.com plutôt qu’une adresse de type Gmail, Hotmail, AOL ou Voila (Bien que je ne critique pas leurs services). Et en plus de faire plus classe, cela vous permet d’avoir un nombre quasi-illimité d’adresses, pas de quotas mais aussi cela vous permet d’envoyer vous même (sans passer par un serveur SMTP tiers) vos mail depuis un script PHP par example.

Comment ça marche les E-mails ?

Pour avoir notre solution de mails complètes, il va nous falloir mettre en place deux service : l’un pour envoyer les mails (SMTP), l’autre pour les recevoir (POP ou IMAP).

Lorsque vous envoyez un mail depuis votre client, ce dernier l’envoi au serveur SMTP (pour Simple Mail Transfer Protocol) qui va se charger de le remettre au serveur IMAP/POP de votre destinataire. Le protocole POP sert à lire ses mails depuis un client de messagerie, il récupère les mails sur le serveur et les stockent sur votre PC. IMAP, quant à lui, est plus récent, il permet lui aussi au client de récupérer les mails mais va travailler directement sur le serveur.

Pour notre solution, nous utiliserons encore notre Debian avec, en plus, Postfix qui s’occupe du SMTP, et Courier qui prends en charge POP et l’IMAP.

Installation

On va créer le groupe et l’utilisateur de postfix :

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

Alors, dans la première ligne, le -g 5000 signifie que l’on veut que le groupe ait un GID de 5000. Pour la seconde ligne : en premier, on demande à ce que l’utilisateur fasse partit du groupe que l’on vient de créer, en deuxième on demande à ce que l’utilisateur ait l’UID 5000, ensuite on indique où sera son répertoire Home et enfin on lui demande de le créer (ben oui, il n’existe pas, on l’a pas créé).

Ensuite on passe aux choses sérieuses :

apt-get install postfix postfix-mysql

Choisissez la configuration ‘Site Internet’ et renseignez votre nom de domaine lorsque cela vous le sera demandé.

Postfix est installé, ça c’est fait.

MySQL

Nous partons du principe où MySQL est installé, donc on va créer la base, l’utilisateur et les tables :

mysql -p
CREATE DATABASE postfix;
USE postfix;
 
CREATE TABLE `admin` (
`username` VARCHAR(255) NOT NULL,
`password` VARCHAR(255) NOT NULL,
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`username`)
);
 
CREATE TABLE `alias` (
`address` VARCHAR(255) NOT NULL,
`goto` text NOT NULL,
`domain` VARCHAR(255) NOT NULL,
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`address`),
KEY `domain` (`domain`)
);
 
CREATE TABLE `alias_domain` (
`alias_domain` VARCHAR(255) NOT NULL,
`target_domain` VARCHAR(255) NOT NULL,
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`alias_domain`),
KEY `active` (`active`),
KEY `target_domain` (`target_domain`)
);
 
CREATE TABLE IF NOT EXISTS `config` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) NOT NULL DEFAULT '',
`value` VARCHAR(20) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
);
 
CREATE TABLE `domain` (
`domain` VARCHAR(255) NOT NULL,
`description` VARCHAR(255) CHARACTER SET utf8 NOT NULL,
`aliases` INT(10) NOT NULL DEFAULT '0',
`mailboxes` INT(10) NOT NULL DEFAULT '0',
`maxquota` BIGINT(20) NOT NULL DEFAULT '0',
`quota` BIGINT(20) NOT NULL DEFAULT '0',
`transport` VARCHAR(255) NOT NULL,
`backupmx` tinyint(1) NOT NULL DEFAULT '0',
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`domain`)
);
 
CREATE TABLE `domain_admins` (
`username` VARCHAR(255) 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',
KEY `username` (`username`)
);
 
CREATE TABLE `log` (
`timestamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`username` VARCHAR(255) NOT NULL,
`domain` VARCHAR(255) NOT NULL,
`action` VARCHAR(255) NOT NULL,
`data` text NOT NULL,
KEY `timestamp` (`timestamp`)
);
 
CREATE TABLE 'mailbox` (
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`name` varchar(255) CHARACTER SET utf8 NOT NULL,
`maildir` varchar(255) NOT NULL,
`quota` bigint(20) NOT NULL DEFAULT '0',
`local_part` varchar(255) NOT NULL,
`domain` varchar(255) NOT NULL,
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`username`),
KEY `domain` (`domain`)
);
 
CREATE TABLE `quota` (
`username` varchar(255) NOT NULL,
`path` varchar(100) NOT NULL,
`current` bigint(20) DEFAULT NULL,
PRIMARY KEY (`username`,`path`)
);
 
CREATE TABLE `quota2` (
`username` varchar(100) NOT NULL,
`bytes` bigint(20) NOT NULL DEFAULT '0',
`messages` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`username`)
);
 
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`)
);
 
GRANT ALL PRIVILEGES ON postfix.* TO 'postfix'@'localhost' IDENTIFIED BY 'votremotdepasse' WITH GRANT OPTION;
<pre escaped="true">INSERT INTO domain (domain, description)
      VALUES ('VOTRENDD', 'UNEDESCRIPTION');
 
INSERT INTO admin (username, password, active)
      VALUES ('contact@Votrendd.tld', 'passwordenmd5', '1');
 
INSERT INTO domain_admins (username, domain, active)
      VALUES ('contact@Votrendd.tld', 'ALL', '1');
 
INSERT INTO mailbox (username, password, name, maildir, domain, active)
      VALUES ('contact@Votrendd.tld', 'passwordenmd5',
              'VotreNom', 'Votrendd.tld/contact/', 'Votrendd', '1');

Pour chiffrer votre mot de passe correctement, vous pouvez utilisez la fonction crypt() de PHP.

DNS

C’est fini pour la base de données (tapez ‘exit’ pour quitter la console), passons à la configuration des DNS. C’est pas compliqué, il vous faut juste ajouter un enregistrement MX dans votre fichier de zone. Mon fichier de zone se situe dans /var/lib/bind/adrien-robert.me.hosts . Il faudra ajouter une ligne comme celle-ci :

VOTRENDD  IN MX PRIORITE ADRESSEIP

Où VOTRENDD sera … votre nom de domaine, IN simplement le mot-clé IN, MX indique qu’il s’agit d’un serveur de mails, PRIORITE est utile quand vous avez plusieurs serveurs de mails, nous mettrons 1 et enfin ADRESSEIP qui est l’adresse IP de votre serveur de mails.

Enregistrez, quittez et rechargez la configuration (/etc/init.d/bind9 restart).

Postfix

Les DNS : Checked ! Passons à la configuration de Postfix. Aller, rentrons à pieds joins dans le fichier /etc/postfix/main.cf

Voilà à quoi ressemble le mien :

# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname
 
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
 
# appending .domain is the MUA's job.
append_dot_mydomain = no
 
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
 
readme_directory = no
 
# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
 
# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.
 
mydomain = MONNDD
myhostname = MONSERVEUR.MONNDD
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = MONNDD
mydestination = localhost, localhost.localdomain, MONSERVEUR
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
 
virtual_mailbox_base = /var/spool/vmail
virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual-alias-maps.cf
virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual-domains-maps.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_minimum_uid = 5000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

La ligne ‘mynetworks’ contient l’adresse IP du/des réseau(x) autorisé(s) à utiliser le serveur SMTP, cette option est utile pour limiter le SPAM par exemple. Les lignes ‘virtual_*’ servent à interfacer Postfix et MySQL. Maintenant, il nous faut créer les dits fichiers :

#/etc/postfix/mysql-virtual-alias-maps.cf
 
user = postfix
password = postfix
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias WHERE address = '%s' and active = '1'
 
#/etc/postfix/mysql-virtual-domains-maps.cf
 
user = postfix
password = postfix
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain = '%s' and active = '1'
 
#/etc/postfix/mysql-virtual-mailbox-maps.cf
 
user = postfix
password = postfix
hosts = 127.0.0.1
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username = '%s' and active = '1'

Verifiez les permissions histoire de voir si Postfix à bien le droit de les lire. Redémarrez Postfix ‘/etc/init.d/postfix restart . Théoriquement, nous pouvons dès à présent envoyer un mail via telnet :

serveur:~# telnet localhost 25
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 smtp.Votrendd.tld ESMTP Postfix (Debian/GNU)
ehlo Votrendd.tld
250-smtp.Votrendd.tld
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
mail from: &lt;postmaster@Votrendd.tld&gt;
250 2.1.0 Ok
rcpt to: &lt;contact@Votrendd.tld&gt;
250 2.1.5 Ok
data
354 End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;
azerty
.
250 2.0.0 Ok: queued as A8B8B304261
quit
221 2.0.0 Bye
Connection closed by foreign host.

Si vous avez quelque chose comme ça dans votre fichier ‘/var/log/mail.log’ :

Jan 9 14:25:58 sb2 postfix/virtual[27794]: 4707B30424C: to=, relay=virtual, delay=0.61, delays=0.57/0.03/0/0.02, dsn=2.0.0, status=sent (delivered to maildir)

C’est que le mail a bien été délivré.

Courier

Maintenant occupons nous de la réception. Nous verrons uniquement l’installation de l’IMAP dans la suite.

Commençons par le commencement :

apt-get install courier-imap courier-authlib-mysql

A la question que l’installation vous pose, répondez non.

Pour la configuration, modifier le fichier ‘/etc/courier/authdaemonrc’ et mettez la variable ‘authmodulelist’ à ‘authmysql’.

Ensuite passons au fichier ‘/etc/courier/authmysqlrc’

MYSQL_SERVER              localhost
MYSQL_USERNAME         postfix
MYSQL_PASSWORD         postfix
MYSQL_PORT                  3306
MYSQL_DATABASE          postfix
MYSQL_USER_TABLE        mailbox
MYSQL_CRYPT_PWFIELD  password
MYSQL_UID_FIELD           5000
MYSQL_GID_FIELD           5000
MYSQL_LOGIN_FIELD       username
MYSQL_HOME_FIELD        "/var/spool/vmail/"
MYSQL_NAME_FIELD        name
MYSQL_MAILDIR_FIELD    maildir
MYSQL_WHERE_CLAUSE   active='1'

A modifier à votre convenance évidemment. On vérifiera une fois encore les permissions sur nos deux fichiers. Ensuite on redémarre les services ‘/etc/init.d/courier-imap restart’ et ‘/etc/init.d/courier-authdaemon restart’ .

Toujours théoriquement le serveur fonctionne. Testons simplement avec la commande ‘authtest contact@Votrendd.tld’, le résultat devrait être explicite. En cas d’erreur, il va falloir vous retaper toute la configuration, courier n’est pas très explicite et en plus de cela, il est capricieux. Si le test est positif, alors c’est gagné, vous devriez pouvoir vous connecter via votre client mail favori.

Cette article présente la base. En effet, nous n’avons pas configuré d’authentification sur le SMTP, donc tout le monde peut s’en servir. Nous n’avons pas non plus de filtre antispam, ni d’antivirus mail. Enfin, tout ce gère en ligne de commande, il nous manque une ou deux interfaces Web. Le mail, c’est vaste …

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *