I host a handful of domains on a single box (Linux, Ubuntu 13.x) and am attempting to use Postfix 2.10.2-1 to route mail to them. (I used sendmail for the past 10 years, so this is new to me.) All my MX records are set up accordingly, so external mail is reaching the box just fine.

I followed the various online tutorials and have the following relevant lines in my configs:

myhostname            = foo.a.com
myorigin              = /etc/mailname     # this just has 'a.com' inside it
mydestination         = a.com localhost.localdomain localhost
virtual_alias_domains = b.com c.org
virtual_alias_maps    = hash:/etc/postfix/virtual

At the moment I just want all mail addressed to postmaster at any of the domains to go to the postmaster account, and all mail addressed to anyone else at any of the domains to go to the associated account.

postmaster@a.com  postmaster
@a.com            userA
postmaster@b.com  postmaster
@b.com            userB
postmaster@c.org  postmaster
@c.org            userC

Unfortunately, all mail addressed to anyone at any of these domains is being routed to userA. Until I enabled verbose logging, I thought that the virtual domains were not being respected. After enabling verbose logging, however, I see this happening for every incoming mail:

postfix/cleanup: maps_find: virtual_alias_maps: hash:/etc/postfix/virtual(0.lock|fold_fix): @b.com = userB
postfix/cleanup: mail_addr_find: foo@b.com -> userB
postfix/cleanup: send attr request = rewrite
postfix/cleanup: send attr rule = local
postfix/cleanup: send attr address = userB

But then trivial-rewrite runs again (for about the 80th time processing this particular piece of mail) and decides that userB is not the true final Unix account recipient, but that it instead represents a mail address at myorigin (or perhaps it's picking the first element in mydestination ... that would make more sense).

postfix/trivial-rewrite: master_notify: status 0
postfix/trivial-rewrite: rewrite socket: wanted attribute: request
postfix/trivial-rewrite: input attribute name: request
postfix/trivial-rewrite: 'local' 'userB' -> 'userB@a.com'  # <-- d'oh!
postfix/trivial-rewrite: send attr flags = 0
postfix/trivial-rewrite: send attr address = userB@a.com
postfix/trivial-rewrite: master_notify: status 1

Then postfix/cleanup takes over

postfix/cleanup: maps_find: virtual_alias_maps: hash:/etc/postfix/virtual(0.lock|fold_fix): @a.com = userA
postfix/cleanup: mail_addr_find: userB@a.com -> userA
postfix/cleanup: send attr request = rewrite
postfix/cleanup: send attr rule = local
postfix/cleanup: send attr address = userA

and concludes that userA is the true intended Unix account recipient.

I know almost nothing about Postfix, but it seems from the logs that it only decides on the final recipient address after running it through rewrite twice and getting the same result twice in a row. How do I prevent it from interpreting the local account userB as a mail address userB@mydestination[0]? I want it to stop as soon as it finds the local userB and just deliver it to him.

Am I not allowed to list @mydestination[0] within /etc/postfix/virtual? While that could perhaps solve my current problem (because these users are real Unix users on the box, so the mail would get to the right place), Postfix would still wind up thinking that userB@a.com is the final recipient. That seems wrong to me. It should just know that userB is a Unix account and stop there.


This is not technically an answer, but it may be the best you get. I worked with alot of sendmail maps for some years. Your best bet is to break it down, make it more simple. Make the map include only one of your domains, get the wildcard working for that domain, and build from there.

Use the sendmail diagnostic flags to make it easier on yourself, such as sendmail -bv flag.


So I was able to solve my problem as I suggested at the end of my question, but I also concluded that avoiding virtual domains may be the correct way to go.

First, the initial proposed solution: remove references to a.com from the virtual file.

#postmaster@a.com  postmaster
#@a.com            userA
postmaster@b.com  postmaster
@b.com            userB
postmaster@c.org  postmaster
@c.org            userC

After I did that, the virtual translations for b.com and c.org generated userB@a.com and userC@a.com as expected, and since a.com is one of the mydestination entries, postfix/local dutifully delivered userB's mail to /var/mail/userB and userC's mail to /var/mail/userC.

Of course, as I feared in my initial question, it's still concluding that a.com is all of these users' final home domain, which feels weird to me. The obvious solution, then, is to not use virtual domains at all -- the whole point of virtual domains is to accept mail for addresses that are not actual Unix users on the system. But since all of my catch-all users are actual Unix users on the system, I should just be using local aliases:

admin: postmaster
www: postmaster
@a.com: userA
@b.com: userB
@c.com: userC

I can still have catch-all addresses without using virtual domains at all.

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.