BigAdmin System Administration Portal
Comportement de la transmission d'e-mails dans Sun Java System Messaging Server 6 2005Q4
Print-friendly VersionPrint-friendly Version

Comportement de la transmission d'e-mails dans Sun Java System Messaging Server 6 2005Q4

Jeff Allison et Ned Freed, décembre 2006

Cet article traite du comportement de la transmission d'e-mails au sein de Sun Java System Messaging Server, notamment au niveau du transport et avec le paramètre redirect en langage Sieve, de même que le mode d'implémentation actuel de la transmission d'e-mails par l'interface de Communications Express.

La fonction de transmission de messages de Messaging Server permet de faire suivre le courrier d'un utilisateur vers une autre adresse e-mail au lieu ou en plus de l'adresse principale de cette personne. Il est primordial de bien comprendre l'implémentation de la transmission de messages de Messaging Server lors de la détection et de la résolution de problèmes de boucle, lesquels font également l'objet d'une discussion dans cet article.

La transmission de messages, à l'instar de nombreuses parties d'un système de messagerie sophistiqué, s'avère plus complexe qu'elle ne le paraît. Les choix effectués en matière d'implémentation de la transmission peuvent aboutir à des comportements peu évidents au départ. Cet article tente d'illustrer certains aspects de la complexité et des ramifications de divers paramètres et options de transmission.


Exemple de transmission au niveau du transport

Supposons que l'utilisateur Alice (alice@exemple.com) envoie à l'utilisateur Bob (bob@exemple.com) un message de ce type :

From: Alice 
To: Bob 
Subject: sample message subject
Date:  whenever
Content-type: text/plain
MIME-Version: 1.0

test message

Imaginons à présent que ce message soit envoyé au moyen du mécanisme de transmission au niveau du transport à charlie@exemple.com. Dans ce cas, le destinataire devient simplement Charlie au lieu de Bob. Les en-têtes et la structure du message restent inchangés et aucun en-tête supplémentaire n'est ajouté. Toutefois, deux modifications visibles sont apportées au message. Tout d'abord, la clause for du champ Received: indique Charlie et non Bob comme destinataire. Deuxièmement, tout champ du destinataire d'origine (original-recipient) ajouté au cours de la distribution·finale spécifie Bob et non pas Charlie.

Cela se produit, par exemple, lorsque Bob définit la transmission de sa messagerie vers Charlie en ayant défini le paramètre mailDeliveryOption sur forward et le paramètre mailForwardingAddress sur charlie@exemple.com. La transmission de la messagerie de Bob vers Charlie est effectuée, par exemple, au niveau de l'entrée de l'utilisateur dans l'annuaire LDAP par l'ajout de l'attribut mailDeliveryOption configuré sur forward et celui de l'attribut mailForwardingAddress défini sur charlie@exemple.com.

Ce type de transmission au niveau du transport dispose de vérifications étendues destinées à détecter et à empêcher les boucles de messages. Par conséquent, une action telle que la transmission d'un message de Bob à lui-même via la configuration de sa propre adresse pour le paramètre mailForwardingAddress est détectée et résolue immédiatement. Une action au cours de laquelle l'utilisateur Bob transmet un message à Charlie, lequel transmet à nouveau ce message à Bob est résolue de la même manière. En réalité, la logique de vérification des boucles de Messaging Server détecte et traite quasiment toutes les boucles inhérentes aux informations de transmission disponibles pour un agent de transfert de messages (MTA, Message Transfer Agent).

Il peut arriver que les boucles relatives à des transmissions au niveau du transport situées sur plusieurs systèmes ne soient pas détectées. Toutefois, comme les champs de réception (Received:) sont systématiquement ajoutés à chaque pas, ce type de boucle peut être détecté en dénombrant les champs Received:. Bien évidemment, ce calcul est effectué par Messaging Server. De plus, les messages sont automatiquement retenus lorsque le nombre de champs Received: dépasse l'une des limites définissables. Cette action attire l'attention de l'administrateur de courrier du site sur le message. Cette personne est censée vérifier régulièrement la présence de messages « auxiliaires » s'affichant sous la forme de fichiers dotés de l'extension .HELD. L'administrateur du courrier a ensuite simplement besoin de consulter les champs Received: du message pour identifier les composants exacts de la boucle et les éléments à modifier afin de rompre la boucle.

Pour plus d'informations sur la vérification des messages .HELD, reportez-vous à la section intitulée Diagnosing and Cleaning up .HELD Messages du document Sun Java System Messaging Server 6 2005Q4 Administration Guide.


Exemple de transmission Sieve

Le comportement d'une transmission à l'aide de l'action redirect en langage Sieve est similaire à celui d'une transmission au niveau du transport, mais pas identique. L'agent MTA implémente l'action de redirection en créant un nouveau destinataire du message et en dirigeant ce dernier vers le canal de retraitement (reprocess). Dans ce cas, un pas de canal est ajouté et le message se termine par un champ Received: supplémentaire.

La complexité des scripts en langage Sieve est telle que l'analyse de détection des boucles est infaisable. Autrement dit, vous pouvez rédiger des scripts Sieve générant une boucle impossible à détecter par analyse. Cela signifie que les boucles impliquant des scripts Sieve doivent être détectées lorsqu'elles surviennent ; elles ne sont pas détectables par le biais d'une analyse statique. Cependant, l'action redirect ajoutant des champs Received: (en réalité, elle ajoute deux fois plus de champs qu'une transmission au niveau MTA), il n'est pas difficile de repérer et d'arrêter les boucles de redirection. L'identification de la cause d'une telle boucle peut s'avérer plus difficile, car le langage Sieve peut s'avérer plus complexe qu'une simple "transmission de ceci sans condition". Malgré tout, comme vous pouvez détecter à partir des champs Received: les actions entreprises au moment d'une boucle, cela n'est généralement pas si difficile. Différentes options de consignation sont disponibles dans l'agent MTA en vue d'enregistrer les actions Sieve. Vous trouverez ces options extrêmement pratiques pour déconstruire les boucles.

Pour plus d'informations sur le langage Sieve, reportez-vous à la section Sieve Filter Support du document Sun Java System Messaging Server 6 2005Q4 Administration Guide.


Exemple de dépannage de boucles de messagerie

L'exemple suivant s'avère pratique pour comprendre les problèmes de transmission d'e-mails. Supposons qu'un utilisateur connaisse des difficultés avec les boucles de messagerie. La première étape consiste à insérer des champs d'en-tête supplémentaires dans le message. Les normes pertinentes définissent des en-têtes dans ce but particulier : les champs de renvoi (Resent-). Si vous ajoutiez des champs Resent- au message, Charlie recevrait un message de ce type :

Resent-from: Bob 
Resent-to: Charlie 
Resent-date: whenever2
From: Alice 
To: Bob 
Subject: sample message subject
Date:  whenever1
Content-type: text/plain
MIME-Version: 1.0

test message

Une autre solution consiste à utiliser un champ non standard tel Forwarded-by. Vous pouvez également baliser la ligne de l'objet de la même manière. Le problème de ces techniques est qu'elles ne fonctionnement pas bien ni l'une ni l'autre en général. De nombreux programmes de client de messagerie rendent difficile, voire impossible, l'affichage d'autres éléments qu'un sous-ensemble restreint de champs d'en-tête. Et, bien que le balisage de la ligne de l'objet soit visible, il tend à influer sur d'autres éléments, tels que le threading de messages. Le balisage de messages ne permet pas non plus de traiter un nombre arbitraire de transmissions. En réalité, il rencontre déjà des difficultés après la première transmission.

Autre problème observé dans Messaging Server 2005Q1 (6.2), l'implémentation de la fonction redirect Sieve ne permet pas d'insérer d'en-têtes supplémentaires dans les messages transmis. Ce problème est corrigé dans la nouvelle version prochainement disponible de Messaging Server (Messaging Server 6.3). Vous pouvez combiner addheader et/ou addtag avec redirect et ajouter des champs Resent-, des en-têtes Forward-by ou encore baliser la ligne de l'objet.

Vous avez la possibilité d'utiliser l'action addheader pour insérer un en-tête au message actuel. Cette action admet un seul argument de chaîne contenant à la fois le nom et le contenu du champ de l'en-tête dans le format field: content habituel. Le nom d'extension addheader peut être défini dans la clause require, mais ce n'est pas obligatoire.

Les versions 6.3 et ultérieures de Messaging Server prendront en charge l'extension Sieve editheader décrite dans le brouillon de document Internet draft-ietf-sieve-editheader-02.txt. Ce brouillon se trouve actuellement au niveau du dernier appel dans le groupe de travail SIEVE IETF.

Grâce à l'action addtag actuellement non standard, vous pouvez insérer un préfixe de chaîne de balise dans le champ de l'objet du message actif. Cette action admet un argument de chaîne unique contenant la chaîne de balise à ajouter. Le programme vérifie la ligne de l'objet afin de détecter la présence de la balise ; aucune action n'est entreprise si tel est le cas. Les balises sont ajoutées juste avant les entrées de file d'attente, une fois le traitement par filtre effectué. Autrement dit, les balises ne peuvent pas servir à établir des communications d'un filtre Sieve à un autre.


Communications Express et langage Sieve

Le client Communications Express emploie une primitive Sieve de transmission différente appelée Notify :echo. Notify permet de créer un message entièrement nouveau doté du contenu spécifié et de joindre éventuellement le message initial (la partie :echo). La construction utilisée ressemble à la suivante :

if header :matches "Subject" "*" {
    notify :method "email" :echo :options "charlie@example.com"
     "auto-forwarded-1:1" "This is an auto-forwarded message";
     stop;
  }

Lorsque ce mécanisme est utilisé, Charlie reçoit ce type de message :

   From: Bob 
   To: Charlie 
   Subject: auto-forwarded-1:sample message subject
   Date: whenever2
   Content-type: multipart/mixed; boundary=a
   MIME-Version: 1.0

   --a
   content-type: text/plain

   This is an auto-forwarded message

   --a
   content-type: message/rfc822

   From: Alice 
   To: Bob 
   Subject: sample message subject
   Date:  whenever1
   Content-type: text/plain
   MIME-Version: 1.0

   test message

Cette méthode de transmission s'avère problématique. Tout d'abord, dans cette approche, il n'est plus possible de détecter de nombreux types de boucles et de les traiter efficacement. Pour quelle raison ? Parce que l'utilisation de messages imbriqués place la plupart des champs Received: au sein des données du message, pas dans l'en-tête situé le plus à l'extérieur. De plus, comme l'architecture de la messagerie Internet ne considère pas cela comme un cas d'utilisation de l'imbrication de messages légitime, il est impossible d'étiqueter les messages imbriqués de sorte qu'ils indiquent qu'« il ne s'agit pas vraiment de messages imbriqués, mais plutôt d'une manière étrange de structurer un message simple ».

Pour tenter de gérer cette situation, un type de compteur de champs Received: a été créé dans le champ de l'objet (Subject:). Malheureusement, ce genre de tentative n'aboutit pas à des résultats satisfaisants. De nombreux éléments peuvent modifier le champ Subject: et interrompre ainsi aisément ce type de logique délicate. C'est la raison pour laquelle il est recommandé de toujours se rabattre sur l'utilisation du décompte de champs Received:. Cette pratique est impossible à appliquer à notify.

Il existe néanmoins une autre façon de détecter les boucles de notification. Bien que cette solution ne soit pas adaptée sur le long terme, elle pourrait vous aider dans l'utilisation de notify jusqu'à ce que vous mettiez Messaging Server à niveau vers la version 6.3, ce qui vous permettra ensuite de vous servir des actions redirect/addheader.

En utilisant l'extension mime-loop Sieve, vous pouvez obtenir un détecteur de boucle féroce capable de compter le nombre de niveaux imbriqués dans le message. La commande de base est la suivante :

if header :mime :anychild :count "gt" :comparator
          "i;ascii-numeric" "MIME-Version" "20"
{
	loop detected
}

Cette commande fonctionne, car :mime :anychild indique au test d'en-tête d'examiner tous les champs d'en-tête imbriqués, pas seulement ceux contenus dans l'en-tête situé le plus à l'extérieur. Chaque paramètre notify ajoute un niveau d'imbrication et un champ MIME-Version: supplémentaires. En définitive, le nombre dépasse le seuil, vous permettant de détecter la boucle. Le revers de cette méthode est sa vulnérabilité aux faux positifs. Un exemple évident de cet inconvénient est un message contenant une synthèse de message (un tel message pourrait aisément inclure des dizaines, voire des centaines, de champs MIME-Version:, ce qui déclencherait le détecteur prématurément). Cependant, il est rare de rencontrer ce type de message. Outre les faux positifs, il existe aussi des faux négatifs liés au fait que tous les constructeurs de notifications n'utilisent pas le type d'encapsulation approprié. Toutefois, comme l'implémentation du paramètre notify par Sun fait systématiquement appel au bon type d'encapsulation, cela ne devrait pas vraiment poser de problèmes.


Différentes approches de la transmission de messages ?

La question évidente à se poser à ce stade de notre réflexion est la suivante : est-il possible d'utiliser des approches de la transmission radicalement différentes de celles évoquées précédemment ? La réponse à cette question est non : il n'existe pas d'autres approches fondamentalement différentes. Cela se comprend aisément lorsque l'on considère que les messages électroniques (e-mails) Internet se composent de trois parties : l'enveloppe, l'en-tête et le corps. Les trois classes d'approches décrites précédemment correspondent à la simple modification de l'enveloppe, à l'altération de l'enveloppe et de l'en-tête et au changement des trois paramètres à la fois. Aucun autre élément n'est modifiable.

Si l'on reprend l'exemple utilisé dans cet article, imaginons que l'utilisateur ait décidé qu'il serait plus efficace d'améliorer le traitement des boucles par le produit après leur détection dans les scripts en langage Sieve générés par le client. L'utilisateur propose une solution envoyant un genre d'avis à l'administrateur du courrier dès lors qu'une boucle est détectée. Les critères d'envoi sont les suivants :

  1. Ce message devrait contenir des informations permettant à l'administrateur du courrier de diagnostiquer le problème. Ces informations pourraient comprendre le message initial et la règle de filtrage de messages qui n'a pas été appliquée.
  2. Le message envoyé à l'utilisateur final devrait également contenir le message qui n'a pas été transmis automatiquement et indiquer la règle qui n'a pas été appliquée. Cela permettrait à l'utilisateur final de connaître les actions précises n'ayant pas eu lieu.
  3. Le nombre de transmissions automatiques autorisées devrait correspondre à un paramètre de serveur de messagerie modifiable.

En étudiant cette requête, il apparaît clairement que l'envoi d'informations à l'administrateur du courrier est effectivement possible à l'aide de l'action notify et que le paramètre :echo permet d'inclure le message initial dans la notification. Par conséquent, vous pourriez implémenter les éléments (1) et (2). Il serait possible d'implémenter l'élément (3) par le biais d'un paramètre qui modifierait le contenu des scripts Sieve générés. Toutefois, un changement de paramètre n'entrerait en vigueur qu'après la modification ultérieure de ces scripts Sieve. Vous devriez alors apporter ce changement aux scripts Sieve existants en recherchant dans l'annuaire des candidats de scripts Sieve potentiels et en les modifiant tous.

Cependant, l'exécution de l'une quelconque de ces étapes enfreint l'une des règles fondamentales du routage d'e-mails : suite à la détection d'une boucle, l'activité que vous ne devez absolument pas effectuer est l'envoi de messages électroniques supplémentaires. Autrement dit, cette requête contredit totalement les conclusions que nous avons pu tirer de nos longues années d'expérience de déploiement concernant les pratiques recommandées en matière de messagerie. Lorsque des boucles sont détectées, l'action recommandée consiste à mettre de côté le message (dans Messaging Server, cela signifie convertir le message en fichier .HELD) et d'attirer dessus l'attention d'une personne capable de résoudre le problème.

En outre, un problème plus subtile se pose. Même si Messaging Server est en mesure d'inclure dans une notification tout ce qu'un utilisateur souhaite, y compris des indicateurs des actions exécutées et/ou non exécutées par les règles Sieve, cela aboutit à des résultats nettement inférieurs à ceux que l'on pourrait imaginer. Le problème vient du fait que les utilisateurs modifient régulièrement leurs configurations Sieve et, lorsque cela se produit, l'inclusion d'informations actuellement incorrectes dans une notification rend en réalité plus difficile l'identification des problèmes au lieu de la faciliter.

Imaginons par ailleurs qu'une boucle se crée et que la logique de détection soit déclenchée, ce qui aura pour conséquence la réception de nombreuses notifications par l'administrateur de courrier. La question est désormais la suivante : qu'est-ce que l'administrateur de courrier est censé faire ? La réponse logique serait de résoudre le problème de la boucle. Néanmoins, comme nous l'avons observé auparavant, les notifications ne facilitent pas autant qu'on le souhaiterait l'isolation du problème. Dans la plupart des cas, le plus grand défi posé par l'interruption d'une boucle n'est pas de trouver l'origine de la boucle, mais plutôt de se demander ce qui doit changer pour qu'elle disparaisse.

Supposons à présent que le problème de la boucle soit résolu. Qu'en est-il des messages perdus à cause de la boucle ? Ils se trouvent dans une mauvaise boîte aux lettres. L'administrateur du courrier doit trouver ces copies, les supprimer et renvoyer les messages aux destinataires pertinents qui ne les ont pas reçus. Il n'est pas envisageable d'abandonner les messages là où ils sont arrivés, car un destinataire erroné qui les rencontrerait pourrait supposer qu'ils doivent être traités alors que cela ne devrait pas être le cas. C'est une chose de recevoir un double superflu d'un message que vous êtes censé recevoir, mais cela n'a rien à voir avec la réception d'un message qui n'aurait jamais dû vous être adressé. Étant donné qu'un utilisateur recevant accidentellement un message ne lui étant pas destiné pourrait y réagir sur le champ, l'administrateur du courrier doit pouvoir agir quasiment instantanément suite à l'envoi en boucle d'un e-mail et, bien évidemment, cela ne va pas être le cas.

Une alternative aux problèmes causés par l'emploi du paramètre notify :echo consiste à abandonner son utilisation et à recourir à la place à la combinaison redirect+addheader/addtag. En procédant ainsi, les mécanismes de détection de boucles existants seront à nouveau opérationnels, avec toutes les implications sous-jacentes. Les structures de messages ne seront plus modifiées.


Informations complémentaires sur l'approche de la transmission adoptée par Communications Express

La génération actuelle par Communications Express d'un filtre utilisant notify au lieu d'un filtre employant redirect pour effectuer les transmissions est un défaut qu'il est prévu de corriger dans la prochaine version (Messaging Server 6.3, qui fera partie de Sun Java Communications Suite Release 5).

Entre temps, si vous rencontrez des boucles de messages dans Communications Express, nous vous conseillons de laisser la fonction de transmission non opérationnelle plutôt que d'activer MAX_NOTIFYS (et ainsi de rendre le site soumis à un nombre potentiellement croissant de boucles de message). Informez également les utilisateurs de s'attendre à rencontrer un comportement « erroné » de la fonction de transmission de Communications Express jusqu'à ce que le problème soit résolu par une mise à jour du logiciel prévue dans la prochaine version.


Unless otherwise licensed, code in all technical manuals herein (including articles, FAQs, samples) is provided under this License.


BigAdmin