17

This is related to this question:

linux - Ways to get a bounceback report for my newsletter application? - Server Fault

Let's say I'm generating email addresses like this when I send out newsletters to identify bounces and unsubscribe them from my newsletter: bounce-123456789@example.com

I assume I'd use this in the return-path, right?

Then how would I set it up in postfix to collect all these addresses prefixed with "bounce-" into one mailbox?

Finally, I've heard people mention a soft bounce vs. a hard bounce. Can someone explain the different and how they should be counted to know when to permanently remove someone from an email newsletter?

Brian Armstrong
  • 1,617
  • 3
  • 19
  • 22
  • Note that an email address that includes the word "bounce" may also be viewed as "yuck"... (spam)—that being said, if you can stick your own `Message-Id` in your header, it has to be sent back and that would be enough to check who's who. – Alexis Wilke Nov 11 '15 at 03:43

3 Answers3

18

The exact answer to your question (handling the bounce-xxx@example.com address) depends on how your server is configured to receive mail. If example.com is the virtual domain the best you can do is collect the messages in the bounce@example.com mailbox (assuming recipient_delimiter = -).

If example.com is the locally delivered domain for the server (mail is delivered to actual system accounts) then you can add a .forward file to the home directory of the bounce user, which delivers to a program that parses the bounce information and records it in a database or file. See man local for more info on the .forward format and how to deliver to a program.

What we do, since we send messages for a large number of domains, is use bounces.example.com as our VERP domain. This domain needs to be added to relay_domains. Create /etc/postfix/transport_maps with this content:

bounces.example.com             bulkbounce:

Then append a line similar to this to /etc/postfix/master.cf:

bulkbounce   unix  -       n       n       -       -       pipe
  user=nobody argv=/usr/local/bin/bounce_handler.py ${recipient}

The bounce_handler.py script accepts the VERP address as its command line option, parses it and makes the necessary database updates to record the bounce.

Insyte
  • 9,394
  • 3
  • 28
  • 45
17

Actually, Instyle's answer is very difficult to implement if you want to support many different domains and it is wrong because:

a) With his example of transport_maps, all the emails sent to that domain are sent to that specific service without any regard to whether the emails are bounced emails or not. Since it uses a specific domain name, it should indeed only be bounced emails... but it cannot be guaranteed that way.

b) The data sent to your script is the email itself and not the bounce message. In other words, your code may have no idea why the email was bounced (i.e. local bounce will send you the original email only.)


The correct way to do that setup in postfix is to use the bounce notification class.

1) In /etc/postfix/main.cf

notify_classes = bounce
bounce_notice_recipient = bounces@example.com
transport_maps = hash:/etc/postfix/transport_maps

2) In /etc/postfix/transport_maps

# when you make changes to this file, run:
#   sudo postmap /etc/postfix/transport_maps
bounces@example.com bulkbounce:

As you can see, we now tell postfix to use bounces@example.com whenever an email gets bounced. Then in the transport map, to use bulkbounce as the service to handle any email address to bounces@example.com.

Finally you can define bulkbounce with your script:

3) In /etc/postfix/master.cf

bulkbounce unix -       n       n       -       -       pipe
  flags=FRq user=bounce argv=/home/bounce/bin/snapbounce --sender ${sender} --recipient ${recipient}

This script requires you to have a user. nobody is a good choice too. If you want to have a specific user, you can create it with:

useradd bounce

Without the script in master.cf, the emails are sent to the bulkbounce account. So if you have a script that parses emails from files, this would work without the transport_maps and master.cf changes.


From a comment below:

fyi - re: double bounces...
if you're modifying the return address (VERP address such as user+id@fromdomain.com, then you will want to comment out the line in main.cf for the bounce_notice_recipient, if you're interested in parsing the +id bounce only in your script.

Alexis Wilke
  • 2,210
  • 1
  • 20
  • 37
  • Using your way I somehow receive the bounce twice, once with bounce+id@... and once with bounce@... from double-bounce - (the user bounce does not actualy exist on the system - as I do not intent to 'save' these emails). The email is sent with a Return-path of bounce+id@... Any idea what I am missing ? – RVandersteen Nov 15 '17 at 23:03
  • @RVandersteen I'm not too sure why you'd get it twice. The one with `+id@` may be an envelop of some kind? – Alexis Wilke Nov 16 '17 at 05:05
  • When I use our default 'from' address - the bounce still gets sent to bounce@example.com and originalfrom@example.com (no return path added anymore) – RVandersteen Nov 16 '17 at 10:41
  • Seems that I am wrong about the 'original from' it is the email listed in /etc/aliases under root (postmaster -> root -> originalfrom@example.com) which also receives the bounce – RVandersteen Nov 16 '17 at 10:45
  • somehow once Sender: MAILER-DAEMON, Recipient: bounce@example.com and once Sender: double-bounce@example.com, Recipient: bounce@example.com (Note that we have a send only postfix) – RVandersteen Nov 16 '17 at 11:04
  • @RVandersteen If you have double bouncing emails, you probably want to search about that. I suppose you did not notice the problem before you tried to install my code here, correct? One thing I could think of is that the transport happens at the wrong place in your case. – Alexis Wilke Nov 16 '17 at 20:47
  • I've been at this for days without finding any usefull information on the matter. Anyhow, I've posted a question here https://serverfault.com/questions/883805/postfix-bounce-sent-twice-double-bounce – RVandersteen Nov 16 '17 at 22:12
  • 2
    For future reference, adding the notify_classes does not change the behaviour of the MTA sending the bounce message to the FROM/Return Path. It adds behaviour on top of it (sends it also to the notify_bounce_recipient). This is why I had double mails coming in. Which answers my question(s) above – RVandersteen Nov 17 '17 at 17:24
  • 1
    fyi - re: double bounces..if you're modifying the return address (VERP address such as 'user+id@fromdomain.com', then you will want to comment out the line in main.cf for the 'bounce_notice_recipient', if you're interested in parsing the +id bounce only in your script. – sarora May 07 '18 at 13:57
1

Most modern mailing list software already knows how to handle VERP messages if the MTA is properly configured to pass them back to the mailing list software. In the case of GNU Mailman you should checkout the FAQ page aptly named "How do I use VERP with a - delimiter (Postfix recipient_delimiter)?".

If you're making your own custom newsletter software to handle this you should ask yourself why you're re-inventing the wheel instead of using existing applications that can handle the task simply and easily for you already.

Jeremy Bouse
  • 11,341
  • 2
  • 28
  • 40
  • 2
    Yep, I'm making my own newsletter software. There is a good reason! – Brian Armstrong Jul 31 '09 at 03:23
  • Then you should look at having it use VERP to handle bounces properly. – Jeremy Bouse Jul 31 '09 at 10:48
  • Hi Jeremy, I think you're right VERP is the standard solution here, although it appears it's only useful to identify the sender and recipient. In this case we need to also identify the particular message which went out that caused the bounce, so I believe we'll have to do a custom solution with our own ID in the address. I think the solution mentioned below using a recipient delimeter will let us group them together in one bounce account. Thanks for the response though I appreciate the help! – Brian Armstrong Jul 31 '09 at 21:39
  • Insyte's solution is just a modified VERP at it's core. You just need to make sure that it provides enough of a unique identifier for your bounce handler to identify it. In most mailing list software that is the email address, but could be anything since you're designing your own. – Jeremy Bouse Aug 01 '09 at 00:25