Postfix supports the configuration item recipient_delimiter
, like:
recipient_delimiter = +
so that one can do ‘plus-expansion’ style e-mail addresses, like: mike+amazon@bfccomputing.com
for myriad reasons, like tracking, spam filtering, auto-sorting, etc.
Unfortunately, while + has long been the standard character for this purpose, half of the websites out there have been written by noodle-heads who figure that any incoming +
character in a parameter is a faux-encoded space character (somebody thwap the guy who came up with that idea with a fish, please). There are lots of good well-done address verifiers which honor RFC 2822, specifically section 3.2.4, the Atom definition. E-mail addresses are very complex in structure, and you are not going to do a better job or save time by writing your own, so please use one of the canned libraries.
Anyway, long-story short, on those sites you often have to use a different character, a -
, for example. However, postfix doesn’t let you use multiple recipient_delimiter
statements, so what is one to do?
The answer is simply to break out postfix’s regexp support. If you have a virtual users table already in place (most do) you’ll have a statement like this:
virtual_alias_maps = hash:/etc/postfix/virtual
in your /etc/postfix/main.cf
file. Add an extra parameter to it, like so:
virtual_alias_maps = hash:/etc/postfix/virtual, regexp:/etc/postfix/virtual-regexp
Now, create a new file called /etc/postfix/virtual-regexp
, and put a line in it like this:
/(.*)-(.*)@example.com/ ${1}+${2}@example.com
Piece by piece:
/
– start a regex match
(.*)
– capture the first block of text up to
-
– a -
character, slash-escaped
(.*)
– and now capture the rest of the text up to the
@
– the @
in the e-mail address
example.com
– and then capture the rest of the address, which will be the domain
/
– and close the match.
The column on the right hand is the replacement which looks like:
${1}
– insert the first capture
+
– and a +
(we don’t need to escape now, we’re not in a regex)
${2}
– and then the second capture
@
– and a @
example.com
– and then the domain name.
You get the idea. Save, and issue:
sudo postmap /etc/postfix/virtual-regexp
sudo postfix reload
and all incoming mails with a ‘-’ expansion will be re-written to a ‘+’ expansion. From there, postfix knows what to do.
You might be temped to use the expression:
/(.*)-(.*)@(.*)/ ${1}+${2}@${3}
but this will also be applied to outbound mail, so be careful. If anybody knows how to only apply the rule to domains listed in the virtual tables, please leave a comment!