Wednesday, June 10, 2009

Troubleshooting Postfix virtual alias maps

Context

(with apologies in advance for the annoying formatting)

At work we use postfix to forward mail for our client's aliased domains to their real email addresses. For the most part postfix just quietly sits in the middle, translating virtual email addresses (bob@ez-domain.com) to their real ones (bob@official-domain.com). Yesterday, however, we started getting calls from clients saying their email redirects weren't working. Anyone trying to email bob@ez-domain.com was getting a bounce back that read something like:

This is the mail system at host mta1.mywork.com.

I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.

For further assistance, please send mail to postmaster.

If you do so, please include this problem report. You can
delete your own text from the attached returned message.

The mail system

<bob@official-domain.com> (expanded from <bob@ez-domain.com>): User
unknown in virtual alias table

Final-Recipient: rfc822; bob@official-domain.com
Original-Recipient: rfc822; bob@ez-domain.com
Action: failed
Status: 5.0.0
Diagnostic-Code: X-Postfix; User unknown in virtual alias table


Vexation

Normally, the "User unknown in virtual alias table" means just that, postfix tried to use the configured lookup tables to find the official address for the alias and couldn't find it. What's interesting about this report (and the dozens of similar ones that started pouring in), is the fact that postfix had already successfully resolved the official email address for bob. Both his ez address and his official address are present in the error message! What's up with that?

Postfix does (at least) two checks on a recipient's email address to verify that it should accept messages for that recipient. The first thing it checks is the recipient's domain, ez-domain.com in our example. This lookup table is specified by the virtual_alias_domains config setting in /etc/postfix/main.cf. The next thing it checks for is the full address, bob@ez-domain.com in our example. This lookup table is specified by the virtual_alias_maps config setting in main.cf.

Great, we knew that already, that's what we set it up to do. In our case, it's even working, correctly finding bob's official email address when given his ez address.


Deliverance

Here's the feature that causes postfix to say it can't find what it can find, virtual alias lookups are recursive. So the lookup for bob@ez-domain.com returns bob@official-domain.com, and then postfix starts the process all over again with bob's official email address as the alias. In my setup, this was never a problem, since we would never receive traffic for official-domain.com. Until the one day when someone enters an alias of alice@official-domain.com that points to another email address (it doesn't even matter what it points to, at this point, postfix is borked).

So now, postfix attempts a virtual_alias_domains lookup on official-domain.com, which works because of alice's alias map. Then postfix thinks to itself, "It looks like I'm supposed to relay traffic for this domain, but what about bob?" to which the virtual_alias_maps lookup quickly responds, "Nope, I don't see any aliases for bob@official-domain.com, just alice", and ba-da-bing ba-da-boom, postfix bounceback's for anyone who's real address is official-domain.com.