Policy Rule for replacing header

Hello,

 

I want to create a policy rule for external mails.

 

If one of this point is true

1. Subject contains [External] or

2. The mail comes from a special domain xxx or

3. the mail comes from an IP from driendly mailservers (SPF List)

then do nothing

else

replace header with Subject=[External]%%Subject

 

My rule looks like


    # attr NAME=Domain Test
     if envelope :comparator "i;ascii-casemap" :all :contains ["from"] ["xxx.de"] {
         # attr NAME=Do not modify Subject
         if anyof(header :comparator "i;ascii-casemap" :contains ["Subject"]
                         ["[External]"],
                  header :comparator "i;ascii-casemap" :memberof ["Received"]
                         ["SPF_Relays"],
                  address :all :memberof :comparator "i;ascii-casemap" ["to",
                                                                        "cc",
                                                                        "bcc"]
                          ["external_recipient"])
         {
         }
         # attr NAME=Modify Subject
         else {
             pmx_replace_header :index 0 :recode "Subject" "[EXTERNAL] %%Subject%%";
         }
     }

 

My problem ist, that the second test "Received Header" is a member of SPF-Relays does not match, altough the testing mail is coming from an IP, that is mentioned in the list SPF-Relays.

Aslo when I test current policy from the interal tool of pure message, it does not work.

 

I hope that somebody can help :-)

BR Sabrina

  • Hi Sabrina,

    you are likely comparing a given longish text line to your list of SPF hosts.
    The header 'Received' is just a bunch of text containing several pieces of information and I don't think there is special treatment from 'envelope' to extract proper relay info from it and have a type consistent (IP:IP) or type casting comparison nor even some simple substring match. You might try to adjust your list of hosts (type of list as well as entries) to regular expressions and to account for the 'additional' text (you should be aware that Received lines are provided by the smtp client and hence might contain all kinds of false or forged information) or see, whether pmx_relay might be an appropriate test in your environment.

    Hope this helps
    Jens

  • In reply to Jens Pönninghaus:

    Hello Jens,

     

    at first I want to thank you,that you answered. :-)

    The problem is, that I want to filter for the special mailservers mentioned in SPF list.

    Unfortunately pmx_relay does not work, because the last mailserver before the mail receive PM is from a provider.

    We want to filter the mailserver in the received header, from which the mail is send.

    Is there a possibility to filter this. If possible, how it works?

    I know that the received header can be spoofed, but our customer want such a policy-rule.

    Best Regards

    Sabrina

  • In reply to Jens Pönninghaus:

    Hello Again,

     

    now I recode my SPF List to type of regular expression and tried the matching again, but it does not work :-(

    Has somebody an idea that I get a matching with the mailserver(sending ones) from the received header with an given IP address (of the mailserver)

    I tried all matching variants "contains", "regex", "member of", "matches" etc....

    I've red also an info that is possible to write an filter for the postfix mailserver in perl or I have to write in sieve, to solve this problem???

    Thank you for reading my post.

    BR Sabrina

  • In reply to Sabrina Rieger:

    Hi Sabrina,

    did you alter the type of the SPF_Relays list and the entries to accommodate for a whole line, so .e.g. (simplified, it might be more tricky, depending on what 'dot' actually matches)    '.*somerelay.domain.tld.*' ?
    Can you provide an obfuscated sample from your SPF-Relays list as well as the policy.siv generated for that envelope 'Received' section and the list.conf section for the SPF-Relays?My approach is based on the assumption to have a membership test (envelope header received memberof SPF-LIST) against a list of entries that in turn need to cover the whole Received line (so list type=regex and entries .*qualifier.*)

    Best regards
    Jens

  • In reply to Jens Pönninghaus:

    Hello Jens,

    I altered the typ of the SPF_Relays list to regex. Also I tried to write the entries as regex. But it doesn`t match also.

    What I have red in the docs was very interesting. When I switch the Anti SPam Option  "DIsable non relay checks" to "no", all relays in the chain will be checked, and not only the connected one.

    In the second step I added the list Trusted Relay IPs with the SPF-Relay IPs, which is a list of IPs.

    With this adjustment the matching works :-)

    THe hint with "pmx-relay" was very good.

    Thank you.

    Best Regards

    Sabrina

  • In reply to Sabrina Rieger:

    Hi Sabrina,

    glad, that at least pmx-relay did the job for you.
    Nevertheless, I wondered why the header "Received" approach does not work for you and setup a small test.
    I currently have a setup that yields expected results.
    At first I fell victim to a difference in GUI (test.cgi) vs. telnet behaviour that seems to go down to my own laziness of having a rather long logical smtp Received line as one line of text rather than folded. Doing the telnet test with a folded smtp 'Received' line yields expected results, too. So maybe you want to check your test procedure whether it contained a long Received line as a single text line. Behaviour of course could be mta or configuration specific.

    lists.conf:

    --8<--

    <list tst1-spf-relay>
        name = tst1-spf-relay
        description = Test header Received check
        match_type = re
        comparator = i;ascii-casemap
        source = file:tst1-spf-relay
    </list>

    --8<--

    #

    policy.siv:

    --8<--
    if header "Received" :memberof ["tst1-spf-relay"] {
      pmx_mark1 "TST1_header_match";
    keep;
    stop;
              }
     else {
      pmx_mark1 "TST1_no_match";
      reject :rcode 550 "no match ";
      stop;}
    pmx_mark1 "really shouldn't be here";
    keep;
    stop;
    --8<--

    cat tst1-spf-relay
    --8<--

    .*boogey.nosuch.domain.com.*

    --8<--

    telnet pmx13 25
    [..]
    helo [127.0.0.1]
    250 pmx13 Hello pmx13[129.a.b.c], pleased to meet you
    mail from:<>
    250 2.1.0 <>... Sender ok
    rcpt to:<jptest@local.domain>
    250 2.1.5 <jptest@local.domain>... Recipient ok
    data
    354 Enter mail, end with "." on a line by itself
    Subject: Test with folded Received line
    Received: from [1.2.3.4] ([129.a.x.y])  by boogey.nosuch.domain.com  (Longish Server Identifier (built Mar 17 2017))
      with ESMTPPA id <0OVS005UHSZXBB40@local
      domain> for  jens.poenninghaus@local.domain (ORCPT jens.poenninghaus@local.domain)

    bodytest
    .
    250 2.0.0 v85BX3TN003876 Message accepted for delivery
    mail from:<>
    250 2.1.0 <>... Sender ok
    rcpt to:<jptest@local.domain>
    250 2.1.5 <jptest@local.domain>... Recipient ok
    data
    354 Enter mail, end with "." on a line by itself
    Subject: Test with folded Received line but mismatching relay
    Received: from [1.2.3.4] ([129.a.x.y])  by boogeyNO.nosuch.domain.com  (Longish Server Identifier (built Mar 17 2017))
      with ESMTPPA id <0OVS005UHSZXBB40@local
      domain> for  jens.poenninghaus@local.domain (ORCPT jens.poenninghaus@local.domain)

    bodytest
    .
    550 5.0.0 no match

    Please mark, all above is just a test setup to verify principle capability / expressiveness. It is by no means suitable for anything beyond just that.