Using '+'-Separated E-Mail Address Suffices for Filtering (Update)

Posted on February 7, 2011 by Hendrik Jäger

Since I’ve heard about ‘+’ being often used as a separator in email-addresses a few years ago, I wanted to try that but never actually got around to make exim behave like that. Finally, I did, and I’d like to explain the concept of the setup a little, mainly for myself to have a place to look it up.

For those not knowing what is meant by this, a short explanation and reasons why I want this: sending mail to foobar@domain usually reaches the user ‘foobar’. This user has only this one user-account, so his mailfiltering cannot be based on the recipient address, but has to be based on subject, sender address or some other header line. It’s not always predictable what domain, mail address or headers will be set in mails you receive. Sometimes your mail address is passed on to other companies and you get mails from them. So it’s sometimes really hard to tell, where a mail comes from or who gave the sender your address. With suffixes this problem can be mitigated. Mails to ‘foobar+test@domain’ will still reach the user foobar but he has a recipient address he can use to filter. So when you register at flattr.com for example, you don’t just register with your email address ‘foobar@domain’ but rather ‘foobar+flattr@domain’.

The magic is done by the router option ‘local_part_suffix’ and ‘local_part_suffix_optional’ which, respectively, specify what a suffix looks like (e.g. "+*") and if it is mandatory. These options have to be set on all routers used for verifying an address or specifying a transport to use. I can’t tell where exactly you need it, that depends too much on your setup. I’m sure if you have a clue about your config you will be able to figure that out for yourself. With a nice little sieve-filter script placed in ~/.dovecot.sieve (~/.forward is handled by exim already, for sieve or exim filters), you can have on the fly created folders for each of those suffixes:

# Sieve filter

require ["fileinto", "regex", "variables", "mailbox", "envelope"];

if envelope :regex "to" "^.*\\+(.*)@.*" {
    fileinto :create "INBOX/${1}"; stop;
}

A little addon I had to make because (probably among others) facebook doesn’t like those ‘+’-addresses too much, even though their mails also contain a ‘+’ in the sender it seems: mails to foobar@test.geekmail.org are rewritten to go to test+foobar@geekmail.org. This fixes the facebook-issue. This is only implemented on one domain on my server, which is the only one already suggesting a ‘mail service’ domain. On all others the possibility of me adding more subdomains which might confuse the rewriting do not work that way (yet). The exim rewriting rule to achieve this:

    ^(.*<)?(.*)@(.*)\.geekmail\.org(>.*)? $1$3+$2@geekmail.org$4 S

UPDATE: The rewriting rule above might be problematic, especially for locally submitted or other mails not coming in via SMTP. The correct way of doing it is documented in the exim wiki: http://wiki.exim.org/FAQ/Routing_for_local_delivery/Q0420 uses this router:

user_from_domain:
    driver = redirect
    data = ${if match{$domain}{\N^(.+)\.mydomain\.com$\N}\
        {$1@mydomain.com}}