Postfix/Virtuelle Domänen

Aus Foxwiki

Die optionale virtuelle Tabelle gibt Umleitungen für lokale und nicht lokale Empfänger oder Domänen an. Die Umleitungen werden vom Bereinigungsdämon (8) verwendet. Die Umleitungen sind rekursiv.

Die virtuelle Umleitung wird nur auf die Adresse des Empfängerumschlags angewandt und wirkt sich nicht auf Nachrichtenkopfzeilen aus. Denken Sie an den Sendmail-Regelsatz S0 , wenn Sie möchten. Verwenden Sie die kanonische Zuordnung , um Header- und Umschlagadressen im Allgemeinen neu zu schreiben.

Die typische Unterstützung für eine virtuelle Domäne sieht folgendermaßen aus:

   virtual.domain ... anything (der Inhalt auf der rechten Seite spielt keine Rolle)
   user1@virtual.domain ... address1
   user2@virtual.domain zugeordnet ... address2, address3 

Damit akzeptiert der SMTP-Server E-Mails fürvirtual.domainund lehnt E-Mails fürunknown@virtual.domainals unzustellbar ab.

Das Format der virtuellen Tabelle lautet wie folgt: Zuordnungen werden in der hier aufgeführten Reihenfolge versucht:

   user@domain zugeordnet zu ... address, address, ... : E-Mail für user@domain wird an address umgeleitet. Diese Form hat die höchste Priorität.
   user zugeordnet zu ... address, address, ... : $myorigin Mail für user@site wird an address umgeleitet, wenn Site gleich $myorigin wenn Site in $mydestination , oder wenn sie in $inet_interfaces . Diese Funktionalität überschneidet sich mit der Funktionalität der lokalen Aliasdatenbank . Der Unterschied besteht darin, dass die virtuelle Zuordnung auf nicht lokale Adressen angewandt werden kann.
   @domain zugeordnet zu ... address, address, ... : @domain Mails für jeden Benutzer in der domain an die address umgeleitet. Diese Form hat die niedrigste Priorität. 

Wenn in allen oben genannten Formularen die Adresse das Formular@otherdomain, ist das Ergebnis derselbe Benutzer in einer anderen Domäne. Dies funktioniert nur für die erste Adresse in der Erweiterung.

ADRESSERWEITERUNG: Wenn die Suche fehlschlägt und der Adress-Localpart den optionalen Empfängerbegrenzer enthält (z. B.  user+foo@domain ), wird die Suche nach der nicht erweiterten Adresse (z. B.  user@domain ) wiederholt und die nicht übereinstimmende Adresserweiterung an weitergegeben das Ergebnis der Expansion. Die passende Reihenfolge ist: user+foo@domain , user@domain , user+foo , user und @domain .

TMP

zh-hans:Virtual user mail system with Postfix, Dovecot and Roundcube Vorlage:Related articles start Vorlage:Related Vorlage:Related Vorlage:Related Vorlage:Related Vorlage:Related articles end Vorlage:Merge

This article describes how to set up a virtual user mail system, i.e. where the senders and recipients do not correspond to the Linux system users.

Roughly, the components used in this article are Postfix as the mail server, Dovecot as the IMAP server, Roundcube as the webmail interface and PostfixAdmin as the administration interface to manage it all.

In the end, the provided solution will allow you to use the best currently available security mechanisms, you will be able to send mails using SMTP and SMTPS and receive mails using POP3, POP3S, IMAP and IMAPS. Additionally, configuration will be easy thanks to PostfixAdmin and users will be able to login using Roundcube.

Installation

Before you start, you must have both a working MySQL server as described in MySQL and a working Postfix server as described in Postfix.

Install the Vorlage:Pkg, Vorlage:Pkg, and Vorlage:Pkg packages.

Configuration

User

For security reasons, a new user should be created to store the mails:

# groupadd -g 5000 vmail
# useradd -u 5000 -g vmail -s /usr/bin/nologin -d /home/vmail -m vmail

A gid and uid of 5000 is used in both cases so that we do not run into conflicts with regular users. All your mail will then be stored in Vorlage:Ic. You could change the home directory to something like Vorlage:Ic but be careful to change this in any configuration below as well.

Database

You will need to create an empty database and corresponding user. In this article, the user postfix_user will have read/write access to the database postfix_db using hunter2 as password. You are expected to create the database and user yourself, and give the user permission to use the database, as shown in the following code.

Vorlage:Hc

Vorlage:Expansion

Now you can go to the PostfixAdmin's setup page, let PostfixAdmin create the needed tables and create the users in there.

PostfixAdmin

See PostfixAdmin.

SSL certificate

You will need a SSL certificate for all encrypted mail communications (SMTPS/IMAPS/POP3S). If you do not have one, create one:

# cd /etc/ssl/private/
# openssl req -new -x509 -nodes -newkey rsa:4096 -keyout vmail.key -out vmail.crt -days 1460 #days are optional
# chmod 400 vmail.key
# chmod 444 vmail.crt

Alternatively, create a free trusted certificate using Let's Encrypt. The private key will be in Vorlage:Ic, the certificate in Vorlage:Ic. Either change the configuration accordingly, or symlink the keys to Vorlage:Ic:

# ln -s /etc/letsencrypt/live/yourdomain/privkey.pem /etc/ssl/private/vmail.key
# ln -s /etc/letsencrypt/live/yourdomain/fullchain.pem /etc/ssl/private/vmail.crt

Postfix

Before you copy & paste the configuration below, check if Vorlage:Ic has already been set. If you leave more than one active, you will receive warnings during runtime.

Vorlage:Warning

Also follow Postfix#Secure SMTP (receiving) pointing to the files you created in #SSL certificate.

Setting up Postfix

To Vorlage:Ic append:

relay_domains = $mydestination
virtual_alias_maps = proxy:mysql:/etc/postfix/virtual_alias_maps.cf
virtual_mailbox_domains = proxy:mysql:/etc/postfix/virtual_mailbox_domains.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/virtual_mailbox_maps.cf
virtual_mailbox_base = /home/vmail
virtual_mailbox_limit = 512000000
virtual_minimum_uid = 5000
virtual_transport = virtual
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
local_transport = virtual
local_recipient_maps = $virtual_mailbox_maps
transport_maps = hash:/etc/postfix/transport

smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = /var/run/dovecot/auth-client
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_sasl_security_options = noanonymous
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_received_header = yes
smtpd_tls_cert_file = /etc/ssl/private/vmail.crt
smtpd_tls_key_file = /etc/ssl/private/vmail.key
smtpd_sasl_local_domain = $mydomain
smtpd_tls_loglevel = 1
smtp_tls_security_level = may
smtp_tls_loglevel = 1
  • In the configuration above Vorlage:Ic is a list of the domains that you want to receive mail for. This CANNOT contain the domain that is set in Vorlage:Ic. That is why we left Vorlage:Ic to be localhost only.
  • Vorlage:Ic will contain the information of virtual users and their mailbox locations. We are using a hash file to store the more permanent maps, and these will then override the forwards in the MySQL database.
  • Vorlage:Ic is the base directory where the virtual mailboxes will be stored.

The Vorlage:Ic and Vorlage:Ic are the real system user IDs that the virtual mails will be owned by. This is for storage purposes.

Vorlage:Note

Create the file structure

Those new additional settings reference a lot of files that do not even exist yet. We will create them with the following steps.

If you were setting up your database with PostfixAdmin and created the database schema through PostfixAdmin, you can create the following files. Do not forget to change the password:

Vorlage:Hc

Vorlage:Hc

Vorlage:Hc

For alias domains functionality adjust the following files:

Vorlage:Hc

Vorlage:Hc

Vorlage:Hc

Vorlage:Note

Vorlage:Hc

Vorlage:Hc

Vorlage:Hc

Run postmap on transport to generate its db:

# postmap /etc/postfix/transport

Dovecot

Instead of using the provided Dovecot example configuration file, we will create our own Vorlage:Ic. Please note that the user and group here might be vmail instead of postfix!

Vorlage:Hc

Vorlage:Note

Now we create Vorlage:Ic, which we just referenced in the configuration above. Use the following contents and check if everything is set accordingly to your system's configuration.

If you used PostfixAdmin, then you add the following:

Vorlage:Hc

Without having used PostfixAdmin you can use:

Vorlage:Hc

Vorlage:Tip

DH parameters

With v2.3 you are required to provide Vorlage:Ic yourself.

To generate a new DH parameters file (this will take very long):

# openssl dhparam -out /etc/dovecot/dh.pem 4096

then add the file to Vorlage:Ic

ssl_dh = /etc/dovecot/dh.pem

PostfixAdmin

See PostfixAdmin.

Note: To match the configuration in this file, config.inc.php should contain the following.

   # /etc/webapps/postfixadmin/config.inc.php
   ...
   $CONF['domain_path'] = 'YES';
   $CONF['domain_in_mailbox'] = 'NO';
   ...

Roundcube

See Roundcube.

Make sure that both Vorlage:Ic and Vorlage:Ic are uncommented in your Vorlage:Ic file. Also check the Vorlage:Ic for access restrictions. Assuming that localhost is your current host, navigate a browser to Vorlage:Ic and follow the instructions.

Roundcube needs a separate database to work. You should not use the same database for Roundcube and PostfixAdmin. Create a second database Vorlage:Ic and a new user named Vorlage:Ic.

While running the installer ...

The post install process is similar to any other webapp like PhpMyAdmin or PostFixAdmin. The configuration file is in Vorlage:Ic which works as an override over Vorlage:Ic.

Apache configuration

If you are using Apache, copy the example configuration file to your webserver configuration directory.

# cp /etc/webapps/roundcubemail/apache.conf /etc/httpd/conf/extra/httpd-roundcubemail.conf

Add the following line in

Vorlage:Hc

Roundcube: Change Password Plugin

To let users change their passwords from within Roundcube, do the following:

Enable the password plugin by adding this line to

Vorlage:Hc

Configure the password plugin and make sure you alter the settings accordingly:

Vorlage:Hc

Fire it up

All necessary daemons should be started in order to test the configuration. Start both Vorlage:Ic and Vorlage:Ic.

Now for testing purposes, create a domain and mail account in PostfixAdmin. Try to login to this account using Roundcube. Now send yourself a mail.

Testing

Vorlage:Style

Now lets see if Postfix is going to deliver mail for our test user. Vorlage:Bc

Error response

451 4.3.0 <lisi@test.com>:Temporary lookup failure

Maybe you have entered the wrong user/password for MySQL or the MySQL socket is not in the right place.

This error will also occur if you neglect to run newaliases at least once before starting postfix. MySQL is not required for local only usage of postfix.

550 5.1.1 <email@spam.me>: Recipient address rejected: User unknown in virtual mailbox table.

Double check content of mysql_virtual_mailboxes.cf and check the main.cf for mydestination

See that you have received a email

Now type Vorlage:Ic.

You should see something like the following: Vorlage:Bc The key is the last entry. This is an actual email, if you see that, it is working.

Optional Items

Although these items are not required, they definitely add more completeness to your setup

Quota

To enable mailbox quota support by dovecot, do the following:

  • First add the following lines to /etc/dovecot/dovecot.conf
dict {
	quotadict = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
}
service dict {
	unix_listener dict {
		group = vmail
		mode = 0660
		user = vmail
	}
	user = root
}
service quota-warning {
	executable = script /usr/local/bin/quota-warning.sh
	user = vmail
	unix_listener quota-warning {
		group = vmail
		mode = 0660
		user = vmail
	}
}	
mail_plugins=quota
protocol pop3 {
	 mail_plugins = quota
	 pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
	 pop3_uidl_format = %08Xu%08Xv
}
protocol lda {
	mail_plugins = quota
	postmaster_address = postmaster@yourdomain.com
}
protocol imap {
	mail_plugins = $mail_plugins imap_quota
	mail_plugin_dir = /usr/lib/dovecot/modules
}
plugin {
       quota = dict:User quota::proxy::quotadict
       quota_rule2 = Trash:storage=+10%%
       quota_warning = storage=100%% quota-warning +100 %u
       quota_warning2 = storage=95%% quota-warning +95 %u
       quota_warning3 = storage=80%% quota-warning +80 %u
       quota_warning4 = -storage=100%% quota-warning -100 %u # user is no longer over quota
}
  • Create a new file /etc/dovecot/dovecot-dict-sql.conf.ext with the following code:
connect = host=localhost dbname=yourdb user=youruser password=yourpassword
map {
	pattern = priv/quota/storage
	table = quota2
	username_field = username
	value_field = bytes
}
map {
	pattern = priv/quota/messages
	table = quota2
	username_field = username
	value_field = messages
}
  • Create a warning script /usr/local/bin/quota-warning.sh and make sure it is executable. This warning script works with postfix lmtp configuration as well.

Vorlage:Bc

  • Edit the user_query line and add iterat_query in dovecot-sql.conf as following:
 user_query = SELECT '/home/vmail/%d/%n' as home, 'maildir:/home/vmail/%d/%n' as mail, 5000 AS uid, 5000 AS gid, concat('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active = '1'
 iterate_query = SELECT username AS user FROM mailbox
  • Set up LDA as described above under SpamAssassin. If you are not using SpamAssassin, the pipe should look like this in /etc/postfix/master.cf :
 dovecot    unix  -       n       n       -       -       pipe
 flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}

As above activate it in Postfix main.cf

 virtual_transport = dovecot
  • You can set up quota per each mailbox in postfixadmin. Make sure the relevant lines in config.inc.php look like this:
$CONF['quota'] = 'YES';
$CONF['quota_multiplier'] = '1024000';

Restart postfix and dovecot services. If things go well, you should be able to list all users' quota and usage by the this command:

doveadm quota get -A

You should be able to see the quota in roundcube too.

Autocreate and autosubscribe folders in Dovecot

To automatically create the "usual" mail hierarchy, modify your Vorlage:Ic as follows, editing to your specific needs.

Vorlage:Bc

Dovecot public folder and global ACLs

In this section we enable IMAP namespace public folders combined with global and per-folder ACLs.

First, add the following lines to Vorlage:Ic:

Vorlage:Bc

Create the root directory Vorlage:Ic and the folders you want to publicly share, for example (the period is required!) Vorlage:Ic.

Change the ownership of all files in the root directory:

$ chown -R vmail:vmail /home/vmail/public

Finally, create and modify your global ACL file to allow users access to these folders:

Vorlage:Hc

In the above example, user Vorlage:Ic has access to, and can do anything to, all the public folders. Edit to fit your specific needs.

Vorlage:Note

Fighting Spam

As an alternative to SpamAssassin, consider Vorlage:Pkg. Out of the box, it delivers an amazing amount of spam reduction, greylisting, etc and includes a nifty webui. See also [1].

Sidenotes

Alternative vmail folder structure

Instead of having a directory structure like Vorlage:Ic you can have cleaner subdirectories (without the additional domain name) by replacing Vorlage:Ic and Vorlage:Ic with: Vorlage:Bc

Troubleshooting

IMAP/POP3 client failing to receive mails

If you get similar errors, take a look into Vorlage:Ic or run Vorlage:Ic as root to find out more.

It may turn out that the Maildir Vorlage:Ic is just being created if there is at least one email waiting. Otherwise there would not be any need for the directory creation before.

Roundcube not able to delete emails or view any 'standard' folders

Ensure that the Roundcube config.inc.php file contains the following:

Vorlage:Bc

LMTP / Sieve

Is LMTP not connecting to sieve? Ensure that your server is not routing the messages locally. This can be set in Vorlage:Ic:

Vorlage:Bc

Are your emails sent to gmail users ending up in their junk/spam folders?

Google gmail (and most other large email providers) will send your emails straight into your recipients junk / spam folder if you have not implemented SPF / DKIM / DMARC policies. (Hint: Rspamd, via the link above, shows you how to set this up, and will DKIM sign your emails.)

See also

TMP

Postfix Virtual Domain Hosting Howto Purpose of this document

This document requires Postfix version 2.0 or later.

This document gives an overview of how Postfix can be used for hosting multiple Internet domains, both for final delivery on the machine itself and for the purpose of forwarding to destinations elsewhere.

The text not only describes delivery mechanisms that are built into Postfix, but also gives pointers for using non-Postfix mail delivery software.

The following topics are covered:

   Canonical versus hosted versus other domains
   Local files versus network databases
   As simple as can be: shared domains, UNIX system accounts
   Postfix virtual ALIAS example: separate domains, UNIX system accounts
   Postfix virtual MAILBOX example: separate domains, non-UNIX accounts
   Non-Postfix mailbox store: separate domains, non-UNIX accounts
   Mail forwarding domains
   Mailing lists
   Autoreplies 

Canonical versus hosted versus other domains

Most Postfix systems are the final destination for only a few domain names. These include the hostnames and [the IP addresses] of the machine that Postfix runs on, and sometimes also include the parent domain of the hostname. The remainder of this document will refer to these domains as the canonical domains. They are usually implemented with the Postfix local domain address class, as defined in the ADDRESS_CLASS_README file.

Besides the canonical domains, Postfix can be configured to be the final destination for any number of additional domains. These domains are called hosted, because they are not directly associated with the name of the machine itself. Hosted domains are usually implemented with the virtual alias domain address class and/or with the virtual mailbox domain address class, as defined in the ADDRESS_CLASS_README file.

But wait! There is more. Postfix can be configured as a backup MX host for other domains. In this case Postfix is not the final destination for those domains. It merely queues the mail when the primary MX host is down, and forwards the mail when the primary MX host becomes available. This function is implemented with the relay domain address class, as defined in the ADDRESS_CLASS_README file.

Finally, Postfix can be configured as a transit host for sending mail across the internet. Obviously, Postfix is not the final destination for such mail. This function is available only for authorized clients and/or users, and is implemented by the default domain address class, as defined in the ADDRESS_CLASS_README file. Local files versus network databases

The examples in this text use table lookups from local files such as DBM or Berkeley DB. These are easy to debug with the postmap command:

   Example: postmap -q info@example.com hash:/etc/postfix/virtual 

See the documentation in LDAP_README, MYSQL_README and PGSQL_README for how to replace local files by databases. The reader is strongly advised to make the system work with local files before migrating to network databases, and to use the postmap command to verify that network database lookups produce the exact same results as local file lookup.

   Example: postmap -q info@example.com ldap:/etc/postfix/virtual.cf 

As simple as can be: shared domains, UNIX system accounts

The simplest method to host an additional domain is to add the domain name to the domains listed in the Postfix mydestination configuration parameter, and to add the user names to the UNIX password file.

This approach makes no distinction between canonical and hosted domains. Each username can receive mail in every domain.

In the examples we will use "example.com" as the domain that is being hosted on the local Postfix machine.

   /etc/postfix/main.cf:
       mydestination = $myhostname localhost.$mydomain ... example.com

The limitations of this approach are:

   A total lack of separation: mail for info@my.host.name is delivered to the same UNIX system account as mail for info@example.com.
   With users in the UNIX password file, administration of large numbers of users becomes inconvenient. 

The examples that follow provide solutions for both limitations. Postfix virtual ALIAS example: separate domains, UNIX system accounts

With the approach described in this section, every hosted domain can have its own info etc. email address. However, it still uses UNIX system accounts for local mailbox deliveries.

With virtual alias domains, each hosted address is aliased to a local UNIX system account or to a remote address. The example below shows how to use this mechanism for the example.com domain.

    1 /etc/postfix/main.cf:
    2     virtual_alias_domains = example.com ...other hosted domains...
    3     virtual_alias_maps = hash:/etc/postfix/virtual
    4 
    5 /etc/postfix/virtual:
    6     postmaster@example.com postmaster
    7     info@example.com       joe
    8     sales@example.com      jane
    9     # Uncomment entry below to implement a catch-all address
   10     # @example.com         jim
   11     ...virtual aliases for more domains...

Notes:

   Line 2: the virtual_alias_domains setting tells Postfix that example.com is a so-called virtual alias domain. If you omit this setting then Postfix will reject mail (relay access denied) or will not be able to deliver it (mail for example.com loops back to myself).
   NEVER list a virtual alias domain name as a mydestination domain!
   Lines 3-8: the /etc/postfix/virtual file contains the virtual aliases. With the example above, mail for postmaster@example.com goes to the local postmaster, while mail for info@example.com goes to the UNIX account joe, and mail for sales@example.com goes to the UNIX account jane. Mail for all other addresses in example.com is rejected with the error message "User unknown".
   Line 10: the commented out entry (text after #) shows how one would implement a catch-all virtual alias that receives mail for every example.com address not listed in the virtual alias file. This is not without risk. Spammers nowadays try to send mail from (or mail to) every possible name that they can think of. A catch-all mailbox is likely to receive many spam messages, and many bounces for spam messages that were sent in the name of anything@example.com.

Execute the command "postmap /etc/postfix/virtual" after changing the virtual file, and execute the command "postfix reload" after changing the main.cf file.

Note: virtual aliases can resolve to a local address or to a remote address, or both. They don't have to resolve to UNIX system accounts on your machine.

More details about the virtual alias file are given in the virtual(5) manual page, including multiple addresses on the right-hand side.

Virtual aliasing solves one problem: it allows each domain to have its own info mail address. But there still is one drawback: each virtual address is aliased to a UNIX system account. As you add more virtual addresses you also add more UNIX system accounts. The next section eliminates this problem. Postfix virtual MAILBOX example: separate domains, non-UNIX accounts

As a system hosts more and more domains and users, it becomes less desirable to give every user their own UNIX system account.

With the Postfix virtual(8) mailbox delivery agent, every recipient address can have its own virtual mailbox. Unlike virtual alias domains, virtual mailbox domains do not need the clumsy translation from each recipient addresses into a different address, and owners of a virtual mailbox address do not need to have a UNIX system account.

The Postfix virtual(8) mailbox delivery agent looks up the user mailbox pathname, uid and gid via separate tables that are searched with the recipient's mail address. Maildir style delivery is turned on by terminating the mailbox pathname with "/".

If you find the idea of multiple tables bothersome, remember that you can migrate the information (once it works), to an SQL database. If you take that route, be sure to review the "local files versus databases" section at the top of this document.

Here is an example of a virtual mailbox domain "example.com":

    1 /etc/postfix/main.cf:
    2     virtual_mailbox_domains = example.com ...more domains...
    3     virtual_mailbox_base = /var/mail/vhosts
    4     virtual_mailbox_maps = hash:/etc/postfix/vmailbox
    5     virtual_minimum_uid = 100
    6     virtual_uid_maps = static:5000
    7     virtual_gid_maps = static:5000
    8     virtual_alias_maps = hash:/etc/postfix/virtual
    9 
   10 /etc/postfix/vmailbox:
   11     info@example.com    example.com/info
   12     sales@example.com   example.com/sales/
   13     # Comment out the entry below to implement a catch-all.
   14     # @example.com      example.com/catchall
   15     ...virtual mailboxes for more domains...
   16 
   17 /etc/postfix/virtual:
   18     postmaster@example.com postmaster

Notes:

   Line 2: The virtual_mailbox_domains setting tells Postfix that example.com is a so-called virtual mailbox domain. If you omit this setting then Postfix will reject mail (relay access denied) or will not be able to deliver it (mail for example.com loops back to myself).
   NEVER list a virtual MAILBOX domain name as a mydestination domain!
   NEVER list a virtual MAILBOX domain name as a virtual ALIAS domain!
   Line 3: The virtual_mailbox_base parameter specifies a prefix for all virtual mailbox pathnames. This is a safety mechanism in case someone makes a mistake. It prevents mail from being delivered all over the file system.
   Lines 4, 10-15: The virtual_mailbox_maps parameter specifies the lookup table with mailbox (or maildir) pathnames, indexed by the virtual mail address. In this example, mail for info@example.com goes to the mailbox at /var/mail/vhosts/example.com/info while mail for sales@example.com goes to the maildir located at /var/mail/vhosts/example.com/sales/.
   Line 5: The virtual_minimum_uid specifies a lower bound on the mailbox or maildir owner's UID. This is a safety mechanism in case someone makes a mistake. It prevents mail from being written to sensitive files.
   Lines 6, 7: The virtual_uid_maps and virtual_gid_maps parameters specify that all the virtual mailboxes are owned by a fixed uid and gid 5000. If this is not what you want, specify lookup tables that are searched by the recipient's mail address.
   Line 14: The commented out entry (text after #) shows how one would implement a catch-all virtual mailbox address. Be prepared to receive a lot of spam, as well as bounced spam that was sent in the name of anything@example.com.
   NEVER put a virtual MAILBOX wild-card in the virtual ALIAS file!!
   Lines 8, 17, 18: As you see, it is possible to mix virtual aliases with virtual mailboxes. We use this feature to redirect mail for example.com's postmaster address to the local postmaster. You can use the same mechanism to redirect an address to a remote address.
   Line 18: This example assumes that in main.cf, $myorigin is listed under the mydestination parameter setting. If that is not the case, specify an explicit domain name on the right-hand side of the virtual alias table entries or else mail will go to the wrong domain.

Execute the command "postmap /etc/postfix/virtual" after changing the virtual file, execute "postmap /etc/postfix/vmailbox" after changing the vmailbox file, and execute the command "postfix reload" after changing the main.cf file.

Note: mail delivery happens with the recipient's UID/GID privileges specified with virtual_uid_maps and virtual_gid_maps. Postfix 2.0 and earlier will not create mailDIRs in world-writable parent directories; you must create them in advance before you can use them. Postfix may be able to create mailBOX files by itself, depending on parent directory write permissions, but it is safer to create mailBOX files ahead of time.

More details about the virtual mailbox delivery agent are given in the virtual(8) manual page. Non-Postfix mailbox store: separate domains, non-UNIX accounts

This is a variation on the Postfix virtual mailbox example. Again, every hosted address can have its own mailbox. However, most parameters that control the virtual(8) delivery agent are no longer applicable: only virtual_mailbox_domains and virtual_mailbox_maps stay in effect. These parameters are needed to reject mail for unknown recipients.

While non-Postfix software is being used for final delivery, some Postfix concepts are still needed in order to glue everything together. For additional background on this glue you may want to take a look at the virtual mailbox domain class as defined in the ADDRESS_CLASS_README file.

The text in this section describes what things should look like from Postfix's point of view. See CYRUS_README or MAILDROP_README for specific information about Cyrus or about Courier maildrop.

Here is an example for a hosted domain example.com that delivers to a non-Postfix delivery agent:

    1 /etc/postfix/main.cf:
    2     virtual_transport = ...see below...
    3     virtual_mailbox_domains = example.com ...more domains...
    4     virtual_mailbox_maps = hash:/etc/postfix/vmailbox
    5     virtual_alias_maps = hash:/etc/postfix/virtual
    6 
    7 /etc/postfix/vmailbox:
    8     info@example.com    whatever
    9     sales@example.com   whatever
   10     # Comment out the entry below to implement a catch-all.
   11     # Configure the mailbox store to accept all addresses.
   12     # @example.com      whatever
   13     ...virtual mailboxes for more domains...
   14 
   15 /etc/postfix/virtual:
   16     postmaster@example.com postmaster

Notes:

   Line 2: With delivery to a non-Postfix mailbox store for hosted domains, the virtual_transport parameter usually specifies the Postfix LMTP client, or the name of a master.cf entry that executes non-Postfix software via the pipe delivery agent. Typical examples (use only one):
       virtual_transport = lmtp:unix:/path/name (uses UNIX-domain socket)
       virtual_transport = lmtp:hostname:port   (uses TCP socket)
       virtual_transport = maildrop:            (uses pipe(8) to command)
   Postfix comes ready with support for LMTP. And an example maildrop delivery method is already defined in the default Postfix master.cf file. See the MAILDROP_README document for more details.
   Line 3: The virtual_mailbox_domains setting tells Postfix that example.com is delivered via the virtual_transport that was discussed in the previous paragraph. If you omit this virtual_mailbox_domains setting then Postfix will either reject mail (relay access denied) or will not be able to deliver it (mail for example.com loops back to myself).
   NEVER list a virtual MAILBOX domain name as a mydestination domain!
   NEVER list a virtual MAILBOX domain name as a virtual ALIAS domain!
   Lines 4, 7-13: The virtual_mailbox_maps parameter specifies the lookup table with all valid recipient addresses. The lookup result value is ignored by Postfix. In the above example, info@example.com and sales@example.com are listed as valid addresses; other mail for example.com is rejected with "User unknown" by the Postfix SMTP server. It's left up to the non-Postfix delivery agent to reject non-existent recipients from local submission or from local alias expansion. If you intend to use LDAP, MySQL or PgSQL instead of local files, be sure to review the "local files versus databases" section at the top of this document!
   Line 12: The commented out entry (text after #) shows how one would inform Postfix of the existence of a catch-all address. Again, the lookup result is ignored by Postfix.
   NEVER put a virtual MAILBOX wild-card in the virtual ALIAS file!!
   Note: if you specify a wildcard in virtual_mailbox_maps, then you still need to configure the non-Postfix mailbox store to receive mail for any address in that domain.
   Lines 5, 15, 16: As you see above, it is possible to mix virtual aliases with virtual mailboxes. We use this feature to redirect mail for example.com's postmaster address to the local postmaster. You can use the same mechanism to redirect any addresses to a local or remote address.
   Line 16: This example assumes that in main.cf, $myorigin is listed under the mydestination parameter setting. If that is not the case, specify an explicit domain name on the right-hand side of the virtual alias table entries or else mail will go to the wrong domain.

Execute the command "postmap /etc/postfix/virtual" after changing the virtual file, execute "postmap /etc/postfix/vmailbox" after changing the vmailbox file, and execute the command "postfix reload" after changing the main.cf file. Mail forwarding domains

Some providers host domains that have no (or only a few) local mailboxes. The main purpose of these domains is to forward mail elsewhere. The following example shows how to set up example.com as a mail forwarding domain:

    1 /etc/postfix/main.cf:
    2     virtual_alias_domains = example.com ...other hosted domains...
    3     virtual_alias_maps = hash:/etc/postfix/virtual
    4 
    5 /etc/postfix/virtual:
    6     postmaster@example.com postmaster
    7     joe@example.com        joe@somewhere
    8     jane@example.com       jane@somewhere-else
    9     # Uncomment entry below to implement a catch-all address
   10     # @example.com         jim@yet-another-site
   11     ...virtual aliases for more domains...

Notes:

   Line 2: The virtual_alias_domains setting tells Postfix that example.com is a so-called virtual alias domain. If you omit this setting then Postfix will reject mail (relay access denied) or will not be able to deliver it (mail for example.com loops back to myself).
   NEVER list a virtual alias domain name as a mydestination domain!
   Lines 3-11: The /etc/postfix/virtual file contains the virtual aliases. With the example above, mail for postmaster@example.com goes to the local postmaster, while mail for joe@example.com goes to the remote address joe@somewhere, and mail for jane@example.com goes to the remote address jane@somewhere-else. Mail for all other addresses in example.com is rejected with the error message "User unknown".
   Line 10: The commented out entry (text after #) shows how one would implement a catch-all virtual alias that receives mail for every example.com address not listed in the virtual alias file. This is not without risk. Spammers nowadays try to send mail from (or mail to) every possible name that they can think of. A catch-all mailbox is likely to receive many spam messages, and many bounces for spam messages that were sent in the name of anything@example.com.

Execute the command "postmap /etc/postfix/virtual" after changing the virtual file, and execute the command "postfix reload" after changing the main.cf file.

More details about the virtual alias file are given in the virtual(5) manual page, including multiple addresses on the right-hand side. Mailing lists

The examples that were given above already show how to direct mail for virtual postmaster addresses to a local postmaster. You can use the same method to direct mail for any address to a local or remote address.

There is one major limitation: virtual aliases and virtual mailboxes can't directly deliver to mailing list managers such as majordomo. The solution is to set up virtual aliases that direct virtual addresses to the local delivery agent:

   /etc/postfix/main.cf:
       virtual_alias_maps = hash:/etc/postfix/virtual
   /etc/postfix/virtual:
       listname-request@example.com listname-request
       listname@example.com         listname
       owner-listname@example.com   owner-listname
   /etc/aliases:
       listname: "|/some/where/majordomo/wrapper ..."
       owner-listname: ...
       listname-request: ...

This example assumes that in main.cf, $myorigin is listed under the mydestination parameter setting. If that is not the case, specify an explicit domain name on the right-hand side of the virtual alias table entries or else mail will go to the wrong domain.

More information about the Postfix local delivery agent can be found in the local(8) manual page.

Why does this example use a clumsy virtual alias instead of a more elegant transport mapping? The reason is that mail for the virtual mailing list would be rejected with "User unknown". In order to make the transport mapping work one would still need a bunch of virtual alias or virtual mailbox table entries.

   In case of a virtual alias domain, there would need to be one identity mapping from each mailing list address to itself.
   In case of a virtual mailbox domain, there would need to be a dummy mailbox for each mailing list address. 

Autoreplies

In order to set up an autoreply for virtual recipients while still delivering mail as normal, set up a rule in a virtual alias table:

   /etc/postfix/main.cf:
       virtual_alias_maps = hash:/etc/postfix/virtual
   /etc/postfix/virtual:
       user@domain.tld user@domain.tld, user@domain.tld@autoreply.mydomain.tld

This delivers mail to the recipient, and sends a copy of the mail to the address that produces automatic replies. The address can be serviced on a different machine, or it can be serviced locally by setting up a transport map entry that pipes all mail for autoreply.mydomain.tld into some script that sends an automatic reply back to the sender.

DO NOT list autoreply.mydomain.tld in mydestination!

   /etc/postfix/main.cf:
       transport_maps = hash:/etc/postfix/transport
   /etc/postfix/transport:
       autoreply.mydomain.tld  autoreply:
   /etc/postfix/master.cf:
       # =============================================================
       # service type  private unpriv  chroot  wakeup  maxproc command
       #               (yes)   (yes)   (yes)   (never) (100)
       # =============================================================
       autoreply unix  -       n       n       -       -       pipe
           flags= user=nobody argv=/path/to/autoreply $sender $mailbox

This invokes /path/to/autoreply with the sender address and the user@domain.tld recipient address on the command line.

For more information, see the pipe(8) manual page, and the comments in the Postfix master.cf file.