Paramétrer son propre serveur mail, version 3

Comment ça, version 3 alors que je n'ai jamais fini la 2 ?

C'est comme ça… Le bordel sur l'autre page ne me plaisait pas.

Une partie est liée à des scripts bash/ansibles.

Concernant les domaines :

  • poste.example.org sera le relai mail (ce qu'on paramètre en priorité ici)
  • example.org sera le nom de domaine du mail, avec des adresses en machin@example.org

Installation du système de base

TODO : lvm, lien vers paramétrage des trucs de base.

Vérifier les DNS

C'est définitivement mieux de le faire en amont. Ça laisse le temps que ça se propage et de voir les erreurs. De toute façon, bosser sans vrai nom de domaine va être une belle galère.

Il faut :

  1. Un nom de sous-domaine pour le serveur mail, MX en A et AAAA vers lui depuis le domaine principal.
  2. Un reverseDNS sur la machine.

Quelque chose dans ce genre, dans la zone DNS :

poste.example.org.  IN  A  a.b.c.d
poste.example.org.  IN  AAAA  2001:a::b
example.org.  IN  MX  10 poste.example.org.

Le faire sur ipv6 si possible… Aujourd'hui tous les serveurs devraient le permettre, mais dans les faits, ça dépend entièrement du bon vouloir du fournisseur. Pas évident de savoir en amont, sauf à déjà avoir des machines chez ce fournisseur et accès à l'interface d'administration.

Quand on monte un serveur mail en local, cela dépend du FAI, mais aussi des capacités de la box.

  • Chez OVH, ma box (jamais remplacée et assez vieille) ne permettais pas de faire de l'ipv6, mais l'interface web d'OVH le prenait en compte ; c'est donc sans doute ok à présent ?
  • Chez Free, la box ne le gère pas non plus et ça reste un problème relevé sur les forums en 2026. De toute façon, les IP de Free seront résidentielles, et cela garantit une déliverabilité très mauvaise…

Pour MX, une priorité plus basse veut dire que ce sera choisi en premier. Donc si on a un relai paramétré à 10 et un second à 20, le courrier sera d'abord envoyé à 10. Si plusieurs relais ont le même chiffre, ça sera l'un ou l'autre. On verra dans un autre document comment mettre un relai backup MX (qui permet de récupérer les mails si notre relai principal tombe, et de lui renvoyer quand il revient) ; quand à avoir deux serveurs mails qui peuvent envoyer et recevoir, c'est sacrément plus complexe donc on va laisser ça de côté pour un bon moment1).

Il faut aussi configurer son Reversedns et ça, c'est permis ou non par l'hébergeur (dans l'interface web de gestion de la machine). La machine prend le “nom” du serveur mail.

  • Sur Oneprovider, pas de souci.
  • Depuis OVH telecom, ça se fait aussi, dans la partie telecom justement. Mais autant leur interface web permet ce qu'il faut en ipv6 et ipv4, autant ma box à la maison galère sur la gestion de l'ipv6 (trop vieille…).
  • Chez Free, dans “Ma freebox” sur https://adsl.free.fr, on a l'option “Personnaliser mon reverse DNS”. Cependant, en 2024, cela n'est possible que sur l'ipv4, ce qui posera souci pour la délivrance du mail avec les acteurs qui forcent à l'ipv6 (genre, gmail).

Ensuite, pour tester :

dig +short -x "a.b.c.d" @9.9.9.9
dig +short -x "2001:a::b" @9.9.9.9

L'un et l'autre doivent donner le nom de domaine configuré pour les ip en question. Le “@9.9.9.9” à la fin permet de passer par l'extérieur, si on teste en local sur un ordi local, dig ne retourne rien

Ports et parefeu

Il faut que certains ports soient accessibles avec internet.

Suivant la configuration, il faut ouvrir ces ports explicitement sur la machine, et potentiellement aussi sur un proxy ou la box avec redirection vers les ports du serveur. On ouvre les ports sur le proxy quand tout le reste est fini… Ça évite d'exposer une machine en cours de paramétrage.

Certains sont non-chiffrés :

  • 25 : SMTP
  • 143 : IMAP
  • 110 : POP (plus vraiment utilisé)

Et d'autres pour les échanges chiffrés :

  • 587 (ou 467) : SMTP ; 587 est “TLS”, 465 est “SSL”.
  • 993 (ou 220) : IMAP, 993 en SSL
  • 995 : POP (SSL)

Et suivant les besoins :

  • 4190 : Sieve
  • 10025 ? : Antivirus ? Vérifier, je ne suis pas sûre de l'intérêt.

En réalité on ne va ouvrir que ceci sur le nftables de la machine : 25, 587, 993, 4190. Oublions POP, l'IMAP en non-chiffré, et préférons SMTP-TLS2).

Avec la config paramétrée dans nftables, ce qu'il faut modifier/surveiller :

  • /etc/nftables.d/30-fight.nft : Protection contre le SMTP/Email Bombing, vérifier si ça ne bloque pas des serveurs légitimes.
  • /etc/nftables.d/40-confperso.nft : Autoriser en entrée 80, 443, 25, 587, 993, 4190 (encore que les deux premiers, uniquement si on a des outils de gestion web sur le serveur même ? mais c'est mon cas…)).
  • /etc/nftables.d/50-output.nft : Autoriser en sortie 25, 465, 587 (TODO : J'ai un petit doute sur SIEVE, on vérifiera…).

/etc/hosts

Vérifier que /etc/hosts a un nom de domaine cohérent (si renseigné) avec notre reversedns. Dans mon cas il avait doublé “poste” ce qui faisait un domaine en “poste.poste.example.org”. Cela créait ensuite des soucis.

Cela donne un fichier de ce genre comme ceci :

/etc/hosts
127.0.0.1       localhost
127.0.1.1       poste.example.org     poste
 
# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Alias avec joker

Gandi a une fonctionnalité épatante : l'alias avec joker.

Extrait de leur doc :

Entrez le nom de d'alias, sans inclure le @. Vous pouvez également utiliser le caractère joker “*” pour, par exemple, avec “pierre*”, rediriger tout ce qui commence par pierre dans votre boite (ex.: pierre@ → pierremartin@, pierreafeu@, etc.). Cette option ne fonctionne toutefois qu'avec un minimum de 2 caractères avant ou après le joker.

Un peu plus d'exemples. J'ai la boite mail vilain@example.org, qui me sert à recevoir les inscriptions des sites, newsletters, commandes internet… autant dire que c'est bien rempli. vilain@ n'est jamais exposé sur le net3), au lieu de ça, je donne des alias, dont voici une liste :

  • nom.prenom@example.org
  • autrealias@example.org
  • news.*@example.org
  • marchand.*@example.org
  • wtf.*@example.org

Les deux premiers (nom.prenom@ et autrealias@) n'ont pas de joker, il faut avoir l'adresse exacte pour leur écrire. Les suivants par contre, je les adapte à la volée ; je donne marchand.site1@example.org à un premier site marchand et marchand.site2@example.org à un second site marchand, sans avoir besoin de créer les alias explicitement. Ensuite je m'en sert pour filtrer ce que je reçois dans ma boite mail et voir qui a revendu mon adresse (elles le sont rarement, en fait).

Je peux non seulement recevoir des mails à ces adresses avec joker, mais aussi répondre avec au besoin, bien que dans ce cas je sois dans l'obligation de déclarer l'alias dans Thunderbird (mais pas chez le fournisseur mail !).

Voilà la killer feature de Gandi, si difficile à trouver ailleurs.

La meilleure alternative est https://addy.io/. C'est libre (une configuration un peu spécifique d'un serveur mail), donc on peut l'installer chez soi, ou déléguer ça en payant le service en question. De mon côté je paie *mais* j'ai encore des adresses sur mon serveur de base qui ont besoin de ces alias avec joker. Coup de bol pour moi, tous mes alias fonctionnels sont de la forme chaine.joker ; sans le point, j'allais avoir des soucis.

J'ai donc fait quelques hacks pour que ce soit possible. Cela demandera quelques bidouilles sur Postfix et Dovecot (détaillées au fil de l'eau).

Installation des paquets

Configuration classique avec postfix, dovecot, mariadb, et postfixadmin pour gérer graphiquement les détails. Ainsi que phpmyadmin le temps des bidouilles (désactivé ensuite pour réduire les surfaces d'attaque).

Il y a plein de possibilité de panachages. J'ai fait un choix, ça m'aura pris des jours à me décider, plus des jours à adapter… Je vais essayer d'expliquer mais ce qui est fait pour un logiciel, peut s'adapter à un autre.

Aucune solution n'est parfaite ou meilleure. D'autres préféreront un serveur “tout en un” où tout est installé et géré. J'en avais listé quelques uns ici. Mais au final je préfère configurer à ma sauce. Cela me permet d'adapter à certains besoins spécifiques (comme les jokers) et de tourner sur une machine peu puissante.

Utilitaires

Quelques outils pratiques à avoir :

  • swaks : “couteau suisse du mail”, fournit divers utilitaires
  • bsd-mailx : permet de lire/envoyer les mails sur le serveur, en ligne de commande, utile lors des tests.
  • mutt : autre logiciel pour voir les mails, plus “graphique” (mais en console), et pratique aussi à d'autres moment. Voir ma doc associée en cas de souci.
  • certbot : le certificat SSL sera géré avec certbot, classique et fonctionnel.

Mon apt est configuré pour ne pas installer par défaut les recommandés et suggérés, ce qui demande de voir la liste et de compléter au besoin. Ici, à installer en complément pour se simplifier la vie :

sudo apt install swaks mutt shared-mime-info xdg-user-dirs

Mariadb

Mariadb ne sert qu'à stocker les utilisateurs donc très peu de données, sa perfomance ne sera pas un souci. Il sera aussi utilisé par Postfixadmin (cf plus bas).

sudo apt install mariadb-server 

Il n'y a plus besoin de lancer “mysql_secure_installation” sur Debian4) (d'ailleurs remplacé par la commande “mariadb-secure-installation”), par défaut c'est propre.

On peut tout de même se paramétrer un user “superadmin” (avec un autre nom que “root”) et un user pour postfixadmin, ce sera fait.

  • phpmyadmin va créer un utilisateur “phpmyadmin” avec le mot de passe entré de la configuration initiale ; utilisateur qui n'a pas le droit de faire grand chose. Notre “superadmin” sera plus pratique pour bidouiller les tables, et avec un nom moins commun5).
  • postfixadmin va attendre un utilisateur et une bdd de ce nom ; autant les faire et ne pas se complexifier la tâche, bien que cela offre une surface d'attaque (nom “commun”). On verra peut-être comment changer, à un moment, si c'est faisable sans trop de galères.

Ce qui suit est un demi-script bash. Juste le copier tel quel ne fonctionnera pas.

DB_ROOT_PASS="" 
DB_POSTAL_PASS=""
 
sudo systemctl enable --now mariadb
 
sudo mariadb -u root 
 
-- Configuration admin avec nom dédié
CREATE USER 'superadmin'@'localhost' IDENTIFIED BY '$DB_ROOT_PASS';
GRANT ALL PRIVILEGES ON *.* TO 'superadmin'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
 
-- Configuration Postfixadmin
CREATE DATABASE IF NOT EXISTS postfixadmin CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
DROP USER IF EXISTS 'postfixadmin'@'localhost';
CREATE USER 'postfixadmin'@'localhost' IDENTIFIED BY '$DB_POSTAL_PASS';
GRANT ALL PRIVILEGES ON postfixadmin.* TO 'postfixadmin'@'localhost';
 
FLUSH PRIVILEGES;
EXIT;

Postfix

Je fais le choix de Postfix (avec postfix-mysql pour parler à Mariadb) ; aujourd'hui pas mal de gens apprécieront plus Opensmtpd et c'est legit. Pourquoi j'ai finalement pris Postfix ?

  • Énormément plus de tutos, à destination des noobs et des experts, sur tous les cas de figures
  • J'aime la doc plus organique que des manpages
  • En discutant avec des sysadmin connaissant les deux logiciels, leur avis n'est pas absolument tranché en faveur de l'un ou l'autre. Opensmtpd est effectivement considéré comme un challenger pertinent, mais la réputation de difficulté à paramétrer Postfix est un peu usurpée (et je confirme, c'est comme plein de logiciels…).
  • Leur avis est aussi que Postfix est extrêmement puissant. Il permet de faire “tout” (y compris des conneries), c'est sa force et son risque. Opensmtpd est encore jeune et certaines options ne sont pas (encore?) possibles ; ceci dit rien qui bloquera la sysadmin hébergeant du mail familial.

Quand Postfix demande sa configuration, répondre “Site Internet”. Vérifier le nom de domaine, par exemple “poste.example.org”.

sudo apt install postfix postfix-mysql 

Dovecot

Dovecot, tout le monde le plébiscite, et ce n'est pas celui qui m'aura posé de souci.

  • dovecot-mysql : pour communiquer avec mysql et donc partager la même base d'utilisateurs
  • dovecot-imapd : pour utiliser l'IMAP donc obligé
  • dovecot-lmtpd : une fois arrivé sur le serveur, va aiguiller les mails aux bons utilisateurs (MDA)
  • dovecot-managesieved : permet aux utilisateurs de définir leurs règles de filtre.
sudo apt install dovecot-mysql dovecot-imapd dovecot-lmtpd dovecot-managesieved 

Et le reste

redis-server, opendkim etc

sudo apt install redis-server opendkim

Antispam

Rspamd est certes plebiscité mais… j'ai des misères à le faire tourner, et puis ça m'agace qu'il fasse “tout” (je préfère le KISS). Je ne veux pas que si rspamd plante, ça fasse foirer la signature DKIM… La solution Spamassassin+Opendkim est sans doute plus adaptée. Je vais quand même refaire des tests avec les deux et voir. Par ailleurs j'ai fait un test avec Modoboa (tout compris !) et rspamd consommait bien plus de mémoire “à vide” que Spamassassin+Amavis+Opendkim…

La chasse au spam reste donc un point en suspens pour le moment, attendant plus d'expérimentations, mais je vais plutôt vers la solution SpamAssassin.

DMARC

Il faudrait que je gère un chouïa mieux DMARC. C'est paramétré mais :

  • Je n'envoie pas de rapports en retour (c'est une mauvaise pratique, il faudrait que je le fasse)
  • Je n'analyse pas les rapports DMARC reçus (du coup quand il y a un souci, je m'en rends compte tardivement).

Dmarc-srg semble plutôt sympa sur l'analyse des rapports. En bonus, il se connecte en imap donc peut être installé sur une autre machine sans aucun souci.

OpenDmarc (référence sur le sujet) génère les rapports à envoyer aux autres admins. Ça semble une sacré usine à gaz, probablement assez lourd. À voir et tester, mais… jusqu'ici, ne pas envoyer les rapports ne me fait pas “jeter” non plus. Par ailleurs cela demande que les milters aient vérifié SPF et DKIM (ce qui, de toute façon, serait mieux…). Opendkim gère DKIM, pour SPF voir le milter policyd-spf peut-être.

Web

Je vais avoir la surcouche graphique avec Postfixadmin, qui permettra à mes utilisateurs de gérer leurs propres alias et mot de passe.

Il y aura aussi phpmyadmin le temps des bidouilles6), mais faut penser à l'enlever à la fin, ça fait une surface d'attaque en moins.

Paramétrer postfixadmin est l'un des premiers trucs qu'on va faire histoire que la base de donnée soit utilisable ensuite par les autres logiciels.

Apache et certbot

On commence par paramétrer Apache, installer ce qu'il faut.

sudo apt install apache2 php certbot php-curl php-gd php-cli php-sqlite3 

Pour la configuration d'apache, cf script Ansible (ouais, ça pourrait être sur une forge ; peut-être un jour).

Demander un certificat let's encrypt

sudo certbot certonly --standalone -d mondomain.org --pre-hook "service apache2 stop" --post-hook "service apache2 restart"

Créer ensuite une page index basique histoire de vérifier si tout va bien. Ou utiliser celle sur /var/www/html (par défaut) pour le moment.

TODO : c'est bien de faire une page qui présente le nom de domaine. Dire que c'est un serveur mail, indiquer comment reporter les abuse, etc. Faudrait que je fasse une page en kit pour ça, respectant les bonnes pratiques (car il y a des attendus). En attendant, osef, c'est pas vital du tout.

/etc/apache2/sites-available/org.example.poste.conf
<VirtualHost *:80>
  ServerName poste.example.org
  DocumentRoot /var/www/html
 
RewriteEngine On
RewriteCond %{REQUEST_URI} !.well-known/acme-challenge
RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [R=301,L]
 
</VirtualHost>
 
<VirtualHost *:443>
  ServerName poste.example.org
  DocumentRoot /var/www/html
  Alias /postfixadmin /srv/postfixadmin/public
 
  <Directory /srv/postfixadmin/public>
      Require all granted
  </Directory>
 
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/poste.example.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/poste.example.org/privkey.pem
 
</VirtualHost>

Désactiver le site de base, activer le “notre” :

sudo a2dissite 000-default.conf 
sudo a2ensite org.example.poste.conf
sudo apachectl -t
sudo apachectl graceful

Postfixadmin

Lors de l'étape de Mariadb, on lui a déjà préparé la base de donnée.

Pour l'installer, on va passer par github plutôt que par le paquet, ce sera plus à jour. La doc d'installation officielle est là, je résume ici mes étapes en français.

Télécharger la dernière release (pas forcément jouer avec master qui est la version dev !) et la dézipper :

wget https://github.com/postfixadmin/postfixadmin/archive/refs/tags/v4.0.1.zip
unzip v4.0.1.zip
mv postfixadmin-4.0.1 /srv/postfixadmin
cd /srv/postfixadmin
sudo chmod a+x install.sh
./install.sh

Modifier /srv/postfixadmin/config.local.php (voir /srv/postfixadmin/config.inc.php pour les options pertinentes) :

/srv/postfixadmin/config.local.php
<?php
// Ce qui est ici surcharge config.inc.php.
 
// Montrer qu'on a compris :
$CONF['configured'] = true;
 
// Parce que j'aime causer en français
$CONF['default_language'] = 'fr';
 
// Les trucs de la BDD
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfixadmin';
$CONF['database_password'] = 'HO JE SAIS PLUS';
$CONF['database_name'] = 'postfixadmin';
 
// Comment on chiffre les mots de passe. Faudrait que je vérifie l'idéal... La doc propose :
$CONF['encrypt'] = 'dovecot:SHA512';
$CONF['dovecotpw'] = "/usr/bin/doveadm pw";

Il y aura d'autres trucs à voir par la suite (transport, autoreply, les alias automatiques (abuse ok, mais les autres ?), etc, mais on voit ça en détail après. Là on met le minimum pour se connecter et le paramétrer.

Se rendre ensuite sur https://poste.example.org/postfixadmin/setup.php : on devrait pouvoir générer le mot de passe et ajouter dans config.local.php quelque chose de ce genre :

$CONF['setup_password'] = 'Un truc chiffré';

En rafraichissant https://poste.example.org/postfixadmin/setup.php , on peut alors corriger d'éventuelles erreurs et créer le premier compte admin (l'identifiant doit être une adresse mail, le mot de passe doit être avec chiffres etc), puis se connecter.

Sécurité

Y'a plus à faire, dans l'absolu autant le paramétrer “là”.

Enfin (parce qu'il est un chouïa pénible sinon)

sudo apt install rkhunter

Snapshot

Refaire un snapshot parce que c'est long d'installer ces logiciels.

sudo lvcreate -L 10g -s -n snap_root_$(date --iso)_logicielsOK /dev/VgPoste/root

Paramétrage des paquets

Postfixadmin, épisode 2

Peut-être que c'est plus intéressant d'y revenir tout à la fin, mais je copie les modifs du fichier ici, pour que ce soit noté.

Diverses modifications sur config.local.php qui me semblent pertinentes, avec un commentaire en français pour s'y retrouver.

config.local.php
<?php
// Ce qui est ici surcharge config.inc.php.
// Modifier "poste.example.org" par le nom du relai.
// Chercher "TODO" pour voir les modifs importantes ;)
// Montrer qu'on a compris :
$CONF['configured'] = true;
$CONF['setup_password'] = 'TODO!!!Quelque chose généré par setup.php';
 
// Les trucs de la BDD
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfixadmin';
$CONF['database_password'] = 'TODO!!!';
$CONF['database_name'] = 'postfixadmin';
 
// Comment on chiffre les mots de passe. Faudrait que je vérifie l'idéal... La doc propose :
$CONF['encrypt'] = 'dovecot:SHA512';
$CONF['dovecotpw'] = "/usr/bin/doveadm pw";
 
// Valeurs par défaut des boîtes. Quota en MB. 5120=5GB, 10240=10GB
$CONF['aliases'] = '100';
$CONF['mailboxes'] = '10';
$CONF['maxquota'] = '5120';
$CONF['domain_quota_default'] = '10240';
// Activer les quotas (lié à Dovecot)
$CONF['quota'] = 'YES';
$CONF['used_quotas'] = 'YES';
$CONF['new_quota_table'] = 'YES';
 
// Structure des Maildir du type /usr/local/virtual/domain.tld/username@domain.tld
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
 
// Transport postfix (quand on utilise autre chose qu'un user system)
$CONF['transport'] = 'YES';
$CONF['transport_default'] = 'virtual';
 
// Vérifier que le domaine est autorisé (name server look-up)
$CONF['emailcheck_resolve_domain']='YES';
// Et qu'il est géré par postfix localement
$CONF['emailcheck_localaliasonly'] = 'YES';
 
// Alias par défaut créés avec un domaine mail.
// adresse complète (pour envoyer vers le domaine maitre) ou juste local (alias de la boite)
// On ne garde que abuse (RFC 2142) et postmaster (RFC 822/2822/5322)
// TODO : mettre le bon domaine !
$CONF['default_aliases'] = array (
    'abuse' => 'abuse@poste.example.org',
    'postmaster' => 'postmaster@poste.example.org',
);
 
// Pas d'expiration de mot de passe, c'est pénible, et à terme ce sera géré via le LDAP.
$CONF['password_expiration'] = 'NO';
 
// TODO : ceci quand on a configuré le reste du serveur mail et que "postmaster" (ou autre) existe.
// Compte admin pour envoyer les notifs
$CONF['admin_email'] = 'postmaster@poste.example.org';
$CONF['admin_smtp_password'] = '';
$CONF['admin_name'] = 'Postmaster';
 
// SMTP Client, évite les erreurs "HELO" lorsque que postfiadmin envoie un truc.
// TODO : mettre le bon domaine !
$CONF['smtp_client'] = 'poste.example.org';
 
// Ne pas permettre l'envoi de mail via cette interface
//$CONF['sendmail'] = 'NO';
 
// Personnalisation de l'interface
// Parce que j'aime causer en français
$CONF['default_language'] = 'fr';
 
// Nombre d'entrée par page. On peut mettre plus que le défaut...
$CONF['page_size'] = '30';
 
// Footer : pas besoin d'un lien vers le domaine de base.
$CONF['show_footer_text'] = 'NO';
 
// MOTD ("Motto of the day")
// Si besoin à un moment, c'est là. Peut se configurer par type d'user.
$CONF['motd_user'] = '';
$CONF['motd_admin'] = '';
$CONF['motd_superadmin'] = '';
 
// Message envoyé lors de la création d'une nouvelle mailbox.
$CONF['welcome_text'] = <<<EOM
Bienvenue,
Votre nouvelle boite mail est active !
 
Lisez notre guide de l'email ( https://alinea.ninm.net/dokuwiki/pratique:informatique:checklist:guide_debutant_mail )
pour éviter tout problème sur nos services !
 
EOM;

Dovecot

Ça devrait aller assez vite, ce n'est pas lui qui demande le plus de bidouilles. En théorie ce que j'ai fait sur l'ancien tuto va être bon.

Toutes les commandes en sudo/root.

Organisation des fichiers

  • /etc/dovecot/local.conf va lister toutes nos modifs, au lieu de modifier les fichiers systèmes dans /etc/dovecot/conf.d/.
    • Cela évitera des conflits lors des mises à jour et c'est plus rapide à paramétrer avec Ansible sans tout péter. Il restera tout de même à tester, à ces moments, si certaines syntaxes n'ont pas changé ; la commande doveconf -n devrait permettre de gérer ça.
    • Ce fichier est prévu pour ça dans Dovecot : tout à la fin de /etc/dovecot/dovecot.conf, la ligne !include_try local.conf indique que le fichier sera inclus (et surchargera tout ce qu'il y a pu y avoir avant).
  • /etc/dovecot/dovecot-sql.conf.ext contient les infos de connexion à la BDD.
  • Il y aura quand même, je crois, quelques modifs à faire dans /etc/dovecot/conf.d/, pour commenter des options dont on ne veut pas ?

Les fichiers Dovecot se terminant par “ext” sont analysés différemment par le logiciel. On ne touche pas à l'extension et on n'essaie pas de mettre n'importe quoi, n'importe où…

Nous allons aussi créer un utilisateur et son répertoire pour stocker les boites mails sur /var/vmail, que Dovecot va en grande partie gérer.

groupadd --system vmail
useradd --system --gid vmail vmail
mkdir -p /var/vmail
chown -R vmail:vmail /var/vmail
chmod u=rwx,g=rx,o= /var/vmail
  • –system crée un utilisateur explicitement “système”, spécialement réservé aux services et daemons. L'ID sera choisi automatiquement dans ce qui est dispo sur la plage réservée aux utilisateurs systèmes.

local.conf

Oui, ce tuto méritera que j'explique quoi et pourquoi. Mais le fichier local.conf devrait être bon avec Dovecot 2.4 (pas avant). Les commentaires devraient être assez parlant.

Sinon :

  • Authentification : visiblement tout passera par mysql à présent ?
  • Les modifs de la BDD sont pour maridab+Postfixadmin, si vous utilisez autre chose, adaptez…
  • SSL : c'est simplifié par rapport à la version précédente. Pensez évidement à indiquer le bon certificat. Ma partie ssl_cipher_list est plus exigente que la version de base, je me base sur les recommandations de Tycho.
  • Pour les plugins :

SIEVE permet de créer des règles de filtre sur le serveur et donc de trier automatiquement les emails sans lien avec le client courriel. Pratique quand on switche entre webmail et divers thunderbird. Snappymail permet de gérer ces filtres ; il y avait un module thunderbird mais actuellement indisponible. Je l'active donc chez moi.

/etc/dovecot/local.conf
# Modifs locales à Dovecot.
# En cas de doute, doc de ref : 
# https://doc.dovecot.org/
# https://workaround.org/ispmail-trixie/dovecot/
 
# Équivalent 10-mail.conf. Boites mails gérés à /var/vmail/domain/user.
####
mail_driver = maildir
mail_home = /var/vmail/%{user | domain}/%{user | username}
mail_path = ~/Maildir
mail_uid = vmail
mail_gid = vmail
mail_inbox_path = ~/Maildir/
 
# Permettre à Postfix d'utiliser Dovecot pour l'authentification
####
service auth {
  unix_listener /var/spool/postfix/private/dovecot-auth {
    mode = 0660
    user = postfix
    group = postfix
  }
}
 
# Connexion à la BDD
####
sql_driver = mysql
 
mysql /var/run/mysqld/mysqld.sock {
  user = postfixadmin
  ## Todo à changer ;)
  password = 'HO LE BEAU MOT DE PASSE'
  dbname = postfixadmin
  host = 127.0.0.1
}
 
userdb sql {
  query = SELECT username AS user, \
    CONCAT('*:bytes=', quota 'M') AS quota_rule \
    FROM mailbox WHERE username = '%{user}' AND active = 1
  iterate_query = SELECT username AS user FROM mailbox WHERE active = 1
}
 
passdb sql {
  # La requête doit retourner le champ 'password'
  query = SELECT password FROM mailbox WHERE username = '%{user}' AND active = 1
}
 
# SSL (10-ssl.conf)
####
ssl = required
ssl_server {
  ## Todo à changer ;)
  cert_file = /etc/letsencrypt/live/poste.example.org/fullchain.pem
  key_file = /etc/letsencrypt/live/poste.example.org/privkey.pem
}
ssl_min_protocol = TLSv1.2
ssl_cipher_list = HIGH:!eNULL:!LOW:!MEDIUM:!EXP:!RC4:!3DES:!MD5:!SHA1:!SHA256:!SHA384:!PSK:!kRSA:!SRP:-DH:+ECDH
 
 
# Plugins
####
mail_plugins = quota zlib quota_clone
 
protocol imap {
  mail_plugins = $mail_plugins imap_zlib imap_quota imap_sieve
}
 
# Pour utiliser lmtp, plus robuste que LDA dans la délivrance des mails
# LMTP gère la réception et la livraison des e-mails dans les boîtes aux lettres.
####
service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}
 
protocol lmtp {
  auth_username_format =
  mail_plugins = $mail_plugins sieve
}
 
# SIEVE
####
service managesieve-login {
  # Listen only on localhost
  inet_listener sieve {
    listen= 127.0.0.1
    port = 4190
  }
 
  # Disable the deprecated listener
  inet_listener sieve_deprecated {
    port = 0
  }
  ## Limite les fuites mémoires tout en laissant plusieurs processus s'éxécuter quand même
  restart_request_count = 50
  ## Garde un processus en attente (limite la latence)
  process_min_avail = 1
}
 
# Quota
#### 
## TODO : Vérifier que "quota2_before_insert" n'existe plus sur la base postfixadmin
 
quota "User quota" {
  driver = count
}
 
dict_server {
  dict mysql_quota {
    driver = sql
    sql_driver = mysql
 
    dict_map priv/quota/messages {
      sql_table = quota2
      username_field = username
      value_field messages {
      }
    }
 
    dict_map priv/quota/storage {
      sql_table = quota2
      username_field = username
      value_field bytes {
      }
    }
  }
}
 
quota_clone {
  dict proxy {
    name = mysql_quota
  }
}
 
# Alias avec joker
#### 
 
recipient_delimiter = .

Quota

Il y a actuellement un conflit avec les quotas sur Dovecot 2.4 (pas avant) et Postfixadmin (c'est ballot). Cependant, je ne semble pas avoir le trigger en question sur la release que j'utilise…

Dans la BDD :

sudo mariadb -u root
 
-- Aller dans la bonne base
USE postfixadmin;
 
-- Vérifier si le trigger existe
SELECT TRIGGER_NAME, EVENT_OBJECT_TABLE 
FROM INFORMATION_SCHEMA.TRIGGERS;
HOW TRIGGERS WHERE `Table` = 'quota2'\G
 
-- S'il y a une réponse, on vire, sinon tout ira bien.
DROP TRIGGER quota2_before_insert;

TODO : il faudra vérifier comment tout marche et si ça marche bien ; je délègue beaucoup à postfixadmin mais est-ce que je ne délègue pas “trop” ? À tester. Sinon reprendre le vieux tuto…

Gestion des droits, commandes de base

S'assurer que les droits empêcheront des malveillants de lire le mot de passe de la BDD : chown root:root /etc/dovecot/local.conf chmod go= /etc/dovecot/local.conf

On vérifie que la configuration n'a pas d'erreur ; si tout va bien, elle s'affiche en retour, sinon ça liste les erreurs à corriger :

doveconf -n

Et après ça on peut redémarrer Dovecot.

service dovecot restart

Si besoin de plus de détail, la doc officielle est là.

Postfix

Ce qu'il y a réellement à modifier :

  • check/header_checks_out ? (sur mon ancien serveur, pas sur base neuve)
  • mycfg : les divers fichiers de config
  • dynamicmaps.cf
  • main.cf
  • master.cf

Échanges entre Postfix et la base de donnée

ISPMail Guide propose une solution où nous référençons un fichier dans main.cf, ce dernier ayant les infos de connexion à la base de donnée et la requête (query) à faire pour l'action demandée.

Par exemple virtual_mailbox_maps = mysql:/etc/postfix/mycfg/mysql-virtual-mailbox-maps.cf dans main.cf. Le fichier mysql-virtual-mailbox-maps.cf a la forme suivante :

user = mailserver
password = MOTDEPASSE
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'

Sauf que je trouve cela redondant et amène à mettre les infos de connexion à la base de donnée à plusieurs endroits. Donc si on change le mot de passe, faut toucher à plusieurs fichiers. Restons à un principe DRY (Don't Repeat Yourself).

Il semblerait (TODO : je teste) qu'on puisse en réalité déclarer une fois les infos dans main.cf, puis la “query” dans ce même fichier7). Ce qui ressemble à ceci :

virtual_mailbox_maps = sqlite:server_sql
server_sql_query = SELECT 1 FROM virtual_domains WHERE name='%s'

C'est plus lisible, mais c'est déprécié, car main.cf a des droits plus permissifs que ce qu'on peut mettre dans les fichiers du type mycfg. Donc, on expose plus le mot de passe de la bdd… Ceci dit, je crains que ce mot de passe soit aussi dans d'autres fichiers “lisibles” (dovecot, postfixadmin)…

 Ce texte est placé sous licence CC0

1)
Faut que les clients aient un seul nom de domaine à renseigner sur leur thunderbird, ce qui veut dire load balancing ou un truc du genre ; on est sur d'autres infra.
2)
Pourquoi ? Je ne sais plus. Ça mérite de vérifier, mais en attendant…
3)
Enfin ça apparait si je répond à un mail mais qui regarde la source ?
4)
À partir de Trixie.
5)
Évidement, il faut l'appeler autrement que “superadmin”. Soyez inventif.
6)
Ou pas. Je ne l'ai pas mis, là, je vais tenter d'installer/gérer sans.
pratique/informatique/mail/serveur_mail3.txt · Dernière modification : 05/06/2026 18:46 de Zatalyz