Configure Postfix

Postfix is one of the most popular MTA (mail transfer agent) products on unix. This article presents a simple way of configuring postfix for virtual domains

Postfix is a complext product. Most likely a normal administrator will never need all the features. In fact the product is so complex it took a book to explain it all -

We assume:

  • You got a machine and multiple domains hosted on it
  • The postfix on your machine receives email for all these domains
  • The domains are configured as virtual domains, each user has a folder configured and email is delivered in those folders


Postfix installation is simple: run your preferred package installer depending on your operating system distribution and postfix will be up and running in a matter of minutes

For a Debian linux system, the command apt-get install postfix as a root will get the module up and running in seconds


Our machine is called and we'll install mail support for the following domains:, and

The email we want delivered in sub-folders under the folder /usr/local/vmail

The user will go to a specific folder. All the other mail will be delivered to the postmaster user associated with each domain (we will cofigure a postmaster user for each of the three domains)

We must ensure that no message relaying will be enabled. Only messages originating from the machine or messages that are sent to users belonging to the three domains are to be processed by our Postfix installation

In the end, we configure an external email address, let's call it whatever@domainhere where the mail sent to will be forwarded

Configuration Steps


su as root and create the folder /usr/local/vmail This is the parent folder for all the subfolders where the mail will be delivered

Under the above mentioned folder, create one folder for each domain, let's call the folders, and

Remember that for the we will have two users, daniel and postmaster, and for the other two domains we will configure only one user for each, postmaster

For each one of the above mentioned users, we create a folder under the folder corresponding to the domain. Therefore we create folders daniel and postmaster under folder, and postmaster folders under and

Now this is important: since you are root, change the owner and the group of the folders created at the previous step to postfix. The command
chown postfix:postfix _foldername_
will achieve this

For privacy, ensure that the folders are only accessible by postfix by the use of chmod command. In the end, the folders will have rwx rights for the owner (postfix user) and no other rights for the group and the "other" category


Your machine must be configured in DNS as being the recipient of the messages for the three domains. See where the domains are parked and modify the MX DNS entry for each of them to point to this machine. MX requires a fully qualified domain name, and not a machine IP address.

/etc/postfix/ is the Postfix main configuration file. We change the settings in the file to achieve the following:

  • Only mail originating from the machine will be relayed
  • Only incoming mail accepted and process is the one for the three domains
  • Any other messages or relay requests will be rejected.

Here is the listing of the

# See /usr/share/postfix/ for a commented, more complete version

# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# TLS parameters
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.

myhostname =
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination =
relayhost = 
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

mynetworks =
virtual_mailbox_domains =
virtual_mailbox_maps = hash:/etc/postfix/virtual
virtual_mailbox_base = /usr/local/vmail
virtual_uid_maps = static:105
virtual_gid_maps = static:108
virtual_alias_maps = hash:/etc/postfix/alias

The entries are pretty standard, please note the following:

  • mynetworks - the list of networks that would get their messages relayed. The value ensures that only messages originating from the machine will be relayed
  • virtual_mailbox_domains - the list of domains that will get their messages processed. You can see all three domains listed here
  • virtual_mailbox_base - the parent of all the mailbox folders, previously created.
  • virtual_uid_maps and virtual_gid_maps - the user id and the group id of the postfix user. The posfix module runs as this user. It is very important the values are accurate. The uid can be taken from the /etc/passwd line that contains the definition of the postfix user, and the gid from the /etc/group line that contains the definition of the postfix group
  • virtual_mailbox_maps - a text file that contains the folder names associated with every domain.
  • virtual_alias_maps - a text file that contains email aliases

These are the current entries in our /etc/group and /etc/passwd files for the postfix user entry

The entry in /etc/group folder


The entry in the /etc/passwd folder


Note about virtual and alias text files - the settings point to these text files, however postfix use them in a compiled form, alias.db and virtual.db.

The db file is obtained from the regular file, compiled with a special program called postmap. The command line postmap /etc/postfix/alias will compile the text file to /etc/postfix/alias.db. Same applies for the /etc/postifx/virtual file.

Upon restart, postfix checks these files. Always *.db files must be newer than the original files. That confirms they contain the lastest info. If they are older, then a warning message is seen in the postfix logs

virtual and virtual.db

/etc/postfix/virtual (and after compilation with postmap /etc/postfix/virtual.db) is a file containing information about how the virtual mail has to be delivered. Basically for each email address for a domain, a folder (relative path to the /usr/local/vmail folder) is specified

In our case, the virtual text file contains the following

Please note the following:

  • The construct @domain_name is to process all the email messages that were sent to addresses within this domain and were not already processed
  • I am not sure whether it is mandatory to define the full blown email addresses before the catch all @domain_name is used, however I believe it is a good practice to do so
  • In the above list, for the domain, all the emails sent to will be written to the folder while any other messages for addresses within the domain will be written to the catch all folder,
  • It is mandatory to put a forward slash at the end of the folder definition, otherwise postifx will believe we want the messages to be written in a file, not a folder.

alias and alias.db

alias (actually /etc/postfix/alias) is a text file containing email aliases. If you want that the email messages sent to a certain email address to be forwarded to another address, then an entry in the alias file is needed

The destination address does not have to be within the domains serviced by the postfix installation - for example I use alias entries to forward some emails on my address at so you can really use any email address

This is an example of alias file       whatever@domainhere

Note: while virtual file must define every single address (or catch all address) for all the domains serviced by the postfix installation, alias file can be empty. However, even when it is empty, you still have to compile it to alias.db using postmap program, while alias.db must be always newer than the original alias file