12

In Postfix 2.10.2, I have a setup with multiple domains and several virtual aliases to assign mail addresses to local users. It works fine as long as I do not add a catchall.

Before I used virtual aliases, I had a catchall defined with

local_recipient_maps =
luser_relay = catchall

but as I need to sort out mail addresses from different domains, I had to use virtual aliases.

Now postfix.org says I should do it like this, which I did:

/etc/postfix/main.cf:

virtual_alias_domains = example.com
virtual_alias_maps = hash:/etc/postfix/virtual

/etc/postfix/virtual:

postmaster@example.com account1
info@example.com       account1
sales@example.com      account2
@example.com         catchall

But if I do so, the catchall address grabs all my mail instead of just the mail to not explicitly defined addresses. Why is that and how do I change it?

I did postmap virtual and also restarted Postfix. There are no errors in the log, it just logs the delivery to the catchall address. And there is a warning "do not list domain example.com in BOTH mydestination and virtual_alias_domains", but I did not do that! I don't even have a mydestination directive. (There is one in the config below, but I added that after NickW suggested so.)

Here is my complete conf:

alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
append_dot_mydomain = no
biff = no
broken_sasl_auth_clients = yes
config_directory = /etc/postfix
home_mailbox = Maildir/
inet_interfaces = all
inet_protocols = all
mailbox_command = /usr/lib/dovecot/deliver -c /etc/dovecot/dovecot.conf -m "${EXTENSION}"
mailbox_size_limit = 0
mydestination = $myhostname
myhostname = mydomain.com
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
myorigin = /etc/mailname
readme_directory = no
recipient_delimiter = +
relayhost =
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_use_tls = yes
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
smtpd_recipient_restrictions = reject_unknown_sender_domain, reject_unknown_recipient_domain, reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sasl_authenticated_header = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_path = private/dovecot-auth
smtpd_sasl_security_options = noanonymous
smtpd_sasl_type = dovecot
smtpd_sender_restrictions = reject_unknown_sender_domain
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/dovecot/dovecot.pem
smtpd_tls_key_file = /etc/dovecot/private/dovecot.pem
smtpd_tls_mandatory_ciphers = medium
smtpd_tls_mandatory_protocols = SSLv3, TLSv1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_use_tls = yes
tls_random_source = dev:/dev/urandom
virtual_alias_domains = $myhostname, myotherdomain.com
virtual_alias_maps = hash:/etc/postfix/virtual
Konzertheld
  • 191
  • 1
  • 1
  • 9

4 Answers4

7

So, I figured it out. Some people suggest that the catch-all has to be on top of the virtual alias file, but I tried that before and it did not help (though I found that solution quite logical).

What worked is:

  1. Set mydestination=localhost (that is not $myhostname)
  2. Add the catchall on top of the virtual alias file: @domain.com catchall-account@localhost
  3. Add all other virtual aliases below: contact@domain.com contact@localhost

The example assumes you have UNIX users named catchall-account and contact. Mails to contact@domain.com will be delivered to the contact user while all other mail will be delivered to the catch-all account.

Maybe this is not necessary in all cases, but in my special case I want to use an account to save mail for some addresses, but mail sent directly to that account should end up in the catch-all.

After all, looks like Postfix is not working it's way through the virtual aliases from top to bottom, and additionally catch-alls have some special priority. I will be glad about further comments in case someone is actually able to explain this behaviour.

Konzertheld
  • 191
  • 1
  • 1
  • 9
  • In http://www.postfix.org/postconf.5.html#virtual_mailbox_maps, there is the following sentence: "In a lookup table, specify a left-hand side of "@domain.tld" to match any user in the specified domain that does not have a specific "user@domain.tld" entry." - I think it's similar in virtual_alias_maps, so that the order doesn't make a difference at all – Daniel Alder Apr 12 '20 at 23:26
7

If you include catch all email address in virtual alias then it will work.

in main.cf:

 virtual_alias_maps = hash:/etc/postfix/virtual

in virtual:

user1@example.com           user1@example.com
user2@example.com           user2@example.com
...
catchall@example.com        catchall@example.com
@example.com                catchall@example.com
Diamond
  • 9,001
  • 3
  • 24
  • 38
Dariusz
  • 71
  • 1
  • 1
2

The important part is that all real mailbox users are also put into the virtual alias lookup. This works around the fact that aliases have priority over real accounts. So it's not about the order of the entries, or whatever your mydestination is set to, you just have to add your real mailboxes as aliases, too, and the catchall will work as intended and only collect the mail for the undefined addresses.

So in the end, your lookup must look like that

@example.org   catchall@example.org
actually-exists@example.org       actually-exists@example.org
concrete-alias1@example.org       actually-exists@example.org
concrete-alias2@example.org       actually-exists@example.org

That way, mails for "actually-exists", "concrete-alias1" and "concrete-alias2" will all go to "actually-exists", a user that does actually exist on the system, while mail for all other possible receipients is shoved into "catchall".

Shoutout to this article for the tip. Confirmed with postfix 3.4.13.

  • The official docs describe that use-case pretty much the same as well: `@domain address, address, ...` `Redirect mail for other users in domain to address. This form has the lowest precedence.` `Note: @domain is a wild-card. With this form, the Postfix SMTP server accepts mail for any recipient in domain, regardless of whether that recipient exists.` http://www.postfix.org/virtual.5.html – Thorsten Schöning May 04 '22 at 13:34
0

Try setting your mydestination = $myhostname, and make sure your hostname is configured in main.cf, for example, myhostname = mail.example.com.

NickW
  • 10,263
  • 1
  • 20
  • 27