Various bcc options in postfix

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

Various bcc options in postfix

@lbutlr

I had a setup that BCCed all the mail on postfix to a backup account, sorted by original date and cleaned out after a couple of weeks.

I would like to change this to only bcc mail that is being delivered to local users.

The current setup uses recipient_bcc_maps which I would have thought did what I wanted, but it actually does all outbound mail as well.

The pcre file for the map is generated each date:

#!/bin/bash

JDATE=$(gdate +%j)
cat << EOF > /etc/postfix/rbcc.pcre
if !/backup.*@/
/^([^+_]*).*@([^.]*)/   backup+${JDATE}.\${1}-\${2}@southgaylord.com
endif

EOF

So, what would I need to do/change so that message I send to this list )for example) are not archived, but the messages received from the list continue to be archived to the backup user?



--
"He is not only dull himself; he is the cause of dullness in others."
        Samuel Johnson

Reply | Threaded
Open this post in threaded view
|

Re: Various bcc options in postfix

Viktor Dukhovni
On Tue, Oct 20, 2020 at 03:08:51PM -0600, @lbutlr wrote:

> I would like to change this to only bcc mail that is being delivered
> to local users.
>
> The current setup uses recipient_bcc_maps which I would have thought
> did what I wanted, but it actually does all outbound mail as well.

With recipient_bcc_maps, the specified BCC recipient from the RHS of the
table is added whenever the message envelope contains a recipient that
matches the LHS of the table.  Therefore, either the outbound mail in
question also had local recipients, or your table inadvertently matches
some or all remote recipients.

> The pcre file for the map is generated each date:
>
> #!/bin/bash
>
> JDATE=$(gdate +%j)
> cat << EOF > /etc/postfix/rbcc.pcre
> if !/backup.*@/
> /^([^+_]*).*@([^.]*)/   backup+${JDATE}.\${1}-\${2}@southgaylord.com
> endif

I don't see anything above that limits the matched recipients to local
users.  Do you?  What is the intent of the "([^.]*)" pattern following
the "@" sign?  It will always match, possibly an empty string if the
first character after "@" is ".", but otherwise some initial substring
of the domain part.

This also misparses quoted local parts with an address extension:

    "user+foo..bar"@example.com

will result in $1 = '"user' and $2 = 'example', which produces a
malformed RHS address with just one bare '"'.

You'd typically want to match quoted forms explicitly before falling
back to matching unquoted forms:

    /"..."@.../ ...
    /...@.../   ...

Also, if you're then using the address extension to create filenames,
I'd want to exclude more characters from $1 and $2.  Bottom line,
regular expressions are power tools with no safety measures, they cut
fingers as well as they cut wood.  My advice would be to stick to
indexed tables whenever possible.

> So, what would I need to do/change so that message I send to this list
> )for example) are not archived, but the messages received from the
> list continue to be archived to the backup user?

Create an indexed table that only matches local addresses.

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

Re: Various bcc options in postfix

@lbutlr


> On 20 Oct 2020, at 16:10, Viktor Dukhovni <[hidden email]> wrote:
>
> On Tue, Oct 20, 2020 at 03:08:51PM -0600, @lbutlr wrote:
>
>> I would like to change this to only bcc mail that is being delivered
>> to local users.
>>
>> The current setup uses recipient_bcc_maps which I would have thought
>> did what I wanted, but it actually does all outbound mail as well.
>
> With recipient_bcc_maps, the specified BCC recipient from the RHS of the
> table is added whenever the message envelope contains a recipient that
> matches the LHS of the table.  Therefore, either the outbound mail in
> question also had local recipients, or your table inadvertently matches
> some or all remote recipients.

Right, which means custom m matches for every domain instead of being able to just catch the local users.

>> The pcre file for the map is generated each date:
>>
>> #!/bin/bash
>>
>> JDATE=$(gdate +%j)
>> cat << EOF > /etc/postfix/rbcc.pcre
>> if !/backup.*@/
>> /^([^+_]*).*@([^.]*)/   backup+${JDATE}.\${1}-\${2}@southgaylord.com
>> endif
>
> I don't see anything above that limits the matched recipients to local
> users.  Do you?  What is the intent of the "([^.]*)" pattern following
> the "@" sign?  It will always match, possibly an empty string if the
> first character after "@" is ".", but otherwise some initial substring
> of the domain part.

The first character cannot be a . in an email address (user@.example.com is invalid), so it matches the first portions of the domain part of the email address. So 'example' in example.com or 'mail' in mail.example.com.

> This also misparses quoted local parts with an address extension:

I'm fine with that. I have no quoted local part emails and if anyone created one with a double .. (an obviously attempt to break things) I'd deal with that with a clue bat.

> Also, if you're then using the address extension to create filenames, I'd want to exclude more characters from $1 and $2.

The issue is not the saving the email the other backup, that works perfectly fine and has no issues. The issue is excluding outbound emails.

> Bottom line, regular expressions are power tools with no safety measures, they cut
> fingers as well as they cut wood.  My advice would be to stick to
> indexed tables whenever possible.

This isn't related to the problem I am trying to solve.

>> So, what would I need to do/change so that message I send to this list
>> )for example) are not archived, but the messages received from the
>> list continue to be archived to the backup user?

> Create an indexed table that only matches local addresses.

So even though postfix must and does know about local domains, I have to tell it which domains are local to use bcc maps without including all sent mail?

There's got to be a better way to do this.

--
I'd rather have my mind opened by wonder than closed by belief

Reply | Threaded
Open this post in threaded view
|

Re: Various bcc options in postfix

Viktor Dukhovni
On Tue, Oct 20, 2020 at 05:29:22PM -0600, @lbutlr wrote:

> >> The current setup uses recipient_bcc_maps which I would have thought
> >> did what I wanted, but it actually does all outbound mail as well.
> >
> > With recipient_bcc_maps, the specified BCC recipient from the RHS of the
> > table is added whenever the message envelope contains a recipient that
> > matches the LHS of the table.  Therefore, either the outbound mail in
> > question also had local recipients, or your table inadvertently matches
> > some or all remote recipients.
>
> Right, which means custom m matches for every domain instead of being
> able to just catch the local users.

No, it just means that the table should not match remote recipients, how
that is done depends on the table type.

> > I don't see anything above that limits the matched recipients to local
> > users.  Do you?  What is the intent of the "([^.]*)" pattern following
> > the "@" sign?  It will always match, possibly an empty string if the
> > first character after "@" is ".", but otherwise some initial substring
> > of the domain part.
>
> The first character cannot be a . in an email address
> (user@.example.com is invalid), so it matches the first portions of
> the domain part of the email address. So 'example' in example.com or
> 'mail' in mail.example.com.

Lossy, but if you just want the first label, so be it.  What is your
definition of a "local" recipient?  Do you literally mean a mailbox
handled via local(8), aliases(5) and delivery to a unix-account, or do
you mean anything you're willing to accept inbound?

If you're abusing terminology and really "local" as in local address
class, then with an indexed table, bare lookup keys only match local
recipients (the domain matches $myorigin or $mydestination).  Of
course you then need to list each user.  Since you're generating
the map anyway:

    getent passwd | awk -F: '{print $1}' | ...

> > This also misparses quoted local parts with an address extension:
>
> I'm fine with that. I have no quoted local part emails and if anyone
> created one with a double .. (an obviously attempt to break things)
> I'd deal with that with a clue bat.

I don't recommend waiting for broken edge-cases to show in practice, but
your system your rules...

> > Bottom line, regular expressions are power tools with no safety
> > measures, they cut fingers as well as they cut wood.  My advice
> > would be to stick to indexed tables whenever possible.
>
> This isn't related to the problem I am trying to solve.

Well it is, if by "local" you mean local address class.

Otherwise, the simplest solution is to completely separate
inbound and outbound mail either with multiple instances,
or just separate smtpd(8) and cleanup(8) instances.

Then your recipient bcc table would never see the outbound
mail in the first place.

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

Re: Various bcc options in postfix

@lbutlr
On 20 Oct 2020, at 19:01, Viktor Dukhovni <[hidden email]> wrote:

> On Tue, Oct 20, 2020 at 05:29:22PM -0600, @lbutlr wrote:
>
>>>> The current setup uses recipient_bcc_maps which I would have thought
>>>> did what I wanted, but it actually does all outbound mail as well.
>>>
>>> With recipient_bcc_maps, the specified BCC recipient from the RHS of the
>>> table is added whenever the message envelope contains a recipient that
>>> matches the LHS of the table.  Therefore, either the outbound mail in
>>> question also had local recipients, or your table inadvertently matches
>>> some or all remote recipients.
>>
>> Right, which means custom m matches for every domain instead of being
>> able to just catch the local users.
>
> No, it just means that the table should not match remote recipients, how
> that is done depends on the table type.
>
>>> I don't see anything above that limits the matched recipients to local
>>> users.  Do you?  What is the intent of the "([^.]*)" pattern following
>>> the "@" sign?  It will always match, possibly an empty string if the
>>> first character after "@" is ".", but otherwise some initial substring
>>> of the domain part.
>>
>> The first character cannot be a . in an email address
>> (user@.example.com is invalid), so it matches the first portions of
>> the domain part of the email address. So 'example' in example.com or
>> 'mail' in mail.example.com.
>
> Lossy, but if you just want the first label, so be it.  What is your
> definition of a "local" recipient?  Do you literally mean a mailbox
> handled via local(8), aliases(5) and delivery to a unix-account, or do
> you mean anything you're willing to accept inbound?

These are the same thing in my case, I only accept mail for accounts that will deliver to a local (well, virtual in the context of postfix) user, though [hidden email] may actually deliver to [hidden email].

> If you're abusing terminology and really "local" as in local address
> class,

No, sorry, I was using 'local' as in 'local to the mail server' and not 'local as in a shell user on $mydomain', apologies. All users are virtual users on virtual domains (even me and where root mail is aliased), but local to the mail server.

>> I'm fine with that. I have no quoted local part emails and if anyone
>> created one with a double .. (an obviously attempt to break things)
>> I'd deal with that with a clue bat.
>
> I don't recommend waiting for broken edge-cases to show in practice, but
> your system your rules...

Every user is known to me, and only a very few users can create new email accounts. Everyone can create aliases, but nearly none know how to.

> Otherwise, the simplest solution is to completely separate
> inbound and outbound mail either with multiple instances,
> or just separate smtpd(8) and cleanup(8) instances.

That is probably the way to go. I am also looking at the possibility of using a default.sieve in dovecot since at that point we've already reached the LDA and the outbound mail cannot be affected. The script I have to generate the postfix configuration file can do much the same for default sieve, and it would take all of this out of postfix.

> Then your recipient bcc table would never see the outbound
> mail in the first place.

Yeah.

The more I think about this, the more I think default.sieve is the way to go. The reason that I did not do this before was because the mail server used to discard high scoring mail that had been expected and I had the backup to recover even those mails, but the mail server now rejects high scoring mail before it is accepted.

I have a suspicion I am forgetting something, though.

Thank you, again, for your time.

--
'They say that whoever pays the piper calls the tune.' 'But,
        gentlemen,' said Mr Saveloy, 'whoever holds a knife to the
        piper's throat writes the symphony.' --Interesting Times