« Serveur de courriels » : différence entre les versions

De Wiki doc

Aucun résumé des modifications
(Replacement des balise de coloration syntaxique en ligne par des balises codes pour optimiser le chargement de la page + correction de fautes de frappes)
 
(62 versions intermédiaires par 2 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
[[Category:linux]]
[[Category:service_courriels]]
[[Category:service_email]]
[[Category:service]]
Postfix est un serveur de messagerie électronique. Il se charge de la livraison de courriers électroniques (courriels) et a été conçu comme une alternative plus rapide, plus facile à administrer et plus sécurisée que l'historique Sendmail.


Dans ce tuto, nous mettrons en place :
''Postfix'' est un serveur de messagerie électronique se chargeant de la livraison de courriels sur un réseau ''IP''. Il a été conçu comme une alternative plus rapide, plus facile à administrer et plus sécurisée que l'historique ''Sendmail''.
* Le serveur de courrier Postfix avec gestion d'IPv6, utilisateurs PAM, SASL, des alias, des domaines secondaires, des listes noires, gestion du SPAM avec SpamAssassin et STARTTLS
* Le serveur IMAP Dovecot avec gestion de l'IPv6, du STARTTLS, les filtres Sieve
* Le client web Rainloop


Pré-requis :
L'environnement gravitant autour de ce thème étant assez complexe (avec son lot de technologies et de termes spécifiques), un [[#Glossaire|glossaire des notions]] utiles a été rédigé en bas de page. Il est recommandé d'aller y jeter un œil si vous n'êtes pas très familier avec le sujet.
* Debian 8
* Un nom de domaine avec un enregistrement MX
* Une IP publique fixe
* LISTE DES PORTS UTILISÉS POUR LE PARE-FEUX


Dans ce document, nous mettrons en place :
* Le service de courrier électronique [http://www.postfix.org/ Postfix] avec support d{{'}}''IPv4/IPv6'', négociation de chiffrement via ''TLS'' et ''STARTTLS'', utilisateurs ''Postfix'' et gestion de domaines via ''SQLite'', authentification ''SASL'', gestion des alias, des domaines secondaires, des listes noires ainsi que de ''Milter'' pour les liaisons avec ''OpenDKIM'' et ''Spamassassin''
* Le service ''IMAP'' [https://www.dovecot.org/ Dovecot] avec gestion d{{'}}''IPv4/IPv6'', du ''TLS'' et de ''STARTTLS'' ainsi que des filtres ''Sieve''
* La signature des messages via le protocole ''DKIM'' par l’intermédiaire du logiciel [http://www.opendkim.org/ OpenDKIM]
* Du traitement du pourriel avec [https://spamassassin.apache.org/ SpamAssassin]


<h1 style="color:red;">Article en cours de rédaction</h1>
=Test du DNS=
Installation des outils.
# apt update && apt install openssl dnsutils telnet


Test du fonctionnement du champ MX
Il faudra vous assurer d'avoir la main sur les éléments suivants :
$ dig exemple.fr MX
* Prérequis :
** ''Debian'' 11 (''Bullseye'')
** Un nom de domaine avec un enregistrement ''MX'' et ''A''
** Une adresse ''IP'' publique fixe avec possibilité d'enregistrement ''PTR''


La réponse doit contenir une "ANSWER SECTION" avec ceci :
* Permettre la communication en écoute des ports ''TCP'' suivants :
** 25 (''SMTP'')
** 465 (''SMTP'' sur ''TLS'' aussi appelé ''Submission'')
** 587 (''SMTP'' ''STARTTLS'')
** 143 (''IMAP'')
** 993 (''IMAPS'')
 
{{info|J'attire votre attention sur l'importance d'avoir un opérateur Internet faisant correctement son travail (ce qui commence à se faire rare en France...). Il est indispensable d'avoir une adresse ''IP'' fixe non listés par les principaux prestataires anti-pourriels (voir https://mxtoolbox.com/blacklists.aspx) ainsi que la possibilité d'ajouter un champ ''PTR'' (''DNS'' inversé ou ''reverse DNS'') dans le registre de nom de votre ''FAI''. Sans ces pré-requis, votre service sera difficilement fiable car une partie de vos messages risquent d'être bloqués par les serveurs destinataires. Si vous ne pouvez souscrire à un vrai accès Internet (avec un fournisseur sachant ce qu'est une adresse ''IP'' au lieu de vous fournir de la ''TV''...) comme ceux proposés par la [https://www.ffdn.org/ FFDN] ou [https://www.k-net.fr/ K-net] par exemple, il faudra vous tourner vers des hébergeurs en centre de données et opter pour un hébergement de votre serveur dans leurs locaux ou réaliser un tunnel afin d'utiliser leur ''IP'' chez vous (l'auto-hébergement étant la solution à privilégier dans une optique d'indépendance numérique).}}
 
=Nom de domaine=
==Prérequis DNS==
La messagerie électronique étant dépendante du système de noms de domaine (''DNS''), il vous en faudra un et y définir un enregistrement de type [https://docs.gandi.net/fr/noms_domaine/faq/type_enregistrements_dns/mx_record.html MX] afin d'assurer la distribution de votre courrier.
 
La façon de configurer les champs de votre zone ''DNS'' étant propre à votre fournisseur de noms, nous ne détaillerons pas cette partie. Sachez seulement que l'enregistrement associant votre nom d'hôte (le champ [https://docs.gandi.net/fr/noms_domaine/faq/type_enregistrements_dns/a_record.html A] pointant sur votre ''IP'' publique) et votre nom de domaine (à ne pas confondre avec le nom de domaine pleinement qualifié (''FQDN'')) devra être configuré pour espérer envoyer et recevoir des courriels.
 
Il vous faudra donc, pour démarrer, un nom de domaine avec un champ ''A'' et ''MX'' (minimum obligatoire) auquel nous ajouterons, par la suite, un enregistrement ''TXT'' ''SPF'' et ''DKIM'' (facultatifs) afin de diminuer vos chances de finir dans les indésirables de vos destinataires.
 
Enfin, et toujours dans un soucis de limiter le désagrément susmentionné, il faudra que vous adressiez une demande à votre fournisseur d'accès Internet pour ajouter votre ''FQDN'' à sa zone ''DNS'' inversée (ajout d'un champ de type ''PTR''). Ce point est le plus délicat car plus aucun "grands" ''FAI'' connus ne le permet en France (en 2021). ''Free'' ne propose plus l'option depuis 2019 (bien que toujours présente dans leur interface ''WEB'', celle-ci ne fonctionne plus depuis la migration de leur infrastructure vers ''IPv6'') et font les morts lorsqu'ils sont contactés à ce sujet ; ''SFR'' et ''Bouygues Telecom'' ne sont plus que des fournisseurs de services audiovisuels et ''Orange'' ne sais même pas ce qu'est une adresse ''IP'' fixe (même ''v6''...) alors du ''rDNS''... Internet étant réservé aux professionnels selon leur doctrine malgré leur service d'amateur...
 
Installation des outils
apt update && apt install --no-install-recommends openssl dnsutils
 
Test de fonctionnement du champ ''MX''
dig exemple.fr MX
 
La réponse doit contenir une ''ANSWER SECTION'' avec ceci :
  exemple.fr 10800 IN MX 10 mail.exemple.fr
  exemple.fr 10800 IN MX 10 mail.exemple.fr


=Installation de Postfix=
Test de fonctionnement du champ ''A''
Génération du certificat et de la clé pour Postfix et Dovecot.
dig mail.exemple.fr A
  # openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -out /etc/ssl/certs/mailcert.pem -keyout /etc/ssl/private/mail.key
 
La réponse doit contenir une ''ANSWER SECTION'' avec ceci :
mail.exemple.fr. <TTL> IN A <VOTRE_IP_PUBLIQUE>
 
==Cas du NAT==
Si votre serveur est placé juste derrière un NAT, il faudra ajouter une entrée dans votre fichier <code>/etc/hosts</code> afin de lui permettre de se résoudre lui-même. Ceci prendra la forme suivante :
<IP_du_serveur> <FQDN>
 
=Éléments secrets=
Comme tout moyen de communication moderne, les correspondances extérieurs seront chiffrées via des algorithmes négociés au travers du traditionnel protocole de sécurité de la couche transport (''TLS''). La génération d'éléments secrets se fera par le fameux logiciel libre [[openssl|OpenSSL]] que l'on ne présente plus. Nous avons pris le parti de réutiliser ces éléments secrets dans l'ensemble des outils faisant intervenir le chiffrement du système de messagerie. Dans l'idéal, un certificat différent doit être utilisée pour chaque module en nécessitant, conformément à la [https://{{SERVERNAME}}/fichiers/messagerie/courriel/serveur_courriels/anssi/anssi-guide-recommandations_de_securite_relatives_a_tls-v1.2.pdf recommandation] numéro 30 (page 46) du guide de [https://www.ssi.gouv.fr/entreprise/guide/recommandations-de-securite-relatives-a-tls/ recommandation de sécurité relative à TLS] (v1.2) des bonnes pratiques de l{{'}}''ANSSI''.
 
Création du répertoire d'accueil pour les clés et le certificat x.509
mkdir -p /etc/postfix/tls
 
Génération du certificat et de la clé pour ''Postfix'' et ''Dovecot''
  openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -out /etc/postfix/tls/courriel.pem -keyout /etc/postfix/tls/courriel.key
 
Pour cette étape, [[Letsencrypt]] peut très bien être utilisé mais sachez que contrairement au ''WEB'', le monde de la messagerie ne vérifie aucunement l'authenticité des certificats (ce qui rend de fait, le chiffrement caduc en cas d'espionnage ciblé...). Il n'est donc pas dérangeant d'utiliser des certificats auto-signés avec une durée de validité démentielle... Pour une confidentialité forte des échanges (en complément de ''TLS''), tournez-vous plutôt vers le protocole [https://fr.wikipedia.org/wiki/Pretty%20Good%20Privacy PGP] qui peut notamment, en plus d'une exploitation manuelle entre deux clients, être utilisé [https://jnphilipp.org/posts/post/auto-encrypt-all-incoming-email-with-postfix/ automatiquement] avec ''Postfix'' via le module ''gpgmail''.
 
Génération de la clé ''Diffie-Hellman'' (si l'on ne le fait pas, ''Postfix'' utilise la sienne)
openssl dhparam -out /etc/postfix/tls/dh4096.pem 4096
 
{{info|Avec l'évolution des suites cryptographiques, il devient de plus en plus rare d'utiliser ''Diffie-Hellman'' (au travers des suites ''DHE''). Avec l’avènement de la faille [https://raccoon-attack.com/ Racoon attack], ce protocole est devenu désuet et peu sûr. L'usage de la cryptographie basée sur les courbes elliptiques (''ECC'') pour l'échange de clés de sessions l'a, dans la pratique, remplacé (notamment via ''ECDHE'' et ''ed25519''). Néanmoins (et vous vous en apercevrez peut-être à vos dépends), le monde de la messagerie électronique accuse d'un lourd héritage technologique et d'installations vieillissantes administrées, ou pas, par des gens généralement peu regardants sur l'évolution des standards et dont le principe de veille informatique échappe totalement. Aussi, il n'est pas rare (coucou ''Orange'', une fois de plus...) de devoir supporter des algorithmes et protocoles complètements dépassés pour pouvoir continuer d'échanger avec certains serveurs non mis à jours depuis plusieurs décennies...}}


Installation du serveur SMTP
=Postfix=
# apt install postfix
Comme présenté en début de page, ''Postfix'' est l'élément central de notre système de messagerie électronique. Il endosse le rôle de ''MTA'' tout en faisant le lien avec les autres composants de l'installation. S'il peut sembler austère à première vue, la complexité de sa configuration est à la hauteur du service qu'il rend car il n'est pas exagéré de dire que la messagerie est la pierre la plus importante d'un auto-hébergement. Logiciel fiable et très personnalisable, c'est l'un des composants qui, une fois mis en place, se fait le plus oublié dans une infrastructure numérique domestique.
Accepter les choix proposés, choisir la configuration "Site internet" et mettre le FQDN au nom du serveur demandé.


Génération de la clé Diffie Hellman (si on ne le fait pas, Postfix utilise la sienne)
==Installation de Postfix==
  # openssl dhparam -out /etc/postfix/dh2048.pem 2048
Installation du serveur ''SMTP''
  apt install --no-install-recommends postfix
 
''Note : Les réponses aux choix proposés n'ont guère d'importance puisque elles ne font que remplir un fichier que nous remplacerons par la suite.''
 
==Configuration de Postfix==
La configuration principale de ''Postfix'' se fait par l'intermédiaire du fichier <code>main.cf</code> qui renseigne un petit sous-ensemble des paramètres contrôlant les opérations du système de messagerie. Les paramètres non explicitement renseignés sont initialisés avec leur valeur par défaut. Les paramètres appliqués explicitement par l'intermédiaire de ce fichier sont visibles après rechargement du service via la commande <code>postconf -n</code>. La commande <code>postconf -p</code> permet quand à elle de visualiser la totalité des paramètres appliqués, y compris ceux par défaut.


=Configuration de Postfix=
==Configuration principale==
La configuration principale de Postfix se fait via l'intermédiaire du fichier main.cf qui renseigne un petit sous-ensemble des paramètres contrôlant les opérations du système de messagerie. Les paramètres non explicitement renseignés sont initialisés avec leur valeur par défaut.
===Main.cf===
===Main.cf===
Édition du fichier de configuration principal
Édition du fichier de configuration principal
  # vim /etc/postfix/main.cf
  vim /etc/postfix/main.cf
 
La configuration suivante sera utilisée :
La configuration suivante sera utilisée :
# smtpd : entrant/inbound                                                                                 
# smtp : sortant/outbound
#------------------------------------Connexion protocol SMTP------------------------------------#
# Bannière affiché lorsqu'on se connecte en SMTP sur le port 25
smtpd_banner            = $myhostname ESMTP $mail_name (Debian/GNU)
# Desactive la commande SMTP VRFY. Arrête certaine technique pour avoir des adresses email
disable_vrfy_command    = yes
# Impose au client SMTP de démarrer la session SMTP par une commande Helo (ou ehlo)
smtpd_helo_required    = yes
#------------------------------------Gestion des messages locaux (innutile)------------------------------------#
# Service qui envoie des notifications "nouveau message"
biff                    = no
# Avec le courrier local ça ajoute .NDD aux adresses incomplètes (seulement le nom d'hote)
append_dot_mydomain    = no
#------------------------------------Nom de machine et réseaux autorisés------------------------------------#
# Le nom de la machine du système de messagerie
# Par défaut c'est host.domain.tld mais on peut mettre un reverse dns
myhostname              = mail.exemple.fr
# Le domaine utilisé par defaut pour poster les messages locaux
myorigin                = mail.exemple.fr
# Liste des domaines pour lequel le serveur doit accepter le courrier
mydestination          = mail.exemple.fr, exemple.fr, localhost.exemple.fr, localhost
# Pour effectuer des livraisons de courrier avec un relay (ici non)
relayhost              =
# Liste des réseaux locaux autorisés (leur permet d'outrepasser le SASL)
mynetworks              = 192.168.1.0/24, 192.168.160.0/24, 127.0.0.0/8
# Activation d'IPv6 (seul v4 est activé par défaut)
inet_protocols          = all
# Séparateur entre le nom d'utilisateur et les extensions d'adresses
recipient_delimiter    = +
# Les utilisateurs locaux ne pourront pas envoyer de messages à "utilisateur@nom-de-domaine-partiel" mais devront spécifier le nom de domaine complet
append_dot_mydomain    = no
# Interfaces réseaux à écouter (ici toutes)
inet_interfaces        = all
#------------------------------------Règles SMTP------------------------------------#
#Restrictions d'accès appliqués dans le contexte d'une commande RCPT TO
# permit_mynetworks : Autorise les requêtes si l'IP du client correspond à l'un des réseaux spécifiés dans $mynetworks
# permit_sasl_authenticated : Accepter la connexion lorsque le client est authentifié
# reject_non_fqdn_recipient : Rejette la requête lorsque l'adresse RCPT TO n'est pas de forme pleinement qualifiée (FQDN)
# reject_unauth_destination : Rejette la requête sauf si l'une des propositions listés dans la doc est vrai
# reject_unknown_recipient_domain : Rejette la requête lorsque le RCPT TO ne correspond à aucun A ou MX
smtpd_recipient_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_non_fqdn_recipient,
        reject_unauth_destination,
        reject_unknown_recipient_domain,
# Règles sur l'échange HELO qui survient avant la connexion
# permit_mynetworks : Autorise les requêtes si l'IP du client correspond à l'un des réseaux spécifiés dans $mynetworks
# reject_invalid_helo_hostname : Refuser les échanges HELO invalides
# reject_non_fqdn_helo_hostname : Refuser les noms d'hôte invalides (non FQDN)
# reject_unknown_helo_hostname : Refuser les noms d'hôte qui n'ont pas de champ DNS A ou MX dans leurs DNS
smtpd_helo_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_invalid_helo_hostname, 
        reject_non_fqdn_helo_hostname,
# Règles de connexion des clients
# permit_mynetworks : Autorise les requêtes si l'IP du client correspond à l'un des réseaux spécifiés dans $mynetworks
# permit_inet_interfaces : Accepte les resuêtes des client entrant par les interfaces listés dans $inet_interfaces
# permit_sasl_authenticated : Accepter la connexion lorsque le client est authentifié
# reject_rbl_client : Refuse les connexion des clients (IP) listés dans une liste RBL suite à des envois massifs de spam
# reject_plaintext_session : Refuser les connexions non sécurisées
# reject_unauth_pipelining : Refuser les défauts lors de la connexion (difficile de synthétiser. Ce référer à la doc)
smtpd_client_restrictions =
        permit_mynetworks,
        permit_inet_interfaces,
        permit_sasl_authenticated, 
        reject_rbl_client zen.spamhaus.org
        # reject_plaintext_session,   
        # reject_unauth_pipelining # L'utilisation de reject_unauth_pipelining dans les autres contextes que smtpd_data_restrictions n'est pas recommandé
# Règles sur les expéditeurs
# reject_non_fqdn_sender : Refuser les expéditeurs invalides (non FQDN)
# reject_unknown_sender_domain : Refuser les expéditeurs qui n'ont pas de champ DNS A ou MX dans leurs DNS
# check_sender_access : Vérifie si l'adresse email (reçue ou envoyée) est dans notre fichier liste noire et applique la directive de celle-ci
smtpd_sender_restrictions =
        reject_non_fqdn_sender,
        reject_unknown_sender_domain,   
        check_sender_access hash:/etc/postfix/adresses-rejet
#Restrictions d'accès optionelles appliqués dans le contexte d'une commande SMTP DATA
# reject_unauth_pipelining : Refuser les défauts lors de la connexion (difficile de synthétiser. Ce référer à la doc)
# permit : Tout est autorisé par défaut
smtpd_data_restrictions =
        reject_unauth_pipelining,
        permit
#------------------------------------Gestion des boites et des messages------------------------------------#
# Taille des boîtes auix lettres (0 = illimité)
mailbox_size_limit      = 0
#Fixer la taille limite des messages (ici 30Mo)
message_size_limit      = 31457280
# Répertoire de destination des courriers
home_mailbox            = Maildir/
mailbox_command        = /usr/lib/dovecot/deliver
#----------------------------------------------
# Gestion des alias de comptes et de domaines |
#----------------------------------------------
#Emplacement du fichier des alias
#Alias de comptes principal
alias_maps              = hash:/etc/aliases
alias_database          = hash:/etc/aliases
#Alias de domaines secondaires
virtual_alias_maps = hash:/etc/postfix/aliases_domaines
virtual_alias_domains = toto.fr, titi.org
#--------------------
# SASL serveur SMTP |
#--------------------
# Authentification SMTP (utilise les identifiants IMAP via SASL en passant par Dovecot)
smtpd_sasl_auth_enable  = yes
smtpd_sasl_type        = dovecot
smtpd_sasl_path        = private/auth
# Interdit les méthodes qui autorisent l'authentification anonyme
smtpd_sasl_security_options    = noanonymous
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
smtpd_sasl_local_domain        = $mydomain
# Reporte le nom d'utilisateur SASL authentifié dans l'en-tête de message Received du serveur
smtpd_sasl_authenticated_header = yes
# N'accepte pas le support de l'ancienne commande AUTH (Outlook 4 par exemple)
broken_sasl_auth_clients        = no
#------------------------------------Chiffrement------------------------------------#
# SSL/TLS clés et certificats
smtpd_tls_cert_file            = /etc/ssl/certs/mailcert.pem
smtpd_tls_key_file              = /etc/ssl/private/mail.key
smtpd_tls_dh1024_param_file    = $config_directory/dh2048.pem
#------------------
# TLS client SMTP |
#------------------
# Verbositer des logs
smtp_tls_loglevel              = 1
# Accepte de ce connecter à des serveurs SMTP en clair mais préfaire le TLS
smtp_tls_security_level        = may
# Interdire le SSLv2 et v3
smtp_tls_protocols              = !SSLv2, !SSLv3
#Interdire le SSLv2 et v3 obligatoirement (ça n'a aucun sens mais que voulez-vous ? Documentation de Postfix quand tu nous tiens...)
smtp_tls_mandatory_protocols    = !SSLv2, !SSLv3
#Postfix retient apparemment qui propose du STARTTLS (je vois pas à quoi ça peut bien servir...)
smtp_tls_note_starttls_offer    = yes
#N'autoriser que les chiffrements costauds
smtp_tls_mandatory_ciphers      = high
#Exclure les algorithmes obsolètes ou insufisants listés ci-dessous
smtp_tls_exclude_ciphers        = aNULL, eNULL, EXPORT, DES, 3DES, RC2, RC4, MD5, PSK, SRP, DSS, AECDH, ADH
#Pas d'explications claires sur la fonction de ce paramètre
tls_preempt_cipherlist          = yes
#Cache TLS. Permet de mémoriser les anciennes sessions TLS afin d'effectuer une poignée de mains raccourcie. Ce qui améliore concidérablement les performances
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
#-------------------
# TLS serveur SMTP |
#-------------------
#Verbositer des logs
smtpd_tls_loglevel              = 1
#Accepte les connexions des clents SMTP en claire mais préfaire le TLS
smtpd_tls_security_level        = may
#Refuse les authentifications SASL en clair si le serveur gère le TLS
smtpd_tls_auth_only            = yes
#Indique le chiffrement utilisé dans l'en-tête du message (ça ne sert pas à grand chose si on passe par plusieurs serveurs car les intermédiaires peuvent y mettre leurs sauce donc ce n'est qu'indicatif)
smtpd_tls_received_header      = yes
# Source du générateur de nombre aléatoire pour les algorithmes de chiffrement
tls_random_source              = dev:/dev/urandom
# Versions de TLS autorisés (SSL refusé)
smtpd_tls_protocols            = TLSv1.2, TLSv1.1, TLSv1, !SSLv3, !SSLv2
# Toujours aucune idée de l'utilité mais c'est activé par défaut de toute façon d'après la documentation
smtpd_tls_mandatory_protocols  = !SSLv2, !SSLv3
#Cache TLS. Permet de mémoriser les ancienne sessions TLS afin d'effectuer une poignée de mains raccourcie. Ce qui améliore concidérablement les performances
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
#------------------------------------Entêtes des courriers------------------------------------#
# Emplacement des fichiers de suppression de certaines en-têtes à caractère privé contenues dans les messages envoyés
# Concrètement, cela supprime toute la section "Received: from" propre au client (contenant son IP par exemple) -> son SMTP. Seul le "Received: from" son SMTP -> SMTP distant reste
mime_header_checks              = regexp:/etc/postfix/header_checks
header_checks                  = regexp:/etc/postfix/header_checks
#------------------------------------Source documentation------------------------------------#
# http://postfix.traduc.org/index.php/postconf.5.html
# http://www.postfix.org/postconf.5.html


===Liste noire===
<syntaxhighlight lang="bash">
Création de la liste noire d'adresse (envoi et réception)
# smtpd : entrant/inbound                                                                                 
# vim /etc/postfix/adresses-rejet
# smtp : sortant/outbound
Avec ce contenu :
 
email@bloquer 554 Parle à ma main, ma tête est malade.
# ------------------------------------ Connexion protocole SMTP ------------------------------------ #
Le message provenant de cette adresse sera rejeté avec un message SMTP (qui apparaîtra dans les log du serveur distant) précisé après le code 554. Si aucun message n'est spécifié, REJECT utilise les paramètres par défauts, à savoir "rejected: Access denied" comme raison du rejet.
 
# Bannière affichée après le code 220 lorsque l'on se connecte en SMTP sur le serveur
smtpd_banner            = $myhostname ESMTP $mail_name
# Désactive la commande SMTP VRFY. Ceci a pour effet d'empêcher de trouver les adresses existante sur le serveur
disable_vrfy_command    = yes
# Impose au client SMTP de démarrer la session SMTP par une commande Helo ou ehlo (cette dernière servant au listage des capacités du serveur)
smtpd_helo_required    = yes
 
# ------------------------------------ Gestion des messages locaux (inutile dans notre cas) ------------------------------------ #
 
# Service qui envoie des notifications "nouveau message"
biff                    = no
# Avec le courrier local ça ajoute .NDD aux adresses incomplètes (seulement le nom d'hôte)
append_dot_mydomain    = no
 
# ------------------------------------ Nom de machine et réseaux autorisés ------------------------------------ #
 
# Le nom de la machine du système de messagerie
# Par défaut c'est hôte.domaine.tld mais il est possible de mettre un nom de domaine inversé
myhostname              = mail.exemple.fr
# Le domaine utilisé par défaut pour poster les messages
myorigin                = mail.exemple.fr
# Liste des domaines pour lesquels le serveur doit accepter le courrier en local
mydestination          = mail.exemple.fr, localhost.exemple.fr, localhost
# Relais par lequel notre serveur doit adresser son trafic (nous n'en utilisons aucun)
relayhost              =
# Liste des réseaux locaux autorisés (leur permet d'outrepasser le SASL)
mynetworks              = 192.168.0.0/16, 127.0.0.0/8
# Activation d'IPv4 et IPv6 (valeur par défaut)
inet_protocols          = all
# Séparateur entre le nom d'utilisateur et les extensions d'adresses
recipient_delimiter    = +
# Les utilisateurs locaux ne pourront pas envoyer de messages à "utilisateur@nom-de-domaine-partiel" mais devront spécifier le nom de domaine complet
append_dot_mydomain    = no
# Interfaces réseaux à écouter (ici toutes)
inet_interfaces        = all
 
# ------------------------------------ Règles SMTP ------------------------------------ #
 
# Restrictions d'accès appliquées dans le contexte d'une commande RCPT TO
# permit_mynetworks : Autorise les requêtes si l'IP du client correspond à l'un des réseaux spécifiés dans $mynetworks
# permit_sasl_authenticated : Accepter la connexion lorsque le client est authentifié
# reject_non_fqdn_recipient : Rejette la requête lorsque l'adresse RCPT TO n'est pas de forme pleinement qualifiée (FQDN)
# reject_unauth_destination : Rejette la requête sauf si l'une des propositions listés dans la documentation officielle est vraie
# check_recipient_access : Rejette les messages à destination des adresses spécifiées dans le fichier correspondant (permet de ne pas envoyer de message à root)
# reject_unknown_recipient_domain : Rejette la requête lorsque le RCPT TO ne correspond à aucun champ DNS A ou MX
smtpd_recipient_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_non_fqdn_recipient,
        reject_unauth_destination,
        check_recipient_access sqlite:/etc/postfix/sqlite-liste-noire-destinataires.cf,
        reject_unknown_recipient_domain,
 
# Règles sur l'échange HELO qui survient avant la connexion
# permit_mynetworks : Autorise les requêtes si l'IP du client correspond à l'un des réseaux spécifiés dans $mynetworks
# reject_invalid_helo_hostname : Refuser les échanges HELO invalides
# reject_non_fqdn_helo_hostname : Refuser les noms d'hôte invalides (non FQDN)
# reject_unknown_helo_hostname : Refuser les noms d'hôte qui n'ont pas de champ DNS A ou MX dans leurs DNS
smtpd_helo_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_invalid_helo_hostname,
        reject_non_fqdn_helo_hostname,
        # reject_unknown_helo_hostname
 
# Règles de connexion des clients
# permit_mynetworks : Autorise les requêtes si l'IP du client correspond à l'un des réseaux spécifiés dans $mynetworks
# permit_inet_interfaces : Accepte les requêtes des clients entrants par les interfaces listés dans $inet_interfaces
# permit_sasl_authenticated : Accepter la connexion lorsque le client est authentifié
# reject_rbl_client : Refuse les connexion des clients (IP) listés dans une liste RBL suite à des envois massifs de pourriels
# reject_plaintext_session : Refuser les connexions non chiffrés
# reject_unauth_pipelining : Vérifie si le drapeau de l'indicateur de session a été activé par Postfix. Si tel est le cas, cela signifierai que le client a utilisé une canalisation ESMTP incorrecte, ce qui est une justification suffisante pour le rejeter.
smtpd_client_restrictions =
        permit_mynetworks,
        permit_inet_interfaces,
        permit_sasl_authenticated,
        # reject_rbl_client zen.spamhaus.org
        # reject_plaintext_session,
        # reject_unauth_pipelining # L'utilisation de reject_unauth_pipelining dans les autres contextes que smtpd_data_restrictions n'est pas recommandé
 
# Règles sur les expéditeurs
# reject_non_fqdn_sender : Refuser les expéditeurs invalides (non FQDN)
# reject_unknown_sender_domain : Refuser les expéditeurs qui n'ont pas de champ DNS A ou MX dans leurs DNS
# check_sender_access : Vérifie si l'adresse de courriel de l'expéditeur est dans notre fichier liste noire et applique la directive de celle-ci
smtpd_sender_restrictions =
        reject_non_fqdn_sender,
        reject_unknown_sender_domain,
        check_sender_access sqlite:/etc/postfix/sqlite-liste-noire-expediteurs.cf
 
# Restrictions d'accès optionnelles appliquées dans le contexte d'une commande SMTP DATA
# reject_unauth_pipelining : Expliqué plus haut (trop long)
# permit : Tout est autorisé par défaut
smtpd_data_restrictions =
        reject_unauth_pipelining,
        permit
 
# ------------------------------------ Gestion des boites aux lettres et des messages ------------------------------------ #
 
# Taille des boîtes aux lettres (0 = illimité)
mailbox_size_limit      = 0
 
# Fixer la taille limite des messages (ici 30Mo)
message_size_limit      = 31457280
 
# Répertoire de destination des courriers
# home_mailbox            = Maildir/
virtual_mailbox_domains = sqlite:/etc/postfix/sqlite-domaines.cf
virtual_mailbox_base    = /var/mail/utilisateurs
virtual_mailbox_maps    = sqlite:/etc/postfix/sqlite-utilisateurs.cf
virtual_minimum_uid    = 3000
virtual_uid_maps        = static:3000
virtual_gid_maps        = static:3000
virtual_transport      = lmtp:unix:private/dovecot-lmtp
 
#----------------------------------------------
# Gestion des alias de comptes et de domaines |
#----------------------------------------------
 
# Emplacement du fichier des alias
# Alias de comptes principaux
alias_maps              = sqlite:/etc/postfix/sqlite-alias.cf
 
# Alias de domaines
virtual_alias_maps      = sqlite:/etc/postfix/sqlite-alias-vituels.cf
# virtual_alias_domains = sqlite:/etc/postfix/sqlite-domaines.cf
 
#--------------------
# SASL serveur SMTP |
#--------------------
 
# Authentification SMTP (utilise les identifiants IMAP via SASL en passant par Dovecot)
smtpd_sasl_auth_enable  = yes
smtpd_sasl_type        = dovecot
smtpd_sasl_path        = private/auth
# Interdit les méthodes qui autorisent l'authentification anonyme
smtpd_sasl_security_options    = noanonymous
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
smtpd_sasl_local_domain        = $mydomain
# Reporte le nom d'utilisateur SASL authentifié dans l'en-tête de message "Received" du serveur
smtpd_sasl_authenticated_header = yes
# N'accepte pas le support de l'ancienne commande AUTH (Outlook 4 par exemple)
broken_sasl_auth_clients        = no
 
# ------------------------------------ Chiffrement ------------------------------------ #
 
# clés et certificats pour les sessions TLS
smtpd_tls_cert_file            = $config_directory/tls/courriel.pem
smtpd_tls_key_file              = $config_directory/tls/courriel.key
smtpd_tls_dh1024_param_file    = $config_directory/tls/dh4096.pem
 
#------------------
# TLS client SMTP |
#------------------
 
# Verbosité des journaux
smtp_tls_loglevel              = 1
# Impose de se connecter à des serveurs SMTP via TLS
smtp_tls_security_level        = encrypt
# N'autoriser que le TLS version 1.2 et 1.3
smtp_tls_protocols              = TLSv1.2:TLSv1.3
# incompréhension exprimé plus haut
smtp_tls_mandatory_protocols    = TLSv1.2:TLSv1.3
# Journaliser les pairs ne gérants que STARTTLS au lieu de TLS. Probablement pour permettre de réaliser des statistiques
smtp_tls_note_starttls_offer    = yes
# N'autoriser que les chiffrements de la liste "medium" définie plus bas
smtp_tls_mandatory_ciphers      = medium
# Exclure les algorithmes cryptographiques obsolètes ou insuffisants listés ci-dessous
smtp_tls_exclude_ciphers        = aNULL, eNULL, EXPORT, DES, 3DES, RC2, RC4, MD5, PSK, SRP, DSS, AECDH, ADH
# Permet d'obliger le client à se conformer à la suite cryptographique du serveur et non l'inverse
tls_preempt_cipherlist          = yes
# Cache TLS. Permet de mémoriser les anciennes sessions TLS afin d'effectuer une poignée de mains raccourcie. Ce qui améliore considérablement les performances
# Inutile avec TLS 1.3 car compris dans la norme
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
 
#-------------------
# TLS serveur SMTP |
#-------------------
 
# Verbosité des journaux
smtpd_tls_loglevel              = 1
# Impose de se connecter à des serveurs SMTP via TLS
smtpd_tls_security_level        = encrypt
# Refuse les authentifications SASL en clair si le serveur gère TLS de façon optionnelle (ça n'a aucun sens mais c'est ce qui est écrit dans la documentation officielle)
smtpd_tls_auth_only            = yes
# Indique le chiffrement utilisé dans l'en-tête du message (ça ne sert pas à grand chose si on passe par plusieurs serveurs car les intermédiaires peuvent y mettre leur sauce donc ce n'est qu'indicatif)
smtpd_tls_received_header      = yes
# Source du générateur de nombre aléatoire pour les algorithmes de chiffrement
tls_random_source              = dev:/dev/urandom
# Versions de TLS autorisés (SSL refusé)
smtpd_tls_protocols            = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1, TLSv1.2, TLSv1.3
# Toujours aucune idée de l'utilité mais c'est activé par défaut de toute façon d'après la documentation
smtpd_tls_mandatory_protocols  = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1, TLSv1.2, TLSv1.3
# N'autoriser que les chiffrements de la liste "medium" définie plus bas
smtpd_tls_mandatory_ciphers = medium
# Liste de chiffrements autorisés dans la liste "medium" exploité par "smtp_tls_mandatory_ciphers" et "smtpd_tls_mandatory_ciphers"
tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
# Exclure les algorithmes obsolètes ou insufisants listés ci-dessous
smtpd_tls_exclude_ciphers        = aNULL, eNULL, EXPORT, DES, 3DES, RC2, RC4, MD5, PSK, SRP, DSS, AECDH, ADH
# Cache TLS. Permet de mémoriser les ancienne sessions TLS afin d'effectuer une poignée de mains raccourcie. Ce qui améliore considérablement les performances
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
 
# ------------------------------------ En-têtes des courriels ------------------------------------ #
 
# Emplacement des fichiers de suppression de certains en-têtes à caractère privé contenus dans les messages envoyés
# Concrètement, cela supprime toute la section "Received: from" propre au client (contenant son IP par exemple) -> son SMTP. Seul le "Received: from" son SMTP -> SMTP distant reste
mime_header_checks              = regexp:/etc/postfix/header_checks
header_checks                  = regexp:/etc/postfix/header_checks
 
# ------------------------------------ OpenDKIM et Spamassassin ------------------------------------ #
 
# Procédez comme si le filtre de courrier n'était pas présent
milter_default_action = accept
# Version du protocole mail filter
milter_protocol = 6
 
# Chemins des sockets pour la communication avec les modules opendkim et spamass
smtpd_milters = unix:/var/run/opendkim/opendkim.sock unix:/spamass/spamass.sock
non_smtpd_milters = unix:/var/run/opendkim/opendkim.sock unix:/spamass/spamass.sock
 
# ------------------------------------ Sources de documentation ------------------------------------ #
 
# http://postfix.traduc.org/index.php/postconf.5.html
# http://www.postfix.org/postconf.5.html
</syntaxhighlight>
 
N'oubliez pas d'adapter les réseaux autorisés de la section <code>mynetworks</code> ainsi que le nom de domaine à votre installation. Vous pouvez utiliser la commande <code>sed</code> comme suit pour vous aider :
sed -i 's/exemple\.fr/domaine\.fr/g' /etc/postfix/main.cf


Postfix utilisant des binaires pour les configurations externes, il faut compiler la liste noire (la directive "check_sender_access hash" du main.cf de façon transparente un ".db" au chemin spécifié) avec la commande suivante :
Si vous voulez afficher pour comparaison la [https://www.mkssoftware.com/docs/man1/openssl_ciphers.1.asp suite cryptographique] ''MEDIUM'' d{{'}}''OpenSSL'' avec le paramètre <code>tls_medium_cipherlist</code> définit dans le fichier, vous pouvez utiliser la commande suivante :
  # postmap /etc/postfix/adresses-rejet
  openssl ciphers MEDIUM | sed 's/:/\n/g'
Cette commande est à exécuter à chaque modifications de la liste (le redémarrage de Postfix n'est pas nécessaire).


===Entêtes_vie_privée===
===En-têtes vie privée===
On va créer une liste de critaires regex servant à supprimer automatiquement certaines entêtes contenant des informations personnelles sur le client éméteur lors de l'envoi du courrier (améliore la vie privée).
On va créer une liste d'expressions régulières servant à supprimer automatiquement certains en-têtes contenant des informations personnelles sur le client émetteur lors de l'envoi du courriel (diminue la quantité d'informations personnelles transmises)
# vim /etc/postfix/header_checks
Ce fichier doit contenir ceci :
/^Received:.*with ESMTPSA/  IGNORE
/^X-Originating-IP:/        IGNORE
/^X-Mailer:/                IGNORE
/^User-Agent:/              IGNORE
Explications : Les directives suivantes contenues dans la section "Entêtes des courriers" du fichier main.cf édité ci-dessus indiquent à Postfix l'emplacement de ces règles.
mime_header_checks              = regexp:/etc/postfix/header_checks
header_checks                  = regexp:/etc/postfix/header_checks
Pour que Postfix les utilises, il faut reconstruire la hash table.
# postmap /etc/postfix/header_checks
Et rafraichire sa configuration.
# postfix reload


==Création d'utilisateurs et d'alias==
<syntaxhighlight lang="bash">
Comme nous utilisons des utilisateurs PAM UNIX pour notre Postfix, il suffit de créer un utilisateur système pour pouvoir s'en servir à envoyer des email
cat << '_EOF_' > /etc/postfix/header_checks
# adduser test
/^Received:.*with ESMTPSA/ IGNORE
Création d'un alias.
/^X-Originating-IP:/        IGNORE
Cette fonctionnalité peut être utile pour s'inscrire sur des sites ou pour donner à des mec relous, les emails envoyés sur ces adresses sont redirigés en interne sur la vrai boite lié à l'alias sauf que l'on voit l'adresse qui a servis pour nous joindre. L'intérêt est double : si on reçois des email louches (SPAM) sur cet alias, on sait quel est le malotru qui a vendu notre adresse et on peut décider d'aller faire nos course ailleurs si c'est une entreprise de e-commerce par exemple. Ensuite on peut tout bonnement supprimer l'alias pour que les personne ayant cette adresse ne puisse plus nous joindre.
/^X-Mailer:/                IGNORE
Si cette fonctionnalité est utilisé sérieusement, le risque de SPAM est quasi nul. Couplé aux règles Sieve abordées plus loin dans le tuto, les alias vont être très utile afin de classer les email reçus automatiquement dans des dossiers et ne pas ce retrouver avec les éternelles boite de reception à plus de 2000 messages "non lus".
/^User-Agent:/             IGNORE
# vim /etc/aliases
_EOF_
La création d'un alias se résume à mettre le nom de l'alias suivit du séparateur ":" ainsi que du nom de l'utilisateur Linux y étant attaché
</syntaxhighlight>
  amazon:test
ldlc:test
keke:kevin
#commentaire:croisillon
Pour mettre à jour la base interne des alias il faut executer la commande suivante :
# newaliases
Un rechargement de la configuration de Postfix n'est pas nécessaire.
==Gestion des domaines secondaires==
Postfix nous laisse la possibilité de gérer plusieurs domaines (un peu comme les Virtual Hosts Apache).
# vim /etc/postfix/aliases_domaines
Si vous voulez gérer plusieurs domaines avec votre serveur, vous entrerez leurs nom dans la section "virtual_alias_domains" du fichier main.cf et entrerez les alias comme suit (adresse complète de l'utilisateur suivit d'un espace et du nom de l'utilisateur Linux y étant rattaché) :
kevin@toto.fr kevin
vanessa@titi.org vanessa
Compiler le fichier d'alias après chaque modifications
# postmap /etc/postfix/aliases_domaines


==Configuration secondaire==
Les directives contenues dans la section "En-têtes des courriels" du fichier [[#Main.cf|main.cf]] édité ci-dessus indiquent à ''Postfix'' l'emplacement de ces règles
La configuration secondaire se fait via le fichier master.cf et permet de gérer la façon dont se connecte les clients au service de messagerie et comment ce dernier réagit lorsqu'une requête lui est destinée.
 
<syntaxhighlight lang="bash">
mime_header_checks              = regexp:/etc/postfix/header_checks
header_checks                  = regexp:/etc/postfix/header_checks
</syntaxhighlight>
 
Pour que Postfix les utilises, il faut reconstruire la table au format hachée avec la commande
postmap /etc/postfix/header_checks


===Master.cf===
===Master.cf===
Il faut dé-commenter certains choses et en commenter d'autre sur 2 paragraphes du début du fichier.
''Postfix'' est un outil dont le fonctionnement sous jacent est complexe et composé de multiples programmes (démons) ayants chacun leur rôle. Le fichier <code>master.cf</code> permet de gérer la façon dont se comportent les différents éléments du système de courrier.
# vim /etc/postfix/master.cf
 
Attention à la première ligne qui commence par SMTP ! Si elle est oublié ça génère des problèmes de ouf in-débogable car Postfix n'écrit de fait rien dans les log... Il ne faut donc pas l'oublier...
Le [http://www.postfix.org/master.5.html fichier] se présente sous forme de tableau. ''Postfix'' va le parcourir et interpréter chaque lignes, correspondants à un démon, colonne par colonne (avec leur signification en en-tête commenté). Voici le contenu du fichier par défaut, épuré de ses commentaires pour ne pas alourdir l'exposé :
smtp      inet  n      -      -      -      -      smtpd
 
  submission inet n      -      -      -      -      smtpd
<syntaxhighlight lang="bash">
   -o syslog_name=postfix/submission
smtp      inet  n      -       y       -      -       smtpd
   -o smtpd_tls_security_level=encrypt
pickup    unix  n       -      y      60      1      pickup
  -o smtpd_sasl_auth_enable=yes
cleanup  unix  n      -      y      -      0      cleanup
  # -o smtpd_reject_unlisted_recipient=no
qmgr      unix n      -      n      300    1      qmgr
  -o smtpd_client_restrictions=$mua_client_restrictions
tlsmgr    unix  -      -      y      1000?  1      tlsmgr
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject
rewrite  unix  -      -      y      -      -      trivial-rewrite
  -o smtpd_helo_restrictions=$mua_helo_restrictions
bounce    unix  -      -      y      -      0      bounce
-o smtpd_sender_restrictions=$mua_sender_restrictions
defer    unix  -      -      y      -      0      bounce
  -o smtpd_recipient_restrictions=
trace    unix  -      -      y      -      0      bounce
# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
verify   unix  -      -      y      -      1      verify
  -o milter_macro_daemon_name=ORIGINATING
flush    unix  n      -      y      1000?  0      flush
smtps    inet  n      -      -       -      -      smtpd
proxymap  unix  -      -      n      -      -      proxymap
  -o syslog_name=postfix/smtps
proxywrite unix -      -      n      -      1      proxymap
  -o smtpd_tls_wrappermode=yes
smtp      unix  -      -      y      -      -      smtp
  -o smtpd_sasl_auth_enable=yes
relay    unix  -      -      y      -      -      smtp
#  -o smtpd_reject_unlisted_recipient=no
        -o syslog_name=postfix/$service_name
  #  -o smtpd_client_restrictions=$mua_client_restrictions
showq    unix  n      -      y      -      -      showq
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
error    unix  -      -      y      -      -      error
# -o smtpd_helo_restrictions=$mua_helo_restrictions
retry    unix  -      -      y      -      -      error
# -o smtpd_sender_restrictions=$mua_sender_restrictions
discard  unix  -      -      y      -      -      discard
# -o smtpd_recipient_restrictions=
local    unix  -      n      n      -      -      local
#  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
virtual  unix  -      n      n      -      -      virtual
  -o milter_macro_daemon_name=ORIGINATING
lmtp      unix  -      -      y      -      -      lmtp
anvil    unix  -      -      y      -      1      anvil
scache   unix  -      -       y      -      1      scache
postlog  unix-dgram n  -      n      -       1      postlogd
maildrop unix -       n      n      -      -      pipe
  flags=DRXhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
uucp      unix -       n      n      -      -      pipe
  flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
ifmail   unix  -       n      n      -      -      pipe
  flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp    unix -       n      n      -      -      pipe
  flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix -      n      n      -       2      pipe
  flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman  unix -       n      n      -      -      pipe
  flags=FRX user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py ${nexthop} ${user}
</syntaxhighlight>
 
L'opération consiste à ajouter un socket ''TCP'' pour les communications ''STARTTLS'' et ''SMTPS'' ainsi qu'un socket ''UNIX'' pour la communication avec [[#Dovecot|Dovecot]]. Le chemin de l'exécutable de ce dernier sera lui aussi précisé en sous-section. Nous ajouterons donc en fin de fichier les trois sections suivantes :
 
<syntaxhighlight lang="bash">
cat << '_EOF_' >> /etc/postfix/master.cf
 
submission inet n      -      y      -      -       smtpd
smtps    inet  n      -      y       -      -      smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
_EOF_
</syntaxhighlight>
 
Il est possible de spécifier des paramètres au différentes lignes via l'argument <code>-o</code> (répétable plusieurs fois). Placés ici, ils réécrivent les paramètres correspondants du fichier [[#Main.cf|main.cf]] et leur sont donc prioritaires. Ces arguments pourraient toutefois être placés dans ce dernier (cela reviendrait au même).
 
==SQLite==
Comme vous l'avez probablement constaté, certaines fonctionnalités utiliserons une base de données [https://fr.wikipedia.org/wiki/SQLite SQLite] (il est également possible de passer par d'autres [http://www.postfix.org/DATABASE_README.html méthode]). Cette technologie a le mérite d'être légère et de permettre la connexion d'outils tiers pour l'édition des données contenues dans la base. Avec la méthode des tables hachées utilisée auparavant, un accès ''root'' combiné à des bidouilles pas très sécurisées étaient nécessaires afin de les éditer sans devoir se connecter manuellement au serveur.
 
Cette section traite de la création de la base ainsi que des fichiers d'exploitation pour ''Postfix''.
 
===Installation et création de la base===
 
Installation de ''SQLite''
  apt install --no-install-recommends sqlite3 postfix-sqlite
 
Création du schéma de la base
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/postfix/postfix.sql
CREATE TABLE IF NOT EXISTS postfix_alias (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      alias TEXT NOT NULL UNIQUE,
      destination TEXT NOT NULL,
      active INTEGER
);
CREATE TABLE IF NOT EXISTS postfix_alias_virtuels (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      courriel TEXT NOT NULL UNIQUE,
      destination TEXT NOT NULL,
      active INTEGER
);
CREATE TABLE IF NOT EXISTS postfix_domaines (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      domaine TEXT NOT NULL UNIQUE,
      defaut BOOLEAN NOT NULL CHECK (defaut IN (0, 1)),
      active INTEGER
);
CREATE TABLE IF NOT EXISTS postfix_liste_noire_destinataires (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      courriel TEXT NOT NULL UNIQUE,
      action TEXT NOT NULL,
      active INTEGER
);
CREATE TABLE IF NOT EXISTS postfix_liste_noire_expediteurs (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      courriel TEXT NOT NULL UNIQUE,
      code_retour INTEGER NOT NULL,
      message TEXT NOT NULL,
      active INTEGER
);
CREATE TABLE postfix_utilisateurs (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      utilisateur TEXT NOT NULL UNIQUE,
      mot_de_passe TEXT NOT NULL,
      nom_complet TEXT,
      rep_perso TEXT NOT NULL,
      uid INTEGER NOT NULL,
      gid INTEGER NOT NULL,
      privilege TEXT NOT NULL,
      prefixe TEXT,
      active INTEGER
);
_EOF_
</syntaxhighlight>
 
Création de la base avec ce schéma
mkdir /etc/postfix/bdd/
  # Pour un usage avec le portail WEB Courtail (voir plus bas), il faudra donner les permission de ce répertoire et de la base à www-data
  sqlite3 /etc/postfix/bdd/postfix.sqlite < /etc/postfix/postfix.sql
 
===Création des fichiers d'exploitation de Postfix===
Ces [http://www.postfix.org/SQLITE_README.html fichiers] permettent à ''Postfix'' d'avoir les éléments lui permettant d'exploiter la base. Nous y retrouverons donc naturellement l'emplacement de celle-ci ainsi que la [http://www.postfix.org/sqlite_table.5.html requête] à lui soumettre afin d'obtenir l'information voulue.
 
Liaison à la table des alias
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/postfix/sqlite-alias.cf
# Chemin de la base SQLite
dbpath = /etc/postfix/bdd/postfix.sqlite
# Requête passée à SQLite
query = SELECT destination FROM postfix_alias WHERE alias='%s' AND active='1'
_EOF_
</syntaxhighlight>
 
Liason à la tables alias virtuels
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/postfix/sqlite-alias-vituels.cf
# Chemin de la base SQLite
dbpath = /etc/postfix/bdd/postfix.sqlite
# Requête passée à SQLite
query = SELECT destination FROM postfix_alias_virtuels WHERE courriel='%s' AND active='1'
_EOF_
</syntaxhighlight>
 
Les alias peuvent êtres utiles lors d'inscriptions sur des sites tiers ou d'une communication à des personnes de moyenne confiance. Le principe étant que les courriels envoyés sur ces adresses (connues uniquement des entités pour lesquelles elles ont étés créées) sont redirigés en interne vers votre vraie boite liée à l'alias. L'adresse de l'émetteur peut donc, par la stratégie que vous mettrez en place dans la diffusion de vos alias, être liée à une adresse de votre base et donc identifier une source d'émission. L'intérêt est double : lors de la réception de pourriels sur celui-ci, nous savons quelle entité l'a transmis ou utilisé puisqu'il est unique à chaque interlocuteur. Une action de désactivation de l'alias suivie d'un boycott et d'une possible plainte à la [https://www.cnil.fr/fr/plaintes CNIL] pour manquement au ''RGPD'' peut ainsi être entreprise.
 
Si cette fonctionnalité est utilisé sérieusement, le risque de pourriels (''SPAM'') est quasiment nul. Couplé aux règles ''Sieve'' abordées plus loin dans la documentation, les alias vont être très utiles afin de classer les courriels reçus automatiquement dans des dossiers et ne pas se retrouver avec les éternelles boite de réception à plus de 2000 messages "non lus". En clair, vous ne subirez plus votre messagerie comme c'est, hélas, bien trop souvent le cas.
 
{{info|La différence entre les alias et les alias virtuelles réside dans l'en-tête ''Delivered-To'' du message à la réception par ''Postfix''. Avec les alias, l'en-tête est inchangé lors de la distribution du message à la boite locale (et correspond donc à l'en-tête ''to'' du même message). Avec les alias virtuels, l'en-tête est modifié par l'adresse réelle de destination (inconnue de l'expéditeur). Dans les deux cas, cela n'influence pas l'acheminement du courrier mais les alias virtuelles permettent la distribution sur des domaines secondaires quand les alias se restreignent au seul domaine par défaut. Vous pouvez utiliser l'un et l'autre ou seulement l'un des deux (cela ne change rien aux bénéfices apportés à la fonctionnalité).}}
 
Le champ ''destination'' '''doit être''' l'adresse réelle de l'utilisateur.
 
Liaison à la table des domaines
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/postfix/sqlite-domaines.cf
# Chemin de la base SQLite
dbpath = /etc/postfix/bdd/postfix.sqlite
# Requête passée à SQLite
query = SELECT domaine FROM postfix_domaines WHERE domaine='%s' AND active='1'
_EOF_
</syntaxhighlight>
 
Liaison à la table de la liste noire des destinataires
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/postfix/sqlite-liste-noire-destinataires.cf
# Chemin de la base SQLite
dbpath = /etc/postfix/bdd/postfix.sqlite
# Requête passée à SQLite
query = SELECT action FROM postfix_liste_noire_destinataires WHERE courriel='%s' AND active='1'
_EOF_
</syntaxhighlight>
 
Liaison à la table de la liste noire des expéditeurs
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/postfix/sqlite-liste-noire-expediteurs.cf
# Chemin de la base SQLite
dbpath = /etc/postfix/bdd/postfix.sqlite
# Requête passée a SQLite
query = SELECT code_retour || ' ' || message FROM postfix_liste_noire_expediteurs WHERE courriel='%s' AND active='1'
_EOF_
</syntaxhighlight>
 
Liaison à la table des utilisateurs
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/postfix/sqlite-utilisateurs.cf
# Chemin de la base SQLite
dbpath = /etc/postfix/bdd/postfix.sqlite
# Requête passée à SQLite
query = SELECT rep_perso FROM postfix_utilisateurs WHERE utilisateur='%s' AND active='1'
_EOF_
</syntaxhighlight>
 
===Administration de la base===
Afin d'ajouter, modifier, supprimer et lister des informations dans la base ''SQLite'', le ''shell'' intégré à l'outil est une bonne première approche. Par la suite, un logiciel plus graphique (comme une application ''WEB'' par exemple), pourra remplir le rôle d'interface d'administration.
 
Le ''shell'' de <code>sqlite3</code> se contrôle via la commande suivante :
  sqlite3 /etc/postfix/bdd/postfix.sqlite
 
Les commandes suivantes permettent une utilisation basique de l'outil :
 
{| class="wikitable"
|-
! Commande !! Signification
|-
| <code>.table</code> || Liste les tables de la base
|-
| <code>.shema <span><</span>table<span>></span></code> || Affiche la structure de la table (en-têtes et propriétés)
|-
| <code>.mode column</code> || Affiche le retour d'une requête sous forme de tableau
|-
| <code>.headers on</code> || Affiche les entêtes (clés) des valeurs retournés
|-
| <code>.quit</code> || Quitte l'outil
|}
 
Gestion des alias :
 
{| class="wikitable"
|-
! Action !! Commande
|-
| Ajout || <syntaxhighlight lang="sql" inline>INSERT INTO postfix_alias (alias,destination,active) VALUES ("toto","test",1);</syntaxhighlight>
|-
| Désactivation || <syntaxhighlight lang="sql" inline>UPDATE postfix_alias SET active = 0 WHERE alias = "toto";</syntaxhighlight>
|-
| Activation || <syntaxhighlight lang="sql" inline>UPDATE postfix_alias SET active = 1 WHERE alias = "toto";</syntaxhighlight>
|-
| Suppression || <syntaxhighlight lang="sql" inline>DELETE FROM postfix_alias WHERE alias = "toto";</syntaxhighlight>
|-
| Listage || <syntaxhighlight lang="sql" inline>SELECT * FROM postfix_alias;</syntaxhighlight>
|}
 
Gestion des alias virtuels :
 
{| class="wikitable"
|-
! Action !! Commande
|-
| Ajout || <syntaxhighlight lang="sql" inline>INSERT INTO postfix_alias_virtuels (courriel,destination,active) VALUES ("ycharbi@exemple.fr","test@exemple.fr",1);</syntaxhighlight>
|-
| Désactivation || <syntaxhighlight lang="sql" inline>UPDATE postfix_alias_virtuels SET active = 0 WHERE courriel = "ycharbi@exemple.fr";</syntaxhighlight>
|-
| Activation || <syntaxhighlight lang="sql" inline>UPDATE postfix_alias_virtuels SET active = 1 WHERE courriel = "ycharbi@exemple.fr";</syntaxhighlight>
|-
| Suppression || <syntaxhighlight lang="sql" inline>DELETE FROM postfix_alias_virtuels WHERE courriel = "ycharbi@exemple.fr";</syntaxhighlight>
|-
| Listage || <syntaxhighlight lang="sql" inline>SELECT * FROM postfix_alias_virtuels;</syntaxhighlight>
|}
 
Gestion des domaines :
 
{| class="wikitable"
|-
! Action !! Commande
|-
| Ajout || <syntaxhighlight lang="sql" inline>INSERT INTO postfix_domaines (domaine,defaut,active) VALUES ("toto.fr",1,1);</syntaxhighlight>
|-
| Désactivation || <syntaxhighlight lang="sql" inline>UPDATE postfix_domaines SET active = 0 WHERE domaine = "toto.fr";</syntaxhighlight>
|-
| Activation || <syntaxhighlight lang="sql" inline>UPDATE postfix_domaines SET active = 1 WHERE domaine = "toto.fr";</syntaxhighlight>
|-
| Suppression || <syntaxhighlight lang="sql" inline>DELETE FROM postfix_domaines WHERE domaine = "toto.fr";</syntaxhighlight>
|-
| Listage || <syntaxhighlight lang="sql" inline>SELECT * FROM postfix_domaines;</syntaxhighlight>
|}
 
{{attention|N'oubliez pas d'ajouter votre domaine à la base (un problème de correspondance de domaine peut entrainer l'erreur ''Relai access denied''). De plus, ne positionnez le drapeau ''defaut'' à ''1'' (pour le mettre en domaine par défaut) que sur un seul domaine. Cette notion n'est utile que pour un usage avec le portail ''WEB'' [https://gitea.ycharbi.fr/YC-NM/Courtail Courtail].}}
 
Gestion de la liste noire des [http://www.postfix.org/access.5.html destinataires] :
 
{| class="wikitable"
|-
! Action !! Commande
|-
| Ajout || <syntaxhighlight lang="sql" inline>INSERT INTO postfix_liste_noire_destinataires (courriel,action,active) VALUES ("root@mail.exemple.fr","REJECT",1);</syntaxhighlight>
|-
| Désactivation || <syntaxhighlight lang="sql" inline>UPDATE postfix_liste_noire_destinataires SET active = 0 WHERE courriel = "root@mail.exemple.fr";</syntaxhighlight>
|-
| Activation || <syntaxhighlight lang="sql" inline>UPDATE postfix_liste_noire_destinataires SET active = 1 WHERE courriel = "root@mail.exemple.fr";</syntaxhighlight>
|-
| Suppression || <syntaxhighlight lang="sql" inline>DELETE FROM postfix_liste_noire_destinataires WHERE courriel = "root@mail.exemple.fr";</syntaxhighlight>
|-
| Listage || <syntaxhighlight lang="sql" inline>SELECT * FROM postfix_liste_noire_destinataires;</syntaxhighlight>
|}
 
Gestion de la liste noire des expéditeurs :
 
{| class="wikitable"
|-
! Action !! Commande
|-
| Ajout || <syntaxhighlight lang="sql" inline>INSERT INTO postfix_liste_noire_expediteurs (courriel,code_retour,message,active) VALUES ("tata@tata.fr",554,"Parle à ma main, ma tête est malade.",1);</syntaxhighlight>
|-
| Désactivation || <syntaxhighlight lang="sql" inline>UPDATE postfix_liste_noire_expediteurs SET active = 0 WHERE courriel = "tata@tata.fr";</syntaxhighlight>
|-
| Activation || <syntaxhighlight lang="sql" inline>UPDATE postfix_liste_noire_expediteurs SET active = 1 WHERE courriel = "tata@tata.fr";</syntaxhighlight>
|-
| Suppression || <syntaxhighlight lang="sql" inline>DELETE FROM postfix_liste_noire_expediteurs WHERE courriel = "tata@tata.fr";</syntaxhighlight>
|-
| Listage || <syntaxhighlight lang="sql" inline>SELECT * FROM postfix_liste_noire_expediteurs;</syntaxhighlight>
|}
 
Gestion des utilisateurs :
 
{| class="wikitable"
|-
! Action !! Commande
|-
| Ajout || <syntaxhighlight lang="sql" inline>INSERT INTO postfix_utilisateurs (utilisateur,mot_de_passe,nom_complet,rep_perso,uid,gid,privilege,prefixe,active) VALUES ("test@exemple.fr","{SHA512-CRYPT}$6$xWfisyC6fLawFcBr$zLm4hfRfs6Pn0RKArnyWcgliBy6lpnRUkDHfHMkvskShfLiv4pRIU6XC5ry0ysd.DeKhoAiZUfnNdmwIai2k50","Test
Dupont","exemple.fr/test/",3000,3000,"administrateur","",1);</syntaxhighlight>
|-
| Désactivation || <syntaxhighlight lang="sql" inline>UPDATE postfix_utilisateurs SET active = 0 WHERE utilisateur = "test@exemple.fr";</syntaxhighlight>
|-
| Activation || <syntaxhighlight lang="sql" inline>UPDATE postfix_utilisateurs SET active = 1 WHERE utilisateur = "test@exemple.fr";</syntaxhighlight>
|-
| Suppression || <syntaxhighlight lang="sql" inline>DELETE FROM postfix_utilisateurs WHERE utilisateur = "test@exemple.fr";</syntaxhighlight>
|-
| Listage || <syntaxhighlight lang="sql" inline>SELECT * FROM postfix_utilisateurs;</syntaxhighlight>
|}
 
{{Info|Le mot de passe est généré avec ''Dovecot'' dans la section suivante.}}


===Intégration de Dovecot===
=Dovecot=
Ajouter à la fin du fichier l'intégration avec Dovecot.
''Dovecot'' est un service gérant les protocoles ''IMAP'' et ''POP''. Il endosse donc le rôle d'intermédiaire entre les utilisateurs et le serveur de messagerie.
dovecot  unix  -      n      n      -      -      pipe
  flags=DRhu user=email:email argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}


=Installation et configuration de Dovecot=
==Installation de Dovecot==
==Installation de Dovecot==
Le serveur IMAP Dovecot s'installe dovecot-common est un paquet virtuel renvoyant vers dovecot-core, l'un peut être remplacé par l'autre dans la ligne de commande suivante de manière indéiférrente
''POP'' ayant été totalement abandonné (tant dans son développement que dans l'usage), seul ''IMAP'' sera supporté.
  # apt install dovecot-common dovecot-imapd
apt install --no-install-recommends dovecot-common dovecot-imapd dovecot-sqlite dovecot-lmtpd
 
==Création d'un utilisateur==
Comme précisé en introduction, nous exploitons des utilisateurs enregistrés dans la base ''SQLite''.
 
Il faut tout d'abord générer un mot de passe à la l'aide de la commande suivante (du paquet <code>dovecot-core</code>, véritable nom de dovecot-common (paquet virtuel) installé plus haut)
doveadm pw -s SHA512-CRYPT -p toto1234567890°+
 
Création de l'utilisateur dans la base
 
<syntaxhighlight lang="bash">
sqlite3 /etc/postfix/bdd/postfix.sqlite 'INSERT INTO postfix_utilisateurs (utilisateur,mot_de_passe,nom_complet,rep_perso,uid,gid,privilege,prefixe,active) VALUES ("test@exemple.fr","{SHA512-CRYPT}$6$xWfisyC6fLawFcBr$zLm4hfRfs6Pn0RKArnyWcgliBy6lpnRUkDHfHMkvskShfLiv4pRIU6XC5ry0ysd.DeKhoAiZUfnNdmwIai2k50","Test
Dupont","exemple.fr/test/",3000,3000,"administrateur","",1)'
</syntaxhighlight>
 
{{info|Le fait que l'utilisateur comporte le nom de domaine dans son nom fait qu'il faut renseigner la chaine complète (''utilisateur@domaine'') dans les clients ''IMAP''. Le champ ''privilege'' permet de définir les fonctions autorisées dans notre interface ''WEB'' [https://gitea.ycharbi.fr/YC-NM/Courtail Courtail] développé par nos soins. Si vous ne l'utilisez pas, ceci n'a pas d'importance. Les valeurs gérés sont ''administrateur'' et ''utilisateur''.}}
 
Créer le répertoire utilisateurs
mkdir /var/mail/utilisateurs
  chown 3000:3000 /var/mail/utilisateurs
 
{{astuce|Dans le cadre d'une migration de serveur (monté en version de ''Debian'' par exemple), nous recommandons d'effectuer une archive ''tar.gz'' du contenu de l'ancien ''MailDir'' et de l'extraire dans le nouveau répertoire utilisateur. Ce répertoire n'existera pas (''Dovecot'' est censé le créer à la première utilisation de son propriétaire), il faudra donc le créer avec un <code>mkdir -p /var/spool/mail/utilisateurs/exemple.fr/votre_utilisateur</code> et lui donner les bons droits avec <code>chown -R 3000:3000 /var/spool/mail/utilisateurs/exemple.fr && chmod -R 700 /var/spool/mail/utilisateurs/exemple.fr</code>.}}
 
==Configuration de Dovecot==
==Configuration de Dovecot==
Ce service utilise un fichier de configuration par fonctionnalité (ce qui en fait pas mal).
===Gestion d'IPv6===
===Gestion d'IPv6===
Activation du support d'IPv6 (optionnel suivant votre configuration)
Activation du support d'IPv6 (optionnel suivant votre configuration)
  # vim /etc/dovecot/dovecot.conf
  echo -e '\nlisten = *, [::]' >> /etc/dovecot/dovecot.conf
Ajouter cette ligne
 
listen = *, [::]
===Emplacement des dossiers utilisateurs===
===Emplacement des dossiers utilisateurs===
Configuration de l'emplacement du répertoire des email des utilisateurs
Configuration de l'[https://doc.dovecot.org/configuration_manual/mail_location/ emplacement du répertoire] des boites aux lettres des utilisateurs
  # vim /etc/dovecot/conf.d/10-mail.conf
  sed -i 's@mail_location = mbox:~/mail:INBOX=/var/mail/%u@mail_location = maildir:/var/mail/utilisateurs/%d/%n@g' /etc/dovecot/conf.d/10-mail.conf
Remplacer mail_location = mbox:~/mail:INBOX=/var/mail/%u par mail_location = maildir:~/Maildir
 
===Couche de chiffrement TLS===
===Emploi du chiffrement===
Configuration de la couche de chiffrement (on va le rendre obligatoire)
Configuration de la [https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/ couche de chiffrement] (qui sera rendue obligatoire)
  # vim /etc/dovecot/conf.d/10-ssl.conf
  mv /etc/dovecot/conf.d/10-ssl.conf /etc/dovecot/conf.d/10-ssl.conf.ori
Ajouter ceci (attention la ligne "ssl = no" est présente par défaut, il faut la supprimer) :
 
# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>                           
<syntaxhighlight lang="bash">
ssl = required
cat << '_EOF_' > /etc/dovecot/conf.d/10-ssl.conf
ssl_cert = </etc/ssl/certs/mailcert.pem
ssl = required
ssl_key = </etc/ssl/private/mail.key
ssl_cert = </etc/postfix/tls/courriel.pem
ssl_protocols = !SSLv2 !SSLv3 # Désactivation du SSLv2 et v3
ssl_key = </etc/postfix/tls/courriel.key
ssl_cipher_list = ALL:!aNULL:!eNULL:!LOW:!MEDIUM:!EXP:!RC2:!RC4:!DES:!3DES:!MD5:!PSK:!SRP:!DSS:!AECDH:!ADH:@STRENGTH
ssl_min_protocol = TLSv1.2
ssl_prefer_server_ciphers = yes # Dovecot > 2.2.x
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
ssl_dh_parameters_length = 2048 # Dovecot > 2.2.x
ssl_prefer_server_ciphers = yes # Oblige l'utilisation de la suite du serveur au lieu du client (Dovecot > 2.2.x)
les valeurs sont précédés d'un chevron ouvert qui ne se ferme jamais "<". C'est louche mais normal (documentation [http://wiki2.dovecot.org/SSL/DovecotConfiguration officielle de Dovecot]). Il n'y a donc pas d'erreur dans les lignes mentionnées ci-dessus.
_EOF_
</syntaxhighlight>
 
les valeurs sont précédées d'un chevron ouvert qui ne se ferme jamais (''<''). C'est louche mais normal (documentation [http://wiki2.dovecot.org/SSL/DovecotConfiguration officielle de Dovecot]). Il n'y a donc pas d'erreur dans les lignes mentionnées ci-dessus.
 
{{info|Il est vivement recommandé de ne plus utiliser des algorithmes de cryptographie non ''ECC''. L'usage de ''Diffie-Hellman'' est de façon générale découragé de nos jours.}}
 
===Configuration de l'authentification===
===Configuration de l'authentification===
Désactiver l'authentification en claire
Désactiver l'authentification en clair ainsi que ''POSIX'' et l'activer par ''SQLite''
  # vim /etc/dovecot/conf.d/10-auth.conf
  sed -i -e 's@#disable_plaintext_auth.*@disable_plaintext_auth = yes@g' -e 's@!include auth-system.conf.ext@#!include auth-system.conf.ext@g' -e 's@#!include auth-sql.conf.ext@!include auth-sql.conf.ext@g' /etc/dovecot/conf.d/10-auth.conf
Décommenter la ligne suivante dans le fichier suivant :
 
disable_plaintext_auth = yes
<syntaxhighlight lang="bash">
cat << '_EOF_' >> /etc/dovecot/dovecot-sql.conf.ext
driver = sqlite
connect = /etc/postfix/bdd/postfix.sqlite
 
password_query = SELECT utilisateur AS user, mot_de_passe AS password, '/var/mail/utilisateurs/%d/%n' AS userdb_home, 'maildir:/var/mail/utilisateurs/%d/%n' AS userdb_mail, 3000 AS userdb_uid, 3000 AS userdb_gid FROM postfix_utilisateurs WHERE utilisateur = '%u' AND active = 1
user_query = SELECT '/var/mail/utilisateurs/%d/%n' AS home, 'maildir:/var/mail/utilisateurs/%d/%n' AS mail, 3000 AS uid, 3000 AS gid FROM postfix_utilisateurs WHERE utilisateur = '%u' AND active = 1
_EOF_
</syntaxhighlight>
 
Configuration de l'authentification
Configuration de l'authentification
  # vim /etc/dovecot/conf.d/10-master.conf
  mv /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/10-master.conf.ori
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/dovecot/conf.d/10-master.conf
service auth {                                                                     
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
 
  unix_listener auth-userdb {
 
  }
}
 
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
    group = postfix
    mode = 0600
    user = postfix
  }
}
_EOF_
</syntaxhighlight>
 
Bien que le contenu proposé ne ressemble en rien à ce qui est préremplis dans celui-ci, il s'agit bien de la configuration décrite dans la [https://doc.dovecot.org/configuration_manual/howto/postfix_and_dovecot_sasl/?highlight=master documentation officielle].
 
===Auto-création des répertoires utilisateurs===
''Dovecot'' peut créer automatiquement les répertoires présents dans une boite au lettres (''/var/mail/utilisateurs/%d/%n@g'') à la connexion des utilisateurs. Ceci leur permet d'avoir un environnement pré-configuré comportant un dossier "envoyé", "brouillons", "Indésirables" et "corbeille" ("réception" est créé par Postfix).
mv /etc/dovecot/conf.d/15-mailboxes.conf /etc/dovecot/conf.d/15-mailboxes.conf.ori
 
Il faut que les sections correspondantes aux répertoires soient présentes et que l'argument "auto = create" (création du dossier dans l'arborescence) ou "auto = suscribe" (création du dossier et inscription automatique dans le client) soient spécifiées.
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/dovecot/conf.d/15-mailboxes.conf
namespace inbox {
  mailbox Sent {
    auto = subscribe
    special_use = \Sent
  }
  mailbox Drafts {
    auto = subscribe
    special_use = \Drafts
  }
  mailbox Trash {
    auto = subscribe
    special_use = \Trash
  }
  mailbox Spam {
    auto = subscribe
    special_use = \Junk
  }
  mailbox Archive {
    auto = subscribe
    special_use = \Archive
  }
  mailbox Notes {
    auto = create
  }
}
_EOF_
</syntaxhighlight>
 
==Sieve==
===Installation de ManageSieve===
''Sieve'' est un système de filtrage du courrier coté serveur permettant l'application d'actions suivant des règles prés-établies. Sa mise en œuvre passe par le service [https://wiki1.dovecot.org/ManageSieve ManageSieve] agissant comme une extension de ''Dovecot''. Les scripts sont créables à la fois sur le serveur et sur les clients (ce sont de simples instructions dans un fichier texte synchronisés par ''IMAP'').
apt install --no-install-recommends dovecot-sieve dovecot-managesieved
 
Ces deux paquets vont créer les 3 fichiers <code>90-sieve.conf</code>, <code>90-sieve-extprograms.conf</code> et <code>20-managesieve.conf</code>.
 
===Configuration de ManageSieve===
Édition du fichier <code>20-lmtp.conf</code> pour dire à ''Dovecot'' d'[https://wiki2.dovecot.org/HowTo/PostfixDovecotLMTP utiliser] le greffon ''Sieve'' via [https://doc.dovecot.org/configuration_manual/protocols/lmtp_server/ LMTP]
mv /etc/dovecot/conf.d/20-lmtp.conf /etc/dovecot/conf.d/20-lmtp.conf.ori
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/dovecot/conf.d/20-lmtp.conf
protocol lmtp {
    postmaster_address = postmaster@exemple.fr
    mail_plugins = quota sieve
}
_EOF_
</syntaxhighlight>
 
Définition du répertoire de destination des scripts ''Sieve'' (par défaut c'est le ''~'') en modifiant le fichier <code>90-sieve.conf</code>
mv /etc/dovecot/conf.d/90-sieve.conf /etc/dovecot/conf.d/90-sieve.conf.ori
 
On demande à ''Dovecot'' de créer le dossier ''Sieve'' dans la boite aux lettres (''Maildir'') de l'utilisateur lors de sa première connexion. De plus, il est demandé à l'outil d'utiliser les scripts qui seront ajoutés côté client par l'intermédiaire du [[#Glossaire|MUA]].
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/dovecot/conf.d/90-sieve.conf
plugin {
  sieve = ~/sieve/.dovecot.sieve
  sieve_before = /var/mail/sieve/before/spam.sieve
  sieve_dir = ~/sieve
}
_EOF_
</syntaxhighlight>
 
Créer l’arborescence pour les scripts ''Sieve'' globaux (actifs pour tous les utilisateurs et s'exécutant avant leurs scripts personnels) et définir les bons droits pour celle-ci
mkdir -p /var/mail/sieve/before && chown -R dovecot: /var/mail/sieve
 
Redémarrer le service ''Dovecot''
systemctl restart dovecot.service
 
===Règle globale de gestion du pourriel===
Mise en place d'un script ''Sieve'' global et actif pour tout les utilisateurs. Il va permettre de placer tout les courriels détectés comme du pourriel par ''SpamAssassin'' dans le dossier ''Maildir'' ''"Spam"'' :
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /var/mail/sieve/before/spam.sieve
require "fileinto";
if header :contains "X-Spam-Flag" "YES" {
  fileinto "Spam";
}
_EOF_
</syntaxhighlight>
 
Compiler le fichier de règle afin de ne pas avoir un message d'avertissement (non bloquant) dans les journaux concernant les droits
sievec /var/mail/sieve/before/spam.sieve
 
Cette commande compile le fichier de règles dans le même répertoire que la source sous le nom <code>spam.svbin</code>.
 
Donner les droits aux fichiers
chown dovecot: /var/mail/sieve/before/spam.*
 
=OpenDKIM=
''OpenDKIM'' est un logiciel libre implémentant le protocole [https://fr.wikipedia.org/wiki/DomainKeys_Identified_Mail DKIM] (''DomainKeys Identified Mail''). Son rôle est d'authentifier le domaine de l'expéditeur (tant en émission qu'en réception) et d'assurer l'intégrité du message. Chaque courriel est alors signé lors de sa transmission initiale et la vérification de celle-ci à la réception permet d'appliquer une politique de traitement (via l'anti pourriel notamment). Couplé à [https://fr.wikipedia.org/wiki/Sender_Policy_Framework SPF] (''Sender Policy Framework''). Il participe donc à réduire la distribution de courriels indésirables aux utilisateurs.
 
{{info|La mise en œuvre de ''DKIM'' étant plus complexe et lourde à mettre en place qu'un simple enregistrement ''DNS'' ''SPF'', son absence est bien moins pénalisante que ce dernier lors du traitement de vos message par les ''MTA'' destinataires (leur politique est beaucoup plus laxiste à ce sujet).
 
À titre personnel, je n'ai pas mis en place cette technologie pendant 7 ans et cela ne m'a jamais handicapé. En revanche, ''SPF'' et un enregistrement ''PTR'' ''rDNS'' sont eux, réellement utiles. ''DKIM'' peut jouer si votre message passe tout juste les critères établis par le serveur distant et qu'un point de plus vous permet de ne pas être considéré comme non désiré.}}
 
Nous nous sommes principalement inspirés de la documentation idoine de ce [https://wiki.debian-fr.xyz/Opendkim Wiki] pour réaliser cette section.
 
==Installation des paquets==
Nous installons l'outil qui sera exploité par ''Postfix'' afin de signé/vérifier les courriels ainsi que celui permettant de générer nos clés
apt install --no-install-recommends opendkim opendkim-tools
 
==Création d'un couple de clés==
Notez que nous écrivons cette documentation afin de permettre un usage multi-domaines. Dans cette optique, nous utiliserons un script de génération des clés se basant sur un tableau listant chacun d'eux. Toutefois, nous documentons ci-après la méthode permettant la création manuelle d'un couple de clés si vous privilégiez une approche plus directe. Nous vous invitons tout de même à considérer l'usage de la méthode scripté qui s'accommode aussi bien d'un ou plusieurs domaine.
 
===Méthode manuelle===
Le paquet ''OpenDKIM'' crée automatiquement le répertoire <code>/etc/dkimkeys</code>. Nous allons donc l'exploiter. La génération d'un couple de clés s'effectue via la commande <code>opendkim-genkey</code> :
 
<syntaxhighlight lang="bash">
mkdir -p /etc/dkimkeys/clefs/exemple.fr
opendkim-genkey -b 4096 -D /etc/dkimkeys/clefs/exemple.fr -r -d exemple.fr -s mail
echo "mail._domainkey.exemple.fr exemple.fr:mail:/etc/dkimkeys/clefs/exemple.fr/mail.private" >> /etc/dkimkeys/TableClefs
echo "exemple.fr mail._domainkey.exemple.fr" >> /etc/dkimkeys/TableSignatures
echo "exemple.fr" >> /etc/dkimkeys/HotesDeConfiance
chown -R opendkim:opendkim /etc/dkimkeys/clefs/exemple.fr
</syntaxhighlight>
 
===Méthode scripté===
Le script suivant permet la création des clés de façon récursive en parcourant une liste de domaines initialisée dans le tableau <code>domaines</code>. Il constitue automatiquement l'arborescence à raison d'un répertoire par occurrence afin d'y ranger les fichiers conçus. Bien sûr, vous pouvez réaliser ces opérations vous mêmes via la commande de la section précédente.
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/dkimkeys/genClefs.sh
#!/bin/bash
# Script de génération des clés DKIM pour du multi-domaine
 
selecteur=mail
repertoire=/etc/dkimkeys
domaines="exemple.fr toto.fr"
 
for domaine in $domaines; do
    mkdir -p $repertoire/clefs/$domaine
    opendkim-genkey -b 4096 -D $repertoire/clefs/$domaine -r -d $domaine -s $selecteur
    echo "$selecteur._domainkey.$domaine $domaine:$selecteur:$repertoire/clefs/$domaine/$selecteur.private" >> $repertoire/TableClefs
    echo "$domaine $selecteur._domainkey.$domaine" >> $repertoire/TableSignatures
    echo "$domaine" >> $repertoire/HotesDeConfiance
    chown -R opendkim:opendkim $repertoire/clefs/$domaine
done
_EOF_
</syntaxhighlight>
 
chmod 740 /etc/dkimkeys/genClefs.sh
/etc/dkimkeys/genClefs.sh
 
===Attribution des droits===
chown opendkim:opendkim /etc/dkimkeys/clefs/
chown opendkim:opendkim /etc/dkimkeys/{TableClefs,TableSignatures,HotesDeConfiance}
chmod 660 /etc/dkimkeys/{TableClefs,TableSignatures,HotesDeConfiance}
 
==Configuration d'OpenDKIM==
Le fichier est assez simple et reprend les éléments abordés précédemment.
mv /etc/opendkim.conf /etc/opendkim.conf.ori
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/opendkim.conf
Syslog                  yes
SyslogSuccess          yes
Canonicalization        relaxed/simple
OversignHeaders        From
UserID                  opendkim
UMask                  007
Socket                  local:/var/spool/postfix/var/run/opendkim/opendkim.sock
PidFile                /run/opendkim/opendkim.pid
TrustAnchorFile        /usr/share/dns/root.key
# Table des clés
KeyTable                /etc/dkimkeys/TableClefs
# Liste les domaines à signer
SigningTable            /etc/dkimkeys/TableSignatures
# SigningTable = Donne la correspondance entre les domaines et les selecteurs
ExternalIgnoreList      /etc/dkimkeys/HotesDeConfiance
# Donne la correspondance entre les selecteurs et les clés à utiliser
InternalHosts          /etc/dkimkeys/HotesDeConfiance
_EOF_
</syntaxhighlight>
 
Création du répertoire d'accueil pour le socket
mkdir -p /var/spool/postfix/var/run/opendkim
 
''Note : ce socket permet la communication entre Postfix et OpenDKIM. Le [https://unix.stackexchange.com/questions/74477/postfix-smtpd-warning-connect-to-milter-service-unix-var-run-opendkim-opendki choix] du chemin est guidé par la [http://www.postfix.org/BASIC_CONFIGURATION_README.html#chroot_setup racine d'exécution] du MTA selon les directives du fichier <code>master.cf</code>.''
 
Don de propriété dessus
chown opendkim:opendkim /var/spool/postfix/var/run/opendkim
 
Ajout de l'utilisateur ''opendkim'' au groupe ''postfix'' afin de permettre la communication via le socket
usermod -a -G opendkim postfix
 
Si vous avez été attentif lors de l'édition du fichier [[#Main.cf|main.cf]], vous avez dû remarqué les valeurs se rapportant à cette section. Je vous invite à y lire les commentaires afin de comprendre chacune d'elles.
 
Tous les éléments locaux sont prêts, nous pouvons redémarrer le service
systemctl restart opendkim.service
 
==Enregistrement DNS DKIM==
Il ne vous a pas échappé que ce protocole se base lui aussi sur le ''DNS''. Il va falloir publier votre clé publique dans un enregistrement dédié sur votre zone. Ajoutez-en un de type ''TXT'' ou ''DKIM'' comportant le contenu du fichier <code><selecteur>.txt</code> généré avec votre clé tout à l'heure. Du fait de la longueur de la clé (4096 bits), son contenu est tronqué en plusieurs lignes. Cet aspect ne dérange nullement les implémentations ''DNS'' que j'ai pu rencontrer. Il est donc possible d'ajouter la clé à votre zone par un simple copier/coller de celle-ci :
 
<syntaxhighlight lang="bash">
mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; s=email; "
  "p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnjMYbRgp+0a7BY5pUdQ2lgMWlnsWCL94nwMfcZ0weEHQoL+ip1s7m95L0HqIjCi3yPn5lL4Lx0wZ8ujPKVhXB3R+E/rjBOUXo26vTULCDdpqfg+IzxvyqjM+644Y8NYb+fRu4WkpBMkptMmogRhHnu3uDS+4/IyEqAH4OOy5SZHW5atwm87KCEDH8LcffLedr/nV22gXe5Wd2M"
  "z3RqLPyaOgOxoIqOZKOIy5Xs5x1FCV8MNRdj8xT65GKsriN5/RSXK1NU1dvhnmTl/zuXP95F21YZPbwZEy3EXsyQuiyb1westiXy4fkWi0qV9vdYvyNZLn+wUk6tvY1mQ/OBewnrqGfHR/Tf8r+6Ku29CAYt4k6DXEmlEmZlM3d8Vg7/krlsYdlZIqDmOktxelGg3Oey5IJeqknHZh0lxxNjGm1zPjUKbF0MgMP1DZzlDgHJKIk558IyBV"
  "3zNDMIvVbbWNzOyeU5513n0AOx7D8jayHvc3R9GkhyeHDH4XBExcobKPZstsGdEdLLTFnT7fDVAqur53HSuLSAum+0IK8VkC5K0QN21A6DNlzKvCbN4l4blVNg7qlnViqFB9g3ZfAsdCfgca1Dq4iFWS+Z9yuwkfWxdQbKYfcwD8Zb8sLpmTYZmjbk9CcD8jTFkJwKpLaT2Beo8YJdKh31V/Fkd6MXbI5gECAwEAAQ==" )  ; ----- DKIM key mail for exemple.fr
</syntaxhighlight>
 
Pour vérifier la prise en compte de votre modification, vous pouvez utiliser la commande suivante pour requêter le serveur ''DNS'' :
dig mail._domainkey.exemple.fr TXT


service auth {                                                                     
Nous utiliserons des [[#Outils_WEB|outils WEB]] à la fin pour tester ceci de façon plus approfondie.
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
  # auth_socket_path points to this userdb socket by default. It's typically
  # used by dovecot-lda, doveadm, possibly imap process, etc. Users that have
  # full permissions to this socket are able to get a list of all usernames and
  # get the results of everyone's userdb lookups.
  #
  # The default 0666 mode allows anyone to connect to the socket, but the
  # userdb lookups will succeed only if the userdb returns an "uid" field that
  # matches the caller process's UID. Also if caller's uid or gid matches the
  # socket's uid or gid the lookup succeeds. Anything else causes a failure.
  #
  # To give the caller full permissions to lookup all users, set the mode to
  # something else than 0666 and Dovecot lets the kernel enforce the
  # permissions (e.g. 0777 allows everyone full permissions).
  unix_listener auth-userdb {
    #mode = 0666
    #user =
    #group =
  }
}
===Auto création des répertoires utilisateurs===
Auto création des répertoires "envoyé", "brouillons", "Indésirables" et "corbeille" ("réception" est créé par Postfix)
# vim /etc/dovecot/conf.d/15-mailboxes.conf
Il faut que les sections correspondantes aux répertoires soient présentes et que l'argement "auto = create" (création du dossier dans l'arboréscence) ou "auto = suscribe" (création du dossier et inscription automatique dans le client) soient spécifiées.
Attention, les espaces avant les acolades sont ultra important (le service ne se lance pas si il n'y en a pas...) ça peut générer une séance de débogage bien chiante juste pour cette merde.
namespace inbox {
  mailbox Sent {
    auto = subscribe
    special_use = \Sent
  }
  mailbox Drafts {
    auto = subscribe
    special_use = \Drafts
  }
  mailbox Trash {
    auto = subscribe
    special_use = \Trash
  }
  mailbox Spam {
    auto = subscribe
    special_use = \Junk
  }
  mailbox Archive {
    auto = subscribe
    special_use = \Archive
  }
  mailbox Notes {
    auto = create
  }
}
La section suivante, présente par défaut, peut être supprimé (il s'agit juste d'un nom alternatif ne présentant aucun intérêt):
mailbox "Sent Messages" {
    special_use = \Sent
}
Redémarrer les services pour prendre en compte les modifications
# service postfix restart
# service dovecot restart


==Installation de Sieve==
=Spamassassin=
===Installation de Sieve===
''Spamassassin'' est un programme écrit en ''Perl'' et en ''C'' diffusé sous la licence libre ''Apache'' version 2.0. Il a pour rôle de filtrer le trafic des courriels transitant par un ''MTA'' (''Postfix'' dans notre cas) dans l'optique d'identifier pour traitement les messages indésirables. Celui-ci peut prendre diverses formes dans la mesure où l'outil donne la possibilité à l'administrateur de réaliser ces propres filtres. Les actions les plus courantes sont de rejeter le message ou de le marquer pour trie via ''Sieve'' (solution retenue). Gardez en tête qu'il n'est pas impossible de faire face à des faux positifs et que le rejet de tels messages peuvent avoir des conséquences pour vos utilisateurs. Il convient alors d'appliquer les mesures adéquates à votre situation selon le flux que représente les pourriels.
Sieve est un système de filtre du courrier coté serveur. Il utilise IMAP pour fonctionner et se comporte comme une extension de Dovecot. Les scripts sont créables à la fois sur le serveur et sur le client (ce sont de simples instructions dans un fichier texte synchronisé par IMAP).
# apt install dovecot-sieve dovecot-managesieved
Ces deux paquets vont créer les 3 fichiers 90-sieve.conf, 90-sieve-extprograms.conf et 20-managesieve.conf.


===Configuration de Sieve===
Pour chaque message filtrés, une note est attribuée au courriel selon des critères arbitraires tels que ceux énoncés en prérequis et sera utilisée lors de la lecture des règles afin de déterminer le sort réservé à celui-ci. Vous comprenez alors l'importance de respecter les standards de "propreté" énoncés en début de page pour que vos propres messages ne soient pas mal-traités par vos destinataires.
Dovecot va se servir du fichier /etc/dovecot/conf.d/15-lda.conf pour la suite des évènements. Si vous laissez ce fichier par défaut (il n'y a aucun paramètres actifs dedans), vous ne verrez aucune différence de fonctionnement. En revanche, si vous mettez des paramètres à l'intérieur, veillez à ne pas supprimer la valeur ajouté dans mailbox_command du main.cf, sinon ça plante (c'est donc les deux notion modifiés ou rien).


Modification du fichier 15-lda.cof pour dire à Dovecot d'utiliser le greffon Sieve
Les sources suivantes ont, entre autres, permis d'écrire cette section :
# vim /etc/dovecot/conf.d/15-lda.conf
* https://wiki.debian.org/DebianSpamAssassin
Les arguments suivants serons utilisés
* https://www.malekal.com/installer-configurer-spamassassin-debian/
protocol lda {
* https://www.linuxbabe.com/redhat/spamassassin-centos-rhel-block-email-spam
  postmaster_address = postmaster@exemple.fr
  lda_mailbox_autocreate = yes
  lda_mailbox_autosubscribe = yes
  mail_plugins = $mail_plugins sieve
}
Définition du répertoire de destination des scriptes Sieve (par défaut c'est le ~) en modifiant le fichier 90-sieve.conf
# vim /etc/dovecot/conf.d/90-sieve.conf
On demande à Dovecot de créer le répertoire Sieve dans le Maildir de l'utilisateur qui se connecte ainsi que d'utiliser les scripts qui serons ajouté par l'utilisateur à l'intérieur par l'intermédiaire de son client de messagerie
plugin {
  sieve = ~/Maildir/sieve/.dovecot.sieve
  sieve_before = /var/mail/sieve/before/spam.sieve
  sieve_dir = ~/Maildir/sieve
}
Créer l’arborescence pour les scripts Sieve globaux (actifs pour tout les utilisateurs et s'exécutants avant leurs scripts personnels) et définir les bon droits pour celle-ci
# mkdir -p /var/mail/sieve/before && chown -R mail: /var/mail/sieve
Redémarrer le service Dovecot
# service dovecot restart


===Création d'une règle globale pour la gestion du SAPM===
==Installation de Spamassassin==
Mise en place d'un script Sieve globale et actif pour tout les utilisateurs
Le système de gestion des indésirables fonctionne au travers de trois composantes. Un module (''spamass-milter'') lié à ''Postfix'' écoutant sur un socket via le protocole ''Milter'' les messages provenant de celui-ci; un client nommé ''spamc'' exécuté par le module et chargé de transmettre les messages à ''spamd'' via un autre socket; un démon (''spamd'') chargé de la qualification des messages ainsi que de leur traitement.
# vim /var/mail/sieve/before/spam.sieve
Ce script va permettre de placer tout les emails détectés comme du spam par SpamAssassin dans le dossier Maildir Spam :
require "fileinto";                                                                                                                 
if header :contains "X-Spam-Flag" "YES" {
  fileinto "Spam";
}
Compiler le fichier de règle afin de ne pas avoir un message d'erreur (non bloquant) dans les log concernant des droits
# sievec /var/mail/sieve/before/spam.sieve
Cette commande compile le fichier de règle dans le même répertoire que la source sous le nom de spam.svbin


Donner les droits aux fichierx
Installation des composants
  # chown mail: /var/mail/sieve/before/spam.*
  apt install --no-install-recommends spamassassin spamc spamass-milter


==Installation de SpamAssassin==
Création d'un utilisateur dédié au service
===Installation de SpamAssassin===
  useradd --system --home-dir /run/spamassassin --shell /usr/sbin/nologin --user-group spamassassin
SpamAssassin permet de detecter et marquer les emails se caractérisants comme du Spam pour simplifier leur traitement.
  # apt install spamassassin spamc


===Intégration de SapmAssassin à Postfix===
Activation du service au démarrage
Ajout des directives concernant Spamassassin dans Postfix via le master.cf
  systemctl enable spamassassin.service
  # vim /etc/postfix/master.cf
En dessous de
smtp      inet  n      -      -      -      -      smtpd
Ajoutez ceci (attention, l'indentation compte) :
    -o content_filter=spamassassin
submission inet n      -      -      -      -      smtpd
    -o content_filter=spamassassin
À la fin de ce fichier, ajoutez ceci :
spamassassin unix -    n      n      -      -      pipe
  user=debian-spamd argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}
Actualiser la configuration de Postfix
# service postfix reload


===Configuration de SpamAssassin===
==Configuration de spamd==
À ce stade, un choix s'offre à nous. La modification suivante est donc à votre appréciation. Lorsqu'un email va être détecté en tant que spam, SpamAssassin va modifier son entête et ajouter une section "X-Spam-Flag: YES". De là, il sera facile de créer une règle de filtrage Sieve s'occupant de placer le courrier indésirable dans le dossier correspondant. La modification suivante va permettre de changer la façon don ce présente le message détecté comme Spam. Si vous dé-commentez la ligne de l'étape suivante, SpamAssassin va ajouter au début du sujet du message la chaîne de caractère "*****SPAM*****". Si vous ne le faite pas, SpamAssassin va juste modifier l'entête du message et le livrer tel-quel. À vous de voir...
Par défaut, le démon ''spamd'' s'exécute avec l'utilisateur <code>postfix</code> et communique au module ''spamass-milter'' via un socket ''TCP''. Dans le respect du [https://fr.wikipedia.org/wiki/Principe_de_moindre_privil%C3%A8ge principe de moindre privilège], un utilisateur dédié a été ajouté et pour des raisons d'optimisation, de sécurité ainsi que de bon sens, le socket ''TCP'' laissera sa place à un socket ''UNIX''. Ce dernier est bien plus rapide (ne se tape pas tout le modèle ''OSI'' pour réaliser une communication locale...) et plus sécurisé (pas d'écoute ni de redirection de trames réseau possible).


Si vous avez du mal à comprendre faites le test et vous verrez bien ce qui vous convient.
''Spamassassin'' ne créant pas lui-même le répertoire d'accueil de son socket, que nous situerons, [https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s15.html conformément] au [https://fr.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] (''FHS''), dans le  <code>/run</code> (qui est monté en ''tmpfs'' dans ''Debian''), nous ajouterons une [https://unix.stackexchange.com/questions/74477/postfix-smtpd-warning-connect-to-milter-service-unix-var-run-opendkim-opendki configuration] pour [https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html systemd-tmpfiles] afin de le fabriquer au démarrage.


Édition du fichier local.cf
<syntaxhighlight lang="bash">
# vim /etc/spamassassin/local.cf
cat << '_EOF_' > /usr/lib/tmpfiles.d/spamassassin.conf
Dé-commenter cette ligne (étape facultative en fonction de votre choix)
d /run/spamassassin 0750 spamassassin spamassassin - -
reriwte_header Subject *****SPAM*****
_EOF_
Ajouter ceci dans le même fichier, tout à la fin :
</syntaxhighlight>
report_safe 0
whitelist_from *@exemple.fr
add_header all Report _REPORT_
add_header spam Flag _YESNOCAPS_
add_header all Status _YESNO_, score=_SCORE_ required=_REQD_ tests=_TESTS_ autolearn=_AUTOLEARN_ version=_VERSION_
add_header all Level _STARS(*)_
add_header all Checker-Version SpamAssassin _VERSION_ (_SUBVERSION_) on _HOSTNAME_
Il faut passer la valeur "ENABLED" à 1 dans le fichier /etc/default/spamassassin pour activer le service et vérifiez que la valeur "CRON" soit bien présente et égale à 0 (0 pour Debian Jessie - 1 pour Debian Wheezy)
# vim /etc/default/spamassassin


ENABLED=1
Pour la session active, nous créerons ce répertoire manuellement afin de ne pas avoir à redémarrer tout de suite
  CRON=0
  mkdir -p /var/run/spamassassin
Activer le service spamassassin au démarrage du système
  chown spamassassin:spamassassin /var/run/spamassassin
  # systemctl enable spamassassin.service
Démarrer le service
# service spamassassin start


===Automatisation de l'apprentissage===
''Note : <code>/var/run</code> est un lien symbolique du tmpfs <code>/run</code> présent de base dans le système.''
Ajout de règles cron pour automatiser les mises à jour de la base de connaissance de Spamassassin
# crontab -e
Si c'est la première fois que vous utiliser Cron, un message va vous inviter à choisir votre éditeur par défaut. Si vous voulez vim, choisissez "vim.basic"
# Mise à jour des règles de spamassassin
20 02 * * * /usr/bin/sa-update
# Auto-apprentissage de spam assassin
30 02 * * * /usr/bin/sa-learn --ham /home/test/Maildir/cur/*
40 02 * * * /usr/bin/sa-learn --spam /home/test/Maildir/.Spam/cur/*
<span style="color:red;">Voir si le fait de remplacer test par * permet de rechercher dans tout les utilisateurs sans avoir à rajouter ces deux lignes par utilisateur.</span>


===Tester la détection de spam===
Configuration du service
Bien qu'il soit compliqué de tester le bon fonctionnement de SpamAssassin nous pouvons nez en moins simuler un email frauduleux en envoyant un message contenant la chaîne de caractère suivante :
 
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
<syntaxhighlight lang="bash">
# Commenter toutes les lignes existantes
sed -i '/^$/!s/^/#/g' /etc/default/spamassassin
 
# Configuration du démon pour utiliser l'utilisateur spamassassin, un PID à un emplacement donné et un socket personnalisé du type UNIX
cat << '_EOF_' >> /etc/default/spamassassin
 
OPTIONS="--username spamassassin --create-prefs --max-children 5 --helper-home-dir --socketpath=/run/spamassassin/spamassassin.sock --socketowner=spamassassin --socketgroup=spamassassin --socketmode=0660"
PIDFILE="/var/run/spamassassin/spamd.pid"
CRON=0
_EOF_
</syntaxhighlight>
 
Ajout d'une action en cas de détection de pourriel
 
<syntaxhighlight lang="bash">
cat << '_EOF_' >> /etc/spamassassin/local.cf
 
rewrite_header Subject *****SPAM*****
report_safe 0
whitelist_from *@exemple.fr
 
add_header all Report _REPORT_
add_header spam Flag _YESNOCAPS_
add_header all Status _YESNO_, score=_SCORE_ required=_REQD_ tests=_TESTS_ autolearn=_AUTOLEARN_ version=_VERSION_
add_header all Level _STARS(*)_
add_header all Checker-Version SpamAssassin _VERSION_ (_SUBVERSION_) on _HOSTNAME_
 
skip_rbl_checks 1
_EOF_
</syntaxhighlight>
 
Cette action ajoutera le préfixe ''*****SPAM*****'' au sujet du message considéré comme indésirable ainsi que des en-têtes de marquage (notamment ''X-Spam-Flag: YES''). Ceci aura pour effet de déclencher l'action de la règle ''Sieve'' globale écrite plus haut et de placer le message dans le dossier approprié. La dernière ligne désactive quant à elle la vérification des adresses ''IP'' émétrices via les [https://www.altospam.com/glossaire/listes-noires.php RBL] intégrées au logiciel (vous pouvez l'enlever si vous en voulez mais je ne sais pas ce qu'ils font des traces que vous laissez).
 
==Configuration de spamass-milter==
<syntaxhighlight lang="bash">
# Commenter toutes les lignes existantes
sed -i '/^$/!s/^/#/g' /etc/default/spamass-milter
 
# Configuration du démon pour utiliser l'utilisateur spamassassin, un PID à un emplacement donné et un socket personnalisé du type UNIX
cat << '_EOF_' >> /etc/default/spamass-milter
 
OPTIONS="-u spamass-milter -i 127.0.0.1 -- -s 10485760 --socket=/run/spamassassin/spamassassin.sock"
SOCKET="/var/spool/postfix/spamass/spamass.sock"
SOCKETOWNER="spamass-milter:spamass-milter"
_EOF_
</syntaxhighlight>
 
{{info|Si vous désirez rejeter les messages identifiés comme indésirables, vous pouvez ajouter le paramètre <code>-r <note></code> à la suite de l'adresse ''IP'' de lien local où ''<note>'' correspond à la note attribué au message par ''Spamassassin'' que vous considérez comme étant le seuil d'acceptabilité. Tout courriel ayant une note égale ou supérieur à ce seuil sera alors rejeté avec un code 550 à l'expéditeur.}}
 
Ajout des utilisateurs <code>spamassassin</code> et <code>postfix</code> au groupe <code>spamass-milter</code> pour permettre la communication inter-socket
usermod -a -G spamassassin spamass-milter
usermod -a -G spamass-milter postfix
 
''Note : la communication entre Postfix et Spamass-milter se fait à la fin du fichier [[#Main.cf|main.cf]] sur la même ligne que pour le socket d'OpenDKIM.''
 
==Automatisation de l'apprentissage==
L'outil dispose d'une fonctionnalité d'apprentissage basée sur l'[https://fr.wikipedia.org/wiki/Inf%C3%A9rence_bay%C3%A9sienne inférence bayésienne]. Afin d'entraîner le moteur sur les messages reçus, vous pouvez utiliser la tâche planifiée suivante (nécessite le logiciel [[Cron]]) :
 
<syntaxhighlight lang="bash">
cat << '_EOF_' > /etc/cron.daily/Spamassassin-bayés
#!/bin/bash
# Script de mise à jour automatique de la base bayésienne de Spamassassin
 
# Mise à jour des règles de spamassassin
# Pour utiliser cette fonctionnalité, il faut importer la clé GPG d'un canal de règles anti-pourriels.
# Dans la mesure où, comme expliqué, nous ne recevons pas de messages non désirés, nous n'avons pas explorer cette piste.
# /usr/bin/sa-update
 
# Auto-apprentissage de Spamassassin sur les messages existants dans les boites aux lettres
/usr/bin/sa-learn --ham /var/spool/mail/utilisateurs/*/*/cur/*
/usr/bin/sa-learn --spam /var/spool/mail/utilisateurs/*/*/.Spam/cur/*
_EOF_
</syntaxhighlight>
 
chmod +x /etc/cron.daily/Spamassassin-bayés
 
{{info|La [https://cwiki.apache.org/confluence/display/SPAMASSASSIN/SiteWideBayesSetup documentation officielle] conseille de ne réaliser cette tâche que manuellement après vérification des messages présents dans votre boite aux lettres. Ceci dans une optique de ne pas apprendre de fausses données. Vous pouvez par exemple effectuer manuellement les commandes de cette section après un épisode de réception non désiré afin d'améliorer la détection. Si vous souhaitez suivre cette recommandation, pensez à ne pas le laisser dans ce répertoire afin que ''Cron'' ne l'exécute pas quotidiennement.}}
 
=Tests de fonctionnement=
Nous voici arrivé au grand moment : celui du test !
 
Il va falloir redémarrer tous les services configurés précédemment afin de valider leur bon fonctionnement. Habituellement, j'aurai procédé par étape au file des sections mais l'écosystème abordé ayant la particularité de faire appel à des composants inter-dépendants, il est difficile de réaliser des tests d'intégration continue sans devoir revenir modifier des configurations tout au long du cheminement, ce qui aurai rendu la lecture exécrable. Ayant conscience de la difficulté de suivre une procédure aussi conséquente (et en vous assurant de la tâche encore plus importante qu'a été sa rédaction), j'ai préféré faire le choix d'une configuration en une traite, quitte à devoir vous faire corriger les quelques erreurs d'inattentions dans la lecture par la suite en vous appuyant sur les journaux du système. Soyez sûr que l'idée d'user au maximum de copier/coller pour l'application de ce document a été la trame directrice de sa rédaction afin de faciliter la mise en place de votre propre messagerie électronique.
 
==Redémarrage des services==
 
{{astuce|Il peut être judicieux d'afficher les journaux concernant la messagerie dans un second terminal pendant que vous redémarrez les services via un <code>tail -f /var/log/mail.log</code>.}}
 
systemctl restart spamass-milter.service
systemctl restart spamassassin.service
systemctl restart opendkim.service
systemctl restart dovecot.service
systemctl restart postfix.service


Vérification de la détection dans les logs
Vous pouvez naturellement afficher le statut de chacun des services via la commande <code>systemctl status <service></code> afin de vérifier l'état de leur exécution ainsi que la commande <code>journalctl -feu <service></code> pour en afficher les journaux propres dans leur intégralité.
# tail -f /var/log/mail.log
Si tout ce passe bien vous verrez dans le fichier de log le message suivant :
stored mail into mailbox 'Spam'
En vous connectant à votre compte vous verrez le message envoyé être arrivé automatiquement dans la boite "indésirable".


=Installation du webmail=
==Tests de communication==
==Installation d'Apache==
Quoi de mieux pour tester le fonctionnement que l'envoi d'un message ? Utilisez un client ''IMAP'' comme [[Rainloop]] ou [https://www.thunderbird.net/fr/ Thunderbird] (vous pouvez également configurer l'[[Thunderbird#Auto-configuration|auto-configuration]] pour celui-ci) et pensez à regarder le code source des messages sur la boite de destination afin de regarder leurs en-têtes. Vous y verrez la suite cryptographique utilisée pour la transmission, la note attribuée par ''Spamassassin'' ainsi que la signature ''DKIM''.
Installation d'apache et des dépendences du site
# apt install apache2 php5 php5-curl zip
Création du répertoire déstiné au site
# mkdir /var/www/rainloop
Adaptation du Virtual Host Apache
# vim /etc/apache2/sites-enabled/000-default.conf
La ligne DocumentRoot /var/www/html doit avoir être remplacé par DocumentRoot /var/www/rainloop. Il faut appliquer la configuration en relançant le service Apache2
# service apache2 reload
La mise en place d'un Apache HTTPS ne sera pas abordé dans ce tuto mais est fortement recommandé afin de grandement limiter les risques de piratage. Deux façons de procéder sont possibles : utiliser la [[Apache#HTTPS|gestion TLS d'Apache]] ou coupler l'installation existante à un [[Haproxy]] qui se chargera de rediriger le trafic HTTP en HTTPS.
==Installation de Rainloop==
Téléchargement de l'archive
# wget http://repository.rainloop.net/v2/webmail/rainloop-community-latest.zip -P /tmp/
Dézippage de l'archive dans le répertoire du site
# unzip /tmp/rainloop-community-latest.zip -d /var/www/rainloop/
Attribution des droit Apache2 à ce dernier
# chown -R www-data: /var/www/rainloop
==Configuration de Rainloop==
Il faut ouvrir un navigateur et aller à l'adresse de votre serveur sur la page admin en ajoutant "/?admin" à la fin de l'URL: http:/mail.exemple.fr/?admin. Le login est "admin" et le mot de passe est "12345" (pensez à le changer).


Dans la section "General", changer la langue de l'interface client en Français (l'interface admin ne possède pas de traduction).
==Outils WEB==
Aller dans la section "Domains" > Supprimez tout les domaines présents par défaut (on monte un serveur à la maison c'est pas pour continuer d'utiliser NSA Cloud Backup) > "add Domain" > "Name" : Ce que vous voulez mais je trouve propre de mettre le domaine MX > "IMAP > "Server" > mail.exemple.fr et "Port" 143 > "Sécure" STARTTLS" et cochez la case "Use short login" > Pour le "SMTP c'est pareil, le port est mis automatiquement quand vous séléctionnez la case STARTLS" (587) et vous cochez la même case pour le short login > "Add".
Après avoir validé l'aspect fonctionnel de votre installation, il peut être judicieux de s'attarder sur l'aspect qualitatif au regard des standards de l'époque.
Dans la section login > "Default Domain" > exemple.fr (ça permettra de ne pas avoir à ce taper le "@exemple" à chaque fois qu'on veut ce connecter.


Une fois terminé, ce déconnecter avec le bouton en haut à droite et revenir à la page de login client en enlevant tout ce qu'il y à après l'adresse du serveur dans l'URL : http:/mail.exemple.fr.
Pour ce faire, vous pouvez utiliser les outils ''WEB'' suivant qui vous attribueront des notes et vous détailleront les divers points examinés dans le but de vous améliorer :
* https://mxtoolbox.com pour vérifier vos résolutions DNS ainsi que la présence de votre adresse ''IP'' dans une liste noire d'indésirable
* https://www.mail-tester.com afin de visualiser les points attrayants à l'acceptabilité de vos messages (cela peut être l'occasion d'utiliser un alias...)
* https://cryptcheck.fr pour lister les suites cryptographiques ayant pu être négocier par le serveur distant


Se connecter. À savoir que c'est au moment de la connexion que la boite mail de l'utilisateur est crée à l'emplacement indiqué dans le fichier 10-mail.conf avec les paramètres renseignés dans le fichier 15-mailboxes.conf.
{{astuce|Vous pouvez [https://rtcamp.com/tutorials/mail/server/testing/smtp/ vérifier] si votre serveur [https://fr.wikipedia.org/wiki/Open_relay relaie ouvertement] les courriels sur Internet (il ne doit pas le faire) via l'outil <code>swaks</code> utilisée comme suit depuis un client :
swaks --server mail.exemple.fr --to toto@tutu.org
}}


<span style="color:red;">Expliquer comment configurer Sieve sur Rainloop et mettre des images.</span>
==Test de détection de pourriels==
Il est possible de simuler un courriel frauduleux en envoyant un message contenant la chaîne de caractère suivante :
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X


==Mise à jour de Rainloop==
Vous verrez dans le journal <code>/var/log/mail.log</code> la phrase <code>stored mail into mailbox 'Spam'</code> informant de l'application de la règle ''Sieve'' de rangement.
Le processus n'est pas très compliqué mais il y a un petit détail de merde qui fait facilement perdre du temps si on n'y fait pas attention.
# Télécharger la dernière version de Rainloop
# La décompresser dans le /tmp (3 éléments serons mis en bordel dedans)
# Copier le dossier "rainloop/v/N°VERSION" dans le même répertoire que la version de production (à coté de la version actuelle)
# Remplacer le numéro de version dans /var/www/rainloop/index.php
# Remplacer le numéro de version dans /var/www/data/VERSION
# (c'est là l'astuce) Donner les droits d’exécutions à la nouvelle version :
# chmod -R u+x /var/www/rainloop/rainloop/v/N°VERSION


=Messages d'erreurs connus=
Depuis votre client de messagerie, vous verrez le message précédemment envoyé placé dans la boite "indésirables".
Cette section regroupe quelques erreurs qui ont été rencontrés lors de la réalisation de cette documentation et observables dans le fichier de log
/var/log/mail.log


==loops back to myself==
=Débogage=
Message :
==Messages d'erreurs connus==
mail for exemple.fr loops back to myself
Cette section regroupe quelques erreurs qui ont déjà étés rencontrés et observables dans le fichier <code>/var/log/mail.log</code>.
Ce fripon m'a bien fait perdre du temps en plus de me faire prononcer des nom d'oiseaux. Il est due au fait que le nom de domaine du champ MX n'est pas renseigné dans le main.cf à au parametre "mydestination". Il faut donc avoir une ligne similaire à celle-ci :
mydestination = exemple.fr, localhost.exemple.fr, localhost


==postfix warning: SASL==
{| class="wikitable"
Message :
|-
postfix warning: SASL: Connect to private/auth failed: No such file or directory
! Message !! Signification
Cette merde ce produit lorsque le service dovecot à un problème (alors pourquoi c'est marqué "postfix warning SASL" ?????? Probablement pour nous induire en erreur...). Pour le régler il faut repasser tout les fichiers modifiés de dovecot au peigne fin. À savoir qu'un modit espace manquant peut générer un plantage du service au démarrage... Là est tout l'intéret de copier chaque fichier de conf avant modification en .old. De cette manière il est possible de revenir en arrière et on à une liste complète des fichiers à modifier en faisan un "ls | grep .old".
|-
| <code>mail for exemple.fr loops back to myself</code> || Le nom de domaine du champ MX n'est pas renseigné au paramètre "mydestination" dans le main.cf
|-
| <code>postfix warning: SASL: Connect to private/auth failed: No such file or directory</code> || Indique un problème avec ''Dovecot'' (gérant l'authentification). Il faut repasser dans les fichiers de configuration de celui-ci
|}


=Commandes utiles=
=Commandes utiles=
==Débogage==
==Affichage des configurations==
Afficher le contenu des logs relatifs aux services de messagerie
 
# tail -f /var/log/mail.log
{| class="wikitable"
Montrer le contenu du fichier main.cf par défaut (celui que les développeurs on fixés à l'installation). Ce n'est pas l'état du fichier après modifications mais cela permet de remettre les valeurs par défaut si on rencontre des problèmes
|-
# postconf -d
! Commande !! Signification
Montrer le contenu actuel du fichier main.cf sans les commentaire (utile pour poser des question dans des forum par exemple)
|-
# postconf -n
| <code>postconf -d</code> || Renvoie le contenu du fichier [[#Main.cf|main.cf]] par défaut
Afficher l’ensemble de la configuration de Dovecot
|-
  # doveconf -n
| <code>postconf -n</code> || Renvoie le contenu actuel du fichier [[#Main.cf|main.cf]] sans les commentaires
ou
|-
  # dovecot -n
| <code>postconf -p</code> || Renvoie la configuration totale de ''Postfix'', valeurs par défaut comprises
|-
| <code>doveconf -n</code> ou <code>dovecot -n</code> || Renvoie l'ensemble de la configuration de ''Dovecot''
|}
 
==Requêter la base de donnée==
Afin de tester les différents fichiers de liaison de la base de données ''SQLite'' à ''Postfix'', il est possible d'utiliser la commande <code>postmap</code> sous cette forme
  postmap -q chaine_à_tester sqlite:/etc/postfix/sqlite-FONCTION.cf
 
Pour vérifier l'existance d'un utilisateur ou d'un domaine, nous utiliserons la commande de cette façon
  postmap -q test@exemple sqlite:/etc/postfix/sqlite-utilisateurs.cf
postmap -q jmador.yo sqlite:/etc/postfix/sqlite-domaines.cf


==Gestion de la file d'attente de courrier==
==Gestion de la file d'attente de courrier==
La file d'attente de courrier de Postfix (mail queue) est l'endroit où sont stockés les emails en cours d'envoi/récéption ou qui sont revenu au serveur suite à un [[#bounce|bounce]]. Les commandes utiles permettant de la gérer sont les suivantes (tirées de [https://www.system-linux.eu/index.php?post/2009/01/27/Traitement-de-Queue-mail-Postfix ce document]) :
La file d'attente des messages de ''Postfix'' (''mail queue'') est l'endroit où sont stockés les courriels en cours d'envoi/réception ou qui sont revenus au serveur suite à un [[#Glossaire|message de non-délivrance]]. Les commandes utiles permettant de la gérer sont les suivantes (tirées de [https://www.system-linux.eu/index.php?post/2009/01/27/Traitement-de-Queue-mail-Postfix ce document]) :
 
{| class="wikitable"
|-
! Commande !! Signification
|-
| <code>postqueue -p</code> || Liste les messages en queue
|-
| <code>postsuper -d DBB3F1A7</code> || Supprime un message en queue
|-
| <code>postsuper -d ALL</code> || Supprime tous les messages en queue
|-
| <code>postsuper -h DBA3F1A7</code> || Mettre un messages en attente
|-
| <code>postsuper -H DBA3F1A7</code> || Remettre un messages en mode normale
|-
| <code>postsuper -r DBA3F1A7</code> || Remettre en queue un message
|-
| <code>postsuper -r ALL</code> || Remettre en queue tous les messages
|-
| <code>postcat -q DBA3F1A9</code> || Afficher le contenu d'un message
|-
| <code>postqueue -f</code> || Forcer l'envoi des messages en queue
|}
 
=Glossaire=
Le lexique entourant le domaine de la messagerie électronique est assez singulier. Voici quelques éléments de vocabulaire.


Lister les messages en Queue
==Rôles de messageries==
# postqueue -p
* Agent de Transport du Courriel ou ''MTA'' (''Mail Transport Agent'') : service chargé d'acheminer les courriels vers un service de distribution du courrier (''MDA''). Ce service est assuré par le protocole ''SMTP'' (utilisé par ''Postfix'' dans notre cas)
Supprimer un message en Queue
* Agent de Distribution du Courriel ou ''MDA'' (''Mail Delivery Agent'') : service chargé de déposer le courriel dans la boite aux lettres d'un utilisateur. Il s'occupe également des contraintes d'espace disque (quota, disque plein..) ou de corruption et prévient le ''MTA'' des erreurs de distribution. Cette tâche est assurée par les protocoles ''POP'', ''IMAP'' et ''JMAP'' (utilisés par ''Dovecot dans notre cas)
# postsuper -d DBB3F1A7
* Agent Utilisateur du Courriel ou ''MUA'' (''Mail User Agent'') : logiciel client de messagerie électronique (''Rainloop'', ''Roundcube'', ''Thenderbird'', ''Outlook''...) chargé de présenter les courriels aux utilisateurs et de permettre leur rédaction. Il parle directement au ''MDA'' pour les requêtes de réception et au ''MTA'' pour l'envoi de ses messages
Supprimer tous les messages en Queue
# postsuper -d ALL
Mettre un messages en attente (hold)
# postsuper -h DBA3F1A7
Remettre un messages en mode normale (actif)
# postsuper -H DBA3F1A7
Remettre en Queue un message
# postsuper -r DBA3F1A7
Pour tous les messages
# postsuper -r ALL
Afficher le contenu d'un message
# postcat -q DBA3F1A9
Forcer l'envoie des messages en Queue (flush)
# postqueue -f




=Glossaire=
==Protocoles mis en œuvre==
* ''Simple Mail Transfer Protocol'' ([https://fr.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol SMTP]) : protocole de communication utilisé pour transférer le courriel vers les serveurs de messagerie électronique
* ''Internet Message Access Protocol'' ([https://fr.wikipedia.org/wiki/Internet_Message_Access_Protocol IMAP]) : protocole permettant à un client d'accéder à ses courriels directement sur les serveurs de messagerie via un logiciel de consultation
* ''Transport Layer Security'' ([https://fr.wikipedia.org/wiki/Transport_Layer_Security TLS]) : protocole de négociation d'éléments secrets entre deux correspondant. Son objectif est de permettre l'établissement d'une communication sécurisée
* ''DomainKeys Identified Mail'' ([https://fr.wikipedia.org/wiki/DomainKeys_Identified_Mail DKIM]) : norme d'authentification fiable du nom de domaine de l'expéditeur d'un courriel. Permet également de garantir l'intégrité d'un message. Plus de détails sur ces balises [https://help.returnpath.com/hc/fr/articles/222481088-Aper%C3%A7u-du-DNS-record-pour-la-signature-DKIM ici]
** Selecteur : élément de l'en-tête ''DKIM'' indiquant l'emplacement de la clé dans la zone ''DNS'' du domaine. Cet élément est concaténé avec le domaine pour effectuer une requête de résolution comme vu [[#Enregistrement_DNS_DKIM|précédemment]]
* ''GNU Privacy Guard'' ([https://fr.wikipedia.org/wiki/GNU_Privacy_Guard GPG]) : implémentation libre du standard [https://fr.wikipedia.org/wiki/OpenPGP OpenPGP] permettant d'assurer la confidentialité et l'intégrité d'un message par un secret connu des seuls correspondants
* Milter : [http://www.postfix.org/MILTER_README.html extension] présente sous forme d'[https://fr.wikipedia.org/wiki/Interface_de_programmation interface de programmation] du ''MTA'' permettant d'intégrer un programme dans la file de traitement des courriels. C'est le mécanisme qui nous permet de traiter les pourriels ainsi que les signatures ''DKIM'' mais peut aussi servir à l'analyse [https://www.clamav.net/ anti-virale]
* ''Domain Name System'' ([https://fr.wikipedia.org/wiki/Domain_Name_System DNS]) : service d'annuaire distribué stockant des informations textuelles dans des enregistrements de différents types
** Enregistrement de type ''A'' et ''AAAA'' : fournit la correspondance entre un nom d'hôte et une adresse ''IP'' (respectivement version 4 et version 6)
** Enregistrement de type ''MX'' : fournit la correspondance entre le nom d'hôte du serveur de messagerie et un domaine. La concaténation de ces deux informations donne le nom pleinement qualifié (''FQDN'') et permet aux ''MTA'' distants de résoudre l'adresse ''IP'' du serveur de destination d'un messsage avec comme seule information le domaine de destination contenu dans le champ ''X-Original-to'' d'un courriel
** Enregistrement de type ''TXT'' : champ de texte libre destiné principalement à rendre le ''DNS'' fléxible aux nouveaux usages. Un autre protocole n'a alors qu'à lire le contenu du champ pour obtenir l'information à traiter selon un formatage qu'aura respecté son rédacteur
* ''Local Mail Transfer Protocol'' ([https://fr.wikipedia.org/wiki/Local_Mail_Transfer_Protocol LMTP]) : protocole ''SMTP'' simplifié destiné aux seuls échange de courriels entre utilisateurs d'un même ''MTA''


=Sources=


Mail queue : https://www.system-linux.eu/index.php?post/2009/01/27/Traitement-de-Queue-mail-Postfix
==Divers==
* Pourriel ou ''SPAM'' : message non désiré et souvent nuisible (hameçonnage, virus, arnaque...). Ils viennent rarement seuls car leurs expéditeurs ont pour habitude d'en envoyer massivement. les pourriels représentaient tout de même entre [https://fr.wikipedia.org/wiki/Spam#Spam_publicitaire 90 et 97%] du trafic total des courriels fin des années 2000. L'[https://fr.wikipedia.org/wiki/Spam#Origine_du_terme_%C2%AB_spam_%C2%BB origine du mot] ''SPAM'' provient d'une marque de viande dont les pratiques publicitaires se rapprochaient de la pratique moderne. Sur un serveur personnel, il reste tout de même assez simple de s'en prémunir en respectant une politique stricte de transmission de vos adresses ([[#Cr.C3.A9ation_des_fichiers_d.27exploitation_de_Postfix|alias]]).
* ''HAM'' : désigne les courriels désirés. Cette notion est utilisée par le logiciel anti-pourriels ''Spamassassin'' lors de son usage de l'[https://fr.wikipedia.org/wiki/Inf%C3%A9rence_bay%C3%A9sienne inférence bayésienne]. Le terme est issue d'une partie du jambon en référence aux origines du mot ''SPAM'' et représente son opposé
* Boites aux lettres (BAL) : répertoire de messagerie personnelle d'un utilisateur destinée à accueillir ses correspondances (répertoire <code>~/Maildir</code> de la documentation)
* Message de non-délivrance ([https://www.altospam.com/glossaire/bounce.php bounce]) : courrier émis par un ''MTA'' à l'émetteur d'un message lorsque celui-ci n'a pu être délivré afin de l'en informer
* Relais de courrier ouvert : serveur ''SMTP'' permettant à n'importe qui sur Internet d'envoyer un courriel par son intermédiaire
* Liste noire en temps réel ([https://www.altospam.com/glossaire/listes-noires.php Realtime Blackhole List] ou ''RBL'') : listes de serveurs ou de réseaux IP connus pour aider, accueillir, produire ou retransmettre des pourriels ou fournir un service pouvant en émettre (relais ouverts)

Dernière version du 27 janvier 2024 à 12:48


Postfix est un serveur de messagerie électronique se chargeant de la livraison de courriels sur un réseau IP. Il a été conçu comme une alternative plus rapide, plus facile à administrer et plus sécurisée que l'historique Sendmail.

L'environnement gravitant autour de ce thème étant assez complexe (avec son lot de technologies et de termes spécifiques), un glossaire des notions utiles a été rédigé en bas de page. Il est recommandé d'aller y jeter un œil si vous n'êtes pas très familier avec le sujet.

Dans ce document, nous mettrons en place :

  • Le service de courrier électronique Postfix avec support d'IPv4/IPv6, négociation de chiffrement via TLS et STARTTLS, utilisateurs Postfix et gestion de domaines via SQLite, authentification SASL, gestion des alias, des domaines secondaires, des listes noires ainsi que de Milter pour les liaisons avec OpenDKIM et Spamassassin
  • Le service IMAP Dovecot avec gestion d'IPv4/IPv6, du TLS et de STARTTLS ainsi que des filtres Sieve
  • La signature des messages via le protocole DKIM par l’intermédiaire du logiciel OpenDKIM
  • Du traitement du pourriel avec SpamAssassin


Il faudra vous assurer d'avoir la main sur les éléments suivants :

  • Prérequis :
    • Debian 11 (Bullseye)
    • Un nom de domaine avec un enregistrement MX et A
    • Une adresse IP publique fixe avec possibilité d'enregistrement PTR
  • Permettre la communication en écoute des ports TCP suivants :
    • 25 (SMTP)
    • 465 (SMTP sur TLS aussi appelé Submission)
    • 587 (SMTP STARTTLS)
    • 143 (IMAP)
    • 993 (IMAPS)

INFORMATION

J'attire votre attention sur l'importance d'avoir un opérateur Internet faisant correctement son travail (ce qui commence à se faire rare en France...). Il est indispensable d'avoir une adresse IP fixe non listés par les principaux prestataires anti-pourriels (voir https://mxtoolbox.com/blacklists.aspx) ainsi que la possibilité d'ajouter un champ PTR (DNS inversé ou reverse DNS) dans le registre de nom de votre FAI. Sans ces pré-requis, votre service sera difficilement fiable car une partie de vos messages risquent d'être bloqués par les serveurs destinataires. Si vous ne pouvez souscrire à un vrai accès Internet (avec un fournisseur sachant ce qu'est une adresse IP au lieu de vous fournir de la TV...) comme ceux proposés par la FFDN ou K-net par exemple, il faudra vous tourner vers des hébergeurs en centre de données et opter pour un hébergement de votre serveur dans leurs locaux ou réaliser un tunnel afin d'utiliser leur IP chez vous (l'auto-hébergement étant la solution à privilégier dans une optique d'indépendance numérique).

Nom de domaine

Prérequis DNS

La messagerie électronique étant dépendante du système de noms de domaine (DNS), il vous en faudra un et y définir un enregistrement de type MX afin d'assurer la distribution de votre courrier.

La façon de configurer les champs de votre zone DNS étant propre à votre fournisseur de noms, nous ne détaillerons pas cette partie. Sachez seulement que l'enregistrement associant votre nom d'hôte (le champ A pointant sur votre IP publique) et votre nom de domaine (à ne pas confondre avec le nom de domaine pleinement qualifié (FQDN)) devra être configuré pour espérer envoyer et recevoir des courriels.

Il vous faudra donc, pour démarrer, un nom de domaine avec un champ A et MX (minimum obligatoire) auquel nous ajouterons, par la suite, un enregistrement TXT SPF et DKIM (facultatifs) afin de diminuer vos chances de finir dans les indésirables de vos destinataires.

Enfin, et toujours dans un soucis de limiter le désagrément susmentionné, il faudra que vous adressiez une demande à votre fournisseur d'accès Internet pour ajouter votre FQDN à sa zone DNS inversée (ajout d'un champ de type PTR). Ce point est le plus délicat car plus aucun "grands" FAI connus ne le permet en France (en 2021). Free ne propose plus l'option depuis 2019 (bien que toujours présente dans leur interface WEB, celle-ci ne fonctionne plus depuis la migration de leur infrastructure vers IPv6) et font les morts lorsqu'ils sont contactés à ce sujet ; SFR et Bouygues Telecom ne sont plus que des fournisseurs de services audiovisuels et Orange ne sais même pas ce qu'est une adresse IP fixe (même v6...) alors du rDNS... Internet étant réservé aux professionnels selon leur doctrine malgré leur service d'amateur...

Installation des outils

apt update && apt install --no-install-recommends openssl dnsutils

Test de fonctionnement du champ MX

dig exemple.fr MX

La réponse doit contenir une ANSWER SECTION avec ceci :

exemple.fr	10800	IN	MX	10	mail.exemple.fr

Test de fonctionnement du champ A

dig mail.exemple.fr A

La réponse doit contenir une ANSWER SECTION avec ceci :

mail.exemple.fr.	<TTL>	IN	A	<VOTRE_IP_PUBLIQUE>

Cas du NAT

Si votre serveur est placé juste derrière un NAT, il faudra ajouter une entrée dans votre fichier /etc/hosts afin de lui permettre de se résoudre lui-même. Ceci prendra la forme suivante :

<IP_du_serveur>	<FQDN>

Éléments secrets

Comme tout moyen de communication moderne, les correspondances extérieurs seront chiffrées via des algorithmes négociés au travers du traditionnel protocole de sécurité de la couche transport (TLS). La génération d'éléments secrets se fera par le fameux logiciel libre OpenSSL que l'on ne présente plus. Nous avons pris le parti de réutiliser ces éléments secrets dans l'ensemble des outils faisant intervenir le chiffrement du système de messagerie. Dans l'idéal, un certificat différent doit être utilisée pour chaque module en nécessitant, conformément à la recommandation numéro 30 (page 46) du guide de recommandation de sécurité relative à TLS (v1.2) des bonnes pratiques de l'ANSSI.

Création du répertoire d'accueil pour les clés et le certificat x.509

mkdir -p /etc/postfix/tls

Génération du certificat et de la clé pour Postfix et Dovecot

openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -out /etc/postfix/tls/courriel.pem -keyout /etc/postfix/tls/courriel.key

Pour cette étape, Letsencrypt peut très bien être utilisé mais sachez que contrairement au WEB, le monde de la messagerie ne vérifie aucunement l'authenticité des certificats (ce qui rend de fait, le chiffrement caduc en cas d'espionnage ciblé...). Il n'est donc pas dérangeant d'utiliser des certificats auto-signés avec une durée de validité démentielle... Pour une confidentialité forte des échanges (en complément de TLS), tournez-vous plutôt vers le protocole PGP qui peut notamment, en plus d'une exploitation manuelle entre deux clients, être utilisé automatiquement avec Postfix via le module gpgmail.

Génération de la clé Diffie-Hellman (si l'on ne le fait pas, Postfix utilise la sienne)

openssl dhparam -out /etc/postfix/tls/dh4096.pem 4096

INFORMATION

Avec l'évolution des suites cryptographiques, il devient de plus en plus rare d'utiliser Diffie-Hellman (au travers des suites DHE). Avec l’avènement de la faille Racoon attack, ce protocole est devenu désuet et peu sûr. L'usage de la cryptographie basée sur les courbes elliptiques (ECC) pour l'échange de clés de sessions l'a, dans la pratique, remplacé (notamment via ECDHE et ed25519). Néanmoins (et vous vous en apercevrez peut-être à vos dépends), le monde de la messagerie électronique accuse d'un lourd héritage technologique et d'installations vieillissantes administrées, ou pas, par des gens généralement peu regardants sur l'évolution des standards et dont le principe de veille informatique échappe totalement. Aussi, il n'est pas rare (coucou Orange, une fois de plus...) de devoir supporter des algorithmes et protocoles complètements dépassés pour pouvoir continuer d'échanger avec certains serveurs non mis à jours depuis plusieurs décennies...

Postfix

Comme présenté en début de page, Postfix est l'élément central de notre système de messagerie électronique. Il endosse le rôle de MTA tout en faisant le lien avec les autres composants de l'installation. S'il peut sembler austère à première vue, la complexité de sa configuration est à la hauteur du service qu'il rend car il n'est pas exagéré de dire que la messagerie est la pierre la plus importante d'un auto-hébergement. Logiciel fiable et très personnalisable, c'est l'un des composants qui, une fois mis en place, se fait le plus oublié dans une infrastructure numérique domestique.

Installation de Postfix

Installation du serveur SMTP

apt install --no-install-recommends postfix

Note : Les réponses aux choix proposés n'ont guère d'importance puisque elles ne font que remplir un fichier que nous remplacerons par la suite.

Configuration de Postfix

La configuration principale de Postfix se fait par l'intermédiaire du fichier main.cf qui renseigne un petit sous-ensemble des paramètres contrôlant les opérations du système de messagerie. Les paramètres non explicitement renseignés sont initialisés avec leur valeur par défaut. Les paramètres appliqués explicitement par l'intermédiaire de ce fichier sont visibles après rechargement du service via la commande postconf -n. La commande postconf -p permet quand à elle de visualiser la totalité des paramètres appliqués, y compris ceux par défaut.

Main.cf

Édition du fichier de configuration principal

vim /etc/postfix/main.cf

La configuration suivante sera utilisée :

# smtpd : entrant/inbound                                                                                  
# smtp : sortant/outbound

# ------------------------------------ Connexion protocole SMTP ------------------------------------ #

# Bannière affichée après le code 220 lorsque l'on se connecte en SMTP sur le serveur
smtpd_banner            = $myhostname ESMTP $mail_name
# Désactive la commande SMTP VRFY. Ceci a pour effet d'empêcher de trouver les adresses existante sur le serveur
disable_vrfy_command    = yes
# Impose au client SMTP de démarrer la session SMTP par une commande Helo ou ehlo (cette dernière servant au listage des capacités du serveur)
smtpd_helo_required     = yes

# ------------------------------------ Gestion des messages locaux (inutile dans notre cas) ------------------------------------ #

# Service qui envoie des notifications "nouveau message"
biff                    = no
# Avec le courrier local ça ajoute .NDD aux adresses incomplètes (seulement le nom d'hôte)
append_dot_mydomain     = no

# ------------------------------------ Nom de machine et réseaux autorisés ------------------------------------ #

# Le nom de la machine du système de messagerie
# Par défaut c'est hôte.domaine.tld mais il est possible de mettre un nom de domaine inversé
myhostname              = mail.exemple.fr
# Le domaine utilisé par défaut pour poster les messages
myorigin                = mail.exemple.fr
# Liste des domaines pour lesquels le serveur doit accepter le courrier en local
mydestination           = mail.exemple.fr, localhost.exemple.fr, localhost
# Relais par lequel notre serveur doit adresser son trafic (nous n'en utilisons aucun)
relayhost               =
# Liste des réseaux locaux autorisés (leur permet d'outrepasser le SASL)
mynetworks              = 192.168.0.0/16, 127.0.0.0/8
# Activation d'IPv4 et IPv6 (valeur par défaut)
inet_protocols          = all
# Séparateur entre le nom d'utilisateur et les extensions d'adresses
recipient_delimiter     = +
# Les utilisateurs locaux ne pourront pas envoyer de messages à "utilisateur@nom-de-domaine-partiel" mais devront spécifier le nom de domaine complet
append_dot_mydomain     = no
# Interfaces réseaux à écouter (ici toutes)
inet_interfaces         = all

# ------------------------------------ Règles SMTP ------------------------------------ #

# Restrictions d'accès appliquées dans le contexte d'une commande RCPT TO
# permit_mynetworks : Autorise les requêtes si l'IP du client correspond à l'un des réseaux spécifiés dans $mynetworks
# permit_sasl_authenticated : Accepter la connexion lorsque le client est authentifié
# reject_non_fqdn_recipient : Rejette la requête lorsque l'adresse RCPT TO n'est pas de forme pleinement qualifiée (FQDN) 
# reject_unauth_destination : Rejette la requête sauf si l'une des propositions listés dans la documentation officielle est vraie
# check_recipient_access : Rejette les messages à destination des adresses spécifiées dans le fichier correspondant (permet de ne pas envoyer de message à root)
# reject_unknown_recipient_domain : Rejette la requête lorsque le RCPT TO ne correspond à aucun champ DNS A ou MX
smtpd_recipient_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_non_fqdn_recipient,
        reject_unauth_destination,
        check_recipient_access sqlite:/etc/postfix/sqlite-liste-noire-destinataires.cf,
        reject_unknown_recipient_domain,

# Règles sur l'échange HELO qui survient avant la connexion
# permit_mynetworks : Autorise les requêtes si l'IP du client correspond à l'un des réseaux spécifiés dans $mynetworks
# reject_invalid_helo_hostname : Refuser les échanges HELO invalides
# reject_non_fqdn_helo_hostname : Refuser les noms d'hôte invalides (non FQDN)
# reject_unknown_helo_hostname : Refuser les noms d'hôte qui n'ont pas de champ DNS A ou MX dans leurs DNS 
smtpd_helo_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_invalid_helo_hostname,
        reject_non_fqdn_helo_hostname,
        # reject_unknown_helo_hostname

# Règles de connexion des clients
# permit_mynetworks : Autorise les requêtes si l'IP du client correspond à l'un des réseaux spécifiés dans $mynetworks
# permit_inet_interfaces : Accepte les requêtes des clients entrants par les interfaces listés dans $inet_interfaces
# permit_sasl_authenticated : Accepter la connexion lorsque le client est authentifié
# reject_rbl_client : Refuse les connexion des clients (IP) listés dans une liste RBL suite à des envois massifs de pourriels
# reject_plaintext_session : Refuser les connexions non chiffrés
# reject_unauth_pipelining : Vérifie si le drapeau de l'indicateur de session a été activé par Postfix. Si tel est le cas, cela signifierai que le client a utilisé une canalisation ESMTP incorrecte, ce qui est une justification suffisante pour le rejeter.
smtpd_client_restrictions =
        permit_mynetworks,
        permit_inet_interfaces,
        permit_sasl_authenticated,
        # reject_rbl_client zen.spamhaus.org
        # reject_plaintext_session,
        # reject_unauth_pipelining # L'utilisation de reject_unauth_pipelining dans les autres contextes que smtpd_data_restrictions n'est pas recommandé

# Règles sur les expéditeurs
# reject_non_fqdn_sender : Refuser les expéditeurs invalides (non FQDN)
# reject_unknown_sender_domain : Refuser les expéditeurs qui n'ont pas de champ DNS A ou MX dans leurs DNS 
# check_sender_access : Vérifie si l'adresse de courriel de l'expéditeur est dans notre fichier liste noire et applique la directive de celle-ci
smtpd_sender_restrictions =
        reject_non_fqdn_sender,
        reject_unknown_sender_domain,
        check_sender_access sqlite:/etc/postfix/sqlite-liste-noire-expediteurs.cf

# Restrictions d'accès optionnelles appliquées dans le contexte d'une commande SMTP DATA
# reject_unauth_pipelining : Expliqué plus haut (trop long)
# permit : Tout est autorisé par défaut
smtpd_data_restrictions =
        reject_unauth_pipelining,
        permit

# ------------------------------------ Gestion des boites aux lettres et des messages ------------------------------------ #

# Taille des boîtes aux lettres (0 = illimité)
mailbox_size_limit      = 0 

# Fixer la taille limite des messages (ici 30Mo)
message_size_limit      = 31457280

# Répertoire de destination des courriers
# home_mailbox            = Maildir/
virtual_mailbox_domains = sqlite:/etc/postfix/sqlite-domaines.cf
virtual_mailbox_base    = /var/mail/utilisateurs
virtual_mailbox_maps    = sqlite:/etc/postfix/sqlite-utilisateurs.cf
virtual_minimum_uid     = 3000
virtual_uid_maps        = static:3000
virtual_gid_maps        = static:3000
virtual_transport       = lmtp:unix:private/dovecot-lmtp

#----------------------------------------------
# Gestion des alias de comptes et de domaines |
#----------------------------------------------

# Emplacement du fichier des alias
# Alias de comptes principaux
alias_maps              = sqlite:/etc/postfix/sqlite-alias.cf

# Alias de domaines
virtual_alias_maps      = sqlite:/etc/postfix/sqlite-alias-vituels.cf
# virtual_alias_domains = sqlite:/etc/postfix/sqlite-domaines.cf

#--------------------
# SASL serveur SMTP |
#--------------------

# Authentification SMTP (utilise les identifiants IMAP via SASL en passant par Dovecot)
smtpd_sasl_auth_enable  = yes
smtpd_sasl_type         = dovecot
smtpd_sasl_path         = private/auth
# Interdit les méthodes qui autorisent l'authentification anonyme
smtpd_sasl_security_options     = noanonymous
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
smtpd_sasl_local_domain         = $mydomain
# Reporte le nom d'utilisateur SASL authentifié dans l'en-tête de message "Received" du serveur
smtpd_sasl_authenticated_header = yes
# N'accepte pas le support de l'ancienne commande AUTH (Outlook 4 par exemple)
broken_sasl_auth_clients        = no

# ------------------------------------ Chiffrement ------------------------------------ #

# clés et certificats pour les sessions TLS
smtpd_tls_cert_file             = $config_directory/tls/courriel.pem
smtpd_tls_key_file              = $config_directory/tls/courriel.key
smtpd_tls_dh1024_param_file     = $config_directory/tls/dh4096.pem

#------------------
# TLS client SMTP |
#------------------

# Verbosité des journaux
smtp_tls_loglevel               = 1
# Impose de se connecter à des serveurs SMTP via TLS
smtp_tls_security_level         = encrypt
# N'autoriser que le TLS version 1.2 et 1.3
smtp_tls_protocols              = TLSv1.2:TLSv1.3
# incompréhension exprimé plus haut
smtp_tls_mandatory_protocols    = TLSv1.2:TLSv1.3
# Journaliser les pairs ne gérants que STARTTLS au lieu de TLS. Probablement pour permettre de réaliser des statistiques
smtp_tls_note_starttls_offer    = yes
# N'autoriser que les chiffrements de la liste "medium" définie plus bas
smtp_tls_mandatory_ciphers      = medium
# Exclure les algorithmes cryptographiques obsolètes ou insuffisants listés ci-dessous
smtp_tls_exclude_ciphers        = aNULL, eNULL, EXPORT, DES, 3DES, RC2, RC4, MD5, PSK, SRP, DSS, AECDH, ADH
# Permet d'obliger le client à se conformer à la suite cryptographique du serveur et non l'inverse
tls_preempt_cipherlist          = yes
# Cache TLS. Permet de mémoriser les anciennes sessions TLS afin d'effectuer une poignée de mains raccourcie. Ce qui améliore considérablement les performances
# Inutile avec TLS 1.3 car compris dans la norme
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

#-------------------
# TLS serveur SMTP |
#-------------------

# Verbosité des journaux
smtpd_tls_loglevel              = 1 
# Impose de se connecter à des serveurs SMTP via TLS
smtpd_tls_security_level        = encrypt
# Refuse les authentifications SASL en clair si le serveur gère TLS de façon optionnelle (ça n'a aucun sens mais c'est ce qui est écrit dans la documentation officielle)
smtpd_tls_auth_only             = yes
# Indique le chiffrement utilisé dans l'en-tête du message (ça ne sert pas à grand chose si on passe par plusieurs serveurs car les intermédiaires peuvent y mettre leur sauce donc ce n'est qu'indicatif)
smtpd_tls_received_header       = yes
# Source du générateur de nombre aléatoire pour les algorithmes de chiffrement
tls_random_source               = dev:/dev/urandom
# Versions de TLS autorisés (SSL refusé)
smtpd_tls_protocols             = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1, TLSv1.2, TLSv1.3
# Toujours aucune idée de l'utilité mais c'est activé par défaut de toute façon d'après la documentation
smtpd_tls_mandatory_protocols   = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1, TLSv1.2, TLSv1.3
# N'autoriser que les chiffrements de la liste "medium" définie plus bas
smtpd_tls_mandatory_ciphers = medium
# Liste de chiffrements autorisés dans la liste "medium" exploité par "smtp_tls_mandatory_ciphers" et "smtpd_tls_mandatory_ciphers"
tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
# Exclure les algorithmes obsolètes ou insufisants listés ci-dessous
smtpd_tls_exclude_ciphers        = aNULL, eNULL, EXPORT, DES, 3DES, RC2, RC4, MD5, PSK, SRP, DSS, AECDH, ADH
# Cache TLS. Permet de mémoriser les ancienne sessions TLS afin d'effectuer une poignée de mains raccourcie. Ce qui améliore considérablement les performances
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache

# ------------------------------------ En-têtes des courriels ------------------------------------ #

# Emplacement des fichiers de suppression de certains en-têtes à caractère privé contenus dans les messages envoyés
# Concrètement, cela supprime toute la section "Received: from" propre au client (contenant son IP par exemple) -> son SMTP. Seul le "Received: from" son SMTP -> SMTP distant reste
mime_header_checks              = regexp:/etc/postfix/header_checks
header_checks                   = regexp:/etc/postfix/header_checks

# ------------------------------------ OpenDKIM et Spamassassin ------------------------------------ #

# Procédez comme si le filtre de courrier n'était pas présent
milter_default_action = accept
# Version du protocole mail filter
milter_protocol = 6

# Chemins des sockets pour la communication avec les modules opendkim et spamass
smtpd_milters = unix:/var/run/opendkim/opendkim.sock unix:/spamass/spamass.sock
non_smtpd_milters = unix:/var/run/opendkim/opendkim.sock unix:/spamass/spamass.sock

# ------------------------------------ Sources de documentation ------------------------------------ #

# http://postfix.traduc.org/index.php/postconf.5.html
# http://www.postfix.org/postconf.5.html

N'oubliez pas d'adapter les réseaux autorisés de la section mynetworks ainsi que le nom de domaine à votre installation. Vous pouvez utiliser la commande sed comme suit pour vous aider :

sed -i 's/exemple\.fr/domaine\.fr/g' /etc/postfix/main.cf

Si vous voulez afficher pour comparaison la suite cryptographique MEDIUM d'OpenSSL avec le paramètre tls_medium_cipherlist définit dans le fichier, vous pouvez utiliser la commande suivante :

openssl ciphers MEDIUM | sed 's/:/\n/g'

En-têtes vie privée

On va créer une liste d'expressions régulières servant à supprimer automatiquement certains en-têtes contenant des informations personnelles sur le client émetteur lors de l'envoi du courriel (diminue la quantité d'informations personnelles transmises)

cat << '_EOF_' > /etc/postfix/header_checks
/^Received:.*with ESMTPSA/  IGNORE
/^X-Originating-IP:/        IGNORE
/^X-Mailer:/                IGNORE
/^User-Agent:/              IGNORE
_EOF_

Les directives contenues dans la section "En-têtes des courriels" du fichier main.cf édité ci-dessus indiquent à Postfix l'emplacement de ces règles

mime_header_checks              = regexp:/etc/postfix/header_checks
header_checks                   = regexp:/etc/postfix/header_checks

Pour que Postfix les utilises, il faut reconstruire la table au format hachée avec la commande

postmap /etc/postfix/header_checks

Master.cf

Postfix est un outil dont le fonctionnement sous jacent est complexe et composé de multiples programmes (démons) ayants chacun leur rôle. Le fichier master.cf permet de gérer la façon dont se comportent les différents éléments du système de courrier.

Le fichier se présente sous forme de tableau. Postfix va le parcourir et interpréter chaque lignes, correspondants à un démon, colonne par colonne (avec leur signification en en-tête commenté). Voici le contenu du fichier par défaut, épuré de ses commentaires pour ne pas alourdir l'exposé :

smtp      inet  n       -       y       -       -       smtpd
pickup    unix  n       -       y       60      1       pickup
cleanup   unix  n       -       y       -       0       cleanup
qmgr      unix  n       -       n       300     1       qmgr
tlsmgr    unix  -       -       y       1000?   1       tlsmgr
rewrite   unix  -       -       y       -       -       trivial-rewrite
bounce    unix  -       -       y       -       0       bounce
defer     unix  -       -       y       -       0       bounce
trace     unix  -       -       y       -       0       bounce
verify    unix  -       -       y       -       1       verify
flush     unix  n       -       y       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       y       -       -       smtp
relay     unix  -       -       y       -       -       smtp
        -o syslog_name=postfix/$service_name
showq     unix  n       -       y       -       -       showq
error     unix  -       -       y       -       -       error
retry     unix  -       -       y       -       -       error
discard   unix  -       -       y       -       -       discard
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       y       -       -       lmtp
anvil     unix  -       -       y       -       1       anvil
scache    unix  -       -       y       -       1       scache
postlog   unix-dgram n  -       n       -       1       postlogd
maildrop  unix  -       n       n       -       -       pipe
  flags=DRXhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
uucp      unix  -       n       n       -       -       pipe
  flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
ifmail    unix  -       n       n       -       -       pipe
  flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp     unix  -       n       n       -       -       pipe
  flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix -       n       n       -       2       pipe
  flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman   unix  -       n       n       -       -       pipe
  flags=FRX user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py ${nexthop} ${user}

L'opération consiste à ajouter un socket TCP pour les communications STARTTLS et SMTPS ainsi qu'un socket UNIX pour la communication avec Dovecot. Le chemin de l'exécutable de ce dernier sera lui aussi précisé en sous-section. Nous ajouterons donc en fin de fichier les trois sections suivantes :

cat << '_EOF_' >> /etc/postfix/master.cf

submission inet n       -       y       -       -       smtpd
smtps     inet  n       -       y       -       -       smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
_EOF_

Il est possible de spécifier des paramètres au différentes lignes via l'argument -o (répétable plusieurs fois). Placés ici, ils réécrivent les paramètres correspondants du fichier main.cf et leur sont donc prioritaires. Ces arguments pourraient toutefois être placés dans ce dernier (cela reviendrait au même).

SQLite

Comme vous l'avez probablement constaté, certaines fonctionnalités utiliserons une base de données SQLite (il est également possible de passer par d'autres méthode). Cette technologie a le mérite d'être légère et de permettre la connexion d'outils tiers pour l'édition des données contenues dans la base. Avec la méthode des tables hachées utilisée auparavant, un accès root combiné à des bidouilles pas très sécurisées étaient nécessaires afin de les éditer sans devoir se connecter manuellement au serveur.

Cette section traite de la création de la base ainsi que des fichiers d'exploitation pour Postfix.

Installation et création de la base

Installation de SQLite

apt install --no-install-recommends sqlite3 postfix-sqlite

Création du schéma de la base

cat << '_EOF_' > /etc/postfix/postfix.sql
CREATE TABLE IF NOT EXISTS postfix_alias (
       id INTEGER PRIMARY KEY AUTOINCREMENT,
       alias TEXT NOT NULL UNIQUE,
       destination TEXT NOT NULL,
       active INTEGER
);
CREATE TABLE IF NOT EXISTS postfix_alias_virtuels (
       id INTEGER PRIMARY KEY AUTOINCREMENT,
       courriel TEXT NOT NULL UNIQUE,
       destination TEXT NOT NULL,
       active INTEGER
);
CREATE TABLE IF NOT EXISTS postfix_domaines (
       id INTEGER PRIMARY KEY AUTOINCREMENT,
       domaine TEXT NOT NULL UNIQUE,
       defaut BOOLEAN NOT NULL CHECK (defaut IN (0, 1)),
       active INTEGER
);
CREATE TABLE IF NOT EXISTS postfix_liste_noire_destinataires (
       id INTEGER PRIMARY KEY AUTOINCREMENT,
       courriel TEXT NOT NULL UNIQUE,
       action TEXT NOT NULL,
       active INTEGER
);
CREATE TABLE IF NOT EXISTS postfix_liste_noire_expediteurs (
       id INTEGER PRIMARY KEY AUTOINCREMENT,
       courriel TEXT NOT NULL UNIQUE,
       code_retour INTEGER NOT NULL,
       message TEXT NOT NULL,
       active INTEGER
);
CREATE TABLE postfix_utilisateurs (
       id INTEGER PRIMARY KEY AUTOINCREMENT,
       utilisateur TEXT NOT NULL UNIQUE,
       mot_de_passe TEXT NOT NULL,
       nom_complet TEXT,
       rep_perso TEXT NOT NULL,
       uid INTEGER NOT NULL,
       gid INTEGER NOT NULL,
       privilege TEXT NOT NULL,
       prefixe TEXT,
       active INTEGER
);
_EOF_

Création de la base avec ce schéma

mkdir /etc/postfix/bdd/
# Pour un usage avec le portail WEB Courtail (voir plus bas), il faudra donner les permission de ce répertoire et de la base à www-data
sqlite3 /etc/postfix/bdd/postfix.sqlite < /etc/postfix/postfix.sql

Création des fichiers d'exploitation de Postfix

Ces fichiers permettent à Postfix d'avoir les éléments lui permettant d'exploiter la base. Nous y retrouverons donc naturellement l'emplacement de celle-ci ainsi que la requête à lui soumettre afin d'obtenir l'information voulue.

Liaison à la table des alias

cat << '_EOF_' > /etc/postfix/sqlite-alias.cf
# Chemin de la base SQLite
dbpath = /etc/postfix/bdd/postfix.sqlite
# Requête passée à SQLite
query = SELECT destination FROM postfix_alias WHERE alias='%s' AND active='1'
_EOF_

Liason à la tables alias virtuels

cat << '_EOF_' > /etc/postfix/sqlite-alias-vituels.cf
# Chemin de la base SQLite
dbpath = /etc/postfix/bdd/postfix.sqlite
# Requête passée à SQLite
query = SELECT destination FROM postfix_alias_virtuels WHERE courriel='%s' AND active='1'
_EOF_

Les alias peuvent êtres utiles lors d'inscriptions sur des sites tiers ou d'une communication à des personnes de moyenne confiance. Le principe étant que les courriels envoyés sur ces adresses (connues uniquement des entités pour lesquelles elles ont étés créées) sont redirigés en interne vers votre vraie boite liée à l'alias. L'adresse de l'émetteur peut donc, par la stratégie que vous mettrez en place dans la diffusion de vos alias, être liée à une adresse de votre base et donc identifier une source d'émission. L'intérêt est double : lors de la réception de pourriels sur celui-ci, nous savons quelle entité l'a transmis ou utilisé puisqu'il est unique à chaque interlocuteur. Une action de désactivation de l'alias suivie d'un boycott et d'une possible plainte à la CNIL pour manquement au RGPD peut ainsi être entreprise.

Si cette fonctionnalité est utilisé sérieusement, le risque de pourriels (SPAM) est quasiment nul. Couplé aux règles Sieve abordées plus loin dans la documentation, les alias vont être très utiles afin de classer les courriels reçus automatiquement dans des dossiers et ne pas se retrouver avec les éternelles boite de réception à plus de 2000 messages "non lus". En clair, vous ne subirez plus votre messagerie comme c'est, hélas, bien trop souvent le cas.

INFORMATION

La différence entre les alias et les alias virtuelles réside dans l'en-tête Delivered-To du message à la réception par Postfix. Avec les alias, l'en-tête est inchangé lors de la distribution du message à la boite locale (et correspond donc à l'en-tête to du même message). Avec les alias virtuels, l'en-tête est modifié par l'adresse réelle de destination (inconnue de l'expéditeur). Dans les deux cas, cela n'influence pas l'acheminement du courrier mais les alias virtuelles permettent la distribution sur des domaines secondaires quand les alias se restreignent au seul domaine par défaut. Vous pouvez utiliser l'un et l'autre ou seulement l'un des deux (cela ne change rien aux bénéfices apportés à la fonctionnalité).

Le champ destination doit être l'adresse réelle de l'utilisateur.

Liaison à la table des domaines

cat << '_EOF_' > /etc/postfix/sqlite-domaines.cf
# Chemin de la base SQLite
dbpath = /etc/postfix/bdd/postfix.sqlite
# Requête passée à SQLite
query = SELECT domaine FROM postfix_domaines WHERE domaine='%s' AND active='1'
_EOF_

Liaison à la table de la liste noire des destinataires

cat << '_EOF_' > /etc/postfix/sqlite-liste-noire-destinataires.cf
# Chemin de la base SQLite
dbpath = /etc/postfix/bdd/postfix.sqlite
# Requête passée à SQLite
query = SELECT action FROM postfix_liste_noire_destinataires WHERE courriel='%s' AND active='1'
_EOF_

Liaison à la table de la liste noire des expéditeurs

cat << '_EOF_' > /etc/postfix/sqlite-liste-noire-expediteurs.cf
# Chemin de la base SQLite
dbpath = /etc/postfix/bdd/postfix.sqlite
# Requête passée a SQLite
query = SELECT code_retour || ' ' || message FROM postfix_liste_noire_expediteurs WHERE courriel='%s' AND active='1'
_EOF_

Liaison à la table des utilisateurs

cat << '_EOF_' > /etc/postfix/sqlite-utilisateurs.cf
# Chemin de la base SQLite
dbpath = /etc/postfix/bdd/postfix.sqlite
# Requête passée à SQLite
query = SELECT rep_perso FROM postfix_utilisateurs WHERE utilisateur='%s' AND active='1'
_EOF_

Administration de la base

Afin d'ajouter, modifier, supprimer et lister des informations dans la base SQLite, le shell intégré à l'outil est une bonne première approche. Par la suite, un logiciel plus graphique (comme une application WEB par exemple), pourra remplir le rôle d'interface d'administration.

Le shell de sqlite3 se contrôle via la commande suivante :

sqlite3 /etc/postfix/bdd/postfix.sqlite

Les commandes suivantes permettent une utilisation basique de l'outil :

Commande Signification
.table Liste les tables de la base
.shema <table> Affiche la structure de la table (en-têtes et propriétés)
.mode column Affiche le retour d'une requête sous forme de tableau
.headers on Affiche les entêtes (clés) des valeurs retournés
.quit Quitte l'outil

Gestion des alias :

Action Commande
Ajout INSERT INTO postfix_alias (alias,destination,active) VALUES ("toto","test",1);
Désactivation UPDATE postfix_alias SET active = 0 WHERE alias = "toto";
Activation UPDATE postfix_alias SET active = 1 WHERE alias = "toto";
Suppression DELETE FROM postfix_alias WHERE alias = "toto";
Listage SELECT * FROM postfix_alias;

Gestion des alias virtuels :

Action Commande
Ajout INSERT INTO postfix_alias_virtuels (courriel,destination,active) VALUES ("ycharbi@exemple.fr","test@exemple.fr",1);
Désactivation UPDATE postfix_alias_virtuels SET active = 0 WHERE courriel = "ycharbi@exemple.fr";
Activation UPDATE postfix_alias_virtuels SET active = 1 WHERE courriel = "ycharbi@exemple.fr";
Suppression DELETE FROM postfix_alias_virtuels WHERE courriel = "ycharbi@exemple.fr";
Listage SELECT * FROM postfix_alias_virtuels;

Gestion des domaines :

Action Commande
Ajout INSERT INTO postfix_domaines (domaine,defaut,active) VALUES ("toto.fr",1,1);
Désactivation UPDATE postfix_domaines SET active = 0 WHERE domaine = "toto.fr";
Activation UPDATE postfix_domaines SET active = 1 WHERE domaine = "toto.fr";
Suppression DELETE FROM postfix_domaines WHERE domaine = "toto.fr";
Listage SELECT * FROM postfix_domaines;

ATTENTION

N'oubliez pas d'ajouter votre domaine à la base (un problème de correspondance de domaine peut entrainer l'erreur Relai access denied). De plus, ne positionnez le drapeau defaut à 1 (pour le mettre en domaine par défaut) que sur un seul domaine. Cette notion n'est utile que pour un usage avec le portail WEB Courtail.

Gestion de la liste noire des destinataires :

Action Commande
Ajout INSERT INTO postfix_liste_noire_destinataires (courriel,action,active) VALUES ("root@mail.exemple.fr","REJECT",1);
Désactivation UPDATE postfix_liste_noire_destinataires SET active = 0 WHERE courriel = "root@mail.exemple.fr";
Activation UPDATE postfix_liste_noire_destinataires SET active = 1 WHERE courriel = "root@mail.exemple.fr";
Suppression DELETE FROM postfix_liste_noire_destinataires WHERE courriel = "root@mail.exemple.fr";
Listage SELECT * FROM postfix_liste_noire_destinataires;

Gestion de la liste noire des expéditeurs :

Action Commande
Ajout INSERT INTO postfix_liste_noire_expediteurs (courriel,code_retour,message,active) VALUES ("tata@tata.fr",554,"Parle à ma main, ma tête est malade.",1);
Désactivation UPDATE postfix_liste_noire_expediteurs SET active = 0 WHERE courriel = "tata@tata.fr";
Activation UPDATE postfix_liste_noire_expediteurs SET active = 1 WHERE courriel = "tata@tata.fr";
Suppression DELETE FROM postfix_liste_noire_expediteurs WHERE courriel = "tata@tata.fr";
Listage SELECT * FROM postfix_liste_noire_expediteurs;

Gestion des utilisateurs :

Action Commande
Ajout INSERT INTO postfix_utilisateurs (utilisateur,mot_de_passe,nom_complet,rep_perso,uid,gid,privilege,prefixe,active) VALUES ("test@exemple.fr","{SHA512-CRYPT}$6$xWfisyC6fLawFcBr$zLm4hfRfs6Pn0RKArnyWcgliBy6lpnRUkDHfHMkvskShfLiv4pRIU6XC5ry0ysd.DeKhoAiZUfnNdmwIai2k50","Test Dupont","exemple.fr/test/",3000,3000,"administrateur","",1);
Désactivation UPDATE postfix_utilisateurs SET active = 0 WHERE utilisateur = "test@exemple.fr";
Activation UPDATE postfix_utilisateurs SET active = 1 WHERE utilisateur = "test@exemple.fr";
Suppression DELETE FROM postfix_utilisateurs WHERE utilisateur = "test@exemple.fr";
Listage SELECT * FROM postfix_utilisateurs;

INFORMATION

Le mot de passe est généré avec Dovecot dans la section suivante.

Dovecot

Dovecot est un service gérant les protocoles IMAP et POP. Il endosse donc le rôle d'intermédiaire entre les utilisateurs et le serveur de messagerie.

Installation de Dovecot

POP ayant été totalement abandonné (tant dans son développement que dans l'usage), seul IMAP sera supporté.

apt install --no-install-recommends dovecot-common dovecot-imapd dovecot-sqlite dovecot-lmtpd

Création d'un utilisateur

Comme précisé en introduction, nous exploitons des utilisateurs enregistrés dans la base SQLite.

Il faut tout d'abord générer un mot de passe à la l'aide de la commande suivante (du paquet dovecot-core, véritable nom de dovecot-common (paquet virtuel) installé plus haut)

doveadm pw -s SHA512-CRYPT -p toto1234567890°+

Création de l'utilisateur dans la base

sqlite3 /etc/postfix/bdd/postfix.sqlite 'INSERT INTO postfix_utilisateurs (utilisateur,mot_de_passe,nom_complet,rep_perso,uid,gid,privilege,prefixe,active) VALUES ("test@exemple.fr","{SHA512-CRYPT}$6$xWfisyC6fLawFcBr$zLm4hfRfs6Pn0RKArnyWcgliBy6lpnRUkDHfHMkvskShfLiv4pRIU6XC5ry0ysd.DeKhoAiZUfnNdmwIai2k50","Test 
Dupont","exemple.fr/test/",3000,3000,"administrateur","",1)'

INFORMATION

Le fait que l'utilisateur comporte le nom de domaine dans son nom fait qu'il faut renseigner la chaine complète (utilisateur@domaine) dans les clients IMAP. Le champ privilege permet de définir les fonctions autorisées dans notre interface WEB Courtail développé par nos soins. Si vous ne l'utilisez pas, ceci n'a pas d'importance. Les valeurs gérés sont administrateur et utilisateur.

Créer le répertoire utilisateurs

mkdir /var/mail/utilisateurs
chown 3000:3000 /var/mail/utilisateurs

ASTUCE

Dans le cadre d'une migration de serveur (monté en version de Debian par exemple), nous recommandons d'effectuer une archive tar.gz du contenu de l'ancien MailDir et de l'extraire dans le nouveau répertoire utilisateur. Ce répertoire n'existera pas (Dovecot est censé le créer à la première utilisation de son propriétaire), il faudra donc le créer avec un mkdir -p /var/spool/mail/utilisateurs/exemple.fr/votre_utilisateur et lui donner les bons droits avec chown -R 3000:3000 /var/spool/mail/utilisateurs/exemple.fr && chmod -R 700 /var/spool/mail/utilisateurs/exemple.fr.

Configuration de Dovecot

Ce service utilise un fichier de configuration par fonctionnalité (ce qui en fait pas mal).

Gestion d'IPv6

Activation du support d'IPv6 (optionnel suivant votre configuration)

echo -e '\nlisten = *, [::]' >> /etc/dovecot/dovecot.conf

Emplacement des dossiers utilisateurs

Configuration de l'emplacement du répertoire des boites aux lettres des utilisateurs

sed -i 's@mail_location = mbox:~/mail:INBOX=/var/mail/%u@mail_location = maildir:/var/mail/utilisateurs/%d/%n@g' /etc/dovecot/conf.d/10-mail.conf

Emploi du chiffrement

Configuration de la couche de chiffrement (qui sera rendue obligatoire)

mv /etc/dovecot/conf.d/10-ssl.conf /etc/dovecot/conf.d/10-ssl.conf.ori
cat << '_EOF_' > /etc/dovecot/conf.d/10-ssl.conf
ssl = required
ssl_cert = </etc/postfix/tls/courriel.pem
ssl_key = </etc/postfix/tls/courriel.key
ssl_min_protocol = TLSv1.2
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
ssl_prefer_server_ciphers = yes # Oblige l'utilisation de la suite du serveur au lieu du client (Dovecot > 2.2.x)
_EOF_

les valeurs sont précédées d'un chevron ouvert qui ne se ferme jamais (<). C'est louche mais normal (documentation officielle de Dovecot). Il n'y a donc pas d'erreur dans les lignes mentionnées ci-dessus.

INFORMATION

Il est vivement recommandé de ne plus utiliser des algorithmes de cryptographie non ECC. L'usage de Diffie-Hellman est de façon générale découragé de nos jours.

Configuration de l'authentification

Désactiver l'authentification en clair ainsi que POSIX et l'activer par SQLite

sed -i -e 's@#disable_plaintext_auth.*@disable_plaintext_auth = yes@g' -e 's@!include auth-system.conf.ext@#!include auth-system.conf.ext@g' -e 's@#!include auth-sql.conf.ext@!include auth-sql.conf.ext@g' /etc/dovecot/conf.d/10-auth.conf
cat << '_EOF_' >> /etc/dovecot/dovecot-sql.conf.ext
driver = sqlite
connect = /etc/postfix/bdd/postfix.sqlite

password_query = SELECT utilisateur AS user, mot_de_passe AS password, '/var/mail/utilisateurs/%d/%n' AS userdb_home, 'maildir:/var/mail/utilisateurs/%d/%n' AS userdb_mail, 3000 AS userdb_uid, 3000 AS userdb_gid FROM postfix_utilisateurs WHERE utilisateur = '%u' AND active = 1
user_query = SELECT '/var/mail/utilisateurs/%d/%n' AS home, 'maildir:/var/mail/utilisateurs/%d/%n' AS mail, 3000 AS uid, 3000 AS gid FROM postfix_utilisateurs WHERE utilisateur = '%u' AND active = 1 
_EOF_

Configuration de l'authentification

mv /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/10-master.conf.ori
cat << '_EOF_' > /etc/dovecot/conf.d/10-master.conf
service auth {                                                                       
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }

  unix_listener auth-userdb {

  }
}

service lmtp {
 unix_listener /var/spool/postfix/private/dovecot-lmtp {
    group = postfix
    mode = 0600
    user = postfix
  }
}
_EOF_

Bien que le contenu proposé ne ressemble en rien à ce qui est préremplis dans celui-ci, il s'agit bien de la configuration décrite dans la documentation officielle.

Auto-création des répertoires utilisateurs

Dovecot peut créer automatiquement les répertoires présents dans une boite au lettres (/var/mail/utilisateurs/%d/%n@g) à la connexion des utilisateurs. Ceci leur permet d'avoir un environnement pré-configuré comportant un dossier "envoyé", "brouillons", "Indésirables" et "corbeille" ("réception" est créé par Postfix).

mv /etc/dovecot/conf.d/15-mailboxes.conf /etc/dovecot/conf.d/15-mailboxes.conf.ori

Il faut que les sections correspondantes aux répertoires soient présentes et que l'argument "auto = create" (création du dossier dans l'arborescence) ou "auto = suscribe" (création du dossier et inscription automatique dans le client) soient spécifiées.

cat << '_EOF_' > /etc/dovecot/conf.d/15-mailboxes.conf
namespace inbox {
  mailbox Sent {
    auto = subscribe
    special_use = \Sent
  }
  mailbox Drafts {
    auto = subscribe
    special_use = \Drafts
  }
  mailbox Trash {
    auto = subscribe
    special_use = \Trash
  }
  mailbox Spam {
    auto = subscribe
    special_use = \Junk
  }
  mailbox Archive {
    auto = subscribe
    special_use = \Archive
  }
  mailbox Notes {
    auto = create
  }
}
_EOF_

Sieve

Installation de ManageSieve

Sieve est un système de filtrage du courrier coté serveur permettant l'application d'actions suivant des règles prés-établies. Sa mise en œuvre passe par le service ManageSieve agissant comme une extension de Dovecot. Les scripts sont créables à la fois sur le serveur et sur les clients (ce sont de simples instructions dans un fichier texte synchronisés par IMAP).

apt install --no-install-recommends dovecot-sieve dovecot-managesieved

Ces deux paquets vont créer les 3 fichiers 90-sieve.conf, 90-sieve-extprograms.conf et 20-managesieve.conf.

Configuration de ManageSieve

Édition du fichier 20-lmtp.conf pour dire à Dovecot d'utiliser le greffon Sieve via LMTP

mv /etc/dovecot/conf.d/20-lmtp.conf /etc/dovecot/conf.d/20-lmtp.conf.ori
cat << '_EOF_' > /etc/dovecot/conf.d/20-lmtp.conf
protocol lmtp {
    postmaster_address = postmaster@exemple.fr
    mail_plugins = quota sieve
}
_EOF_

Définition du répertoire de destination des scripts Sieve (par défaut c'est le ~) en modifiant le fichier 90-sieve.conf

mv /etc/dovecot/conf.d/90-sieve.conf /etc/dovecot/conf.d/90-sieve.conf.ori

On demande à Dovecot de créer le dossier Sieve dans la boite aux lettres (Maildir) de l'utilisateur lors de sa première connexion. De plus, il est demandé à l'outil d'utiliser les scripts qui seront ajoutés côté client par l'intermédiaire du MUA.

cat << '_EOF_' > /etc/dovecot/conf.d/90-sieve.conf
plugin {
  sieve = ~/sieve/.dovecot.sieve
  sieve_before = /var/mail/sieve/before/spam.sieve
  sieve_dir = ~/sieve
}
_EOF_

Créer l’arborescence pour les scripts Sieve globaux (actifs pour tous les utilisateurs et s'exécutant avant leurs scripts personnels) et définir les bons droits pour celle-ci

mkdir -p /var/mail/sieve/before && chown -R dovecot: /var/mail/sieve

Redémarrer le service Dovecot

systemctl restart dovecot.service

Règle globale de gestion du pourriel

Mise en place d'un script Sieve global et actif pour tout les utilisateurs. Il va permettre de placer tout les courriels détectés comme du pourriel par SpamAssassin dans le dossier Maildir "Spam" :

cat << '_EOF_' > /var/mail/sieve/before/spam.sieve
require "fileinto";
if header :contains "X-Spam-Flag" "YES" {
  fileinto "Spam";
}
_EOF_

Compiler le fichier de règle afin de ne pas avoir un message d'avertissement (non bloquant) dans les journaux concernant les droits

sievec /var/mail/sieve/before/spam.sieve

Cette commande compile le fichier de règles dans le même répertoire que la source sous le nom spam.svbin.

Donner les droits aux fichiers

chown dovecot: /var/mail/sieve/before/spam.*

OpenDKIM

OpenDKIM est un logiciel libre implémentant le protocole DKIM (DomainKeys Identified Mail). Son rôle est d'authentifier le domaine de l'expéditeur (tant en émission qu'en réception) et d'assurer l'intégrité du message. Chaque courriel est alors signé lors de sa transmission initiale et la vérification de celle-ci à la réception permet d'appliquer une politique de traitement (via l'anti pourriel notamment). Couplé à SPF (Sender Policy Framework). Il participe donc à réduire la distribution de courriels indésirables aux utilisateurs.

INFORMATION

La mise en œuvre de DKIM étant plus complexe et lourde à mettre en place qu'un simple enregistrement DNS SPF, son absence est bien moins pénalisante que ce dernier lors du traitement de vos message par les MTA destinataires (leur politique est beaucoup plus laxiste à ce sujet). À titre personnel, je n'ai pas mis en place cette technologie pendant 7 ans et cela ne m'a jamais handicapé. En revanche, SPF et un enregistrement PTR rDNS sont eux, réellement utiles. DKIM peut jouer si votre message passe tout juste les critères établis par le serveur distant et qu'un point de plus vous permet de ne pas être considéré comme non désiré.

Nous nous sommes principalement inspirés de la documentation idoine de ce Wiki pour réaliser cette section.

Installation des paquets

Nous installons l'outil qui sera exploité par Postfix afin de signé/vérifier les courriels ainsi que celui permettant de générer nos clés

apt install --no-install-recommends opendkim opendkim-tools

Création d'un couple de clés

Notez que nous écrivons cette documentation afin de permettre un usage multi-domaines. Dans cette optique, nous utiliserons un script de génération des clés se basant sur un tableau listant chacun d'eux. Toutefois, nous documentons ci-après la méthode permettant la création manuelle d'un couple de clés si vous privilégiez une approche plus directe. Nous vous invitons tout de même à considérer l'usage de la méthode scripté qui s'accommode aussi bien d'un ou plusieurs domaine.

Méthode manuelle

Le paquet OpenDKIM crée automatiquement le répertoire /etc/dkimkeys. Nous allons donc l'exploiter. La génération d'un couple de clés s'effectue via la commande opendkim-genkey :

mkdir -p /etc/dkimkeys/clefs/exemple.fr
opendkim-genkey -b 4096 -D /etc/dkimkeys/clefs/exemple.fr -r -d exemple.fr -s mail
echo "mail._domainkey.exemple.fr exemple.fr:mail:/etc/dkimkeys/clefs/exemple.fr/mail.private" >> /etc/dkimkeys/TableClefs
echo "exemple.fr mail._domainkey.exemple.fr" >> /etc/dkimkeys/TableSignatures
echo "exemple.fr" >> /etc/dkimkeys/HotesDeConfiance
chown -R opendkim:opendkim /etc/dkimkeys/clefs/exemple.fr

Méthode scripté

Le script suivant permet la création des clés de façon récursive en parcourant une liste de domaines initialisée dans le tableau domaines. Il constitue automatiquement l'arborescence à raison d'un répertoire par occurrence afin d'y ranger les fichiers conçus. Bien sûr, vous pouvez réaliser ces opérations vous mêmes via la commande de la section précédente.

cat << '_EOF_' > /etc/dkimkeys/genClefs.sh
#!/bin/bash
# Script de génération des clés DKIM pour du multi-domaine

selecteur=mail
repertoire=/etc/dkimkeys
domaines="exemple.fr toto.fr"

for domaine in $domaines; do
    mkdir -p $repertoire/clefs/$domaine
    opendkim-genkey -b 4096 -D $repertoire/clefs/$domaine -r -d $domaine -s $selecteur
    echo "$selecteur._domainkey.$domaine $domaine:$selecteur:$repertoire/clefs/$domaine/$selecteur.private" >> $repertoire/TableClefs
    echo "$domaine $selecteur._domainkey.$domaine" >> $repertoire/TableSignatures
    echo "$domaine" >> $repertoire/HotesDeConfiance
    chown -R opendkim:opendkim $repertoire/clefs/$domaine
done
_EOF_
chmod 740 /etc/dkimkeys/genClefs.sh
/etc/dkimkeys/genClefs.sh

Attribution des droits

chown opendkim:opendkim /etc/dkimkeys/clefs/
chown opendkim:opendkim /etc/dkimkeys/{TableClefs,TableSignatures,HotesDeConfiance}
chmod 660 /etc/dkimkeys/{TableClefs,TableSignatures,HotesDeConfiance}

Configuration d'OpenDKIM

Le fichier est assez simple et reprend les éléments abordés précédemment.

mv /etc/opendkim.conf /etc/opendkim.conf.ori
cat << '_EOF_' > /etc/opendkim.conf
Syslog                  yes
SyslogSuccess           yes
Canonicalization        relaxed/simple
OversignHeaders         From
UserID                  opendkim
UMask                   007
Socket                  local:/var/spool/postfix/var/run/opendkim/opendkim.sock
PidFile                 /run/opendkim/opendkim.pid
TrustAnchorFile         /usr/share/dns/root.key
# Table des clés
KeyTable                /etc/dkimkeys/TableClefs
# Liste les domaines à signer
SigningTable            /etc/dkimkeys/TableSignatures
# SigningTable = Donne la correspondance entre les domaines et les selecteurs
ExternalIgnoreList      /etc/dkimkeys/HotesDeConfiance
# Donne la correspondance entre les selecteurs et les clés à utiliser
InternalHosts           /etc/dkimkeys/HotesDeConfiance
_EOF_

Création du répertoire d'accueil pour le socket

mkdir -p /var/spool/postfix/var/run/opendkim

Note : ce socket permet la communication entre Postfix et OpenDKIM. Le choix du chemin est guidé par la racine d'exécution du MTA selon les directives du fichier master.cf.

Don de propriété dessus

chown opendkim:opendkim /var/spool/postfix/var/run/opendkim

Ajout de l'utilisateur opendkim au groupe postfix afin de permettre la communication via le socket

usermod -a -G opendkim postfix

Si vous avez été attentif lors de l'édition du fichier main.cf, vous avez dû remarqué les valeurs se rapportant à cette section. Je vous invite à y lire les commentaires afin de comprendre chacune d'elles.

Tous les éléments locaux sont prêts, nous pouvons redémarrer le service

systemctl restart opendkim.service

Enregistrement DNS DKIM

Il ne vous a pas échappé que ce protocole se base lui aussi sur le DNS. Il va falloir publier votre clé publique dans un enregistrement dédié sur votre zone. Ajoutez-en un de type TXT ou DKIM comportant le contenu du fichier <selecteur>.txt généré avec votre clé tout à l'heure. Du fait de la longueur de la clé (4096 bits), son contenu est tronqué en plusieurs lignes. Cet aspect ne dérange nullement les implémentations DNS que j'ai pu rencontrer. Il est donc possible d'ajouter la clé à votre zone par un simple copier/coller de celle-ci :

mail._domainkey	IN	TXT	( "v=DKIM1; h=sha256; k=rsa; s=email; "
	  "p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnjMYbRgp+0a7BY5pUdQ2lgMWlnsWCL94nwMfcZ0weEHQoL+ip1s7m95L0HqIjCi3yPn5lL4Lx0wZ8ujPKVhXB3R+E/rjBOUXo26vTULCDdpqfg+IzxvyqjM+644Y8NYb+fRu4WkpBMkptMmogRhHnu3uDS+4/IyEqAH4OOy5SZHW5atwm87KCEDH8LcffLedr/nV22gXe5Wd2M"
	  "z3RqLPyaOgOxoIqOZKOIy5Xs5x1FCV8MNRdj8xT65GKsriN5/RSXK1NU1dvhnmTl/zuXP95F21YZPbwZEy3EXsyQuiyb1westiXy4fkWi0qV9vdYvyNZLn+wUk6tvY1mQ/OBewnrqGfHR/Tf8r+6Ku29CAYt4k6DXEmlEmZlM3d8Vg7/krlsYdlZIqDmOktxelGg3Oey5IJeqknHZh0lxxNjGm1zPjUKbF0MgMP1DZzlDgHJKIk558IyBV"
	  "3zNDMIvVbbWNzOyeU5513n0AOx7D8jayHvc3R9GkhyeHDH4XBExcobKPZstsGdEdLLTFnT7fDVAqur53HSuLSAum+0IK8VkC5K0QN21A6DNlzKvCbN4l4blVNg7qlnViqFB9g3ZfAsdCfgca1Dq4iFWS+Z9yuwkfWxdQbKYfcwD8Zb8sLpmTYZmjbk9CcD8jTFkJwKpLaT2Beo8YJdKh31V/Fkd6MXbI5gECAwEAAQ==" )  ; ----- DKIM key mail for exemple.fr

Pour vérifier la prise en compte de votre modification, vous pouvez utiliser la commande suivante pour requêter le serveur DNS :

dig mail._domainkey.exemple.fr TXT

Nous utiliserons des outils WEB à la fin pour tester ceci de façon plus approfondie.

Spamassassin

Spamassassin est un programme écrit en Perl et en C diffusé sous la licence libre Apache version 2.0. Il a pour rôle de filtrer le trafic des courriels transitant par un MTA (Postfix dans notre cas) dans l'optique d'identifier pour traitement les messages indésirables. Celui-ci peut prendre diverses formes dans la mesure où l'outil donne la possibilité à l'administrateur de réaliser ces propres filtres. Les actions les plus courantes sont de rejeter le message ou de le marquer pour trie via Sieve (solution retenue). Gardez en tête qu'il n'est pas impossible de faire face à des faux positifs et que le rejet de tels messages peuvent avoir des conséquences pour vos utilisateurs. Il convient alors d'appliquer les mesures adéquates à votre situation selon le flux que représente les pourriels.

Pour chaque message filtrés, une note est attribuée au courriel selon des critères arbitraires tels que ceux énoncés en prérequis et sera utilisée lors de la lecture des règles afin de déterminer le sort réservé à celui-ci. Vous comprenez alors l'importance de respecter les standards de "propreté" énoncés en début de page pour que vos propres messages ne soient pas mal-traités par vos destinataires.

Les sources suivantes ont, entre autres, permis d'écrire cette section :

Installation de Spamassassin

Le système de gestion des indésirables fonctionne au travers de trois composantes. Un module (spamass-milter) lié à Postfix écoutant sur un socket via le protocole Milter les messages provenant de celui-ci; un client nommé spamc exécuté par le module et chargé de transmettre les messages à spamd via un autre socket; un démon (spamd) chargé de la qualification des messages ainsi que de leur traitement.

Installation des composants

apt install --no-install-recommends spamassassin spamc spamass-milter

Création d'un utilisateur dédié au service

useradd --system --home-dir /run/spamassassin --shell /usr/sbin/nologin --user-group spamassassin

Activation du service au démarrage

systemctl enable spamassassin.service

Configuration de spamd

Par défaut, le démon spamd s'exécute avec l'utilisateur postfix et communique au module spamass-milter via un socket TCP. Dans le respect du principe de moindre privilège, un utilisateur dédié a été ajouté et pour des raisons d'optimisation, de sécurité ainsi que de bon sens, le socket TCP laissera sa place à un socket UNIX. Ce dernier est bien plus rapide (ne se tape pas tout le modèle OSI pour réaliser une communication locale...) et plus sécurisé (pas d'écoute ni de redirection de trames réseau possible).

Spamassassin ne créant pas lui-même le répertoire d'accueil de son socket, que nous situerons, conformément au Filesystem Hierarchy Standard (FHS), dans le /run (qui est monté en tmpfs dans Debian), nous ajouterons une configuration pour systemd-tmpfiles afin de le fabriquer au démarrage.

cat << '_EOF_' > /usr/lib/tmpfiles.d/spamassassin.conf
d /run/spamassassin 0750 spamassassin spamassassin - -
_EOF_

Pour la session active, nous créerons ce répertoire manuellement afin de ne pas avoir à redémarrer tout de suite

mkdir -p /var/run/spamassassin
chown spamassassin:spamassassin /var/run/spamassassin

Note : /var/run est un lien symbolique du tmpfs /run présent de base dans le système.

Configuration du service

# Commenter toutes les lignes existantes
sed -i '/^$/!s/^/#/g' /etc/default/spamassassin

# Configuration du démon pour utiliser l'utilisateur spamassassin, un PID à un emplacement donné et un socket personnalisé du type UNIX
cat << '_EOF_' >> /etc/default/spamassassin

OPTIONS="--username spamassassin --create-prefs --max-children 5 --helper-home-dir --socketpath=/run/spamassassin/spamassassin.sock --socketowner=spamassassin --socketgroup=spamassassin --socketmode=0660"
PIDFILE="/var/run/spamassassin/spamd.pid"
CRON=0
_EOF_

Ajout d'une action en cas de détection de pourriel

cat << '_EOF_' >> /etc/spamassassin/local.cf

rewrite_header Subject *****SPAM*****
report_safe 0
whitelist_from *@exemple.fr

add_header all Report _REPORT_
add_header spam Flag _YESNOCAPS_
add_header all Status _YESNO_, score=_SCORE_ required=_REQD_ tests=_TESTS_ autolearn=_AUTOLEARN_ version=_VERSION_
add_header all Level _STARS(*)_
add_header all Checker-Version SpamAssassin _VERSION_ (_SUBVERSION_) on _HOSTNAME_

skip_rbl_checks 1
_EOF_

Cette action ajoutera le préfixe *****SPAM***** au sujet du message considéré comme indésirable ainsi que des en-têtes de marquage (notamment X-Spam-Flag: YES). Ceci aura pour effet de déclencher l'action de la règle Sieve globale écrite plus haut et de placer le message dans le dossier approprié. La dernière ligne désactive quant à elle la vérification des adresses IP émétrices via les RBL intégrées au logiciel (vous pouvez l'enlever si vous en voulez mais je ne sais pas ce qu'ils font des traces que vous laissez).

Configuration de spamass-milter

# Commenter toutes les lignes existantes
sed -i '/^$/!s/^/#/g' /etc/default/spamass-milter

# Configuration du démon pour utiliser l'utilisateur spamassassin, un PID à un emplacement donné et un socket personnalisé du type UNIX
cat << '_EOF_' >> /etc/default/spamass-milter

OPTIONS="-u spamass-milter -i 127.0.0.1 -- -s 10485760 --socket=/run/spamassassin/spamassassin.sock"
SOCKET="/var/spool/postfix/spamass/spamass.sock"
SOCKETOWNER="spamass-milter:spamass-milter"
_EOF_

INFORMATION

Si vous désirez rejeter les messages identifiés comme indésirables, vous pouvez ajouter le paramètre -r <note> à la suite de l'adresse IP de lien local où <note> correspond à la note attribué au message par Spamassassin que vous considérez comme étant le seuil d'acceptabilité. Tout courriel ayant une note égale ou supérieur à ce seuil sera alors rejeté avec un code 550 à l'expéditeur.

Ajout des utilisateurs spamassassin et postfix au groupe spamass-milter pour permettre la communication inter-socket

usermod -a -G spamassassin spamass-milter
usermod -a -G spamass-milter postfix

Note : la communication entre Postfix et Spamass-milter se fait à la fin du fichier main.cf sur la même ligne que pour le socket d'OpenDKIM.

Automatisation de l'apprentissage

L'outil dispose d'une fonctionnalité d'apprentissage basée sur l'inférence bayésienne. Afin d'entraîner le moteur sur les messages reçus, vous pouvez utiliser la tâche planifiée suivante (nécessite le logiciel Cron) :

cat << '_EOF_' > /etc/cron.daily/Spamassassin-bayés
#!/bin/bash
# Script de mise à jour automatique de la base bayésienne de Spamassassin

# Mise à jour des règles de spamassassin
# Pour utiliser cette fonctionnalité, il faut importer la clé GPG d'un canal de règles anti-pourriels.
# Dans la mesure où, comme expliqué, nous ne recevons pas de messages non désirés, nous n'avons pas explorer cette piste.
# /usr/bin/sa-update

# Auto-apprentissage de Spamassassin sur les messages existants dans les boites aux lettres
/usr/bin/sa-learn --ham /var/spool/mail/utilisateurs/*/*/cur/*
/usr/bin/sa-learn --spam /var/spool/mail/utilisateurs/*/*/.Spam/cur/*
_EOF_
chmod +x /etc/cron.daily/Spamassassin-bayés

INFORMATION

La documentation officielle conseille de ne réaliser cette tâche que manuellement après vérification des messages présents dans votre boite aux lettres. Ceci dans une optique de ne pas apprendre de fausses données. Vous pouvez par exemple effectuer manuellement les commandes de cette section après un épisode de réception non désiré afin d'améliorer la détection. Si vous souhaitez suivre cette recommandation, pensez à ne pas le laisser dans ce répertoire afin que Cron ne l'exécute pas quotidiennement.

Tests de fonctionnement

Nous voici arrivé au grand moment : celui du test !

Il va falloir redémarrer tous les services configurés précédemment afin de valider leur bon fonctionnement. Habituellement, j'aurai procédé par étape au file des sections mais l'écosystème abordé ayant la particularité de faire appel à des composants inter-dépendants, il est difficile de réaliser des tests d'intégration continue sans devoir revenir modifier des configurations tout au long du cheminement, ce qui aurai rendu la lecture exécrable. Ayant conscience de la difficulté de suivre une procédure aussi conséquente (et en vous assurant de la tâche encore plus importante qu'a été sa rédaction), j'ai préféré faire le choix d'une configuration en une traite, quitte à devoir vous faire corriger les quelques erreurs d'inattentions dans la lecture par la suite en vous appuyant sur les journaux du système. Soyez sûr que l'idée d'user au maximum de copier/coller pour l'application de ce document a été la trame directrice de sa rédaction afin de faciliter la mise en place de votre propre messagerie électronique.

Redémarrage des services

ASTUCE

Il peut être judicieux d'afficher les journaux concernant la messagerie dans un second terminal pendant que vous redémarrez les services via un tail -f /var/log/mail.log.
systemctl restart spamass-milter.service
systemctl restart spamassassin.service
systemctl restart opendkim.service
systemctl restart dovecot.service
systemctl restart postfix.service

Vous pouvez naturellement afficher le statut de chacun des services via la commande systemctl status <service> afin de vérifier l'état de leur exécution ainsi que la commande journalctl -feu <service> pour en afficher les journaux propres dans leur intégralité.

Tests de communication

Quoi de mieux pour tester le fonctionnement que l'envoi d'un message ? Utilisez un client IMAP comme Rainloop ou Thunderbird (vous pouvez également configurer l'auto-configuration pour celui-ci) et pensez à regarder le code source des messages sur la boite de destination afin de regarder leurs en-têtes. Vous y verrez la suite cryptographique utilisée pour la transmission, la note attribuée par Spamassassin ainsi que la signature DKIM.

Outils WEB

Après avoir validé l'aspect fonctionnel de votre installation, il peut être judicieux de s'attarder sur l'aspect qualitatif au regard des standards de l'époque.

Pour ce faire, vous pouvez utiliser les outils WEB suivant qui vous attribueront des notes et vous détailleront les divers points examinés dans le but de vous améliorer :

  • https://mxtoolbox.com pour vérifier vos résolutions DNS ainsi que la présence de votre adresse IP dans une liste noire d'indésirable
  • https://www.mail-tester.com afin de visualiser les points attrayants à l'acceptabilité de vos messages (cela peut être l'occasion d'utiliser un alias...)
  • https://cryptcheck.fr pour lister les suites cryptographiques ayant pu être négocier par le serveur distant

ASTUCE

Vous pouvez vérifier si votre serveur relaie ouvertement les courriels sur Internet (il ne doit pas le faire) via l'outil swaks utilisée comme suit depuis un client :
swaks --server mail.exemple.fr --to toto@tutu.org

Test de détection de pourriels

Il est possible de simuler un courriel frauduleux en envoyant un message contenant la chaîne de caractère suivante :

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

Vous verrez dans le journal /var/log/mail.log la phrase stored mail into mailbox 'Spam' informant de l'application de la règle Sieve de rangement.

Depuis votre client de messagerie, vous verrez le message précédemment envoyé placé dans la boite "indésirables".

Débogage

Messages d'erreurs connus

Cette section regroupe quelques erreurs qui ont déjà étés rencontrés et observables dans le fichier /var/log/mail.log.

Message Signification
mail for exemple.fr loops back to myself Le nom de domaine du champ MX n'est pas renseigné au paramètre "mydestination" dans le main.cf
postfix warning: SASL: Connect to private/auth failed: No such file or directory Indique un problème avec Dovecot (gérant l'authentification). Il faut repasser dans les fichiers de configuration de celui-ci

Commandes utiles

Affichage des configurations

Commande Signification
postconf -d Renvoie le contenu du fichier main.cf par défaut
postconf -n Renvoie le contenu actuel du fichier main.cf sans les commentaires
postconf -p Renvoie la configuration totale de Postfix, valeurs par défaut comprises
doveconf -n ou dovecot -n Renvoie l'ensemble de la configuration de Dovecot

Requêter la base de donnée

Afin de tester les différents fichiers de liaison de la base de données SQLite à Postfix, il est possible d'utiliser la commande postmap sous cette forme

postmap -q chaine_à_tester sqlite:/etc/postfix/sqlite-FONCTION.cf

Pour vérifier l'existance d'un utilisateur ou d'un domaine, nous utiliserons la commande de cette façon

postmap -q test@exemple sqlite:/etc/postfix/sqlite-utilisateurs.cf
postmap -q jmador.yo sqlite:/etc/postfix/sqlite-domaines.cf

Gestion de la file d'attente de courrier

La file d'attente des messages de Postfix (mail queue) est l'endroit où sont stockés les courriels en cours d'envoi/réception ou qui sont revenus au serveur suite à un message de non-délivrance. Les commandes utiles permettant de la gérer sont les suivantes (tirées de ce document) :

Commande Signification
postqueue -p Liste les messages en queue
postsuper -d DBB3F1A7 Supprime un message en queue
postsuper -d ALL Supprime tous les messages en queue
postsuper -h DBA3F1A7 Mettre un messages en attente
postsuper -H DBA3F1A7 Remettre un messages en mode normale
postsuper -r DBA3F1A7 Remettre en queue un message
postsuper -r ALL Remettre en queue tous les messages
postcat -q DBA3F1A9 Afficher le contenu d'un message
postqueue -f Forcer l'envoi des messages en queue

Glossaire

Le lexique entourant le domaine de la messagerie électronique est assez singulier. Voici quelques éléments de vocabulaire.

Rôles de messageries

  • Agent de Transport du Courriel ou MTA (Mail Transport Agent) : service chargé d'acheminer les courriels vers un service de distribution du courrier (MDA). Ce service est assuré par le protocole SMTP (utilisé par Postfix dans notre cas)
  • Agent de Distribution du Courriel ou MDA (Mail Delivery Agent) : service chargé de déposer le courriel dans la boite aux lettres d'un utilisateur. Il s'occupe également des contraintes d'espace disque (quota, disque plein..) ou de corruption et prévient le MTA des erreurs de distribution. Cette tâche est assurée par les protocoles POP, IMAP et JMAP (utilisés par Dovecot dans notre cas)
  • Agent Utilisateur du Courriel ou MUA (Mail User Agent) : logiciel client de messagerie électronique (Rainloop, Roundcube, Thenderbird, Outlook...) chargé de présenter les courriels aux utilisateurs et de permettre leur rédaction. Il parle directement au MDA pour les requêtes de réception et au MTA pour l'envoi de ses messages


Protocoles mis en œuvre

  • Simple Mail Transfer Protocol (SMTP) : protocole de communication utilisé pour transférer le courriel vers les serveurs de messagerie électronique
  • Internet Message Access Protocol (IMAP) : protocole permettant à un client d'accéder à ses courriels directement sur les serveurs de messagerie via un logiciel de consultation
  • Transport Layer Security (TLS) : protocole de négociation d'éléments secrets entre deux correspondant. Son objectif est de permettre l'établissement d'une communication sécurisée
  • DomainKeys Identified Mail (DKIM) : norme d'authentification fiable du nom de domaine de l'expéditeur d'un courriel. Permet également de garantir l'intégrité d'un message. Plus de détails sur ces balises ici
    • Selecteur : élément de l'en-tête DKIM indiquant l'emplacement de la clé dans la zone DNS du domaine. Cet élément est concaténé avec le domaine pour effectuer une requête de résolution comme vu précédemment
  • GNU Privacy Guard (GPG) : implémentation libre du standard OpenPGP permettant d'assurer la confidentialité et l'intégrité d'un message par un secret connu des seuls correspondants
  • Milter : extension présente sous forme d'interface de programmation du MTA permettant d'intégrer un programme dans la file de traitement des courriels. C'est le mécanisme qui nous permet de traiter les pourriels ainsi que les signatures DKIM mais peut aussi servir à l'analyse anti-virale
  • Domain Name System (DNS) : service d'annuaire distribué stockant des informations textuelles dans des enregistrements de différents types
    • Enregistrement de type A et AAAA : fournit la correspondance entre un nom d'hôte et une adresse IP (respectivement version 4 et version 6)
    • Enregistrement de type MX : fournit la correspondance entre le nom d'hôte du serveur de messagerie et un domaine. La concaténation de ces deux informations donne le nom pleinement qualifié (FQDN) et permet aux MTA distants de résoudre l'adresse IP du serveur de destination d'un messsage avec comme seule information le domaine de destination contenu dans le champ X-Original-to d'un courriel
    • Enregistrement de type TXT : champ de texte libre destiné principalement à rendre le DNS fléxible aux nouveaux usages. Un autre protocole n'a alors qu'à lire le contenu du champ pour obtenir l'information à traiter selon un formatage qu'aura respecté son rédacteur
  • Local Mail Transfer Protocol (LMTP) : protocole SMTP simplifié destiné aux seuls échange de courriels entre utilisateurs d'un même MTA


Divers

  • Pourriel ou SPAM : message non désiré et souvent nuisible (hameçonnage, virus, arnaque...). Ils viennent rarement seuls car leurs expéditeurs ont pour habitude d'en envoyer massivement. les pourriels représentaient tout de même entre 90 et 97% du trafic total des courriels fin des années 2000. L'origine du mot SPAM provient d'une marque de viande dont les pratiques publicitaires se rapprochaient de la pratique moderne. Sur un serveur personnel, il reste tout de même assez simple de s'en prémunir en respectant une politique stricte de transmission de vos adresses (alias).
  • HAM : désigne les courriels désirés. Cette notion est utilisée par le logiciel anti-pourriels Spamassassin lors de son usage de l'inférence bayésienne. Le terme est issue d'une partie du jambon en référence aux origines du mot SPAM et représente son opposé
  • Boites aux lettres (BAL) : répertoire de messagerie personnelle d'un utilisateur destinée à accueillir ses correspondances (répertoire ~/Maildir de la documentation)
  • Message de non-délivrance (bounce) : courrier émis par un MTA à l'émetteur d'un message lorsque celui-ci n'a pu être délivré afin de l'en informer
  • Relais de courrier ouvert : serveur SMTP permettant à n'importe qui sur Internet d'envoyer un courriel par son intermédiaire
  • Liste noire en temps réel (Realtime Blackhole List ou RBL) : listes de serveurs ou de réseaux IP connus pour aider, accueillir, produire ou retransmettre des pourriels ou fournir un service pouvant en émettre (relais ouverts)