This code was created by Andrew McNamara and adapted to snapshot 20001121 by Xavier Beaudouin. It was merged with mainstream Postfix for snapshot 20010128 by Wietse. Purpose of this software ======================== You can use the virtual delivery agent for mailbox delivery of some or all domains that are handled by a machine. This mechanism is different from virtual domains that are implemented by translating each virtual address into a real local user. For that, see the virtual(5) manual page. This is what Andrew McNamara wrote when he made the virtual delivery agent available. "This code is designed for ISP's who offer virtual mail hosting. It looks up the user mailbox location, uid and gid via separate maps, and the mailbox location map can specify either mailbox or maildir delivery (controlled by trailing slash on mailbox name). The agent does not support user+foo address extensions, aliases or .forward files (use the virtual table instead), and therefore doesn't support file or program aliases. This choice was made to simplify and streamline the code (it allowed me to dispense with 70% of local's code - mostly the bits that are a security headache) - if you need this functionality, this agent isn't for you. It also doesn't support writing to a common spool as root and then chowning the mailbox to the user - I felt this functionality didn't fit with my overall aims." [End of Andrew McNamara's words] The result is the most secure local delivery agent that you will find with Postfix. This delivery agent requires three different lookup tables in order to define its recipients as (mailbox path, user ID, group ID). This is because Postfix table lookups can't return multiple results. If your virtual mailboxes are all owned by the same user/group ID, just specify "static" maps that always return the same result. See below for examples. If your virtual mailboxes must be owned by different user/group IDs, and if it is too inconvenient for you to maintain three parallel tables, use an LDAP or MYSQL database (or generate the three parallel tables from one common template). Configuration parameters ======================== virtual_mailbox_base Specifies a path that is prepended to all mailbox paths. This is a safety measure to ensure an that out of control map doesn't litter the filesystem with mailboxes (or worse). While it could be set to "/", this isn't recommended. virtual_mailbox_maps Recipients are looked up in this map to determine the path to their mailbox. If the returned path ends in a slash ("/"), maildir-style delivery is carried out, otherwise the path is assumed to specify a mailbox file. The virtual_mailbox_base directory is unconditionally prepended to this path. If the recipient is not found the mail is bounced. If a recipient is not found the mail is returned to the sender. For security reasons, regexp maps are not allowed here, because their $1 etc. substitutions would open a security hole. The mail administrator is expected to create and chown recipient mailbox files or maildir directories ahead of time. virtual_minimum_uid Specifies a minimum uid that will be accepted as a return from a virtual_uid_maps lookup. Returned values less than this will be rejected, and the message will be deferred. virtual_uid_maps Recipients are looked up in this map to determine the UID (owner privileges) to be used when writing to the target mailbox. For security reasons, regexp maps are not allowed here, because their $1 etc. substitutions would open a security hole. Specify a static map if all mailboxes should be owned by the same UID. For example, to specify that all mailboxes are owned by the UID 5000, specify: virtual_uid_maps = static:5000 virtual_gid_maps Recipients are looked up in this map to determine the GID (group privileges) to be used when writing to the target mailbox. For security reasons, regexp maps are not allowed here, because their $1 etc. substitutions would open a security hole. Specify a static map if all mailboxes should be owned by the same GID. For example, to specify that all mailboxes are owned by the GID 5000, specify: virtual_gid_maps = static:5000 virtual_mailbox_lock This setting is ignored in case of maildir delivery. Locking method to use when updating a mailbox. Defaults to fcntl or flock depending on the system. Depending on the POP or IMAP server you may have to specify dotlock locking, which requires that the recipient UID or GID has write access to the parent directory of the mailbox file. Use the "postconf -m" command to find out what locking methods Postfix supports on your system. virtual_mailbox_size An upper limit on the size of a mailbox file or maildir file. Example 1: using the virtual delivery agent for all local mail ============================================================== This example does not use the Postfix local delivery agent at all. With this configuration Postfix does no user+foo address extension, no alias expansion, no .forward file expansion, and no lookups of recipients in /etc/passwd. Instead of "hash" specify "dbm" or "btree", depending on your system type. The command "postconf -m" displays possible lookup table types. /etc/postfix/main.cf: local_transport = virtual virtual_mailbox_base = /var/mail/vhosts virtual_mailbox_maps = hash:/etc/postfix/vmailbox virtual_minimum_uid = 100 virtual_uid_maps = hash:/etc/postfix/vuid virtual_gid_maps = hash:/etc/postfix/vgid # All domains that are listed in $mydestination are delivered # with $local_transport, which is the virtual delivery agent. mydestination = $myhostname localhost.$mydomain virtual1.domain virtual2.domain Define a virtual delivery agent if the entry doesn't already exist: /etc/postfix/master.cf: virtual unix - n n - - virtual Example recipients, one UNIX-style mailbox, one qmail-style maildir: /etc/postfix/vmailbox: test1@virtual1.domain test1 test2@virtual2.domain test2/ /etc/postfix/vuid: test1@virtual1.domain 5001 test2@virtual2.domain 5002 /etc/postfix/vgid: test1@virtual1.domain 5001 test2@virtual2.domain 5002 Execute something like the following commands for each mailbox recipient: # touch /var/mail/vhosts/test1 # chown 5001:5001 /var/mail/vhosts/test1 Execute something like the following commands for each maildir recipient: # mkdir /var/mail/vhosts/test2 # chown 5002:5002 /var/mail/vhosts/test2 Be sure to make the necessary entries for root@$myhostname, postmaster@$myhostname and for any other necessary addresses. Example 2: co-existing with the default local delivery agent ============================================================ In this example, the default Postfix local delivery agent handles the mail for non-virtual recipients; the virtual delivery agent handles virtual recipients, and all virtual mailboxes are owned by user ID 5000, group ID 5000. Instead of "hash" specify "dbm" or "btree", depending on your system type. The command "postconf -m" displays possible lookup table types. /etc/postfix/main.cf: virtual_mailbox_base = /var/mail/vhosts virtual_mailbox_maps = hash:/etc/postfix/vmailbox virtual_minimum_uid = 100 virtual_uid_maps = static:5000 virtual_gid_maps = static:5000 transport_maps = hash:/etc/postfix/transport # All domains that are delivered by the local delivery agent. mydestination = $myhostname $localhost.$mydomain # Reject unknown local recipients at the SMTP port. local_recipient_maps = unix:passwd.byname $alias_maps Define a virtual delivery agent if the entry doesn't already exist: /etc/postfix/master.cf: virtual unix - n n - - virtual Route virtual domains to the virtual delivery agent: /etc/postfix/transport: virtual1.domain virtual virtual2.domain virtual Example recipients, one UNIX-style mailbox, one qmail-style maildir: /etc/postfix/vmailbox: virtual1.domain required to prevent relay access denied errors virtual2.domain required to prevent relay access denied errors test1@virtual1.domain test1 test2@virtual2.domain test2/ Execute something like the following commands for each mailbox recipient: # touch /var/mail/vhosts/test1 # chown 5000:5000 /var/mail/vhosts/test1 Execute something like the following commands for each maildir recipient: # mkdir /var/mail/vhosts/test2 # chown 5000:5000 /var/mail/vhosts/test2 Remember that each domain is required to have a postmaster contact address. Example 3: forwarding mail for an old account to a new address ============================================================== In order to forward mail for a user who no longer exists, one would set up a rule in a virtual table (please ignore the text in the virtual configuration file about virtual domains): /etc/postfix/main.cf: virtual_maps = hash:/etc/postfix/virtual /etc/postfix/virtual: old_user@old.domain new_user@new.domain Example 4: setting up a virtual vacation autoresponder ====================================================== In order to set up an autoreply for virtual recipients while still delivering mail as normal, set up a rule in a virtual table (please ignore the text in the virtual configuration file about virtual domains): /etc/postfix/main.cf: virtual_maps = hash:/etc/postfix/virtual /etc/postfix/virtual: user@domain.name user@domain.name, user@autoreply.domain.name 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 the autoreply.domain.name into some script that sends an automatic reply back to the sender.