« Serveur de courriels » : différence entre les versions
(Ajout des ports nécessaires pour le pare-feu.) |
(Replacement des balise de coloration syntaxique en ligne par des balises codes pour optimiser le chargement de la page + correction de fautes de frappes) |
||
(17 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
[[Category: | [[Category:service_courriels]] | ||
Postfix est un serveur de messagerie électronique | ''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|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 [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] | ||
* | |||
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'' | |||
La réponse doit contenir une | * 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 | ||
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> | |||
Génération de la clé Diffie Hellman (si on ne le fait pas, Postfix utilise la sienne) | ==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 : | |||
{{info| | <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...}} | |||
=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 <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. | |||
===Main.cf=== | ===Main.cf=== | ||
Édition du fichier de configuration principal | Édition du fichier de configuration principal | ||
vim /etc/postfix/main.cf | |||
La configuration suivante sera utilisée : | La configuration suivante sera utilisée : | ||
< | <syntaxhighlight lang="bash"> | ||
# smtpd : entrant/inbound | # smtpd : entrant/inbound | ||
# smtp : sortant/outbound | # smtp : sortant/outbound | ||
#------------------------------------Connexion | # ------------------------------------ Connexion protocole SMTP ------------------------------------ # | ||
# Bannière | # 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 | 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 | disable_vrfy_command = yes | ||
# Impose au client SMTP de démarrer la session SMTP par une commande Helo | # 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 | smtpd_helo_required = yes | ||
#------------------------------------Gestion des messages locaux ( | # ------------------------------------ Gestion des messages locaux (inutile dans notre cas) ------------------------------------ # | ||
# Service qui envoie des notifications "nouveau message" | # Service qui envoie des notifications "nouveau message" | ||
biff = no | biff = no | ||
# Avec le courrier local ça ajoute .NDD aux adresses incomplètes (seulement le nom d' | # Avec le courrier local ça ajoute .NDD aux adresses incomplètes (seulement le nom d'hôte) | ||
append_dot_mydomain = no | append_dot_mydomain = no | ||
#------------------------------------Nom de machine et réseaux autorisés------------------------------------# | # ------------------------------------ Nom de machine et réseaux autorisés ------------------------------------ # | ||
# Le nom de la machine du système de messagerie | # Le nom de la machine du système de messagerie | ||
# Par défaut c'est | # Par défaut c'est hôte.domaine.tld mais il est possible de mettre un nom de domaine inversé | ||
myhostname = mail.exemple.fr | myhostname = mail.exemple.fr | ||
# Le domaine utilisé par | # Le domaine utilisé par défaut pour poster les messages | ||
myorigin = mail.exemple.fr | myorigin = mail.exemple.fr | ||
# Liste des domaines pour | # Liste des domaines pour lesquels le serveur doit accepter le courrier en local | ||
mydestination = mail. | mydestination = mail.exemple.fr, localhost.exemple.fr, localhost | ||
# | # Relais par lequel notre serveur doit adresser son trafic (nous n'en utilisons aucun) | ||
relayhost = | relayhost = | ||
# Liste des réseaux locaux autorisés (leur permet d'outrepasser le SASL) | # Liste des réseaux locaux autorisés (leur permet d'outrepasser le SASL) | ||
mynetworks = 192.168 | mynetworks = 192.168.0.0/16, 127.0.0.0/8 | ||
# Activation d'IPv6 ( | # Activation d'IPv4 et IPv6 (valeur par défaut) | ||
inet_protocols = all | inet_protocols = all | ||
# Séparateur entre le nom d'utilisateur et les extensions d'adresses | # Séparateur entre le nom d'utilisateur et les extensions d'adresses | ||
Ligne 91 : | Ligne 132 : | ||
inet_interfaces = all | inet_interfaces = all | ||
#------------------------------------Règles SMTP------------------------------------# | # ------------------------------------ Règles SMTP ------------------------------------ # | ||
#Restrictions d'accès | # 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_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é | # 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_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 | # reject_unauth_destination : Rejette la requête sauf si l'une des propositions listés dans la documentation officielle est vraie | ||
# reject_unknown_recipient_domain : Rejette la requête lorsque le RCPT TO ne correspond à aucun A ou MX | # 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 = | smtpd_recipient_restrictions = | ||
permit_mynetworks, | permit_mynetworks, | ||
Ligne 104 : | Ligne 146 : | ||
reject_non_fqdn_recipient, | reject_non_fqdn_recipient, | ||
reject_unauth_destination, | reject_unauth_destination, | ||
check_recipient_access sqlite:/etc/postfix/sqlite-liste-noire-destinataires.cf, | |||
reject_unknown_recipient_domain, | reject_unknown_recipient_domain, | ||
Ligne 114 : | Ligne 157 : | ||
permit_mynetworks, | permit_mynetworks, | ||
permit_sasl_authenticated, | permit_sasl_authenticated, | ||
reject_invalid_helo_hostname, | reject_invalid_helo_hostname, | ||
reject_non_fqdn_helo_hostname, | reject_non_fqdn_helo_hostname, | ||
# reject_unknown_helo_hostname | |||
# Règles de connexion des clients | # 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_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 | # 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é | # 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 | # 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 | # reject_plaintext_session : Refuser les connexions non chiffrés | ||
# reject_unauth_pipelining : | # 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 = | smtpd_client_restrictions = | ||
permit_mynetworks, | permit_mynetworks, | ||
permit_inet_interfaces, | permit_inet_interfaces, | ||
permit_sasl_authenticated, | permit_sasl_authenticated, | ||
reject_rbl_client zen.spamhaus.org | # reject_rbl_client zen.spamhaus.org | ||
# reject_plaintext_session, | # reject_plaintext_session, | ||
# reject_unauth_pipelining # L'utilisation de reject_unauth_pipelining dans les autres contextes que smtpd_data_restrictions n'est pas recommandé | # reject_unauth_pipelining # L'utilisation de reject_unauth_pipelining dans les autres contextes que smtpd_data_restrictions n'est pas recommandé | ||
Ligne 135 : | Ligne 179 : | ||
# reject_non_fqdn_sender : Refuser les expéditeurs invalides (non FQDN) | # 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 | # 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 | # 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 = | smtpd_sender_restrictions = | ||
reject_non_fqdn_sender, | reject_non_fqdn_sender, | ||
reject_unknown_sender_domain, | reject_unknown_sender_domain, | ||
check_sender_access | check_sender_access sqlite:/etc/postfix/sqlite-liste-noire-expediteurs.cf | ||
#Restrictions d'accès | # Restrictions d'accès optionnelles appliquées dans le contexte d'une commande SMTP DATA | ||
# reject_unauth_pipelining : | # reject_unauth_pipelining : Expliqué plus haut (trop long) | ||
# permit : Tout est autorisé par défaut | # permit : Tout est autorisé par défaut | ||
smtpd_data_restrictions = | smtpd_data_restrictions = | ||
Ligne 148 : | Ligne 192 : | ||
permit | permit | ||
#------------------------------------Gestion des boites et des messages------------------------------------# | # ------------------------------------ Gestion des boites aux lettres et des messages ------------------------------------ # | ||
# Taille des boîtes | # Taille des boîtes aux lettres (0 = illimité) | ||
mailbox_size_limit = 0 | mailbox_size_limit = 0 | ||
#Fixer la taille limite des messages (ici 30Mo) | # Fixer la taille limite des messages (ici 30Mo) | ||
message_size_limit = 31457280 | message_size_limit = 31457280 | ||
# Répertoire de destination des courriers | # Répertoire de destination des courriers | ||
home_mailbox = Maildir/ | # 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 | |||
#---------------------------------------------- | #---------------------------------------------- | ||
Ligne 165 : | Ligne 214 : | ||
#---------------------------------------------- | #---------------------------------------------- | ||
#Emplacement du fichier des alias | # Emplacement du fichier des alias | ||
#Alias de comptes | # Alias de comptes principaux | ||
alias_maps = | alias_maps = sqlite:/etc/postfix/sqlite-alias.cf | ||
#Alias de domaines | # Alias de domaines | ||
virtual_alias_maps = | virtual_alias_maps = sqlite:/etc/postfix/sqlite-alias-vituels.cf | ||
virtual_alias_domains = | # virtual_alias_domains = sqlite:/etc/postfix/sqlite-domaines.cf | ||
#-------------------- | #-------------------- | ||
Ligne 186 : | Ligne 234 : | ||
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options | smtpd_sasl_tls_security_options = $smtpd_sasl_security_options | ||
smtpd_sasl_local_domain = $mydomain | smtpd_sasl_local_domain = $mydomain | ||
# Reporte le nom d'utilisateur SASL authentifié dans l'en-tête de message Received du serveur | # Reporte le nom d'utilisateur SASL authentifié dans l'en-tête de message "Received" du serveur | ||
smtpd_sasl_authenticated_header = yes | smtpd_sasl_authenticated_header = yes | ||
# N'accepte pas le support de l'ancienne commande AUTH (Outlook 4 par exemple) | # N'accepte pas le support de l'ancienne commande AUTH (Outlook 4 par exemple) | ||
broken_sasl_auth_clients = no | broken_sasl_auth_clients = no | ||
#------------------------------------Chiffrement------------------------------------# | # ------------------------------------ Chiffrement ------------------------------------ # | ||
# | # clés et certificats pour les sessions TLS | ||
smtpd_tls_cert_file = / | smtpd_tls_cert_file = $config_directory/tls/courriel.pem | ||
smtpd_tls_key_file = / | smtpd_tls_key_file = $config_directory/tls/courriel.key | ||
smtpd_tls_dh1024_param_file = $config_directory/ | smtpd_tls_dh1024_param_file = $config_directory/tls/dh4096.pem | ||
#------------------ | #------------------ | ||
Ligne 202 : | Ligne 250 : | ||
#------------------ | #------------------ | ||
# | # Verbosité des journaux | ||
smtp_tls_loglevel = 1 | smtp_tls_loglevel = 1 | ||
# | # Impose de se connecter à des serveurs SMTP via TLS | ||
smtp_tls_security_level = | smtp_tls_security_level = encrypt | ||
# | # N'autoriser que le TLS version 1.2 et 1.3 | ||
smtp_tls_protocols = | smtp_tls_protocols = TLSv1.2:TLSv1.3 | ||
# | # incompréhension exprimé plus haut | ||
smtp_tls_mandatory_protocols = | 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 | smtp_tls_note_starttls_offer = yes | ||
#N'autoriser que les chiffrements | # N'autoriser que les chiffrements de la liste "medium" définie plus bas | ||
smtp_tls_mandatory_ciphers = | smtp_tls_mandatory_ciphers = medium | ||
#Exclure les algorithmes obsolètes ou | # 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 | 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 | 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 | # 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 | smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache | ||
Ligne 225 : | Ligne 274 : | ||
#------------------- | #------------------- | ||
# | # Verbosité des journaux | ||
smtpd_tls_loglevel = 1 | smtpd_tls_loglevel = 1 | ||
# | # Impose de se connecter à des serveurs SMTP via TLS | ||
smtpd_tls_security_level = | smtpd_tls_security_level = encrypt | ||
#Refuse les authentifications SASL en clair si le serveur gère | # 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 | 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 | # 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 | smtpd_tls_received_header = yes | ||
# Source du générateur de nombre aléatoire pour les algorithmes de chiffrement | # Source du générateur de nombre aléatoire pour les algorithmes de chiffrement | ||
tls_random_source = dev:/dev/urandom | tls_random_source = dev:/dev/urandom | ||
# Versions de TLS autorisés (SSL refusé) | # Versions de TLS autorisés (SSL refusé) | ||
smtpd_tls_protocols = TLSv1 | 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 | # 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 | smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1, TLSv1.2, TLSv1.3 | ||
#Cache TLS. Permet de mémoriser les ancienne sessions TLS afin d'effectuer une poignée de mains raccourcie. Ce qui améliore | # 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 | smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache | ||
#------------------------------------ | # ------------------------------------ En-têtes des courriels ------------------------------------ # | ||
# Emplacement des fichiers de suppression de | # 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 | # 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 | mime_header_checks = regexp:/etc/postfix/header_checks | ||
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://postfix.traduc.org/index.php/postconf.5.html | ||
# http://www.postfix.org/postconf.5.html | # http://www.postfix.org/postconf.5.html | ||
</source> | </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 | |||
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 : | |||
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) | |||
<syntaxhighlight lang="bash"> | |||
cat << '_EOF_' > /etc/postfix/header_checks | |||
/^Received:.*with ESMTPSA/ IGNORE | |||
/^X-Originating-IP:/ IGNORE | |||
/^X-Mailer:/ IGNORE | |||
/^User-Agent:/ IGNORE | |||
_EOF_ | |||
</syntaxhighlight> | |||
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 | |||
<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=== | |||
''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. | |||
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é : | |||
<syntaxhighlight lang="bash"> | |||
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} | |||
</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.}} | |||
=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== | ==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 <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) | ||
echo -e '\nlisten = *, [::]' >> /etc/dovecot/dovecot.conf | |||
===Emplacement des dossiers utilisateurs=== | ===Emplacement des dossiers utilisateurs=== | ||
Configuration de l'emplacement du répertoire des | Configuration de l'[https://doc.dovecot.org/configuration_manual/mail_location/ 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 ( | Configuration de la [https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/ couche de chiffrement] (qui sera rendue obligatoire) | ||
mv /etc/dovecot/conf.d/10-ssl.conf /etc/dovecot/conf.d/10-ssl.conf.ori | |||
<syntaxhighlight lang="bash"> | |||
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_ | |||
</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 | 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 | ||
< | <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 | ||
# | 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 | |||
Nous utiliserons des [[#Outils_WEB|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 : | |||
* https://wiki.debian.org/DebianSpamAssassin | |||
* https://www.malekal.com/installer-configurer-spamassassin-debian/ | |||
* https://www.linuxbabe.com/redhat/spamassassin-centos-rhel-block-email-spam | |||
==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 <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). | |||
''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. | |||
<syntaxhighlight lang="bash"> | |||
cat << '_EOF_' > /usr/lib/tmpfiles.d/spamassassin.conf | |||
d /run/spamassassin 0750 spamassassin spamassassin - - | |||
_EOF_ | |||
</syntaxhighlight> | |||
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 : <code>/var/run</code> est un lien symbolique du tmpfs <code>/run</code> présent de base dans le système.'' | |||
Configuration du service | |||
<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 | |||
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é. | |||
==Tests de communication== | |||
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''. | |||
==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 [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 | |||
}} | |||
== | ==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 <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. | |||
Depuis votre client de messagerie, vous verrez le message précédemment envoyé placé dans la boite "indésirables". | |||
== | =Débogage= | ||
Message | ==Messages d'erreurs connus== | ||
Cette section regroupe quelques erreurs qui ont déjà étés rencontrés et observables dans le fichier <code>/var/log/mail.log</code>. | |||
{| class="wikitable" | |||
|- | |||
! Message !! Signification | |||
|- | |||
| <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= | ||
== | ==Affichage des configurations== | ||
{| class="wikitable" | |||
|- | |||
! Commande !! Signification | |||
|- | |||
| <code>postconf -d</code> || Renvoie le contenu du fichier [[#Main.cf|main.cf]] par défaut | |||
|- | |||
| <code>postconf -n</code> || Renvoie le contenu actuel du fichier [[#Main.cf|main.cf]] sans les commentaires | |||
ou | |- | ||
| <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 | 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 | |||
|- | |||
Mettre un messages en attente | | <code>postsuper -d DBB3F1A7</code> || Supprime un message en queue | ||
|- | |||
Remettre un messages en mode normale | | <code>postsuper -d ALL</code> || Supprime tous les messages en queue | ||
|- | |||
Remettre en | | <code>postsuper -h DBA3F1A7</code> || Mettre un messages en attente | ||
|- | |||
| <code>postsuper -H DBA3F1A7</code> || Remettre un messages en mode normale | |||
|- | |||
Afficher le contenu d'un message | | <code>postsuper -r DBA3F1A7</code> || Remettre en queue un message | ||
|- | |||
Forcer l' | | <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. | |||
= | ==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'' ([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'' | |||
==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 unmkdir -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 :
- https://wiki.debian.org/DebianSpamAssassin
- https://www.malekal.com/installer-configurer-spamassassin-debian/
- https://www.linuxbabe.com/redhat/spamassassin-centos-rhel-block-email-spam
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 untail -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'outilswaks
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)