Rien ne vous fait vieillir plus vite qu’une panne de messagerie dont la cause racine est « nous sommes devenus un relais ouvert ». Une minute vous publiez une version normale ; la suivante, vous voyez votre IP publique se faire mettre sur liste noire pendant que votre PDG se demande pourquoi « notre serveur mail spamme la Moldavie ».
Ce n’est pas un risque théorique. C’est un mode de défaillance de configuration avec des tests clairs et reproductibles et des preuves non ambiguës dans les logs. La correction est ennuyeuse, précise et entièrement sous votre contrôle. Faisons-le comme les systèmes de production l’exigent : testez, prouvez, neutralisez, et documentez pour éviter une régression.
Ce que « relais ouvert » signifie réellement (et ce que ce n’est pas)
Un relais ouvert est un serveur SMTP qui acceptera un message d’un client non authentifié et non approuvé et le transférera vers un domaine tiers. En clair : un hôte internet aléatoire se connecte à votre Postfix, lui remet un message « de » n’importe qui « à » n’importe qui, et votre serveur accepte de le livrer vers l’extérieur.
C’est le cœur du problème. Tout le reste n’est que bruit.
- Pas un relais ouvert : un serveur qui accepte du courrier pour ses propres domaines (
mydestination, domaines virtuels) depuis Internet et le délivre localement. - Pas un relais ouvert : un serveur qui relaie le courrier sortant uniquement pour des utilisateurs authentifiés (SASL sur submission) ou des réseaux de confiance (
mynetworks). - Est un relais ouvert : accepte du courrier de sources arbitraires et relaie vers des destinations arbitraires.
Le malentendu dangereux : « nous sommes derrière un pare-feu » ou « le port 25 est seulement pour l’entrée » peut se transformer en « Bien sûr, autorisons le relais depuis 10.0.0.0/8 » puis quelqu’un ajoute un VPN, un sous-réseau mal routé ou un réseau de conteneurs qui ne devrait pas être de confiance. Félicitations, vous avez donné à votre infrastructure l’équivalent électronique d’un laissez-passer invité qui n’expire jamais.
Exactement ce que vous devez pouvoir dire : « Depuis une IP non approuvée, sans authentification, Postfix rejette les tentatives de relais vers des destinations non locales avec une erreur de politique claire. » C’est votre preuve. Le reste, ce sont des impressions.
Faits et historique : pourquoi cela réapparaît
Les relais ouverts sont un vieux problème, mais ils réapparaissent parce que le mail est un champ de compatibilité et que certains le traitent comme une case à cocher.
- Le SMTP initial supposait un réseau amical. L’écosystème mail originel se comportait comme un club où tout le monde se connaissait. Cette hypothèse a disparu sur l’Internet public.
- Dans les années 1990, les relais ouverts étaient partout. Ils étaient souvent configurés pour « aider » à livrer le courrier d’utilisateurs en dial-up ou de petits réseaux d’entreprise mal configurés.
- Les listes noires sont devenues un mécanisme de survie. Quand le spam a explosé, les opérateurs ont commencé à publier les IPs des relais et spammeurs connus. La délivrabilité est devenue une propriété opérationnelle, pas seulement technique.
- Postfix a été conçu pour être plus sûr que ses prédécesseurs. L’une des raisons du succès de Postfix est son objectif d’être sécurisé par défaut comparé à la culture « éditez ce fichier et espérez ».
- La submission (587) existe parce que le port 25 est chaotique. L’industrie a séparé le SMTP « serveur-à-serveur » de la « soumission utilisateur » pour améliorer l’authentification et le contrôle des politiques.
- SASL et TLS n’ont pas « résolu » le spam, mais ils ont déplacé l’endroit où appliquer la politique. Le modèle moderne : authentifier les utilisateurs sur 587, être strict sur 25.
- NAT et réseaux cloud ont créé de nouvelles frontières de confiance. « IP interne » ne signifie plus « hôte contrôlé par l’opérateur ». Cela peut être un conteneur oublié.
- La mauvaise configuration est la cause dominante. Les relais ouverts sont rarement des intrusions sophistiquées. Il s’agit généralement de « nous avons mis
mynetworks=0.0.0.0/0pendant un test et avons oublié. »
Une citation à coller près de votre config MTA : « L’espoir n’est pas une stratégie. »
— Gordon R. Dickson
Modèle de menace : comment les attaquants trouvent et exploitent les relais
Les attaquants n’ont pas besoin de « pirater » Postfix pour l’abuser. Ils ont juste besoin que le serveur dise « OK » au mauvais moment.
Découverte
Ils scannent. Constamment. Des plages IPv4 entières sont sondées pour SMTP sur 25, 465, 587. L’hôte de scan peut être un nœud de botnet, un VPS ou quelque chose déjà listé. Vous verrez des connexions brèves, des chaînes HELO ressemblant à des frappes au hasard et une tentative rapide d’envoyer vers un domaine externe.
Exploitation
Si le relais est permis, l’attaquant remet à votre serveur un tas de courriels. Votre système devient le canon ; votre IP devient l’empreinte. Vous payez la bande passante, le stockage de la file, le CPU et la réputation.
Impact
- Immédiaire : croissance de la file mail, pics d’utilisation disque, saturation des workers SMTP, mails sortants légitimes retardés ou perdus.
- Secondaire : mise sur liste noire ; partenaires refusant le courrier ; emails de réinitialisation de mot de passe non reçus ; tickets support en hausse.
- Long terme : la récupération de la délivrabilité prend du temps même après la correction du relais. La réputation est tenace ; les listes noires aussi.
Blague n°1 : Un relais ouvert, c’est comme laisser une affiche « livraison gratuite » sur votre quai de chargement. Internet ne prendra pas poliment qu’une seule boîte.
Playbook de diagnostic rapide (premiers/deuxièmes/troisièmes contrôles)
Si vous suspectez une exposition de relais ouvert — ou si vous répondez à « pourquoi la file mail explose » — ne parcourez pas les fichiers de config comme si vous cherchiez une clé perdue. Exécutez systématiquement ces trois contrôles à chaque fois.
Premier : Confirmer le symptôme (est-ce que nous relayons ?)
- Cherchez
status=sentvers des domaines externes originant d’IPs suspectes. - Cherchez
Relay access denied(bon) versus relais réussi (mauvais). - Vérifiez si l’afflux est sur le port 25 (serveur-à-serveur) ou 587 (submission).
Deuxième : Identifier la porte de politique qui a échoué
- Inspectez
smtpd_recipient_restrictions,smtpd_relay_restrictions,mynetworkset les paramètres SASL. - Confirmez ce que Postfix considère comme « local » via
mydestinationet les maps de domaines virtuels.
Troisième : Arrêter l’hémorragie en toute sécurité
- Resserrez temporairement les restrictions (rejeter le relais depuis partout sauf réseaux connus / authentification).
- Appliquez des limites de débit et/ou rejetez les clients suspects ; envisagez le blocage au pare-feu si le trafic est extrême.
- Gérez et contrôlez la file (ne supprimez pas à l’aveugle — identifiez d’abord l’étendue).
Une fois l’incendie maîtrisé, vous pourrez faire le travail plus minutieux : prouver le comportement non-relai depuis l’extérieur, valider la configuration de submission et mettre à jour les runbooks.
Prouvez-le avec des tests : commandes, sorties, décisions (12+ tâches)
Ci-dessous des tâches pratiques à exécuter sur un hôte Linux typique exécutant Postfix. Le but n’est pas d’admirer la sortie. Le but est de prendre des décisions à partir de celle-ci.
Task 1: Confirm Postfix is running and what ports it’s listening on
cr0x@server:~$ systemctl status postfix --no-pager
● postfix.service - Postfix Mail Transport Agent
Loaded: loaded (/lib/systemd/system/postfix.service; enabled; preset: enabled)
Active: active (running) since Tue 2026-01-03 08:11:32 UTC; 3h 14min ago
Docs: man:postfix(1)
Main PID: 1223 (master)
Tasks: 4 (limit: 18921)
Memory: 18.4M
CPU: 1min 12s
Ce que cela signifie : Postfix est actif. S’il n’est pas en cours, vous n’êtes pas un relais ouvert — vous êtes simplement en panne.
Décision : Passez aux vérifications des ports. Si inactif, restaurez le service d’abord, puis validez les configs avant de rouvrir le pare-feu.
cr0x@server:~$ ss -lntp | egrep ':(25|465|587)\s'
LISTEN 0 100 0.0.0.0:25 0.0.0.0:* users:(("master",pid=1223,fd=13))
LISTEN 0 100 0.0.0.0:587 0.0.0.0:* users:(("master",pid=1223,fd=15))
Ce que cela signifie : Les ports 25 et 587 sont ouverts sur toutes les interfaces. C’est normal pour de nombreux serveurs ; c’est aussi la raison pour laquelle vous devez être strict sur la politique de relais.
Décision : Si cet hôte ne doit pas accepter SMTP public, liez-le à des interfaces spécifiques ou fermez les ports au pare-feu/groupe de sécurité.
Task 2: See Postfix’s effective configuration (not what you think you set)
cr0x@server:~$ postconf -n
myhostname = mx1.example.net
mydestination = $myhostname, localhost.example.net, localhost
mynetworks = 127.0.0.0/8 [::1]/128 10.10.0.0/16
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
smtpd_recipient_restrictions = permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_tls_security_level = may
Ce que cela signifie : Ceci est la configuration effective non par défaut. Vous vous souciez surtout de mynetworks, smtpd_relay_restrictions et de l’endroit où reject_unauth_destination apparaît.
Décision : Si defer_unauth_destination ou reject_unauth_destination manque, vous êtes en terrain dangereux. Corrigez immédiatement.
Task 3: Verify mynetworks isn’t “the internet in disguise”
cr0x@server:~$ postconf mynetworks
mynetworks = 127.0.0.0/8 [::1]/128 10.10.0.0/16
Ce que cela signifie : La confiance est accordée à 10.10.0.0/16. C’est acceptable uniquement si vous contrôlez pleinement ce réseau et pouvez garantir chaque hôte qui peut atteindre le port 25/587.
Décision : Si vous voyez 0.0.0.0/0, 10.0.0.0/8 « parce que c’est interne », ou des CIDR de cloud VPC qui incluent des workloads tiers ou transitoires, resserrez-le. Préférez des sous-réseaux explicites pour les clients mail, ou évitez d’utiliser permit_mynetworks pour le relais.
Task 4: Confirm the relay restrictions are in the right place (Postfix version nuance)
cr0x@server:~$ postconf smtpd_relay_restrictions
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
Ce que cela signifie : Postfix permettra le relais pour les réseaux de confiance et les clients authentifiés, et différera les destinations non autorisées (effectivement « pas autorisé »). Les versions modernes de Postfix attendent la politique de relais ici.
Décision : Si smtpd_relay_restrictions est vide ou trop permissif, vous êtes candidat pour un relais ouvert. Corrigez cela avant toute autre action.
Task 5: Test relay behavior from the server itself (baseline)
Ce test n’est pas suffisant en soi (car localhost peut être dans mynetworks), mais il confirme vos outils et les bases DNS.
cr0x@server:~$ swaks --server 127.0.0.1 --from test@external.example --to someone@gmail.com
=== Trying 127.0.0.1:25...
=== Connected to 127.0.0.1.
<-- 220 mx1.example.net ESMTP Postfix
--> EHLO server
<-- 250-mx1.example.net
<-- 250 PIPELINING
--> MAIL FROM:<test@external.example>
<-- 250 2.1.0 Ok
--> RCPT TO:<someone@gmail.com>
<-- 554 5.7.1 <someone@gmail.com>: Relay access denied
Ce que cela signifie : Le serveur a refusé le relais vers Gmail. C’est bon. S’il avait accepté RCPT et poursuivi vers DATA, c’est une alerte rouge.
Décision : Même si cela semble bon, vous devez tester depuis un hôte non approuvé en dehors de mynetworks.
Task 6: Test relay behavior from an external host (the proof)
Exécutez depuis une machine séparée sur Internet qui n’est pas dans vos réseaux de confiance et non authentifiée. Utilisez un domaine de destination que vous ne contrôlez pas.
cr0x@server:~$ swaks --server mx1.example.net --from probe@external.example --to someone@yahoo.com --timeout 15
=== Trying 203.0.113.10:25...
=== Connected to 203.0.113.10.
<-- 220 mx1.example.net ESMTP Postfix
--> EHLO probehost
<-- 250-mx1.example.net
<-- 250 STARTTLS
--> MAIL FROM:<probe@external.example>
<-- 250 2.1.0 Ok
--> RCPT TO:<someone@yahoo.com>
<-- 554 5.7.1 <someone@yahoo.com>: Relay access denied
Ce que cela signifie : C’est votre preuve. Le serveur rejette le relais pour des clients externes non authentifiés.
Décision : Sauvegardez cette sortie (ticket, notes d’incident, preuve d’audit). Si ce test ne rejette pas, traitez-le comme un incident.
Task 7: Confirm it still accepts inbound mail for local domains
cr0x@server:~$ swaks --server mx1.example.net --from probe@external.example --to postmaster@example.net --timeout 15
=== Trying 203.0.113.10:25...
=== Connected to 203.0.113.10.
<-- 220 mx1.example.net ESMTP Postfix
--> EHLO probehost
<-- 250-mx1.example.net
--> MAIL FROM:<probe@external.example>
<-- 250 2.1.0 Ok
--> RCPT TO:<postmaster@example.net>
<-- 250 2.1.5 Ok
--> DATA
<-- 354 End data with <CR><LF>.<CR><LF>
Ce que cela signifie : Votre serveur n’est pas « fermé » pour les affaires. Il accepte le courrier pour des destinataires locaux tout en refusant le relais vers des tiers.
Décision : Si la livraison locale échoue, vérifiez mydestination, les maps de domaines virtuels et les tables de destinataires avant de toucher aux règles de relais.
Task 8: Inspect mail logs for relay decisions (what Postfix actually did)
cr0x@server:~$ sudo grep -E "Relay access denied|reject_unauth_destination|status=sent" /var/log/mail.log | tail -n 20
Jan 03 10:44:11 mx1 postfix/smtpd[18844]: NOQUEUE: reject: RCPT from unknown[198.51.100.77]: 554 5.7.1 <someone@yahoo.com>: Relay access denied; from=<probe@external.example> to=<someone@yahoo.com> proto=ESMTP helo=<probehost>
Jan 03 10:44:42 mx1 postfix/smtpd[18845]: NOQUEUE: reject: RCPT from unknown[198.51.100.78]: 554 5.7.1 <random@gmail.com>: Relay access denied; from=<payroll@external.example> to=<random@gmail.com> proto=ESMTP helo=<workstation>
Ce que cela signifie : NOQUEUE et « rejet au RCPT » est ce que vous voulez : un rejet peu coûteux avant d’accepter les données du message.
Décision : Si vous voyez des relais réussis (status=sent) pour des clients que vous ne reconnaissez pas, commencez la contention et la revue de configuration maintenant.
Task 9: Check the queue size and whether it’s runaway spam
cr0x@server:~$ mailq | head -n 20
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
A1B2C3D4E5 1423 Tue Jan 3 10:49:02 spammer@fake.example
victim1@gmail.com
F6G7H8I9J0 1501 Tue Jan 3 10:49:03 spammer@fake.example
victim2@yahoo.com
Ce que cela signifie : Destinataires externes et expéditeurs suspects sont un schéma classique d’abus de relais. La file va consommer le disque et les IOPS jusqu’à ce que votre machine devienne un chauffe-eau très coûteux.
Décision : Si la file croît activement, contientez : resserrez les règles de relais, bloquez les IP abusives et envisagez des limites de débit temporaires. Ensuite, décidez de purger les spams après avoir conservé des preuves.
Task 10: Inspect a specific queued message (scope and origin)
cr0x@server:~$ postcat -q A1B2C3D4E5 | sed -n '1,60p'
*** ENVELOPE RECORDS ***
message_size: 1423
message_arrival_time: Tue Jan 3 10:49:02 2026
sender: spammer@fake.example
recipient: victim1@gmail.com
*** MESSAGE CONTENTS ***
Received: from unknown (unknown [198.51.100.77])
by mx1.example.net (Postfix) with ESMTP id A1B2C3D4E5
for <victim1@gmail.com>; Tue, 3 Jan 2026 10:49:02 +0000 (UTC)
Subject: Urgent invoice
Ce que cela signifie : Il montre une connexion depuis une IP non approuvée. C’est votre preuve évidente si le relais a été accepté.
Décision : Si vous confirmez l’abus, conservez un échantillon d’en-têtes et les lignes de logs. Puis purgez les spams et changez les identifiants si une authentification a été impliquée.
Task 11: Check master.cf for unintended services (submission, smtps, policy overrides)
cr0x@server:~$ sudo postconf -M | egrep '^(smtp|submission|smtps)/'
smtp/inet/smtp
submission/inet/submission
Ce que cela signifie : Les services existent. C’est bien. Le danger vient des overrides par service qui autorisent par inadvertance un relais large.
Décision : Inspectez les strophes submission et smtps pour des overrides -o qui affaiblissent les restrictions.
cr0x@server:~$ sudo sed -n '1,160p' /etc/postfix/master.cf
smtp inet n - y - - smtpd
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
Ce que cela signifie : Submission exige TLS et authentification, et rejette autrement. C’est bien : cela empêche la « soumission anonyme ».
Décision : Si vous voyez permit_mynetworks sur submission sans un mynetworks restreint, vous faites confiance à la mauvaise couche.
Task 12: Confirm SASL is actually working on 587 (or you’ll punch holes elsewhere)
cr0x@server:~$ swaks --server mx1.example.net --port 587 --tls --auth LOGIN --auth-user 'user@example.net' --auth-password 'wrongpass' --from user@example.net --to someone@gmail.com
=== Trying 203.0.113.10:587...
=== Connected to 203.0.113.10.
<-- 220 mx1.example.net ESMTP Postfix
--> EHLO probehost
<-- 250-AUTH PLAIN LOGIN
--> AUTH LOGIN
<-- 334 VXNlcm5hbWU6
--> dXNlckBleGFtcGxlLm5ldA==
<-- 334 UGFzc3dvcmQ6
--> d3JvbmdwYXNz
<-- 535 5.7.8 Error: authentication failed: authentication failure
Ce que cela signifie : L’auth est appliquée. Un mauvais mot de passe échoue. Bien.
Décision : Si l’auth est « off » ou non annoncée, corrigez cela plutôt que d’élargir mynetworks comme solution de contournement.
Task 13: Validate the server’s local domains and avoid accidental “local = relay” confusion
cr0x@server:~$ postconf mydestination
mydestination = $myhostname, localhost.example.net, localhost
Ce que cela signifie : Seuls ces domaines sont considérés comme locaux pour la livraison classique. Si vous hébergez example.net en tant que domaine entrant, il doit apparaître via virtual_mailbox_domains ou similaire, pas nécessairement dans mydestination.
Décision : Gardez les définitions de domaines locaux précises. Des « domaines locaux » trop larges peuvent provoquer des boucles de routage et des surprises de politique.
Task 14: Confirm what IP Postfix thinks the client is (proxy and load balancer traps)
cr0x@server:~$ postconf smtpd_upstream_proxy_protocol
smtpd_upstream_proxy_protocol =
Ce que cela signifie : Pas de proxy protocol. Si vous êtes derrière un load balancer TCP ou un reverse proxy pour SMTP et que vous avez mal configuré la conservation de l’IP client, Postfix peut considérer chaque client comme « interne » (l’IP du proxy), accordant par erreur le relais.
Décision : Si vous frontpez SMTP avec un proxy, concevez soigneusement : préservez l’IP client et restreignez en fonction des sources réelles, pas du proxy.
Modèle mental de configuration Postfix : les réglages qui comptent
Postfix peut ressembler à un sac de paramètres jusqu’à ce que vous appreniez la forme de l’arbre de décision.
The key distinction: accepting mail vs relaying mail
La politique SMTP se décide majoritairement à l’étape RCPT TO :
- Si le destinataire est local (un domaine que vous hébergez), Postfix peut l’accepter depuis Internet. C’est le courrier entrant normal.
- Si le destinataire n’est pas local, alors l’accepter est du relais. Le relais doit être restreint aux utilisateurs authentifiés ou aux réseaux explicitement approuvés.
reject_unauth_destination est le videur
Le contrôle anti-relais le plus important dans Postfix est reject_unauth_destination (ou sa variante defer). Il rejette les tentatives d’envoi vers des domaines non locaux à moins que le client soit approuvé par des règles antérieures.
Dans Postfix moderne, vous placez généralement ceci dans smtpd_relay_restrictions. Dans des configurations plus anciennes, il était courant dans smtpd_recipient_restrictions. Vous pouvez avoir les deux, mais vous devez comprendre précisément quelle liste est évaluée pour quoi. Ce que vous ne devez pas faire, c’est le supprimer parce que « ça casse le forwarding une fois ». Ce n’est pas corriger ; c’est enlever les freins parce que la voiture grince.
mynetworks : la façon la plus simple de vous tirer une balle dans le pied
permit_mynetworks est pratique et dangereux. Il signifie : « si vous êtes dans ces plages IP sources, vous êtes digne de confiance pour relayer. » C’est acceptable pour un petit environnement contrôlé. C’est risqué dans des réseaux modernes où « interne » inclut des laptops, BYOD, nœuds Kubernetes et instances éphémères créées par la CI.
Bonnes pratiques :
- Gardez
mynetworkslimité à la loopback et au sous-réseau spécifique où résident vos clients mail authentifiés (si nécessaire). - Privilégiez la submission authentifiée (587) pour les utilisateurs.
- Si des applications ont besoin de relayer, authentifiez-les ou restreignez-les par IP avec précision chirurgicale.
mydestination et les « domaines locaux » définissent ce qui n’est pas du relais
Si Postfix considère un domaine comme local, il acceptera le courrier pour celui-ci (sous réserve d’autres restrictions). Si Postfix considère un domaine comme non local, l’accepter constitue un relais. Une mauvaise définition des domaines locaux provoque deux problèmes courants :
- Rejeter du courrier entrant légitime (« utilisateur inconnu » ou « relay access denied » pour vos propres domaines).
- Accepter accidentellement du courrier qui ne devrait jamais être traité par ce serveur (boucles de routage, tempêtes de courrier, exposition réglementaire étrange).
La submission est l’endroit où vous pouvez être généreux (avec authentification)
Le port 587 est l’endroit pour permettre à vos utilisateurs et applications d’envoyer du courrier vers l’extérieur, avec :
- TLS obligatoire
- Authentification SASL obligatoire
- Restrictions explicites pour éviter que la submission ne devienne une porte dérobée
Neutraliser : modèles sûrs pour Postfix en production
Soyons opinionés. Si votre instance Postfix est exposée à Internet sur le port 25, la posture par défaut devrait être : accepter le courrier uniquement pour vos domaines hébergés ; ne pas relayer pour des étrangers ; fournir l’envoi sortant via submission authentifiée.
Pattern A : MX Internet pour le courrier entrant, pas de relais sortant public
C’est le rôle MX « classique ». Vous acceptez le courrier entrant pour vos domaines. Vous ne laissez pas des clients aléatoires relayer vers l’extérieur.
Paramètres clés (illustratifs, pas à copier-coller aveuglément) :
smtpd_relay_restrictions: doit se terminer pardefer_unauth_destinationoureject_unauth_destinationmynetworks: loopback uniquement, sauf si vous avez un cas d’utilisation d’relais interne contrôlémydestination/domaines virtuels : exactement vos domaines hébergés
Pattern B : relais sortant pour applications internes (recommandé : authentifié)
Vos applications veulent envoyer du courrier. Vous ne voulez pas prendre de décisions de confiance basées sur l’IP à travers des réseaux compliqués.
Utilisez la submission avec SASL. Si votre application ne peut pas faire de SASL, c’est un problème produit ; traitez-le comme tel. Si vous devez absolument utiliser la confiance par IP, isolez-la : écoute séparée liée à une interface interne seulement, pare-feu strict et CIDR minimaux.
Pattern C : Smart host / relayhost (éviter le transit accidentel)
Certains hôtes Postfix ne devraient jamais parler directement à Internet. Ils doivent envoyer tout via un relayhost corporate ou une passerelle de sécurité e-mail.
Cela est plus sûr pour le contrôle de sortie, mais ne le confondez pas avec la prévention d’un relais ouvert. Un système peut envoyer tout son courrier vers un smart host et rester un relais ouvert s’il accepte du courrier externe non authentifié et le fait suivre.
Deux garde-fous pratiques à implémenter
- Rendez « prouver qu’on n’est pas un relais ouvert » obligatoire au déploiement. Un test swaks externe simple dans CI/CD ou au moins dans la gestion de changement.
- Réduisez le rayon d’action avec des contrôles réseau. Groupes de sécurité/pare-feux restreignant qui peut atteindre 587, et dans certains designs même 25 (si vous n’êtes pas un MX).
Blague n°2 : Postfix fera exactement ce que vous lui dites, c’est pourquoi il se comporte parfois comme un stagiaire extrêmement poli mais désastreux.
Trois mini-récits d’entreprise des tranchées
Mini-récit 1 : L’incident causé par une mauvaise hypothèse
Ils ont migré les services mail d’un cluster VM legacy vers un environnement cloud. L’ancien design reposait sur « réseau interne = de confiance ». Ça fonctionnait depuis des années parce que « interne » signifiait quelques serveurs applicatifs sur un VLAN statique. Puis l’entreprise a modernisé.
Dans le nouveau VPC, « interne » incluait des nœuds Kubernetes, des agents de build, des jump boxes et des clients VPN de sous-traitants atterrissant sur le même espace d’adresses large. Personne n’avait la carte complète en tête. La config Postfix a fait ce qu’elle faisait toujours : permit_mynetworks pour le relais, avec mynetworks réglé sur une large plage RFC1918.
Le premier signe n’a pas été des plaintes de spam. Ce fut des alertes disque. La file mail a grossi assez vite pour déclencher des seuils du système de fichiers. L’ingénieur on-call a vu beaucoup de livraisons sortantes vers des domaines webmail gratuits. Au début ils ont supposé une fuite d’identifiants sur le port de submission.
La tournure était plus simple : il n’y avait pas d’authentification. Un runner CI compromis à l’intérieur du VPC se connectait au port 25 et relayait à volonté parce qu’il correspondait à mynetworks. Le runner était de courte durée, donc l’IP source changeait et les tentatives de blocage ressemblaient à du whack-a-mole.
La correction fut ennuyeuse et décisive : supprimer la confiance RFC1918 large, exiger l’auth pour l’outbound, et restreindre l’accès au port 25 à la passerelle mail entrante seulement. Ils ont aussi ajouté un test swaks externe comme étape de validation post-changement. La phrase clé du rapport d’incident : « Nous avons traité l’emplacement réseau comme identité. » Cette hypothèse était courante ; aujourd’hui elle coûte cher.
Mini-récit 2 : L’optimisation qui a mal tourné
Une autre entreprise faisait tourner Postfix comme MX entrant et relais sortant pour des applications internes. Ils optimisaient pour la performance parce que des campagnes marketing créaient de gros pics sortants. Ils voulaient moins de « rejets SMTP » dans les logs parce que quelqu’un les avait mal lus comme des erreurs.
Un ingénieur « a optimisé » en assouplissant les restrictions et en déplaçant les contrôles plus tard dans la conversation SMTP. L’idée : accepter rapidement le message, le mettre en file, puis décider. Ils ont aussi permis un CIDR interne plus large dans mynetworks pour éviter des échecs d’auth depuis des sous-réseaux étranges.
Ce changement a réduit les rejets au moment du RCPT. Il a aussi augmenté le coût de dire non. Quand l’abus a commencé — déclenché par un hôte compromis sur un subnet de confiance — Postfix acceptait les données du message et les mettait en file avant que la politique en aval ne rejette. Le CPU a monté. Les écritures disque ont augmenté. La latence a augmenté. Le MTA est devenu un moteur de déni de service contre lui-même.
La délivrabilité a ensuite souffert parce que le système passait ses ressources à traiter des ordures. Le courrier sortant légitime arrivait en retard, ce qui a fait échouer des flux de réinitialisation de mot de passe. L’impact business ressemblait à une panne d’authentification, pas à un problème mail, jusqu’à ce que quelqu’un vérifie la profondeur de la file mail.
Ils sont revenus au rejet précoce au RCPT et ont resserré les frontières de confiance. Les performances se sont améliorées parce que refuser tôt coûte moins cher que recevoir du spam. La leçon : « moins de bruit dans les logs » n’est pas un objectif d’optimisation. C’est une métrique de vanité qui finit par causer un incident.
Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une équipe de services financiers exécutait Postfix pour des systèmes internes et utilisait une passerelle externe de sécurité e-mail pour le mail Internet. Leur configuration n’était pas ingénieuse ; elle était explicite. Le port 25 était filtré pour n’accepter que les connexions depuis les IPs de la passerelle. Le port 587 exigeait TLS et SASL, et était restreint aux plages bureau/VPN.
Ils avaient aussi un petit runbook : après tout changement, exécuter deux tests swaks depuis un hôte probe externe — un vers un destinataire local (doit réussir), un vers un destinataire externe (doit échouer avec relay denied). Les sorties étaient attachées au ticket de changement. Les auditeurs ont adoré ; plus important, les opérateurs aussi : cela transformait la politique mail en preuve.
Un jour, un changement réseau a accidentellement étendu l’accès entrant au port 25 depuis tout Internet. Ce n’était pas malveillant ; c’était un modèle de groupe de sécurité mal appliqué. Leur monitoring a détecté immédiatement de nouveaux patterns de connexion, mais le vrai sauvetage fut le runbook : la modification suivante a inclus l’étape de preuve swaks, qui a échoué au test « doit refuser le relais » parce qu’une dérive de configuration indépendante avait aussi affaibli les restrictions.
Ils l’ont corrigé avant que l’abus ne prenne de l’ampleur. Pas de drame de liste noire, pas d’implosion de file, pas d’appels fournisseurs en colère. La pratique n’était pas glamour. C’était une checklist et une preuve. En production, l’ennuyeux est une fonctionnalité.
Erreurs fréquentes : symptôme → cause racine → correction
Cette section est destinée à raccourcir votre incident. Trouvez votre symptôme, arrêtez de deviner, et appliquez la correction spécifique.
1) Symptom: External swaks test relays successfully to Gmail/Yahoo
- Cause racine :
reject_unauth_destination/defer_unauth_destinationmanquant ou mal placé dans les restrictions de relais/réception. - Correction : Définir
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination(ou reject). Recharger et retester depuis l’extérieur.
2) Symptom: “Relay access denied” for your own domains
- Cause racine : Votre domaine n’est pas considéré comme local (mauvais
mydestination, config de domaine virtuel manquante, mauvaises maps de transport). - Correction : Définir correctement les domaines hébergés (domaines virtuels ou mydestination). Ne « corrigez » pas en autorisant le relais largement.
3) Symptom: Works internally, fails for roaming users
- Cause racine : Les utilisateurs comptent sur la confiance basée sur l’IP (
mynetworks) plutôt que sur l’auth de submission ; les IP VPN/hors site ne sont pas approuvées. - Correction : Configurer la submission (587) avec TLS + SASL ; dire aux clients de l’utiliser. Cessez d’élargir
mynetworkspour suivre des IP mobiles.
4) Symptom: Queue grows, disk fills, logs show many outbound deliveries
- Cause racine : Relais ouvert ou expéditeur authentifié compromis ; rejet trop tardif ; pas de limitation de débit.
- Correction : Prouvez le comportement de relais depuis l’extérieur, resserrez les restrictions de relais, bloquez les sources abusives et envisagez policyd/limites de débit. Purgez le spam après avoir défini l’étendue.
5) Symptom: Every client appears as the same IP in logs
- Cause racine : SMTP est derrière un proxy/load balancer sans conservation correcte de l’IP client ; Postfix fait confiance à l’IP du proxy.
- Correction : Utiliser un design qui préserve l’IP client (proxy protocol si supporté) ou ne pas se reposer sur
mynetworkspour la confiance. Restreindre au bord réseau.
6) Symptom: Submission port allows mail without auth
- Cause racine : Service submission mal configuré dans
master.cf;smtpd_sasl_auth_enable=yesmanquant ou restrictions de destinataire trop permissives. - Correction : Appliquer l’auth et rejeter sinon sur submission. Retester avec swaks en mot de passe erroné et sans auth.
7) Symptom: Some internal hosts can relay, others cannot, and nobody knows why
- Cause racine : Routage/NAT incohérent ou CIDR qui se chevauchent ;
mynetworksmal assorti ; plusieurs instances Postfix avec configs différentes. - Correction : Identifier les IP sources réelles, resserrer les listes de confiance, standardiser la config avec gestion de configuration, et ajouter des tests de preuve externes.
Checklists / plan étape par étape
Checklist A: “Are we an open relay?” (15 minutes, evidence-driven)
- Depuis un hôte externe, exécutez swaks vers un destinataire tiers. Attendez-vous à
Relay access denied. - Depuis le même hôte externe, exécutez swaks vers un destinataire d’un domaine local. Attendez-vous à
250 Oket acceptation de DATA. - Sur l’hôte Postfix, capturez
postconf -net confirmez quesmtpd_relay_restrictionsinclut le rejet des destinations non autorisées. - Vérifiez les logs mail pour des rejets de relais récents et tout relais réussi suspect.
- Joignez la sortie swaks + les lignes de logs pertinentes à votre ticket/enregistrement de changement.
Checklist B: Closing an open relay safely (incident mode)
- Contenir : Corrigez immédiatement les restrictions de relais ; si le trafic est écrasant, bloquez les sources abusives au pare-feu.
- Conserver des preuves : Sauvegardez des extraits de logs et quelques en-têtes de messages (
postcat -q) pour confirmer l’origine. - Valider depuis l’extérieur : Relancez le test swaks externe jusqu’à ce qu’il échoue avec relay denied.
- Triage de la file : Inspectez la file ; identifiez si le courrier en file est légitime ou du spam.
- Nettoyage : Supprimez les entrées de file spam après confirmation de l’étendue ; évitez de supprimer du courrier légitime.
- Récupération de la délivrabilité : Si vous avez été mis sur liste noire, coordonnez le délisting et communiquez avec les parties prenantes.
- Prévenir la récurrence : Réduisez
mynetworks, forcez l’auth en submission, et ajoutez un test de preuve récurrent.
Checklist C: Hardening changes you can standardize
- Restreindre l’exposition du port 25 à ce dont vous avez besoin (trafic MX ou IPs de passerelle).
- Exiger TLS + SASL sur le port 587. Ne faites pas de 587 un relais de confort.
- Rendre
mynetworkspetit et revu comme des règles de pare-feu. - Rejeter tôt à l’étape RCPT. N’acceptez pas DATA à moins d’en avoir l’intention.
- Ajouter du monitoring pour la profondeur de file, le courrier différé et le volume sortant inhabituel.
FAQ
1) How do I definitively prove Postfix is not an open relay?
Exécutez une transaction SMTP depuis un hôte externe non approuvé vers un domaine tiers. Si RCPT est rejeté avec « Relay access denied », vous avez la preuve. Sauvegardez la sortie.
2) Why isn’t testing from localhost enough?
Parce que localhost est généralement approuvé via mynetworks. Un relais large à Internet peut sembler « sécurisé » lorsqu’il est testé depuis 127.0.0.1.
3) What’s the difference between smtpd_recipient_restrictions and smtpd_relay_restrictions?
smtpd_relay_restrictions est l’endroit moderne pour les décisions de politique de relais. smtpd_recipient_restrictions contrôle plus généralement l’acceptation des destinataires. Mal placer les règles peut affaiblir vos contrôles de relais.
4) Should I use reject_unauth_destination or defer_unauth_destination?
Les deux empêchent un relais ouvert. reject est immédiat et clair. defer peut être utilisé dans certains flux de politique, mais il est plus simple de raisonner avec reject lors du durcissement.
5) Can I rely on mynetworks alone for internal apps?
Vous pouvez, mais vous ne devriez probablement pas. Les réseaux « internes » sont souvent tentaculaires et poreux. Préférez la submission authentifiée pour les apps ; si vous devez utiliser la confiance IP, isolez-la strictement.
6) If port 25 is firewalled to the world, can I ignore open relay risk?
Non. Si un quelconque réseau non approuvé peut atteindre le port 25 (y compris VPNs, VPC peered ou groupes de sécurité mal configurés), vous pouvez encore être abusé. De plus, la dérive de configuration arrive ; les tests de preuve la détectent.
7) Why did we get blocklisted if we fixed the relay quickly?
Les listes noires réagissent au volume de spam observé et au comportement, et la réputation prend du retard sur la réalité. Corriger le relais arrête l’hémorragie ; le délisting et la récupération de réputation peuvent prendre plus de temps.
8) How do I distinguish “open relay” from “compromised mailbox sending spam”?
Le spam d’un relais ouvert provient de connexions non authentifiées (souvent port 25) et de nombreuses IP sources. Les comptes compromis montrent généralement des soumissions SASL authentifiées sur 587 depuis des identités utilisateurs spécifiques et moins d’IPs sources.
9) Does enabling TLS prevent open relay?
Non. TLS chiffre la connexion ; il n’impose pas qui peut relayer. Vous avez toujours besoin de restrictions de relais et/ou d’authentification.
10) What’s the safest minimal configuration goal?
Sur le port 25 : accepter le courrier uniquement pour les domaines que vous hébergez ; rejeter le relais non autorisé. Sur le port 587 : exiger TLS et SASL ; autoriser l’envoi authentifié.
Prochaines étapes à effectuer réellement
N’attendez pas un email de liste noire pour apprendre si vous êtes un relais ouvert. Faites-en une preuve de routine.
- Exécutez aujourd’hui le test swaks relais externe (Task 6). Sauvegardez la sortie là où les auditeurs et le futur vous pourront la trouver.
- Revoyez
postconf -net confirmez quesmtpd_relay_restrictionsse termine par le rejet des destinations non autorisées. - Réduisez
mynetworksà ce que vous pouvez défendre en réunion. La loopback est un bon point de départ. - Faites de la submission (587) la voie officielle de sortie avec TLS + SASL, et arrêtez de résoudre les problèmes d’auth par des CIDR.
- Ajoutez un tableau de bord de monitoring : taille de la file, nombre différé, volume sortant. C’est étonnant comme cela détecte souvent « le mail est étrange » avant que les utilisateurs ne le remarquent.
- Transformez la preuve en processus : chaque changement lié au mail inclut les deux tests swaks (acceptation locale, refus de relais externe). Joignez la preuve. Répétez indéfiniment.