Skip to content

# Catch-all addresses

Optional feature

This page is entirely optional. Skip it if you are not interested in catching all emails in a domain that otherwise have no alias or mailbox.

As explained earlier in the tutorial there is way to forward all undefined email addresses in a domain to a certain destination email address. This is called a catch-all alias. Those aliases catch all emails for a domain if there is no specific virtual user or virtual alias for that email address. The drawback is that you will get more spam because spammers will send their stuff to any address of your domain. Or perhaps a sender mixed up the proper spelling of a recipient but the mail server will forward the email instead of rejecting it for a good reason.

You still want to use catch-all addresses? Well, okay. Let’s do it then. A catchall alias looks like “@example.org” and forwards email for the whole domain to other addresses. We have created the `john@example.org` user and would like to forward all other email on the domain to `kerstin@example.com`. So we would add a catchall alias like:

source | destination
--- | ---
`@example.org` | `kerstin@example.com`

But there is a small catch. Postfix will apply the aliases (virtual_alias_maps) before delivering an email. So the catch-all alias will “steal” all emails. But we can add this to the aliases table to prevent that:

email | destination
--- | ---
`@example.org` | `kerstin@example.com`
`john@example.org` | `john@example.org`

Postfix will consider more specific aliases first. And `john@example.org` is more specific than `@example.org`. Consider that someone is trying to reach `john@example.org`’s mailbox. So to make a mixture of catch-all addresses and specific addresses work, we need this little trickery.

Postfix will lookup all these mappings for each of:

- john@example.org (most specific)
- @example.org (catchall – least specific)

This is outlined in the virtual(5) man page in the TABLE SEARCH ORDER section.

We do not want to add that “more specific” entry for each email address manually. Fortunately we can easily automate that. For that “john-to-himself” mapping you need to create another “.cf” file `/etc/postfix/mysql-email2email.cf`:

Run this on your server

    # Create the john-to-himself mappingcat > /etc/postfix/mariadb-email2email.cf << EOFuser = mailserverpassword = MAILSERVER-PASSWORD-HEREhosts = 127.0.0.1dbname = mailserverquery = SELECT email FROM virtual_users WHERE email='%s'EOF
    # Fix the permissions of that filechgrp postfix /etc/postfix/mariadb-*.cfchmod u=rw,g=r,o= /etc/postfix/mariadb-*.cf
    # Add the new mapping to the virtual_alias_maps# (The order is not important. Postfix will check all mapping files.)postconf virtual_alias_maps=mysql:/etc/postfix/mariadb-virtual-alias-maps.cf,mysql:/etc/postfix/mariadb-email2email.cf

Check that you get John’s email address back when you ask Postfix if there are any aliases for him:

Run this on your server

    postmap -q john@example.org mysql:/etc/postfix/mariadb-email2email.cf

The result should be the same address:

    john@example.org

Now you are ready to add catch-all aliases.