Regex+postfix+header_checks

Résolu
salut a tous et merci de me lire

j'ai besoins d'aide pour la création d'un régex

En analysant les mails parti depuis mon client outlook (pc at home) en passant par mon serveur postfix (SMTP TLS sur un serveur VPS) je constate ceci :

from 192.168.1.2 (unknown [xx.xxx.xx.xx]) (Authenticated sender: xxxxxx) by mail.MON-SERVEUR-SMTP.com (Postfix) with ESMTPA id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)

que je veux transformer en ceci :

from mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1]) by mail.MON-SERVEUR-SMTP.com (Postfix) with SMTP id E67A58929974 for <xxx@xxx.com>; Sun, 20 Mar 2011 00:18:41 +0000 (GMT) 

les mots a changer sont donc :
from 192.168.1.2 (unknown [xx.xxx.xx.xx]) (Authenticated sender: xxxxxx)

par
from mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1])

et
with ESMTPA 

par
with SMTP 

dans mon header_checks j'ai déjà essayez plusieurs combinaisons de regex sans succès, j'ai réussi facilement a faire ignorer complétement la ligne et pas a la remplacer correctement.

quelqu'un qui si connait en regex peut-il m'aidez a résoudre mon problème ?

Merci d'avance a tous.
Cordialement
jonigood

14 réponses

Résumé de la discussion

Problème : l'utilisation d'un regex dans header_checks de Postfix pour transformer une ligne d'en-tête mail et remplacer des éléments comme l'adresse source et ESMTPA par des valeurs locales. Des propositions visent à capturer la ligne Received et à remplacer le préambule et le protocole, via des motifs ^Received:\s*(from\s*)192\.168\.1\.\d.*\(Authenticated sender:.*\)(\s+by mail\.MON-SERVEUR-SMTP\.com.*)ESMTPA(.*)$ et REPLACE. Des échanges ultérieurs soulignent l'importance de tester avant d'envoyer un mail réel, via postmap -q - regexp:/etc/postfix/header_checks, et d'adapter le motif selon que l'on puisse utiliser [0-9] ou \\d et présence de la ligne Received. Une nuance utile est de vérifier que le header à modifier commence bien par Received, et que l'utilisateur fournisse l'exemple exact d'entrée pour que la regex ne casse pas d'autres lignes.

Bobot (l’IA à votre service)
  1. Modérateur
    Re,

    De rien.
    Pour la fin de l'histoire ;-)

    comment tester la regex sans avoir a m'envoyer un mail a chaque fois ?
    Effectivement s'envoyer à chaque fois un mail ce n'est pas le top.

    Voici une manière de tester la regex sans avoir besoin de s'envoyer à chaque fois un mail.
    La commande est (à faire en root)
    postmap -q - regexp:/etc/postfix/header_checks < fichier_qui_contient_l'en_tête


    On constate effectivement que la classe de caractères \d n'est pas reconnue, la commande ne retourne rien

    :~$ cat /etc/postfix/header_checks 
    /^Received:\s*(from\s*)192\.168\.1\.\d.*\(Authenticated sender:.*\)(\s+by mail\.MON-SERVEUR-SMTP\.com.*)ESMTPA(.*)$/      REPLACE       Received: $1 mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1]) $2 SMTP $3 
    ~$ cat test_head 
    Received: from 192.168.1.2 (unknown [xx.xxx.xx.xx]) (Authenticated sender: xxxxxx) by mail.MON-SERVEUR-SMTP.com (Postfix) with ESMTPA id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)
    ~$ sudo postmap -q - regexp:/etc/postfix/header_checks < test_head 
    ~$ 
    


    Si on mets [0-9] ça fonctionne.
    Cette fois en revanche la commande retourne le contenu de fichier et la chaîne de remplacement obtenu grâce à la regex

    ~$ cat /etc/postfix/header_checks 
    /^Received:\s*(from\s*)192\.168\.1\.[0-9].*\(Authenticated sender:.*\)(\s+by mail\.MON-SERVEUR-SMTP\.com.*)ESMTPA(.*)$/      REPLACE       Received: $1 mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1]) $2 SMTP $3 
    ~$ cat test_head 
    Received: from 192.168.1.2 (unknown [xx.xxx.xx.xx]) (Authenticated sender: xxxxxx) by mail.MON-SERVEUR-SMTP.com (Postfix) with ESMTPA id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)
    ~$ sudo postmap -q - regexp:/etc/postfix/header_checks < test_head 
    Received: from 192.168.1.2 (unknown [xx.xxx.xx.xx]) (Authenticated sender: xxxxxx) by mail.MON-SERVEUR-SMTP.com (Postfix) with ESMTPA id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)	REPLACE       Received: from  mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1])  by mail.MON-SERVEUR-SMTP.com (Postfix) with  SMTP  id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)


    1. RÉSOLU

      my name is jonigood

      winer is l'ami20jgood verry goooooood !

      merci a toi tu a trouver la bonne regex (pas facile tout de même)

      le mot de la fin est :

      /^Received:\s*(from\s*)192\.168\.1\.[0-9].*\(Authenticated sender:.*\)(\s+by mail\.MON-SERVEUR-SMTP\.com.*)ESMTPA(.*)$/      REPLACE       Received: $1 mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1]) $2 SMTP $3 


      a bientôt et merci a tous

      petite précision , il fallait mètre Received: après le REPLACE et "\d" n'est pas pris en compte, il fallait donc "[0-9]" a la place
      1. pour vérifier je test directement en m'envoyant un mail sur ma boite ymail ou il est possible d'analyser les header, avec ta regex il n'y a aucun changement, le header reste exactement le même

        quand je teste avec un truc simple comme :
        /^Received:.*\[192\.168\.0\.[0-9]/   REPLACE  Received  from mail.MON-SERVEUR-SMTP.com


        me header change correctement en :
        Received  from mail.MON-SERVEUR-SMTP.com


        comment tester la regex sans avoir a m'envoyer un mail a chaque fois ?
        j'ai vue que tu fait sa dans un .pl, tu peut m'expliquer ?
        1. Modérateur
          j'ai vue que tu fait sa dans un .pl, tu peut m'expliquer ?

          Ben, justement, dans le .pl ça marche puisque c'est directement du Perl

          Essaie comme ça

          /^(Received:\s*from\s*)192\.168\.\d{1,3}\.\d{1,3}.*unknown.*\(Authenticated sender:.*\)(\s+by mail\.MON-SERVEUR-SMTP\.com.*)ESMTPA(.*)$/      REPLACE       "$1" mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1]) "$2" SMTP "$3"
        2. Modérateur
          Si ça ne marchera pas alors on va faire petit à petit pour voir ce qui ne passe pas.
        3. Modérateur
          Et encore une chose, enlève le crochet, il n'a rien à faire là.
          Il n'y a pas de crochet avec 192

          quand je teste avec un truc simple comme :
          /^Received:.*\[192\.168\.0\.[0-9]/


          Justement je suis vraiment étonné que ça marche
          Si c'est le cas alors il faudrait que tu m'envoie par mail l'entête puisque je dois comprendre que lorsque tu colles sur ccm ça ne passe pas le crochet
        4. je m'inspire de :

          http://www.starbridge.org/support/viewtopic.php?f=2&t=772 (bas de page)
          et
          http://tech.groups.yahoo.com/group/postfix-users/message/274241 (bas de page)

          ça a l'air de fonctionner pour eux ....
      2. fonctionne pas :-(

        je précise que le [xx.xxx.xx.xx] dans le header original est une adresse ip....
        1. Modérateur
          peu importe xx.xxx.xxx.xx puisque .* reconnaît tout

          Regarde mon test, on voit que tout est modifié correctement
          lami20j@debian-acer:~$ cat joniperdu.pl 
          #!/usr/bin/perl
          
          while(<DATA>){
            s/^(Received:\s*from\s*)192\.168\.\d{1,3}\.\d{1,3}.*unknown.*\(Authenticated sender:.*\)(\s+by mail\.MON-SERVEUR-SMTP\.com.*)ESMTPA(.*)$/$1 mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1])$2SMTP$3/;
            print;
          }
          __DATA__
          Received: from 192.168.1.2 (unknown [xx.xxx.xx.xx]) (Authenticated sender: xxxxxx) by mail.MON-SERVEUR-SMTP.com (Postfix) with ESMTPA id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)
          lami20j@debian-acer:~$ 
          lami20j@debian-acer:~$ perl joniperdu.pl
          Received: from  mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1]) by mail.MON-SERVEUR-SMTP.com (Postfix) with SMTP id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)
          


          Bref, il faudrait que tu montres ce que tu obtiens pour voir ce qui ne va pas sinon on ne peux pas avancer.
      3. Modérateur
        /^(Received:\s*from\s*)192\.168\.\d{1,3}\.\d{1,3}.*unknown.*\(Authenticated sender:.*\)(\s+by mail\.MON-SERVEUR-SMTP\.com.*)ESMTPA(.*)$/      REPLACE       $1 mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1])${2}SMTP$3


        GNU/Linux:Linux is Not Ubuntu! Quel linux choisir ne veut pas dire votre Distribution préférée,
        106485010510997108
        1. je précise qu'il est possible de mètre plusieurs regex dans ce fichier, peut être que la solution la plus simple serait de faire deux regex différentes ?

          une première regex pour la première partie a changer 192.168.1.2 (unknown [xx.xxx.xx.xx]) (Authenticated sender: xxxxxx)

          et une deuxièmes regex pour la deuxièmes parties a changer ESMTPA

          ....
          1. oui c'est tout a fait normale

            chaque mail a forcément un ID différent
            chaque mail a forcément une heure d'envoi différente

            donc c'est deux information ne doive pas être changer par la regex et c'est la que ça coince pour moi ....
            1. déjà , merci de prendre de ton temps pour mon problème.

              Dans ton premier message tu dis
              from 192.168.1.2 (unknown [xx.xxx.xx.xx]) (Authenticated sender: xxxxxx) by mail.MON-SERVEUR-SMTP.com (Postfix) with ESMTPA id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)

              et puis tu cherche une ligne qui commence avec Received

              en faite "Received " est forcément avant le "from" c'est un des header des mails envoyés.

              donc quand je fait /^Received:.*\[192\.168\.0\.[0-9]/ REPLACE Received from mail.MON-SERVEUR-SMTP.com sa prend tout ce qui est après "Received: 192.168.1.2" , pour plus de clarté voici la ligne complète :

              Received: from 192.168.1.2 (unknown [xx.xxx.xx.xx]) (Authenticated sender: xxxxxx) by mail.MON-SERVEUR-SMTP.com (Postfix) with ESMTPA id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)


              donc /^Received:.*\[192\.168\.0\.[0-9]/ REPLACE Received from mail.MON-SERVEUR-SMTP.com fonctionne correctement. et transforme toute la ligne en Received: from mail.MON-SERVEUR-SMTP.com qui est après REPLACE de ma regex

              - tu cherches ESMTPA mais dans regex tu mets ESMTPSA
              effectivement une erreur de frape
              - pourquoi tu mets de backslash avant les tiret?
              car c'est plus jolie (lol)
              - dans ton message initial tu dis que tu veuilles obtenir ceci mais tu changes id et aussi l'heure. C'est normal?
              encore une erreur de ma part
              - c'est quoi le crochet avant 192?
              ça aussi c'est jolis :-)

              blague à part , voici exactement ce que je veux obtenir, tout ce qui est en gras doit être changer par la regex :

              Received: from 192.168.1.2 (unknown [xx.xxx.xx.xx]) (Authenticated sender: xxxxxx) by mail.MON-SERVEUR-SMTP.com (Postfix) with ESMTPA id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)

              ce qui donne :

              Received: from mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1]) by mail.MON-SERVEUR-SMTP.com (Postfix) with SMTP id E67A58929974 for <xxx@xxx.com>; Sun, 20 Mar 2011 00:18:41 +0000 (GMT)

              j'espère que c'est déjà plus compréhensible comme ça
              1. Modérateur
                j'espère que c'est déjà plus compréhensible comme ça

                Pas toute à fait ;-)
                Regarde ce que j'ai souligné.

                Received: from 192.168.1.2 (unknown [xx.xxx.xx.xx]) (Authenticated sender: xxxxxx) by mail.MON-SERVEUR-SMTP.com (Postfix) with ESMTPA id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)


                Ce ne sont pas les mêmes en-têtes (id et heure ont changé)
                C'est normal?

                Received: from mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1]) by mail.MON-SERVEUR-SMTP.com (Postfix) with SMTP id E67A58929974 for <xxx@xxx.com>; Sun, 20 Mar 2011 00:18:41 +0000 (GMT)
                


                Il faut que je regarde comment fonctionnent, si jamais c'est possible, les captures des motifs avec headers_check
            2. Modérateur
              mon souci est pour construire cette règle, je n'y arrive pas, j'arrive a replacer la ligne entière avec : 
              
              /^Received:.*\[192\.168\.0\.[0-9]/   REPLACE  Received  from mail.MON-SERVEUR-SMTP.com 
              
              
              qui détecte toutes lignes contenant 192.168.1.2 et la remplace par Received from mail.MON-SERVEUR-SMTP.com 


              Je ne crois pas.
              Dans ta regex tu cherches et les lignes contient 1 (voir en gras

              de mon coté voila ou j'en suis :

              /^Received:.*\[192\.168\.0\.[0-9]\(Authenticated sender:.*\)\s+(.*by mail\.MON\-SERVEUR\-SMTP\.com[^\n]+ESMTPSA .*)$/im REPLACE from mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1]) by mail.MON-SERVEUR-SMTP.com (Postfix) with SMPT

              et ca ne fonctionne pas, il doit y avoir une erreur dans ma ligne.
              une idée ?


              Oui, t'arrêtes de boire quand tu fais des regex ;-DDD

              - tu cherches ESMTPA mais dans regex tu mets ESMTPSA
              - pour ip dans 192.168 je te conseille d'utiliser 192\.168\.\d{1,3}\.\d{1,3}
              - pourquoi tu mets de backslash avant les tiret?
              - dans ton message initial tu dis que tu veuilles obtenir ceci mais tu changes id et aussi l'heure. C'est normal?
              - c'est quoi le crochet avant 192?

              Quelque chose comme ça, mais je ne suis pas convaincu, il faudrait que tu dises exactement ce que tu veux remplacer exactement et avec quoi.
              A vrai dire ce que tu demande c'est relativement simple.
              Ce n'est pas la construction de la regex qui me pose de problèmes mais la façon dont elle est utilisé. Je ne connais pas headers_check

              /^Received:.*192\.168\.\d{1,3}\.\d{1,3}.*\(Authenticated sender:.*\)\s+by mail\.MON-SERVEUR-SMTP\.com.*ESMTPA.*$/      REPLACE       from mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1]) by mail.MON-SERVEUR-SMTP.com (Postfix) with SMPT


              GNU/Linux:Linux is Not Ubuntu! Quel linux choisir ne veut pas dire votre Distribution préférée,
              106485010510997108
              1. l'ami20j
                Ok, mais tu mets avec quoi?
                Script shell, script perl, script php?
                Il faut savoir quelle application utilise les regex.
                

                désolé l'ami je suis pas encore calé en la matière pour te répondre correctement.
                ce que je sais c'est que postfix doit utiliser cette regex pour filtré les mails sortants et donc REPLACE les mots définits.

                sous putty j'ai créer ce fichier "/etc/postfix/header_checks" et j'écris la regex dedans...

                zipe31
                merci pour ce lien c'est exactement ça.
                mon souci est pour construire cette règle, je n'y arrive pas, j'arrive a replacer la ligne entière avec :
                /^Received:.*\[192\.168\.0\.[0-9]/   REPLACE  Received  from mail.MON-SERVEUR-SMTP.com
                

                qui détecte toutes lignes contenant 192.168.1.2 et la remplace par Received from mail.MON-SERVEUR-SMTP.com
                je doit donc construire cette règle avec les bonnes regex pour ne pas remplacer toute la ligne....
                1. Modérateur
                  Ok.

                  Mais tu ne donnes pas la ligne complète alors.

                  Dans ton premier message tu dis

                  from 192.168.1.2 (unknown [xx.xxx.xx.xx]) (Authenticated sender: xxxxxx) by mail.MON-SERVEUR-SMTP.com (Postfix) with ESMTPA id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)

                  et puis tu cherche une ligne qui commence avec Received

                  Bref, ta regex ne va jamais fonctionner.
                  Il faudra que tu donnes le contenus correct des données en entrée.
                2. Modérateur
                  En plus entre IP et Authenticated sender il y a des choses qu'on ne voit pas dans ta regex

                  \[192\.168\.0\.[0-9]\(Authenticated sender
              2. Modérateur
                Salut à vous deux,

                langage pcre
                Tu ne fais pas ça en php, par hasard?
                1. Contributeur
                  Salut à toi,

                  Merchi ;-))
                2. Modérateur
                  Re,

                  De rien.

                  Pour joniperdu, je vais regarder ce soir ;-))).
                  Ca ne t'empêchera pas de répondre à ma question ;-)
                3. salut l'amie20j !! ;-)

                  en php ? comment ca ?

                  je met sa dans mon fichier /etc/postfix/header_checks que j'ai préalablement créer suite a la lecture de plusieurs poste

                  JONIPERDU lol
                4. Modérateur
                  je met sa dans mon fichier /etc/postfix/header_checks

                  Ok, mais tu mets avec quoi?
                  Script shell, script perl, script php?
                  Il faut savoir quelle application utilise les regex.

                  pcre ne désigne qu'un type des regex compatible avec perl, mais si tu ne fais pas en perl alors tu fais avec quoi?

                  Montre tes tests?
              3. salut zipe31 et merci de ton intervention,

                je ne pense pas que c'est écrit sous la bonne forme, pour exemple voici comment j'arrive a remplacer TOUTE LA LIGNE sans exception (ce n'est donc pas le résultat souhaité) :
                /^Received:.*\[192\.168\.0\.[0-9]/   REPLACE  Received  from mail.MON-SERVEUR-SMTP.com

                ceci remplace toute la ligne par Received from mail.MON-SERVEUR-SMTP.com

                de mon coté voila ou j'en suis :
                /^Received:.*\[192\.168\.0\.[0-9]\(Authenticated sender:.*\)\s+(.*by mail\.MON\-SERVEUR\-SMTP\.com[^\n]+ESMTPSA .*)$/im      REPLACE       from mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1]) by mail.MON-SERVEUR-SMTP.com (Postfix) with SMPT

                et ca ne fonctionne pas, il doit y avoir une erreur dans ma ligne.
                une idée ?
                1. Contributeur
                  Perso j'ai utilisé "sed", mais toi tu utilises (ou comptes utiliser) quel langage ?
                2. langage pcre

                  merci de ton aide
                3. Contributeur
                  Euh... là je vais céder ma place à "lami20j" qui s'y connait bien plus que moi dans ce genre de regex ;-)

                  Par contre dans ta regex il y a un truc qui me chagrine, c'est le "[^\n]+" ???
                  Qu'as-tu voulu exprimer avec ça ?
                4. oups
                  effectivement "[^\n]+" pas bon, désolé les regex c'est pas mon fort je suis perdu ...

                  l'amie20J plese help !!!!!
              4. Contributeur
                Salut,

                Une piste...

                $ cat plop
                from 192.168.1.2 (unknown [xx.xxx.xx.xx]) (Authenticated sender: xxxxxx) by mail.MON-SERVEUR-SMTP.com (Postfix) with ESMTPA id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)
                
                $ sed 's/^from 192\.168\.1\.2.*sender:[^)]*)/from mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1])/;s/ESMTPA/SMPT/' plop
                from mail.MON-SERVEUR-SMTP.com (localhost.localdomain [127.0.0.1]) by mail.MON-SERVEUR-SMTP.com (Postfix) with SMPT id 1E-65424927097 for <xxx@xxx.com>; Sun, 20 Mar 2011 02:18:43 +0000 (GMT)
                
                $

                ;-))