content_filter with external script and virtual_alias_maps

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

content_filter with external script and virtual_alias_maps

Stats Student
Hi, I would like to configure Postfix to do the following:

1) receive messages for users in a Postgres database and hand those
messages to an external script for processing (no traditional
mailstore). The server handles mail for only one domain.

2) for a handful of accounts (postmaster, help, root), the messages
should be forwarded to another address (different domain). Would be
great for this forwarding to take place without going through the
processing script in (1).

A very long time ago, I had it working with content_filter (as
described in http://www.postfix.org/FILTER_README.html#advanced_filter)
and virtual_alias_maps.
But for some reason (receive_override_options = no_address_mappings)
causes the server to ignore users in virtual_alias_maps and bounce.
Hence the question.

I used to use qpsmtpd on port 10025 with a custom plugin (in Perl)
which did the processing - but maybe there is a better way to do the
same.

What's the best way to get this configured? Would appreciate specific
setup recommendations (relay vs virtual aliases, content_filter, etc).
Happy to provide additional details.

Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: content_filter with external script and virtual_alias_maps

Wietse Venema
Stats Student:
> Hi, I would like to configure Postfix to do the following:
>
> 1) receive messages for users in a Postgres database and hand those
> messages to an external script for processing (no traditional
> mailstore). The server handles mail for only one domain.

Postfix chooses the delivery method based on the recipient domain
(the part on the right-hand side of the '@').

Here, we direct mail for example.com to your message store, and we
make sure that all cronjob mail comes from [hidden email],
[hidden email] etc.

/etc/postfix/main.cf
    virtual_transport = mailstore
    mailstore_destination_recipient_limit=1
    virtual_mailbox_domains = example.com
    virtual_mailbox_maps = hash:/etc/postfix/mailstore-users
    myorigin = example.com
    mydestination =

/etc/postfix/master.cf:
    # Requires mailstore_destination_recipient_limit=1 in main.cf.
    mailstore  unix  -       n       n       -       -       pipe
        flags=DRhu user=vmail argv=/path/to/script ${recipient}

/etc/postfix/mailstore-users:
    [hidden email] whatever
    [hidden email] whatever

Once you have this working, replace hash:/etc/postfix/mailstore-users
with a pgsql table that returns a non-emnpty string for existing
users, and 'not found' otherwise. See "man pgsql_table", especially
the section "LIST MEMBERSHIP".

> 2) for a handful of accounts (postmaster, help, root), the messages
> should be forwarded to another address (different domain). Would be
> great for this forwarding to take place without going through the
> processing script in (1).

Use virtual_alias_maps:

/etc/postfix/main.cf:
    virtual_alias_maps = hash:/etc/postfix/virtual

/etc/postfix/virtual:
    postmaster  user1@example
    root        user2@example
    help        user3@example

No need to muck with content filters.

        Wand ietse
Reply | Threaded
Open this post in threaded view
|

Re: content_filter with external script and virtual_alias_maps

Wietse Venema
Wietse Venema:
> Stats Student:
> > Hi, I would like to configure Postfix to do the following:
> >
> > 1) receive messages for users in a Postgres database and hand those
> > messages to an external script for processing (no traditional
> > mailstore). The server handles mail for only one domain.

With a few minor refinements:

Postfix chooses the delivery method based on the recipient domain
(the part on the right-hand side of the '@').

Here, we direct mail for example.com to your message store, and we
make sure that all cronjob mail comes from [hidden email],
[hidden email] etc.

This uses the name 'mailstore' for all things related to your
database. Of course you can use a different name.

/etc/postfix/main.cf
    virtual_transport = mailstore
    mailstore_destination_recipient_limit=1
    virtual_mailbox_domains = example.com
    virtual_mailbox_maps = hash:/etc/postfix/mailstore-users
    myorigin = example.com
    mydestination =

/etc/postfix/master.cf:
    # Requires mailstore_destination_recipient_limit=1 in main.cf.
    mailstore  unix  -       n       n       -       -       pipe
        flags=DRXhu user=vmail argv=/path/to/script ${recipient}

/etc/postfix/mailstore-users:
    [hidden email] whatever
    [hidden email] whatever

This requires that you have have a UNIX system account 'vmail'
(command: useradd vmail). Of course you can use a different name.

Once you have this working, replace hash:/etc/postfix/mailstore-users
with a pgsql table that returns a non-emnpty string for existing
users, and 'not found' otherwise. See "man pgsql_table", especially
the section "LIST MEMBERSHIP".

> 2) for a handful of accounts (postmaster, help, root), the messages
> should be forwarded to another address (different domain). Would be
> great for this forwarding to take place without going through the
> processing script in (1).

Use virtual_alias_maps:

/etc/postfix/main.cf:
    virtual_alias_maps = hash:/etc/postfix/virtual

/etc/postfix/virtual:
    postmaster  user1@example
    root        user2@example
    help        user3@example

No need to muck with content filters.

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: content_filter with external script and virtual_alias_maps

Viktor Dukhovni
In reply to this post by Stats Student
On Mon, Dec 30, 2019 at 12:46:50AM -0800, Stats Student wrote:

> 1) receive messages for users in a Postgres database and hand those
> messages to an external script for processing (no traditional
> mailstore). The server handles mail for only one domain.
>
> 2) for a handful of accounts (postmaster, help, root), the messages
> should be forwarded to another address (different domain).

This is easily handled via virtual_alias_maps, rewriting the recipients in
question.

> Would be great for this forwarding to take place without going through the
> processing script in (1).

Virtual alias rewriting happens before message delivery.  Note
that the domain need not be configured as a virtual alias domain,
virtual alias rewriting happens for all recipients, regardless
of address class.

> A very long time ago, I had it working with content_filter (as
> described in http://www.postfix.org/FILTER_README.html#advanced_filter)
> and virtual_alias_maps.

That's unnecessary, a pipe(8) transport is just fine, unless the mail is
going back into Postfix after processing by the script.

> But for some reason (receive_override_options = no_address_mappings)
> causes the server to ignore users in virtual_alias_maps and bounce.

Well, that's simply not how Postfix works, when you have a
content_filter.  The bounce only happens with no_address_mappings in
combination with NO content_filter.  But, you don't need either a filter
or no_address_mappings.

> What's the best way to get this configured? Would appreciate specific
> setup recommendations (relay vs virtual aliases, content_filter, etc).
> Happy to provide additional details.

Rewrite the exempt users to a different domain, resolve the original
domain to a pipe(8) transport that runs the script.  Provided the script
does not re-inject modified email back into Postfix with the same
recipient domain.

--
    Viktor.
Reply | Threaded
Open this post in threaded view
|

Re: content_filter with external script and virtual_alias_maps

Stats Student
In reply to this post by Wietse Venema
Thanks very much, appreciate the detailed explanation. Everything
seems to working as advertised.

On Mon, Dec 30, 2019 at 7:32 AM Wietse Venema <[hidden email]> wrote:

>
> Wietse Venema:
> > Stats Student:
> > > Hi, I would like to configure Postfix to do the following:
> > >
> > > 1) receive messages for users in a Postgres database and hand those
> > > messages to an external script for processing (no traditional
> > > mailstore). The server handles mail for only one domain.
>
> With a few minor refinements:
>
> Postfix chooses the delivery method based on the recipient domain
> (the part on the right-hand side of the '@').
>
> Here, we direct mail for example.com to your message store, and we
> make sure that all cronjob mail comes from [hidden email],
> [hidden email] etc.
>
> This uses the name 'mailstore' for all things related to your
> database. Of course you can use a different name.
>
> /etc/postfix/main.cf
>     virtual_transport = mailstore
>     mailstore_destination_recipient_limit=1
>     virtual_mailbox_domains = example.com
>     virtual_mailbox_maps = hash:/etc/postfix/mailstore-users
>     myorigin = example.com
>     mydestination =
>
> /etc/postfix/master.cf:
>     # Requires mailstore_destination_recipient_limit=1 in main.cf.
>     mailstore  unix  -       n       n       -       -       pipe
>         flags=DRXhu user=vmail argv=/path/to/script ${recipient}
>
> /etc/postfix/mailstore-users:
>     [hidden email]     whatever
>     [hidden email]     whatever
>
> This requires that you have have a UNIX system account 'vmail'
> (command: useradd vmail). Of course you can use a different name.
>
> Once you have this working, replace hash:/etc/postfix/mailstore-users
> with a pgsql table that returns a non-emnpty string for existing
> users, and 'not found' otherwise. See "man pgsql_table", especially
> the section "LIST MEMBERSHIP".
>
> > 2) for a handful of accounts (postmaster, help, root), the messages
> > should be forwarded to another address (different domain). Would be
> > great for this forwarding to take place without going through the
> > processing script in (1).
>
> Use virtual_alias_maps:
>
> /etc/postfix/main.cf:
>     virtual_alias_maps = hash:/etc/postfix/virtual
>
> /etc/postfix/virtual:
>     postmaster  user1@example
>     root        user2@example
>     help        user3@example
>
> No need to muck with content filters.
>
>         Wietse