Le 25/05/2007 par Marc Falzon -- Version 0.1
Autrefois réservée à une élite de barbus asociaux, l'administration système tend à se démocratiser à mesure que
les tarifs pour les locations de serveurs dédiés baissent. Moyennent quelques dizaines d'euros par mois, le quidam
peut souscrire à une offre dédiée chez un fournisseur d'hébergement Internet (pas fournisseur d'accès
Internet, attention à la confusion) et se faire une installation comme il l'entend avec les services dont il a
envie, configurés selon ses besoins.
Nous allons voir dans ce document comment monter une plateforme de messagerie électronique multi-domaines
(E-mail) à moindre coût en se basant exclusivement sur des logiciels
libres. Au final, notre architecture sera capable d'envoyer et de recevoir des e-mails de plusieurs domaines,
et ce en SMTP(S), POP3(S) et IMAP(S) avec une authentification SMTP-AUTH.
Cet article est destiné à des sysadmins confirmés : je considère que vous avez une bonne connaissance en administration système GNU/Linux ainsi que des protocoles que nous allons mettre en oeuvre ici (SMTP, POP3, IMAP, TCP/IP et DNS).
Dans un souci de fiabilité, de faible coût et surtout de liberté nous n'utiliserons que des logiciels libres. À noter également que le système d'exploitation utilisé pour réaliser cette documentation est GNU/Linux Debian 4.0 "Etch" (stable).
Notre serveur de messagerie est connecté directement sur Internet et dispose donc d'une adresse IP publique. Pendant toute la durée des travaux, assurez-vous bien que l'accès à la machine ne soit pas entravé par un firewall (à moins de savoir ce que vous faites) : nous verrons plus tard comment le régler pour laisser passer les flux requis.
À titre d'exemple, nous allons utiliser les domaines legumes.org, yaourts.fr et fruits.net afin de simuler une activité multi-domaines.
Avant d'attaquer le gros des travaux nous devons régler quelques détails sur l'OS sur lequel notre architecture va reposer. Voici les quelques paramètres à ajuster pour la bonne conduite de notre projet (à remplacer bien entendu par vos propres valeurs) :
De plus, les domaines pour lesquels nous serons déclarés MX (serveur de messagerie) doivent comporter un champ MX dans leurs informations de zone ; voici un exemple de configuration pour nos domaines d'exemple :
fruits.net IN MX 10 pomme.fruits.net.
yaourts.fr IN MX 10 pomme.fruits.net.
legumes.org IN MX 10 pomme.fruits.net.
Note : un enregistrement MX doit désigner impérativement un nom d'hôte direct (non CNAME) et non une adresse IP ! (cf. RFC 1912, paragraphe 2.4)
Nous considérons que le système sur lequel nous basons notre architecture est fonctionnel et "propre" - idéalement,
tout juste installé. Le plus important est qu'aucun autre MTA ne doit
être déjà installé avant ou pendant, veillez à effacer tous ses fichiers de configuration si tel était le cas.
Sur un système Debian le MTA Exim est installé de base : pour le supprimer, tapez la commande
suivante(2) :
root@pomme# aptitude remove --purge exim4 exim4-base exim4-config exim4-daemon-config
Et c'est parti : on commence par installer le serveur SMTP Postfix à l'aide de la commande aptitude :
root@pomme# aptitude install postfix
Ce paquet install au passage les dépendances openssl et ssl-certs ; le script de configuration post-installation du paquet postfix vous propose plusieurs configurations type : optez pour "Pas de configuration" afin de partir sur une base neutre, puis arrêtez le service lancé automatiquement par l'installeur :
root@pomme# /etc/init.d/postfix stop
C'est maintenant que les choses se gâtent : il est l'heure de configurer Postfix. Bien que SMTP ne soit pas un protocole très complexe en soi, les MTA ont la fâcheuse tendance à être relativement difficiles à configurer et Postfix, bien que plus simple que le très redouté Sendmail ne fait pas exception à la règle.
La configuration que je vais vous proposer est volontairement simple - voire simpliste - mais a le mérite de
fonctionner ; une fois que votre base sera fonctionnelle, vous aurez tout le loisir de rajouter des couches de restrictions
et autres optimisations. Voici le contenu du fichier /etc/postfix/main.cf, fichier de configuration
principal de Postfix :
Note : les paramètres commençant par le signe $ (dollar) sont des variables remplacées en interne par la valeur du paramètre de même nom. Exemple : écrire "myorigin = $myhostname" revient au même que "myorigin = pomme.fruits.net" car myhostname vaut "pomme.fruits.net".
eth0)À ce stade de la configuration, notre serveur SMTP est en mesure d'envoyer des e-mails mais pas encore d'en réceptionner. Il manque en effet les directives permettant d'indiquer à Postfix où stocker le courier et surtout pour qui : c'est la configuration des comptes "virtuels". Ces lignes sont à ajouter à la suite des précédentes :
Nous pouvons à présent passer au contenu des fichiers définissant quels sont les noms de domaines que nous gérons,
quelles seront les BAL de chacun de ses domaines ainsi que leurs alias. Dans un souci de clarté,
nous créons un répertoire virtual/ où nous stockerons nos fichiers de définitions :
root@pomme# mkdir /etc/postfix/virtual root@pomme# cd /etc/postfix/virtual
À l'aide de votre éditeur de texte favori, nous éditons le fichier qui recensera les noms de domaines dont nous
sommes destinataires. Voici le contenu du fichier /etc/postfix/virtual/domains pour notre contexte :
Jusqu'ici rien de bien méchant : un nom de domaine par ligne, et rien d'autre. Passons maintenant à la déclaration
des BAL pour chaque domaine. Dégainez une fois de plus votre éditeur de texte et tirez sur le fichier
/etc/postfix/virtual/boxes :
Voilà qui est déjà plus intéressant. Nous constatons que chaque ligne est composée de deux colonnes (deux "champs") :
le premier champ est l'adresse e-mail et le second précise le répertoire où doivent être stockés sur le système les
e-mails destinés à cette adresse. Ce chemin relatif est concaténé au chemin défini précédemment dans le fichier
main.cf par la directive "virtual_mailbox_base" : pour la première ligne le chemin entier est donc
/var/spool/mail/fruits.net/marc/, pour la deuxième /var/spool/mail/legumes.org/postmaster/ et ainsi de
suite. Le slash final est très important : c'est grâce à cela que nous pourrons stocker les mails au format
Maildir(4).
Notez au passage que nous avons opté pour une centralisation de toutes les BAL de chaque domaine
dans un répertoire de même nom que le domaine. Avant de tester notre système, nous allons déclarer quelques alias
dans le fichier /etc/postfix/virtual/aliases :
Ici nous venons de créer deux alias : postmaster@fruits.net qui est un alias de marc@fruits.net et patatemaster@legumes.org qui est un alias de postmaster@legumes.org. Notez au passage qu'il est possible de créer un alias qui pointe vers plusieurs adresses (les écrire les unes à la suite des autres, séparées uniquement par des virgules sans espaces), créant ainsi une liste de diffusion de fortune ; cette méthode a le mérite d'être extrêmement simple et rapide à mettre en place, toutefois il est recommandé d'utiliser des logiciels de gestion de listes de diffusions prévus à cet effet(5) pour des listes de tailles conséquentes.
Contrairement au fichier domains, nous avons une petite manipulation supplémentaire à faire pour
boxes et aliases. En effet, dans le fichier de configuration main.cf
le chemin vers ces deux fichiers est préfixé d'un hash: : ceci indique à postfix que ces fichiers sont
hachés, c'est-à-dire rédigés sous une forme "clé/valeur" (les deux champs dont nous parlions précédement).
En interne, Postfix cherchera à lire non pas le fichier spécifié mais sa version binaire (suffixée d'une extension
".db") : pour hacher nos fichiers, nous devons utiliser la commande postmap comme suit :
root@pomme# postmap /etc/postfix/virtual/aliases root@pomme# postmap /etc/postfix/virtual/boxes
Nous hachons aussi au passage le fichier d'alias système :
root@pomme# postalias /etc/aliases
Maintenant que nous avons déclaré quelques BAL et alias et générés les index des fichiers hachés, créons les répertoires des domaines dans le répertoire spécifié par la directive "virtual_mailbox_base" :
root@pomme# cd /var/spool/mail root@pomme# mkdir fruits.net legumes.org yaourts.fr root@pomme# chmod 750 * root@pomme# chown 5000:5000 *
Nous n'avons pas besoin de créer les répertoires des BAL, Postfix le fait automatiquement quand il reçoit un e-mail et que la BAL n'existe pas.
Voici l'heure de vérité : il est temps de tester si notre configuration fonctionne. Pour ce faire, démarrons le service et envoyons un e-mail depuis la machine à l'adresse marc@fruits.net :
root@pomme# etc/init.d/postfix start root@pomme# echo "Ceci est un test" | mail -s "Mail de test" marc@fruits.net
Dans les logs du système (/var/log/mail.log), nous avons la confirmation de remise de l'e-mail
que nous venons d'envoyer :
Apr 26 15:58:45 pomme postfix/master[2902]: daemon started -- version 2.3.8, configuration /etc/postfix Apr 26 17:16:06 pomme postfix/pickup[2904]: 4C27427BF4: uid=0 from=<root> Apr 26 17:16:06 pomme postfix/cleanup[3001]: 4C27427BF4: message-id=<20070426151606.4C27427BF4@pomme.fruits.net> Apr 26 17:16:06 pomme postfix/qmgr[2905]: 4C27427BF4: from=<root@fruits.net>, size=310, nrcpt=1 (queue active) Apr 26 17:16:06 pomme postfix/virtual[3003]: 4C27427BF4: to=<marc@fruits.net>, relay=virtual, delay=0.17, delays=0.13/0.01/0/0.03, dsn=2.0.0, status=sent (delivered to maildir) Apr 26 17:16:06 pomme postfix/qmgr[2905]: 4C27427BF4: removed
En effet, si nous regardons dans le répertoire du domaine fruits.net nous voyons que la BAL de l'adresse marc@fruits.net a été créée automatiquement, et le mail que nous venons d'envoyer est bien présent :
root@pomme# ls -l /var/spool/mail/fruits.net/ total 4 drwx------ 5 5000 5000 4096 2007-04-27 01:46 marc root@pomme# cat /var/spool/mail/fruits.net/marc/new/1177631215.V801I17d0eM958472.pomme Return-Path: <root@fruits.net> X-Original-To: marc@fruits.net Delivered-To: marc@fruits.net Received: by pomme.fruits.net (Postfix, from userid 0) id D921517D0B; Fri, 27 Apr 2007 01:46:55 +0200 (CEST) To: marc@fruits.net Subject: Mail de test Message-Id: <20070426234655.D921517D0B@pomme.fruits.net> Date: Fri, 27 Apr 2007 01:46:55 +0200 (CEST) From: root@fruits.net (root) Ceci est un test
Vous pouvez souffler, le plus dur est fait ;-)
Envoyer et recevoir des e-mails c'est bien, mais on aimerait bien pouvoir les lire de temps en temps. Nous allons maintenant installer et configurer Dovecot, le serveur POP3 et IMAP.
Toujours à l'aide de la commande aptitude, nous installons les paquets nécessaires :
root@pomme# aptitude install dovecot-common dovecot-imapd dovecot-pop3d
Ces paquets installent également en dépendances les librairies nécessaires pour interfacer avec les bases de données MySQL, PostgreSQL et SQLite. Comme pour Postfix, assurons-nous que le service est bien arrêté pendant que nous le configurons :
root@pomme# etc/init.d/dovecot stop
Par défaut, le fichier de configuration de Dovecot (/etc/dovecot/dovecot.conf) contient toutes les
directives de configuration possibles, mais la plupart sont commentées et leur valeur fixée comme valeur par défaut
(qui sont dans la plupart des cas appropriées). Voici une configuration minimale, mais fonctionnelle :
Il nous faut maintenant déclarer les mots de passe protégeant l'accès aux BAL. Comme spécifié dans le
fichier de configuration ci-dessus, nous plaçons notre fichier passwds avec les autres fichiers dans le
répertoire /etc/postfix/virtual pour une question de cohérence.
L'utilitaire dovecotpw, fourni avec Dovecot, permet de générer des mots de passe. À l'instar des
fichiers utilisés par Postfix, le fichier qui va contenir nos mots de passe se compose de lignes à la syntaxe simplissime
; dans l'exemple qui suit nous affectons le mot de passe "marc" à la BAL marc@fruits.net :
root@pomme# cd /etc/postfix/virtual
root@pomme# echo "marc@fruits.net:`dovecotpw -p m0nP4s$`" > passwds
root@pomme# cat passwds
marc@fruits.net:{HMAC-MD5}82d79042a587dc82256017754ddaff6d750b93bc6c64b48cca25f33880653bc2
Ici le séparateur de champs n'est pas l'espace (ou tabulation) mais le signe deux points (":") ; chaque ligne est composée au minimum de deux champs (6), le premier est l'adresse e-mail de la BAL et le second le mot de passe crypté (préfixé par l'algorithme utilisé pour le crypter entre deux accolades). Pour nous assurer du bon fonctionnement de notre serveur POP3/IMAP, essayons de lire notre e-mail précédemment envoyé en POP3 :
marc@banane:~% telnet pomme.fruits.net 110 Trying 89.142.23.50... Connected to pomme.fruits.net. Escape character is '^]'. +OK Dovecot ready. user marc@fruits.net +OK pass m0nP4s$ +OK Logged in. list +OK 1 messages: 1 405 . retr 1 +OK 405 octets Return-Path: <root@fruits.net> X-Original-To: marc@fruits.net Delivered-To: marc@fruits.net Received: by pomme.fruits.net (Postfix, from userid 0) id D921517D0B; Fri, 27 Apr 2007 01:46:55 +0200 (CEST) To: marc@fruits.net Subject: Mail de test Message-Id: <20070426234655.D921517D0B@pomme.fruits.net> Date: Fri, 27 Apr 2007 01:46:55 +0200 (CEST) From: root@fruits.net (root) Ceci est un test . quit +OK Logging out.
Tout est OK, nous pouvons désormais aussi consulter notre courier.
Avant de nous attaquer à des changement en profondeur nous pouvons commencer par le minimum syndical. Tout d'abord il est vivement recommandé de masquer les versions des logiciels que nous utilisons - voire les logiciels si c'est possible - afin d'empêcher les mauvais lutins préparant un complot contre notre rutilante architecture de messagerie de se renseigner sur des failles potentielles des services selon les versions.
Voici la directive à ajouter dans le main.cf de Postfix pour limiter la bannière à sa plus simple expression :
Ainsi, notre serveur se présentera en tant que "pomme.fruits.net SMTP". Idem pour Dovecot, nous ajoutons au
dovecot.conf la ligne suivante :
Aussi, nous réajustons les permissions sur les fichiers de configuration car ils contiennent des informations plus que sensibles :
root@pomme# find /etc/dovecot -type f -exec chmod 600 {} \;
root@pomme# find /etc/postfix -type f -exec chmod 600 {} \;
root@pomme# chmod u+x /etc/postfix/postfix-script /etc/postfix/post-install
Nous pouvons mainenant envoyer et recevoir des e-mails, seulement un problème se pose : comment faire pour permettre à des utilisateur de se servir de notre serveur SMTP à distance (comprendre : sans se logger sur la machine) sans pour autant permettre à tout le monde de le faire (y compris les spammeurs) ? Notre machine était directement connectée sur Internet et nos utilisateurs légitimes pouvant se situer n'importe où dans le monde, ils peuvent avoir des adresses IP très diversifiées : il n'est donc pas envisageable d'autoriser uniquement une plage réseau à envoyer des e-mails via notre serveur.
La méthode pour laquelle j'ai opté s'appelle SMTP-AUTH. Nous partons du principe que nous n'autorisons l'envoi d'e-mails via notre serveur SMTP que pour nos utilisateurs, par conséquent ceux qui disposent d'au moins une BAL sur notre serveur. En pratique, nous allons faire en sorte que Postfix reconnaisse les utilisateurs du service POP3/IMAP en se servant directement du mécanisme d'authentification de Dovecot. Pour ce faire, nous ajoutons les lignes suivantes dans le fichier main.cf de Postfix :
/var/spool/postfix : dans notre exemple, la socket est donc
/var/spool/postfix/private/auth)Il faut également ajouter quelques lignes de configuration dans le dovecot.conf de Dovecot (au sein de la
section auth default { ... }) :
Redémarrez maintenant Dovecot puis Postfix : vous constatez qu'une nouvelle socket auth s'est ajoutée aux
autres sockets de Postfix dans le répertoire /var/spool/postfix/private.
Testons à présent notre configuration en situation réelle :
marc@banane:~% telnet pomme.fruits.net 25
Trying 89.142.23.50
Connected to pomme.
Escape character is '^]'.
220 pomme.fruits.net ESMTP Postfix
helo esmtp
250 pomme.fruits.net
mail from: marc@fruits.net
250 2.1.0 Ok
rcpt to: postmaster@bouh.com
554 5.7.1 <postmaster@bouh.com>: Relay access denied
Ici nous constatons que les restrictions imposées à Postfix sont entrées en vigueur : lorsque l'on essaye d'envoyer un
e-mail à une adresse extérieure à nos domaines sans avoir été authentifié notre tentative est rejetée.
Essayons à present en nous authentifiant au préalable :
auth plain AG1hcmNAZnJ1aXRzLm5ldABtYXJj 235 2.0.0 Authentication successful mail from: marc@fruits.net 250 2.1.0 Ok rcpt to: postmaster@bouh.com 250 2.1.5 Ok data 354 End data with <CR><LF>.<CR><LF> coucou ! . 250 2.0.0 Ok: queued as 4998727C60 quit 221 2.0.0 Bye Connection closed by foreign host.
La première instruction déclenche l'authentification SMTP-AUTH (ici en utilisant le mécanisme PLAIN, c'est-à-dire non chiffré)(9). Une fois authentifié(10), nous rententons d'envoyer un message à l'adresse extérieure : Postfix nous laisse maintenant faire.
Si toutefois vous pensez qu'on vous espionne, que votre vie est en danger mais que vous n'avez pas trop envie de courir dans les rues de New York en peignoir poursuivi par des agents de la NSA, alors vous voudrez peut-être chiffrer les connexions SMTP, POP3 et IMAP entre les utilisateurs et le serveur. Voici les directives de configuration à ajouter dans le main.cf de Postfix pour activer le support de TLS au niveau SMTP :
Au passage, notons qu'il est possible d'exiger que l'authentification des utilisateurs lors du SMTP-AUTH soit chiffrée par TLS ; il vous faut ajouter cette directive dans le même fichier de configuration :
De même, nous ajoutons à Dovecot le support du POP3S et IMAPS à l'aide des directives suivantes dans le
dovecot.conf :
À cela il faut ajouter les mots clés pop3s et imaps à la directive "procotols" (cf. ligne 1 du listing au chapitre 5) pour que Dovecot supporte explicitement les protocoles POP3S et IMAPS :
protocols = imap imaps pop3 pop3s
Il est possible d'interdire l'authentification d'utilisateurs par des méchanismes faisant transiter les mots de passe en clair (méthodes PLAIN et LOGIN notamment), ou plutôt de ne les autoriser qu'au sein d'une connexion TLS. Pour ce faire, il faut ajouter cette directive aux deux précédentes :
disable_plaintext_auth = yes
Redémarrez une fois de plus Postfix et Dovecot : vous pouvez à présent accéder à votre serveur e-mail en SMTP(S), POP3(S) et IMAP(S) !
Pour tout sysadmin il est une association d'idée inévitable quand on parle d'e-mail : le spam. Fléau quasi impossible à éradiquer définitivement, difficile à juguler... Voici une méthode parmi d'autres, mais qui a à mon sens le meilleur rapport complexité de mise en oeuvre/rendement.
Notre protection antispam va consister à refuser tous les e-mails envoyés depuis un hôte présent sur une blacklist
recensant les émetteurs de spam (type Spamhaus,
SpamCop) ou dont la structure n'est pas conforme aux
RFC (normes et protocoles standardisés internationalement) - signe distinctif
de l'écrasante majorité des spammeurs. Grâce à une poignée de directives à ajouter au fichier de configuration
main.cf de Postfix il est possible d'éliminer efficacement près de 95% du spam reçu :
HELO.VRFY (utilisée par les premiers spammeurs).Avec tout cela, les spammeurs seront bien (mal) reçus ;-) Mon serveur de messagerie tourne avec cette configuration, et depuis je ne reçois presque plus de spam tout en recevant toujours les e-mails "légitimes", même les plus commerciaux d'entre eux. Il est arrivé qu'un de mes utilisateurs se plaigne de ne pas recevoir des e-mails, après inspection des logs il s'est avéré que le serveur SMTP de l'université était blacklisté par rfc-ignorant.org...
Parce que nos utilisateurs peuvent être soumis à des contraintes diverses et variées (firewall d'entreprise, déplacements fréquents etc.) il peut être confortable de pouvoir accéder à ses e-mails via un webmail depuis un simple navigateur.
J'ai opté pour Squirrelmail, un webmail en PHP qui a fait ses preuves depuis plusieurs années et qui est activement
maintenu par la communauté du logiciel libre. De plus, il est simple mais efficace. Pour l'utiliser, vous devez disposer d'un
serveur HTTP et de PHP : ici nous utiliserons Apache comme serveur web.
Afin de ne pas sortir du contexte de ce guide je considère que vous disposez d'une configuration HTTP/PHP fonctionnelle :
nous ne verrons ici que la configuration du virtual host de notre webmail.
root@pomme# aptitude install squirrelmail squirrelmail-locales gettext root@pomme# /etc/init.d/apache2 stop
Opérant sur un serveur "vierge" ne disposant pas encore de serveur web, APT nous installe au passage les dépendances
apache2-* et php4-* : si vous voulez utiliser PHP5 il vous faudra installer ce dernier avant
Squirrelmail. Notez aussi que nous installons les locales de Squirrel pour disposer de la traduction française : il faut
installer le paquet gettext car l'internationalisation est basée sur ce logiciel.
Le paquet squirrelmail fournit un utiliaire squirrelmail-configure faciliant la configuration du webmail,
recommandé afin d'éviter toute erreur de le fichier de configuration. Passons maintenant à la configuration du vhost :
il doit contenir au moins les lignes suivantes
Rien de bien insurmontable : on définit le FQDN du vhost à mail.fruits.net et on spécifie où sont localisés les
fichiers de Squirrelmail (par défaut sur Debian, dans /usr/share/squirrelmail).
Une fois le fichier édité, démarrez le serveur web Apache ; pensez à déclarer mail.fruits.net au niveau DNS
(vers pomme.fruits.net ou directement sur l'adresse IP du servuer), soit chez votre registrar ou directement dans la zone
si vous gérez le domaine vous-même.
Pointez maintenant votre navigateur sur http://mail.fruits.net/ : vous êtes redirigé vers la page de login de
Squirrelmail. Entrez votre login (adresse e-mail entière) et mot de passe (défini au chapitre 5 dans le fichier
passwds), et le tour est joué ! Vous pouvez là aussi ajouter une couche de chiffrement SSL/TLS si votre
paranoïa vous le recommande, mais cela dépasse le cadre de cet article.
Si tout s'est passé comme prévu vous devriez à présent disposer d'une plateforme de messagerie simple, fonctionnelle, performante et surtout (relativement) sécurisée. Si vous jugez que vous recevez encore trop de spam vous pouvez passer au calibre supérieur et utiliser un filtre de contenu tel que Spamassassin et un antivirus. Personnellement, j'estime que la configuration proposée dans ce guide blinde suffisament le serveur contre le spam et que tout filtrage supplémentaire incombe aux utilisateurs.
master.cf mentionné
existe bien à cet endroit) :
awk '/^[0-9a-z]/ && ($5 ~ "[-yY]") { print "oui"; exit}' /etc/postfix/master.cf
Si la commande retourne "oui" alors votre Postfix est chrooté.\0identifiant\0motdepasse) nécessite d'être encodée en base64 :
perl -MMIME::Base64 -e 'print encode_base64("\0adresse\@email.com\0motdepasse");'Auteur et mainteneur : Marc FALZON <marc (chez) falzon (point) info>
$LastChangedDate: 2008-03-22 18:15:58 +0100 (sam, 22 mar 2008) $
Ce document est publié sous Licence FDL |
