Miam ! Un petit billet technique, tiens. Le lendemain de ma migration de la forge CodingTeam.net vers son nouveau serveur, j'ai eu envie de me pencher sur la configuration d'un serveur mail histoire d'être complètement indépendant des registrar fournissant des adresses mail (ou pas) avec les noms de domaines et de découvrir par la pratique les méandres de la communication pré-historique pré-XMPP. Après avoir fait un rapide tour d'horizon des tutoriels permettant l'installation de ce genre de solutions, je me suis vite rabattu sur cette antiquitée publiée sur Léa-Linux. En effet, ce tutoriel est court et simple. Tout le contraire de ce qu'on peut voir ailleurs sur le net où les auteurs ont dû se dire « mince, si je ne mets pas quatre sous-parties minimum par partie et 42 annexes à la fin, j'aurais l'air d'un con ». Le seul défaut (parce qu'il y en a toujours forcément un /o\) c'est que c'est vieux. Très vieux. 2006. C'était l'époque où Internet naissait et où l'on allumait encore un feu en frottant deux silex. Voilà pourquoi je le remet un peu au goût du jour et j'y change un peu les fichiers de configuration parce que depuis, on a inventé l'électricité.

Alors bon, je vais mettre ici la marche à suivre pour installer un serveur de mail à la mode de chez moi, plus ou moins basée sur ce tutoriel écrit par un certain Space2D (qu'on salue tous, bien entendu). Comme en plus, tout ça c'est nouveau pour moi, ça me fera un post-it grandeur nature au cas où je dois réinstaller une solution de ce genre et puis, si ça peut servir à quelqu'un ça sera top. De plus, si j'ai fait une bêtise, au moins, on me le dira. Les plus perspicaces d'entre-vous noteront (sans être nombreux) que j'ai volontairement oublié la partie anti-virus : oui parce que je ne suis pas fan de ces bestiaux là et que ledit tutoriel parlait de deux paquets non-libres. Ah ah, deux paquets non-libres ! En pré-requis, il vous faudra juste un serveur MySQL.

Allez les loulous, on ne perd pas le rythme ! On va tout de suite se lancer dans aptitude et se faire une install du tonnerre histoire de rapatrier les paquets postfix et postfix-mysql. Bien entendu, contrairement à ce que dit le tutoriel, on ne va pas utiliser des dépôts tiers, hein (de toute manière, les quota ça pue ça ne sert à rien). Là maintenant, on va taper du SQL, c'est rigolo. Allez hop, mysql -p (notez que vous avez un mot de passe à remplacer là dedans, indice, c'est à la fin).

CREATE DATABASE `postfix`;
USE postfix;

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';

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';

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';

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

Pour le moment, donc, pas de grosses différences avec le tutoriel initial puisque je n'ai pas changé le schéma SQL. Si vous êtes plus perfectionnistes que moi, n'hésitez pas à le retaper pour virer cette saleté de mélange de français et d'anglais !

Maintenant, toujours pour ne pas innover avec le tutoriel initial, on va donc créer l'utilisateur qui va nous permettre de stocker tous nos mails dans un seul dossier. Cet utilisateur s'appelle très justement vmail.

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

Hop, à vos claviers, on va s'attaquer au fichier de configuration de postfix. Personnellement je me suis généré le nécessaire pour utiliser TLS avant mais on ne va pas s'attarder là dessus, ça ne nous concerne pas plus que ça ici. Allez bon, vous êtes sympa, j'ai utilisé cette méthode là. Mais sans SASL, c'est pas possible (ou alors il doit falloir s'arracher les cheveux 3 jours de suite pour trouver une solution pour que ça marche) avec les utilisateurs virtuels MySQL qu'on se fait là.

Voilà donc le contenu de mon /etc/postfix/main.cf :

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

# SSL, ça je l'ai mis mais vous n'avez pas forcément besoin de ça
# smtpd_tls_key_file = /etc/postfix/ssl/smtpd.key
# smtpd_tls_cert_file = /etc/postfix/ssl/smtpd.crt
# smtpd_tls_CAfile = /etc/postfix/ssl/cacert.pem
# smtpd_use_tls = yes
# smtp_use_tls = yes
# smtpd_tls_auth_only = no
# smtpd_tls_security_level = may

append_dot_mydomain = yes

# Là c'est le nom de ma machine.
myhostname = ma.machine.sur.le.grand.internet

# Le « REVERSE_DNS » qu'est là, c'est un tuto sur le net qui en parlait, ça se trouve, ça ne sert à rien
mydestination = REVERSE_DNS, localhost.localdomain, localhost
myorigin = REVERSE_DNS
relayhost =

# Là ici, notez l'adresse IP locale (127.0.0.0/8),
# l'adresse IP de la machine sur l'Internet (142.214.142.214)
# et le fichier de pop-before-smtp
mynetworks = 127.0.0.0/8, 142.214.142.214, hash:/var/lib/pop-before-smtp/hosts

inet_interfaces = all

smtpd_sender_restrictions =
        permit_mynetworks

smtpd_recipient_restrictions =
        permit_mynetworks,
        reject_unauth_destination,
        reject_unknown_recipient_domain,
        reject_non_fqdn_recipient

smtpd_client_restrictions =
        reject_unknown_client,
        permit_mynetworks

alias_maps = hash:/etc/aliases

virtual_alias_maps = mysql:/etc/postfix/mysql-virtual_aliases.cf,mysql:/etc/postfix/mysql-virtual_aliases_mailbox.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 = "Sorry but the user quota is exceeded. Try again later."
virtual_overquota_bounce = yes

Et maintenant, on va créer les fichiers qui vont mettre en relation notre serveur postfix et le serveur MySQL. Premier fichier, mysql-virtual_aliases.cf :

hosts = 127.0.0.1
user = postfix
password = un_super_mot_de_passe_de_roxor
dbname = postfix
select_field = destination
table = alias
where_field = source
additional_conditions = AND actif=1

On passe maintenant à mysql-virtual_aliases_mailbox.cf :

hosts = 127.0.0.1
user = postfix
password = un_super_mot_de_passe_de_roxor
dbname = postfix
select_field = email
table = mailbox
where_field = email
additional_conditions = AND actif=1

Ne nous essouflons pas, passons à mysql-virtual_domains.cf :

hosts = 127.0.0.1
user = postfix
password = un_super_mot_de_passe_de_roxor
dbname = postfix
select_field = 'virtual'
table = domain
where_field = domain
additional_conditions = AND actif=1

Allez, l'avant dernier, ce sera mysql-virtual_mailbox_limit_maps.cf :

hosts = 127.0.0.1
user = postfix
password = un_super_mot_de_passe_de_roxor
dbname = postfix
select_field = quota
table = mailbox
where_field = email

Et pour terminer, remplissons ce bon mysql-virtual_mailboxes.cf :

hosts = 127.0.0.1
user = postfix
password = un_super_mot_de_passe_de_roxor
dbname = postfix
select_field = CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/')
table = mailbox
where_field = email
additional_conditions = AND actif=1

Comme tous les fichiers créés contiennent le mot de passé d'accès à la base de données, on va les sécuriser un petit peu en changeant le groupe propriétaire et les droits :

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

Bon, pour le moment, on en a terminé avec postfix et on va se lancer sur courier. Voilà comment j'ai installé et configuré courier-pop (et pas courier-imap parce que l'IMAP, je n'en ai pas besoin). Installons donc les paquets courier-base, courier-authdaemon, courier-authlib-mysql et courier-pop.

Courrons dans le fichier /etc/courier/authdaemonrc et cherchons y la ligne :

authmodulelist="authpam"

Remplaçons-la par :

authmodulelist="authmysql"
# La ligne qui suit, c'est issu d'un autre article sur le net, peut-être que ça marche sans \o/
version="authdaemond.mysql"

On va ensuite allez donner les paramètres de connexion qui vont bien dans le fichier /etc/courier/authmysqlrc. Pour ça, rien n'a changé depuis le temps, vous devrez bien entendu remplir les valeurs de MYSQL_SERVER, MYSQL_USERNAME, MYSQL_PASSWORD, MYSQL_DATABASE et MYSQL_USER_TABLE. Mais n'oublions pas les variables moins célèbres pour lesquels vous mettrez ces valeurs :

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),'/')

# MYSQL_NAME_FIELD       name

MYSQL_QUOTA_FIELD       quota

Maintenant, on va s'installer razor et spamassassin histoire de se protéger un minimum. Là, vous allez dans /etc/default/spamassassin et vous changez la valeur de ENABLED à 1. Tout simplement.

On va maintenant activer spamassassin et tout le toutim dans /etc/postfix/master.cf. Personnellement, si vous avez suivi, j'ai généré une clef histoire de causer en TLS à mon SMTP. Si vous aussi vous l'avez fait, chez moi, ça marche très bien avec ça :

smtps      inet  n       -       -       -       -       smtpd
        -o content_filter=spamassassin -o smtpd_tls_wrappermode=yes
465        inet  n       -       -       -       -       smtpd

Mais sinon, ça, ça devrait aller :

smtp      inet  n       -       -       -       -       smtpd
        -o content_filter=spamassassin

En tout cas, à la fin de votre fichier, ajoutez ces quelques lignes :

smtp    inet    n       -       -       -       -       smtpd
   -o content_filter=spamassassin
spamassassin    unix    -       n       n       -       -       pipe
      user=nobody argv=/usr/bin/spamc -f -e
         /usr/sbin/sendmail -oi -f ${sender} ${recipient}

Vous avez lu le tutoriel de Léa-Linux et vous vous dîtes que maintenant c'est bon, tout est terminé ? Que nenni ! Essayez d'envoyer un mail vers l'exérieur et vous aurez un bonne et jolie erreur. Comme rajouter votre IP (si tant est qu'elle soit fixe) dans le mynetworks du /etc/postfix/main.cf n'est pas ce qu'on fait de plus léger, voilà la solution miracle : installez le paquet pop-before-smtp ! Là, vous allez dans le fichier /etc/pop-before-smtp/pop-before-smtp.conf et vous devrez décommenter et commenter les lignes qui vont bien. En l'occurence, on utilise courier-pop donc c'est ça qu'il faut décommenter :

# For Courier-POP3 and Courier-IMAP:
$pat = '^[LOGTIME] (?:\[|\S+ )(?:pop3|imap|couriertcp)(?:d|d-ssl|login)\]?: ' .
    'LOGIN, user=\S+, ip=\[[:f]*(\d+\.\d+\.\d+\.\d+)\]';
$out_pat = '^[LOGTIME] (?:\[|\S+ )(?:pop3|imap|couriertcp)(?:d|d-ssl|login)\]?: ' .
    '(?:LOGOUT|DISCONNECTED), user=\S+, ip=\[[:f]*(\d+\.\d+\.\d+\.\d+)\]';

C'est beau, en plus.

Tiens, tant qu'on y est, j'ai dit qu'il y avait du TLS pour le SMTP, ne faisons pas de jaloux, mettons du SSL sur le POP et en plus d'être indépendants, vos communications avec le serveur seront chiffrées, c'est top. En plus, c'est pas compliqué, on installe le paquet courier-pop-ssl et on va configurer les informations de son certificat dans le fichier /etc/courier/pop3d.cnf pour mettre les informations qui vont bien (là encore donc, c'est du certificat auto-signé saymal-toussa-toussa). Et ensuite, en console :

# rm /usr/lib/courier/pop3d.pem
# rm /etc/courier/pop3d.pem
# mkpop3dcert
# cp /usr/lib/courier/pop3d.pem /etc/courier/pop3d.pem

Et maintenant ? Vous allez vous créer vos utilisateurs, vos alias et vos domaines (via le shell MySQL ou bien via un truc genre PHPMyAdmin si vous êtes fatigués). Et il ne vous restera plus qu'à relancer la « machine », soit les services postfix, courier-authdaemon, courier-pop, courier-pop-ssl, spamassassin et pop-before-smtp.

Et voilà ! Si comme moi, vous vous étiez déjà installé votre serveur Jabber, vous êtes maintenant complètement indépendants au niveau de vos moyens de communication sur le net. Ça se fête ! Ce que j'aime bien avec cette manière de faire, c'est que le multi-domaines est géré simplement, que je n'ai pas à créer des vrais utilisateurs pour chaque boîte mail et surtout qu'on peut très bien imaginer l'intégrer facilement dans une application existante (du coup, il suffirait d'aller chercher les infos dans la base de données). Bon, ma mise en œuvre n'est peut-être pas formidable (au réveil je n'y connaissais rien alors qu'au coucher tout était en place) mais ça marche pas mal du tout.