Articles

Different SMTP relays in postfix based on regular expressions


Use Case: Choosing SMTP routes based on the email subject

So I had this particular situation where a site sends lots of emails to its registered users, and some of those emails go directly to the Spam folder of hotmail, yahoo, or gmail, for various reasons.

This was acceptable for the majority of the emails, but some of them were really important (like password resets, registration confirmations, and the like) so the site hired a paid smtp relay to be used for sending *only* those emails (the company charged by email volume, so the requirement was to only use this service with the very important emails, and continue using their own smtp server to delivery the rest).

I was told to use the subject of the email as the discriminator. Important emails would have some special keywords like "Reminder", or "Confirmation", those would have to be delivered using the paid smtp relay, while the others wouldn't.

So I started fiddling with the Postfix SMTP server, and here's how I could do it (in an amazingly easy way).

Setting up Postfix to check Email headers

In your main.cf file (usually /etc/postfix/main.cf or /usr/local/etc/postfix/main.cf), specify your header_checks:

And in your header_checks file (usually /etc/postfix/header_checks or /usr/local/etc/postfix/header_checks), specify your regular expressions and rules. This file accepts lots of possible configurations, so I encourage you to read the manual page.

In my particular case, I've specified the following rules:

Those lines will make postfix apply a transport filter based on the regular expression (that is applied to the whole mail content) and will let you choose a different transport (relay) based on those rules exactly.

This will match with lines starting with "subject:" and having the words Reminder or Confirmation in it. Of course it is possible to match not only the header, but a text line inside the very same body of the mail, so use these kind of rules with care when you cant trust the origin of the email.

Then invoke postmap to regenerate the transports db, and reload postfix:

That's it. Hey don't you just love postfix?