I'm maintaining an IMAP server running FreeBSD which uses exim 4.80 as its MTA. Right now I try to create an email alias so that I can address all users of the system for informing them about scheduled downtimes and the like. The idea is that a mail to vmailusers@imap.mydomain.com should get forwarded to all users on the system.

I initially considered having a simple simple /etc/aliases entry but noticed that it's not what I want since users of the system may have Sieve filters in place which drop all incoming mails except a few whitelisted ones.

I did notice that exim can be made to deliver to a local Maildir directory straight away (by-passing any other MDA and thus bypassing Sieve filters) using the appendfile transport - but how can I make a single incoming mail to vmailusers get redirected to multiple local maildirs?

1 Answer 1


You can use the redirect router to process alias messages. This is also the one which runs scripts / forward files given by the users. The processing of the routers happens from top to bottom, so the example below works roughly like this:

  1. The syswide_alias router checks aliases in the /etc/aliases file. If one is found, the routing sequence restarts.
  2. The forced_delivery makes the same check, but this time it uses the original_local_part variable which is empty if no forwarding were done. If the lookup is successful, the message is delivered. In this case the processing stops (since a delivery was done), so any filters or forwards the user might have are ignored.
  3. If the forced_delivery router declines, the .forward file will be processed. If this file contains aliases, the routing sequence restarts.
  4. Finally, the message gets delivered to the user's mailbox. This will happen only if the filter file in the previous step didn't result in a significant delivery (that is, it doesn't contain a forward alias, or doesn't drop the message entirely).

The routers section should look like this:

    driver = redirect
    data = ${lookup{$local_part}lsearch{/etc/aliases}}

    driver = accept
    transport = local_delivery
    condition = ${if eq {${lookup{$original_local_part}lsearch{/etc/aliases}}}{}{no}{yes}}

    driver = redirect
    file = ${home}/.forward

    driver = accept
    transport = local_delivery

Both the syswide_alias and the forced_delivery routers have the allow_defer option, which is needed if the file is not found (which is probably won't be the case, but it doesn't hurt anyway)

Edit: The above example now contains a full set of routers needed to achieve the goals of the question.

  • The issue is that if I let processing continue (or restart the routing sequence), the mail will be treated as if it was addressed directly to, say, joe - so it will be (in my case) passed to the LDA which uses Sieve filters. I would like to alias to multiple recipients and then have exim deliver straight to their Maildir directories (by-passing Sieve, so they can't possibly miss the mail), without considering other routers. Sep 20, 2012 at 11:20
  • @FrerichRaabe: Nope, exim favors the Sieve scripts only if it is instructed to do so. For this, you need a router where you specify the file = $home/.forward statement. If no such router exist, exim will deliver the mail directly, bypassing any filters the user may have set. Exim processes the routers from top to bottom, so you should set up your routers so the alias router (from my post) comes first, then an other which specifies an appendfile transport and a condition (so it will bypass filters on delivering the 'alias mail'), and finally the "regular" router.
    – Lacek
    Sep 20, 2012 at 13:52
  • I see - but what would the condition for the appendfile transport be? At the point it's tested, the ${local_part} of the mail is no longer the vmailusers alias but rather the actual address as far as I can tell - I don't see a way to tell apart whether this is an actual mail to joe or just a mail to joe triggered by the alias. Sep 20, 2012 at 13:54
  • 1
    The condition can be the same which is used when forwarding, but use the ${original_local_part} variable. The second router is reached only if the alias is expanded, or if the message isn't an alias at all. In the latter case the lookup condition will fail.
    – Lacek
    Sep 20, 2012 at 15:25
  • I've rewritten the answer so it now contains an example of what you want to achieve.
    – Lacek
    Sep 21, 2012 at 7:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.