How to make postfix to deliver via a command

postfix

I have setup a postfix server that will receive several emails and deliver
them to OpenERP. It's currently working, but I would like to improve the
overall schema so that postfix delivers (i.e Delivered-To) to the OpenERP
email alias.

More details about the instalation

The big schema is the following:

  1. Installed postfix-pgsql. In my main.cf file I have something like:

    alias_maps = hash:/etc/aliases
    alias_database = hash:/etc/aliases
    myorigin = /etc/mailname
    mydestination = localhost
    
    virtual_alias_domains = mydomain.com
    virtual_alias_maps = pgsql:/etc/postfix/pgsql-aliases.cf
    
  2. The query in pgsql-aliases.cf

    query = SELECT 'oerp@localhost'
            FROM mail_alias a, ir_config_parameter d
            WHERE (d.key = 'mail.catchall.domain')
                  AND (d.value = '%d')
                  AND (a.alias_name = '%u');
    
  3. Then I have the "oerp" alias in /etc/aliases:

    oerp: "| openerp_mailgate ...args... "
    

The issue

This setup works fairly well. Mails are being delivered, etc. But then, I
have an out-of-my-control MTA (my postfix can relay to that for outsiders)
that relays emails coming to "mydomain.com" to my postfix.

In that MTA there are several rules. For instance, I you email
to "contact@external-domain.com", the MTA will re-deliver the email
to "contact@mydomain.com" and "boss@external-domain.com". That redelivery
won't touch original headers.

The "contact@mydomain.com" will handed to my postfix and, ultimately, it will
end up being piped to the mailgate script. But the "Delivered-To" header will
be changed to "oerp@localhost".

OpenERP looks for the "Delivered-To" header (among others) of the message to
know what to do with it. But in this case the "Delivered-To" will always be
the same and thus we can't use it for anything important.

I would like to change the schema so that postfix will deliver the email to my
mailgate script without resorting to "oerp@localhost" alias and
the "Delivered-To" remains unchanged (in the example it is expected to
be "contact@mydomain.com").

Any ideas? I've been playing with the master.cf but failed to accomplish
anything.

Best Answer

Summary of the solution I found:

  1. Remove the alias that matches 'oerp@localhost' with the script.

  2. Place the script as a pipe in master.cf.

  3. Create a transport map that matches your OpenERP domain to be delivered to the script previously defined in master.cf.

  4. Use the pg_aliases.cf for a virtual mailbox map instead for alias. Then remove the oerp alias in /etc/aliases.

Long answer

The previous solution simply gave the same alias for every match resulting in the unreliability of the 'Delivered-To'. Now what I have done is to recast the entire solution and use a virtual mailbox instead, like:

virtual_mailbox_domains = mydomain.com
virtual_mailbox_maps = pgsql:/etc/postfix/pg-aliases.cf

This take another view to the problem, and IMO is more correct: Instead giving the same "aliased" mailbox to each message, simply find a positive virtual mailbox.

The pg-aliases.cf was modified (though this is not strictly need I find it more convenient for logging purposes) to:

query = SELECT '%u@%d'
      FROM mail_alias a, ir_config_parameter d
      WHERE (d.key = 'mail.catchall.domain')
            AND (d.value = '%d')
            AND (a.alias_name = '%u');

Now you need to define a transport that actually delivers the incoming emails to the mailgate script. This is done in two steps:

First, configure the mailgate script in the master.cf file, like this:

openerp   unix  -       n       n       -       1       pipe
   flags=DFR user=openerp argv=/path/to/mailgate.py -d dbname ... etc ..

Notice that 1 as the limit. This is done so that concurrent access to OpenERP server is not possible otherwise messages coming to several @mydomain.com address may double in the DB because of transactional isolation.

The write a simple /etc/postfix/transports file:

mydomain.com  openerp

And instruct main.cf to read this transport file:

transport_maps = hash:/etc/postfix/transports

You may forget about the transport map use virtual_transport=openerp if the only virtual domain you have is this one. However, you may find useful to have other internal domains for internal messages, etc.

Related Topic