3

Here is my SMTP situation.

Mail flow is tagged by an online relay provider (!!SPAM!!, !!BULK!!, etc)

Mail flow is received by an internal postfix. Transport is configured to relay to our internal Exchange else if subject are tagged. I do that using Header_checks. The tagged mail flow is dispatched to our quarantine server (webUI for individual users etc ...)

/^[sS]ubject:.*!!SPAM!!*/ FILTER smtp:192.168.11.250
/^[sS]ubject:.*!!BULK!!*/ FILTER smtp:192.168.11.250
/^[sS]ubject:.*!!SUSPECT!!*/ FILTER smtp:192.168.11.250

It works fine. Our quarantine server can generate a list of trusted sender for users. This whitelist is availlable and I can download it to my postfix.

My question is: how can I apply my whitelist before the header checking ?

 If Subject contains *!!SPAM!!*
  then
   If from contains trustedsender@domain.com AND if to contains InternalUser@domain.com
    Then redirect to internal exchange server
    else redirect to quarantine server
  endif
 endif

I don't know how to do that. Any hints?

  • 1
    Perhaps you can play with SMTP_POLICY (postfix.org/SMTPD_POLICY_README.html). Unfortuntaly the mail itself is not passed to the PolicyServer so you cannot inspect content. Perhaps on the FILTER you can FILTER to policyserver and then in the policy server return FILTER to smtp:exchange if meets conditions or smtp:quarantine if not. Interesting in any case, I will try to reproduce it on a test VM :) – alphamikevictor May 4 '15 at 16:26
  • Hello alphamikevictor. Thank's for your reply. I'm going to read about SMTP_POLICY this afternoon. If you have any other ideas I stay tuned :-) – Thomas May 5 '15 at 9:50
  • You're welcome, I hope I can do some tests, for fun – alphamikevictor May 5 '15 at 10:02
4

After comment from @masegaloeh I've found a solution. The idea is to have a second postfix SMTP server listening on 10025 with a policy server in order to send mails to the normal server (if whitelisted) or to the quarantine server.

The idea was starting as your header_checks solution, in main.cf:

header_checks = regexp:/etc/postfix/header_checks

In header_checks:

/^(S|s)ubject: .*!!(SPAM|BULK|SUSPECT)!!.*/ FILTER  smtp:127.0.0.1:10025

Then in master.cf (edited with @masegaloeh comments):

10025      inet  n       -       n       -       -       smtpd
        -o receive_override_options=no_header_body_checks
        -o smtpd_recipient_restrictions=${my_switcher_restrictions}
policy  unix    -       n       n       -       0       spawn   user=nobody argv=/etc/postfix/policy-server-switcher

This makes the second instance of postfix override the use of header_checks.

And in main.cf

my_switcher_restrictions = check_policy_service unix:private/policy

And the contents of policy-server-switcher

!/bin/bash

sender=""
recipient=""

while read line
    do
    key=$(echo $line | cut -f1 -d=)
    value=$(echo $line|cut -f2 -d=)
    if [ "$key" == "sender" ] 
        then
        sender=${value}
        logger -p mail.info -t PolicyServer "Sender is: ${value}"
        fi
    if [ "$key" == "recipient" ] 
        then
        recipient=${value}
        logger -p mail.info -t PolicyServer "Recipient is: ${value}"
        fi
    if [  "x${recipient}" != "x" ] && [  "x${sender}" != "x" ]
        then
        if [ "$sender" == "alphamikevictor@serverfault.com" ] && [ "$recipient" == "alphamikevictor@example.com" ]
            then
            echo "action=FILTER smtp:192.168.1.150"
            echo
            exit 0
            fi
        if [ "$sender" == "thomas@serverfault.com" ] && [ "$recipient" == "thomas@example.com" ]
            then
            echo "action=FILTER smtp:192.168.1.150"
            echo
            exit 0
            fi
        echo "action=FILTER smtp:192.168.1.151"
        echo
        exit 0
        fi
    done

Of course you will need to program your policy server to load the whitelist from database or LDAP, here is just an example to get the idea.

But this still have some caveats, suppose I send a mail with this

From: thomas@serverfault.com

To: alphamikevictor@example.com

To: thomas@example.com

This will go to the normal server for alphamikevictor and for thomas, as far as the last test against the policy server returns FILTER to the normal, but if you place alphamikevictor on second position then it will send mail for both recipients to quarantine.

  • 2
    If you want to turn off header_checks, no need to use separate postfix server. Just pass -o receive_override_options=no_header_body_checks in second smtpd a.k.a port 10025. References: postfix.org/postconf.5.html#receive_override_options – masegaloeh May 9 '15 at 11:19
  • 1
    Thomas, if you add the configuration suggested by @masegaloeh then it works. – alphamikevictor May 9 '15 at 19:23

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.