Files
BaC/content/2023-04-18-Configurer-un-relais-SMTP-(proprement).md
2025-02-27 12:52:48 +01:00

9.3 KiB
Raw Blame History

+++ 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é…

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 (Transactional E-Mail). 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 avecSubmission

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 Mail Delivery Agent par exemple) et dans dautres cas, il doit aller le transmettre à un autre serveur (un autre Mail Transport Agent).

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:

# 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:

[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.

Submissionfailed!

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:

[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:

relayhost = [localhost]:10465

Et évidemment, changer également le login/pass/host dans /etc/postfix/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:

recipient_canonical_maps = regexp:/etc/postfix/recipient_canonical

Et le fichier /etc/postfix/recipient_canonical se présentera comme suit:

/.+/ 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:

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):

/.+/ 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.