first commit

This commit is contained in:
VC
2025-02-27 12:51:50 +01:00
commit f5e914e533
234 changed files with 11519 additions and 0 deletions

View File

@@ -0,0 +1,165 @@
+++
title = "Configurer un relais SMTP (proprement)"
date = 2023-04-18
[taxonomies]
tags = [ "système", "smtp", "tem" ]
+++
> Ah oué, cest tant si simple que ça en fait…
*Michel, désespéré…*
<!-- more -->
Coucou mes ptits Rondoudous, ça faisait un moment.
Il mest arrivé récemment une aventure magique avec des relais SMTP et je me suis dit que ce serait la bonne occasion de faire un petit résumé de ce quil faut faire pour gérer des cas un peu tordus.
Lidée est donc de configurer un relais SMTP dabord simple avec un serveur SMTP que tu maîtrises à 100% et qui est dans le même réseau que toi, puis de sattaquer à un relais SMTP un peu plus compliqué, passant par un TEM (_**T**ransactional **E**-**M**ail_). En loccurence, cest celui de *Scaleway* mais tous ont un fonctionnement remarquablement similaire, donc ça devrait pouvoir sappliquer à tous.
Et comme cest un peu le standard, on va faire tout ça avec du *Postfix*, je suppose quon peut aussi avoir des configurations similaires avec dautres serveur SMTP, mais cest ce que jai sous la main (et cest fort probable que toi aussi).
# Commençons par le pourquoi
Dabord, tu pourrais te demander: mais pourquoi diable devrais-je me crever le cul à installer un relais SMTP qui envoient des messages tout propres depuis mes serveurs?
Bah, cest tout con: quand il y a des soucis, le serveur a tendance à le signaler par courriel. Et il y a encore beaucoup de services (*cron* est lexemple le plus frappant) qui informe les utilisateurs par courriel de ce qui se passe.
Ça permet également dans le cas où un logiciel est installé sur le serveur de le faire sappuyer sur le SMTP du relais plutôt que sur dobscures configurations hétérogènes par toujours facile à manipuler.
Alors évidemment, si tu nas ni *cron*, ni *NUT*, ni quoique ce soit qui serait susceptible denvoyer des courriels depuis ton serveur, tu peux parfaitement ten passer. Mais lexpérience montre que ça arrive bien plus souvent quon ne le souhaiterait.
# Relais SMTP avec_Submission_
Un des trucs importants à comprendre dans *Postfix*, cest quil y a une différence fondamentale entre *SMTP* et *SMTPD*: le premier est la partie «cliente» de SMTP, le second est la partie «serveur». Oui, parce que dans certains cas, *Postfix* reçoit du courrier et sarrange pour le traiter correctement (le transmettre à un _**M**ail **D**elivery **A**gent_ par exemple) et dans dautres cas, il doit aller le transmettre à un autre serveur (un autre _**M**ail **T**ransport **A**gent_).
Pour faire tout ça, il y a des ports standards:
* le port 25 est le port SMTP standard quand on ne chiffre pas la communication (ce qui nempêche de la chiffrer _a posteriori_ avec une commande `STARTTLS`);
* le port 465 est le port SMTP standard mais avec chiffrement _a priori_ (donc pas de `STARTTLS`, on est déjà chiffré quand on arrive);
* le port 587 est le port de soumission pour **demander** gentiment à *Postfix* de livrer le message suggéré. Il est chiffré par défaut et demande généralement une authentification (pas forcément complexe mais voilà).
Donc, voilà, pour cette partie, je vais supposer que tu as déjà un serveur SMTP correctement configuré et que tu as accès au port 587 de ce dernier pour balancer tes mails.
En toute logique, cest un cas assez standard et plutôt simple à mettre en œuvre.
Donc côté «client», on peut donc commencer par un `main.cf` de ce type:
```postfix
# des trucs génériques dont on se fout un peu
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
# !!! TRÈS IMPORTANT
append_dot_mydomain = no
myorigin = buttse.cx # il faut mettre ici le domaine dorigine du message,
# sinon, ça risque de poser pas mal de souci
# ça cest les trucs génériques de Postfix
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
# la destination, cest important: cest un relais, donc il nest pas
# supposé recevoir de messages autrement que pour les utilisateurs
# locaux
mydestination = $myhostname, localhost.$mydomain, localhost
# cest là que la magie opère
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_use_tls = yes
relayhost = [smtp.buttse.cx]:587
# notre serveur ne doit écouter quen local, jamais ailleurs
mynetworks = 127.0.0.0/8
inet_interfaces = loopback-only
smtpd_relay_restrictions = permit_mynetworks,defer_unauth_destination,reject
```
Et donc effectivement, toute la magie tient dans les variables `smtp_sasl_*` et notamment le fichier `/etc/postfix/sasl_passwd`, qui contient lutilisateur/mot de passe pour le serveur SMTP:
```postfix
[smtp.buttse.cx]:587 utilisateur:mot_de_passe
```
Il faut un fichier de hash, donc un petit coup de `postmap` sur le fichier en question et hop!, tout fonctionne! Dès que le serveur veut envoyer un message, il passera par le SMTP local, il aura la bonne adresse source et devrait sappuyer sur le relais qui a été donné.
Ça cétait le cas le plus simple.
# _Submission_failed!
Mais alors que se passe-t-il si ton fournisseur ou ton hébergeur ne te laisse pas accéder au port 587? Généralement, la plupart des TEM ont une config alternatives pour ce cas-là: le port 2525 pour certains, ou comme *Scaleway* le port 2465 (mais le problème est le même pour le port 465). Lidée, cest donc dutiliser le port *SMTPS* avec *Postfix*.
Sauf que loption `relayhost` de *Postfix* ne supporte pas les connexions *SMTPS*. Parce que bien sûr que non.
Du coup, il va falloir ruser pour convaincre *Postfix* de faire comme dhabitude. Et cette ruse, elle nest pas si compliquée que ça, elle sappelle `stunnel`.
Sous Debian/Ubuntu, tu peux donc installer le paquet `stunnel4` et faire une petite configuration de ce type, dans `/etc/stunnel/smtp-wrapper.conf`:
```stunnel
[smtp-tls-wrapper]
accept = 10465
client = yes
connect = smtp.tem.buttse.cx:465
```
Et du coup, lorsque lon démarre le service `stunnel4`, on voit effectivement quil écoute sur le port 10465. Il suffit alors de reconfigurer notre petit *Postfix* comme suit pour sadapter:
```postfix
relayhost = [localhost]:10465
```
Et évidemment, changer également le login/pass/host dans `/etc/postfix/sasl_passwd`:
```sasl_passwd
[localhost]:10465 login:pass
```
Et boum!, ça fait des chocapics!
# Bonus 1: configurer Postfix pour réécrire ladresse cible
Quand il sagit de *cron*, le service a tendance à envoyer les messages à lutilisateur local concerné. Donc si le *cron* `www-data`, qui gère les services Web, se vautre complètement, il enverra un mail à `www-data`, lutilisateur local. Cest super intéressant, mais en loccurence, on préfèrerait largement quil lenvoie à un autre destinataire, jai nommé ladministrateur du système.
Pour cela, on peut forcer *Postfix* à faire une réécriture de tous les messages de destination pour les envoyer ailleurs. Ce nest pas bien compliqué, il suffit dajouter la ligne suivante dans le `main.cf`:
```postfix
recipient_canonical_maps = regexp:/etc/postfix/recipient_canonical
```
Et le fichier `/etc/postfix/recipient_canonical` se présentera comme suit:
```postfix
/.+/ admin@buttse.cx
```
Évidemment, petit malin, rien nempêche daller mettre dautres choses dans ce fichier. Là, tout sera réécrit vers `admin@buttse.cx`, ce nest pas forcément le comportement souhaité _in fine_.
# Bonus 2: configurer Postfix pour réécrire les adresses sources
_Normalement™_, le simple fait davoir un `myorigin` dans le `main.cf` devrait suffire à containdre les adresses locales à utiliser un nom de domaine bien précis.
Malheureusement pour certaines configurations, ce nest pas toujours le cas. Et notamment le `From` et le `Envelope-From` SMTP ne sont pas toujours identiques. Pis, il peut arriver que le TEM ou le relais SMTP refuse le message sil ny a pas correspondance entre ces deux entêtes dans le courriel. Cest en réalité parfaitement logique, lobjectif étant déviter que le message ne se retrouve perdu pour non-respect de SPF/DKIM par exemple.
Mais du coup, ça fait un peu chier…
Heureusement, encore une fois *Postfix* à la rescousse! On peut aussi forcer ce dernier a réécrire les adresses (tous les champs entêtes) pour y mettre une adresse donc on est certain de la conformité.
Pour cela, il va falloir ajouter quelques lignes dans notre `main.cf`:
```postfix
sender_canonical_classes = envelope_sender, header_sender
sender_canonical_maps = regexp:/etc/postfix/sender_canonical_maps
smtp_header_checks = regexp:/etc/postfix/header_check
```
Et on produit donc les deux *maps* permettant de changer les deux entêtes à la fois dans `/etc/postfix/sender_canonical_maps` et `/etc/postfix/header_check` (cest exactement le même fichier):
```postfix
/.+/ youplaboom@mondomainesour.ce
```
Et voilà, tous les courriels vont maintenant venir de `youplaboom@mondomainesour.ce`!
# Conclusation
Bah voilà, maintenant, il ny a plus dexcuses pour ne pas mettre un relais SMTP tout propre sur tes serveurs histoire davoir une idée de ce qui se passe sur le système.