Langues: es fr

Auto-hébergement des mails avec OpenSMTPD

Date : dernière revue en Octobre 2023 (OpenBSD 7.3).

L’objectif de ce tutoriel est de servir de guide pour auto-héberger ses mails de façon assez minimaliste. Le serveur mail utilisé, choisi pour sa simplicité, sera OpenSMTPD, que l’on supposera déjà installé.

Dans la suite, on suppose que toto et titi sont les noms d’utilisateurs système du serveur auto-hébergé, qui lui s’appellera mail.example.com.

1 Auto-hébergement minimaliste de ses mails

1.1 Pas à pas

On veut permettre à toto d’envoyer des mails à d’autres utilisateurs du serveur, mais aussi à d’autres serveurs et, qu’inversement, il puisse recevoir des mails.

La configuration d’OpenSMTPD (smtpd) se fait principalement dans le fichier smtpd.conf qui se trouve sur OpenBSD à l’adresse /etc/mail/smtpd.conf et probablement à une adresse similaire sur d’autres systèmes. La page man smtpd.conf(5) décrit toutes les possibilités de configuration, mais ici on n’aura besoin que d’une petite partie, et on va lister progressivement les lignes que contiendra smtpd.conf pour nos besoins.

Tout d’abord, il faut dire à smtpd d’écouter sur l’interface loopback locale pour que les utilisateurs locaux du serveur puissent communiquer avec smtpd.

listen on lo0

Puis on veut que d’autres serveurs puissent envoyer des mails à notre utilisateur. Pour cela, le serveur doit écouter sur l’interface réseau attachée à la route par défaut, le "gateway".

listen on egress

On peut remplacer le nom de groupe egress par le nom exact de l’interface réseau.

On s’occupe, maintenant, de la livraison des mails. Pour cela, on a d’abord besoin de définir la répartition des mails vers les utilisateurs, à l’aide du fichier /etc/mail/aliases. Dans ce fichier on écrit, par exemple :

toto: toto
titi: toto, titi

pour spécifier que les mails destinés à toto@mail.example.com doivent parvenir à l’utilisateur toto et que ceux destinés à titi@mail.example.com seront reçus par les deux utilisateurs toto et titi. La page man aliases(5) décrit d’autres possibilités plus avancées qu’offre le fichier aliases.

La commande newaliases permet ensuite de générer une base de données /etc/mail/aliases.db à partir du fichier aliases.

Ceci nous conduit à définir maintenant dans smtpd.conf une table aliases.

table aliases db:/etc/mail/aliases.db

On veut que la boîte mail de l’utilisateur toto se trouve à l’adresse /home/toto/mail/inbox et qu’elle soit de type maildir.

Premièrement, on permet aux utilisateurs locaux (dont toto) de recevoir des mails des autres utilisateurs locaux en utilisant la distribution donnée par la table <aliases> (syntaxe entre < et > pour se référer à la table). La syntaxe %{user.username} permet de récupérer le nom de l’utilisateur qui doit recevoir le mail.

action "local" maildir "/home/%{user.username}/mail/inbox" alias <aliases> 
match from local for local action "local"

Par défaut, smtpd n’accepte que les requêtes locales, donc la ligne précédente peut se simplifier en :

action "local" maildir "/home/%{user.username}/mail/inbox" alias <aliases> 
match for local action "local"

Deuxièmement, on veut que d’autres serveurs puissent envoyer des mails à nos utilisateurs :

action "fromout" maildir "/home/%{user.username}/mail/inbox" alias <aliases>
match from any for domain mail.example.com action "fromout"

Enfin, on veut que les utilisateurs locaux puissent relayer des mails à d’autres utilisateurs locaux, mais aussi vers d’autres serveurs :

action "toout" relay
match for any action "toout"

De même, le from local est implicite ici aussi.

1.2 Récapitulatif

Finalement, notre fichier smtpd.conf ressemble à ceci :

listen on lo0
listen on egress
table aliases db:/etc/mail/aliases.db

action "local" maildir "/home/%{user.username}/mail/inbox" alias <aliases>
action "fromout" maildir "/home/%{user.username}/mail/inbox" alias <aliases>
action "toout" relay

match for local action "local"
match from any for domain mail.example.com action "fromout"
match for any action "toout"

et il ne reste plus qu’à démarrer le serveur.

2 Mais je veux lire et envoyer des mails d’où je veux !

La configuration proposée ci-dessus permet aux utilisateurs locaux du serveur d’envoyer et de recevoir des mails sans problèmes, mais ne permet pas d’utiliser le serveur pour ce faire depuis une autre machine.

Plusieurs chemins sont possibles. Le plus simple, et qui ne demande pas de configuration particulière, est peut-être d’utiliser OpenSSH pour se loguer en tant qu’utilisateur local du serveur, et d’utiliser un client mail en mode texte comme mutt. C’est la méthode que j’utilise personnellement, qui ne demande pas de mettre en place un nouveau serveur (ssh tourne de toutes façons probablement déjà sur le serveur) et qui permet des échanges à l’abri des oreilles indiscrètes avec d’autres utilisateurs du serveur.

Il existe aussi la possibilité de permettre au serveur smtpd de relayer des mails de l’extérieur en s’authentifiant comme un utilisateur local à l’aide de l’argument auth-optional de la directive listen, ce qui règle le problème de l’envoi. On peut aussi utiliser des utilisateurs virtuels pour l’authentification en utilisant une table d’authentification. Pour accéder aux mails depuis l’extérieur, c’est plus compliqué et il faut passer par un serveur pop/imap comme dovecot, par exemple, ce qui dépasse l’objectif de ce tutoriel.

3 À propos de chiffrement et de certificats

Dans la configuration présentée plus haut, les messages reçus depuis d’autres serveurs transitent en clair, sans chiffrement, et quelqu’un les interceptant pourrait les lire. Pour se protéger des indiscrets, la mode actuelle veut qu’on chiffre les mails d’une manière ou d’une autre.

On peut, par exemple, vouloir utiliser un certificat dans le serveur, ce qui n’est pas très difficile à mettre en place, mais plus délicat à comprendre. Il y a d’autres voies possibles, du même ordre de difficulté, comme chiffrer ses mails avec PGP, ce qui est utile avec des personnes avec qui on a fait un échange de clés par un moyen sûr.

Il faut noter, quand même, qu’utiliser un certificat n’est pas une obligation, et qu’ajouter des fonctionnalités à son serveur, c’est ajouter de possibles erreurs humaines ou failles de sécurité, et que la méthode avec PGP n’a pas cet inconvénient.

Pour qu’un certificat soit fiable pour l’envoyeur externe, il faut qu’il soit signé par une autorité de certification (cf. wikipédia sur le sujet), en laquelle on a raisonnablement confiance. C’est relativement facile de nos jours avec Let’s Encrypt (voir la page man acme-client(1) sur OpenBSD, par exemple), ça l’était moins avant. Pour ce tutoriel, on va va se contenter d’un certificat auto-signé, c’est-à-dire sans passer par une autorité de certification. Du coup, à moins d’avoir, par quelque moyen sûr, accès à la clé publique (ce qui est possible par exemple lors d’un échange avec des gens qu’on voit en vrai), l’envoyeur extérieur ne pourra pas être sûr que quelqu’un ne s’est pas placé entre notre serveur et lui, en se faisant passer pour nous. Ceci dit, les messages n’iront plus en clair par défaut et la tâche d’intercepter les messages demandera au moins un peu plus d’efforts, faute de mieux.

Pour créer le certificat, la page man smtpd.conf(5) donne l’exemple des commandes  :

# openssl genrsa -out /etc/ssl/private/mail.example.com.key 4096
# openssl req -new -x509 -key /etc/ssl/private/mail.example.com.key \
          -out /etc/ssl/mail.example.com.crt -days 365
# chmod 600 /etc/ssl/mail.example.com.crt
# chmod 600 /etc/ssl/private/mail.example.com.key

ce qui crée une clé publique /etc/ssl/smtpd.example.com.crt et une clé privée /etc/ssl/private/mail.example.com.key. Ensuite, dans smtpd.conf, on peut rajouter les lignes

pki mail.example.com cert "/etc/ssl/mail.example.com.crt"
pki mail.example.com key "/etc/ssl/private/mail.example.com.key"

Ici, mail.example.com est juste un nom, il peut être remplacé par n’importe quoi.

Il faut, enfin, changer la ligne

listen on egress

par

listen on egress tls pki mail.example.com

pour que le serveur utilise le chiffrement en utilisant le certificat défini comme mail.example.com. Dans ce cas, le chiffrement est permis (mais optionnel) grâce à l’option tls. Le fait de choisir un chiffrement optionnel est le plus raisonnable à faire, puisque tous les fournisseurs d’hébergement mail sur internet n’utilisent pas forcément de chiffrement, et on veut pouvoir recevoir des mails de tout le monde. À plus forte raison, pour un échange particulier que l’on veut à l’abri des oreilles indiscrètes, cette méthode n’est probablement pas la meilleure.

4 Et quid du pourriel ?

Je ne me suis pas vraiment penché sur la question, n’en recevant encore que très peu souvent, donc je n’en parlerai pas dans ce tutoriel.

5 Conclusion

Même si ce tutoriel donne un serveur mail assez minimaliste, qui peut sembler peu pratique en préconisant préférablement l’utilisation de ssh pour l’utiliser à distance, il peut se révéler suffisant d’après mon expérience. Il ne faut pas oublier que, à moins d’être un sysadmin aguerri, c’est mieux de tendre vers la simplicité côté serveur, ça évite les erreurs. Moins il y a de services démarrés et plus simple est la configuration, moins il y a de chances d’avoir oublié un détail qui se transforme en faille, et moins il y a de chances qu’au bout d’un an on ne comprenne plus ce qu’on a fait.


Écrit par Anaseto.