Comment acheminer les e-mails entrants vers votre application avec Exim
Exim est un agent de transfert de messages (MTA) populaire pour les systèmes Unix. Il offre une grande variété d’options de routage et de transport. Dans cet article, nous montrerons comment utiliser Exim pour rediriger les e-mails entrants dans votre propre script.
Nous supposerons que vous avez déjà un serveur Exim fonctionnel capable de recevoir des e-mails. Le wiki officiel fournit des conseils informatifs si vous partez de zéro avec une nouvelle installation.
Sommaire
Gestion de la configuration d’Exim
Les approches de configuration disponibles varient selon la distribution du système d’exploitation. Une installation Exim construite à partir des sources utilisera src/configure.default
comme son fichier de configuration.
Le fichier pour Exim installé à partir d’un gestionnaire de packages est généralement /etc/exim/config
ou /etc/exim.conf
. Vous pouvez trouver le chemin actuellement utilisé en exécutant exim -bP configure_file
.
Les systèmes d’exploitation basés sur Debian ont un système légèrement plus compliqué. Il existe deux méthodes de configuration possibles : un seul fichier, /etc/exim4/exim4.conf.template
, ou diviser les fichiers de configuration dans /etc/exim4/conf.d
. Vous devez courir update-exim4.conf
après avoir apporté des modifications. Cela crée un seul fichier fusionné qui est en fait lu par Exim.
Exim doit être redémarré à chaque fois que vous modifiez sa configuration. Courir service exim4 restart
pour appliquer vos modifications.
Création d’un routeur
La première étape pour envoyer un e-mail à votre application consiste à définir un routeur personnalisé. Les routeurs associent les e-mails entrants à un ensemble de conditions pour déterminer le mécanisme de livraison à utiliser.
Les routeurs sont traités dans l’ordre séquentiel dans lequel ils se trouvent dans le fichier de configuration. Tous les routeurs situés au-dessus du vôtre dans le fichier peuvent d’abord correspondre aux e-mails entrants.
Ajoutez votre routeur à votre fichier de configuration dans le ROUTERS CONFIGURATION
section. Si vous utilisez la configuration Debian fractionnée, vous pouvez créer un nouveau fichier dans /etc/exim4/conf.d/routers
au lieu. Les routeurs seront combinés par ordre alphabétique lorsque vous utilisez cette approche.
Voici un exemple de routeur :
example_router: driver = accept domains = example.com transport = example_transport
Il s’agit d’un routeur de base qui correspond à tout e-mail envoyé à example.com
. Lorsqu’une correspondance est traitée, Exim accept
le message et le transmettre en utilisant le example_transport
transport. Nous allons créer ceci ensuite.
Création d’un transport
Une fois qu’un e-mail a été accepté par un routeur, il est livré par un transport. Les transports sont responsables de la mise en œuvre de la routine de livraison des messages. Différents pilotes peuvent envoyer sur Internet en utilisant SMTP, transférer vers un utilisateur Unix local ou écrire dans un fichier.
La création d’un transport personnalisé basé sur un pilote intégré vous permet de fournir des e-mails correspondants à votre propre application. Vous pouvez ensuite traiter chaque e-mail individuellement, en dehors d’Exim.
Contrairement aux routeurs, l’ordre des transports n’a pas d’importance. Chaque e-mail entrant correspondra au transport unique spécifié par le routeur qui l’accepte. Ajoutez votre transport n’importe où dans le TRANSPORTS CONFIGURATION
section de votre fichier Exim. Les utilisateurs de Debian dont la configuration fractionnée est activée peuvent créer un fichier dans /etc/exim4/conf.d/transports
.
Voici un transport qui invoque un script PHP :
example_transport: driver = pipe command = /usr/bin/php /var/www/html/handle_incoming_email.php user = www-data group = www-data
Lorsqu’il est combiné avec l’exemple de routeur ci-dessus, tout e-mail envoyé à @example.com
sera livré à handle_incoming_email.php
. Exim fournit l’intégralité de l’e-mail au format compatible RFC en tant qu’entrée standard de la commande que vous pouvez lire dans votre langage de programmation.
// Get email content from standard input in PHP $email = fopen("php://stdin", "r"); // To: user@example.com // Subject: Demo Email // // This is an email.
Le transport est configuré avec le pipe
conducteur. Cela utilise un tuyau Unix pour fournir l’e-mail entrant à votre command
. La commande sera exécutée en tant qu’utilisateur et groupe que vous spécifiez.
Utilisation de variables d’environnement
Exim définira plusieurs variables d’environnement avant d’exécuter votre commande. Ceux-ci peuvent être utilisés pour accéder aux informations sur le message sans avoir à analyser le format complet de l’e-mail.
Les variables disponibles incluent :
DOMAIN
– Le domaine auquel l’e-mail entrant a été envoyé.MESSAGE_ID
– L’ID interne d’Exim représentant l’e-mail.RECIPIENT
– L’adresse e-mail à laquelle le message a été envoyé.SENDER
– L’adresse e-mail d’où provient le message.
Vous pouvez ajouter des variables supplémentaires à l’environnement de la commande en définissant le environment
option dans votre transport. Cela accepte une liste de paires clé-valeur séparées par des virgules :
example_transport: environment = foo=bar,demo=example
Valeurs de retour
Votre commande devrait se terminer avec un 0
code d’état pour confirmer une livraison réussie. Un code de sortie différent de zéro sera interprété comme un échec de livraison. L’expéditeur recevra un message de rebond.
Ce comportement est désactivé en définissant le ignore_status
option dans votre transport. Exim traitera alors les codes d’état non nuls comme réussis.
De plus, vous pouvez utiliser le temp_errors
option pour définir des codes de sortie de script qui indiquent qu’une erreur a été rencontrée mais qu’elle devrait être temporaire. Lorsqu’Exim voit l’un de ces codes d’état, la livraison du message est différée et réessayée ultérieurement.
Le contenu des messages de rebond peut être personnalisé avec le return_fail_output
option. Lorsque celui-ci est défini sur true
, Exim inclura le contenu de la sortie standard de votre script dans son e-mail de rebond. Le mécanisme facilite l’utilisation de votre code d’application pour fournir des réponses de rebond personnalisées aux expéditeurs.
Invocation de commande
Exim appelle généralement votre commande directement depuis le transport. Si vous définissez le use_shell
option, il passera la commande à /bin/sh
au lieu. Cela peut être utile dans les scénarios où votre script nécessite qu’un environnement shell complet soit disponible.
L’exécution de la commande expire après une heure avec la configuration par défaut. Un timeout est traité comme une erreur de livraison. La commande sera terminée et un message de rebond sera renvoyé à l’expéditeur. Le délai d’attente peut être personnalisé avec le timeout
réglage. En outre, le réglage du timeout_defer
L’option entraînera le traitement des délais d’attente comme des erreurs temporaires, permettant une autre tentative de livraison après un délai.
example_transport: timeout = 5m timeout_defer
Vous devez également considérer que votre script peut être exécuté simultanément si plusieurs e-mails arrivent en même temps. Votre application doit pouvoir résister à cette éventualité. Les systèmes de verrouillage qui n’autorisent qu’une seule instance à s’exécuter simultanément doivent être désactivés pour votre script de gestion des e-mails.
Conclusion
Exim est facilement configuré pour acheminer les e-mails entrants vers votre propre application. Une configuration simple qui dirige tous les messages reçus peut être réalisée avec un routeur de base couplé à un transport utilisant le pipe
conducteur.
Vous devez fournir un binaire qui accepte un e-mail sur entrée standard dans le cadre de votre candidature. Le binaire sera invoqué par Exim chaque fois qu’un nouveau message est reçu. Vous devez ensuite analyser l’e-mail d’une manière conforme aux normes pour extraire le contenu du corps et les en-têtes de message pertinents pour votre système.