J'ai trouvé une approche très hack que pour cela.
Fondamentalement, j'ai mis en place un 'serveur' SMTP personnalisé écrit en Python tournant entre le serveur Postfix et le serveur Exchange qui gère en réalité le routage de relais réel. Il est écrit en Python et fonctionne en tant que superutilisateur sur le port 25 (en raison des restrictions de liaison de port).
Le script Python traite ensuite le message comme on le ferait normalement, en passant par un analyseur de chaîne d'e-mails, puis en lisant la ligne d'objet pour déterminer où l'envoyer, puis en envoyant le message original, inchangé, soit au serveur SMTP Postfix local (pour être envoyé directement vers l'extérieur), soit à l'autre relais sur le réseau. Jusqu'à présent, cela semble fonctionner.
Voici le code que j'utilise pour cela du côté Python :
#!/usr/bin/env python3
# Bibliothèques
import smtplib
import smtpd
import asyncore
import email
import sys
from datetime import datetime
print('Démarrage du serveur de gestion des mails personnalisé...')
# VARIABLES DE CONFIGURATION - Nous nous attendons à relayer, alors... relayons.
SMTP_RELAY = 'NOM_HOTE_OU_IP_RELAY_SMTP'
SMTP_DIRECT = 'localhost'
#############
#############
# SERVEUR SMTP
#############
#############
# noinspection PyMissingTypeHints,PyBroadException
class AutoReplyHandlerSMTP(smtpd.SMTPServer):
def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):
print('MESSAGE REÇU - [%s]' % datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
print('Réception du message de :', peer)
print('Message adressé de :', mailfrom)
print('Message adressé à :', rcpttos)
print('Longueur du message :', len(data))
print(data)
# Vide le tampon de sortie (pratique avec le lancement nohup)
sys.stdout.flush()
# Analyser et extraire les en-têtes des données
msg = email.message_from_string(data)
subject = ''
try:
subject = msg['Subject']
subject = subject.lower()
except:
print("Erreur de sujet :", sys.exc_info()[0])
print('Sujet du message :', msg['Subject'])
# Déterminer si nous envoyons directement vers l'extérieur, ou si nous relayons vers un autre serveur.
if "réponse automatique" in subject:
print("Réponse automatique reçue, envoi direct.")
# Le postfix SMTPd local est sur tcp/6625.
conn = smtplib.SMTP(host=SMTP_DIRECT, port=6625, timeout=60)
conn.sendmail(mailfrom, rcpttos, msg.as_string())
conn.quit()
else:
print("Message standard détecté, envoi au relais.")
# L'autre serveur de relais est sur tcp/25 (smtp standard)
conn = smtplib.SMTP(host=SMTP_RELAY, timeout=60)
conn.sendmail(mailfrom, rcpttos, msg.as_string())
# Vide le tampon de sortie (pratique avec le lancement nohup)
print("\n\n")
sys.stdout.flush()
return
# Écoute sur le port 25 ( 0.0.0.0 peut être remplacé par l'adresse IP de votre serveur mais cela fonctionnera avec 0.0.0.0 )
serveur = AutoReplyHandlerSMTP(('0.0.0.0', 25), None)
# Attendez les e-mails entrants
asyncore.loop()
J'ai configuré Postfix pour écouter sur SMTP sur un port différent. En effet, voici ce qui a été fait, dans /etc/postfix/master.cf
sur mon serveur Ubuntu pour cela, et ce sont finalement les deux lignes et comment j'ai configuré SMTPd dans Postfix - notez que vous pouvez utiliser n'importe quel port numéroté élevé pour tout autre port pour Postfix SMTPd, mais j'ai choisi quelque chose de simple:
#smtp inet n - y - - smtpd
6625 inet n - y - - smtpd
Le script Python transfère ensuite les données vers le port 6625
, et le SMTPd de Postfix fonctionnant là-bas ; cela fait, nous laissons spécifiquement à Python déterminer quel serveur SMTP ou relais est le "prochain saut". Ceci casse un peu les en-têtes standard "Reçu par", mais cela semble fonctionner correctement avec les messages.
Je n'ai rencontré aucun problème avec ma solution, et cela semble fonctionner. Des tests supplémentaires sont nécessaires, mais cette 'solution' semble résoudre le problème de routage pour comment acheminer les messages (SMTP sortant direct, ou à travers le reste des relais) sans toucher vraiment à la configuration de Postfix.