Want catch-all as fallback, but neither virtual_alias_maps nor virtual_mailbox_maps does the job?

What type of hardware are you using: VPS bought online
What YunoHost version are you running: 12.1.36
How are you able to access your server: The webadmin
SSH

Describe your issue

I am trying to get a catch-all address working on a domain that also has some existing addresses which should continue to work. Example:

And now I want to also accept emails at whatever@example.com and give them to bob. So I use the modification described by @xananax at Catch-All address · Issue #557 · YunoHost/issues · GitHub which adds a hash table as the end of virtual_alias_maps.

But now all emails arrive in the account of bob, even those sent to alice@example.com :cry:
If I understand it correctly this happens because postfix first uses virtual_alias_maps and only after that (if it has not found a match yet) it will look into the virtual_mailbox_maps setting that tells it how to find the yunohost accounts, correct?

So then I tried putting the extra hash table at the end of the virtual_mailbox_maps setting instead. But that does not give me a working catch-all address, mails to whatever@example.com are then rejected.

So long story short: how can I have a catch-all address but still keep the mail for existing yunohost users on the same domain delivered to them and not to the catch-all account? :thinking:

Thank for any help!

Share relevant logs or error messages

Relevant part of /etc/postfix/main.cf:

# this way bob gets all the mail and alice nothing:
virtual_mailbox_maps = ldap:/etc/postfix/ldap-accounts.cf,hash:/etc/postfix/app_senders_login_maps
virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf,ldap:/etc/postfix/ldap-groups.cf,hash:/etc/postfix/my-catchalls

# this way the catch-all does not work, email to whatever@example.com is rejected.
virtual_mailbox_maps = ldap:/etc/postfix/ldap-accounts.cf,hash:/etc/postfix/app_senders_login_maps,hash:/etc/postfix/my-catchalls
virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf,ldap:/etc/postfix/ldap-groups.cf

I am sorry, but I’m not really able to help, because I don’t know postfix well enough.

In my case, I do not actually have a catch-all for any email, but only emails following a specific pattern. That must be why it works.

For reminder, in my case I don’t use hash:, but use regexp: instead. I do remember a catchall regexp working (e.g, /.*?@domain.tld/ your-address@domain.tld), but currently I use a more complex pattern so I cannot be sure.

Did you try moving hash: to the beginning or end of the virtual_alias_maps line?

Can you show your catch-all file? Does it follow the format described in this article? How to Setup Catch-All Email Account in Postfix

1 Like

Thanks for the reply, you still put me on the right track, and I got it to work :tada:

First, I noticed that without any catch-all additions an email to a non-existing user would be reject with Diagnostic-Code: smtp; 550 5.1.1 <``catch@example.com``>: Recipient address rejected: User unknown in virtual mailbox table whereas with the addition

virtual_mailbox_maps = ldap:/etc/postfix/ldap-accounts.cf,hash:/etc/postfix/app_senders_login_maps,hash:/etc/postfix/my-catchalls

the error would change to only “user unknown” and Diagnostic-Code: x-unix; user unknown. So I assume this malbox map did actually get applied but then postfix (or rather, the dovecot delivery thingy?) could not find the unix user I was mapping to. Which makes sense because in the hash file I still put email addresses and not unix usernames on the right side. (I also tried the latter but that did not work.)

So I went back to adding the mapping to virtual_alias_maps instead, and as you suggested put it at the beginning. That would lead to bob getting all the mail, but I saw here the trick that we can just mention all the non-catch-all addresses as well and map them to themselves.

So now I have this in main.cf:

virtual_alias_maps = hash:/etc/postfix/my-catchalls,ldap:/etc/postfix/ldap-aliases.cf,ldap:/etc/postfix/ldap-groups.cf

And this in my-catchalls:

alice@example.com             alice@example.com
alice.wonderland@example.com  alice@example.com
@example.com                  bob@example.com

Note that if alice has an alias declared in the yunohost LDAP we also need to mention it here, otherwise mail to it would also land at bob.

And don’t forget to run postmap /etc/postfix/my-catchalls.

Overall this works, it is just a bit clumsy that now every time we want to add a new yunohost user that should get a non-catch-all address on this domain, we also need to edit the my-catchalls file. For the long term future a “proper” solution would be to do all this in LDAP I guess.

Bonus part: doing the main.cf modification with a conf_regen hook

Put the following into /etc/yunohost/hooks.d/conf_regen/21-postfix-add-my-catch-all-domains.sh.

#!/bin/bash

action=$1
pending_dir=$4

postfix_conf=$pending_dir/../postfix/etc/postfix/main.cf

# only continue if we are in the "pre" step, and only if $postfix_conf exists:
[[ "$action" == "pre" ]] || exit 0
[[ -e $postfix_conf ]] || exit 0

# NOTE: we are assuming that /etc/postfix/my-catchalls exists and stays as it is. Edit it manually!

# we want to replace
# virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf,ldap:/etc/postfix/ldap-groups.cf
# with
# virtual_alias_maps = hash:/etc/postfix/my-catchalls,ldap:/etc/postfix/ldap-aliases.cf,ldap:/etc/postfix/ldap-groups.cf

sed -i 's#virtual_alias_maps\ =\ ldap:/etc/postfix/ldap-aliases.cf,ldap:/etc/postfix/ldap-groups.cf#virtual_alias_maps\ =\ hash:/etc/postfix/my-catchalls,ldap:/etc/postfix/ldap-aliases.cf,ldap:/etc/postfix/ldap-groups.cf#' $postfix_conf

Neat! I hope it helps others.

I’m fairly certain there must be a way to do this without having to specify every existing map, but I am not well-versed enough in postfix to guess what the right config could be, and looking online got me no additional answers. This works, so I will probably use this too.

Thanks for the hook also, I didn’t know about this functionality

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.