Gentoo Wiki




This article will guide you through the process of setting up a basic virtual mail server using Postfix (SMTP), PostfixAdmin (web administration) and Dovecot (POP3 and IMAP) with quotas.

This article does not cover setting up sieve, secure connections (SSL/TLS), mailing lists, anti-virus or spam filtering (including the anti-spam measures built in to Postfix).

Versions Used

This article was written for both Dovecot 1.0 and 1.1 (differences are noted where applicable), Postfix 2.5.1 and PostfixAdmin 2.1.0. If you are using higher versions than these, please consult the software documentation for a list of changes.


This article assumes that you already have Apache 2 installed and set up for virtual hosting, PHP installed and set up under Apache2 with the mysqli module and MySQL installed. This article assumes everything will be housed on a single server.

Mail Storage

This article will set up the mail storage to be under /var/mail/<domain>/<username>/Maildir/ using the Maildir (Qmail style) format. The /var/mail/<domain>/<username>/ directory is considered to be the virtual users home directory. This home directory is used for storing things like indexes that are not normally part of the Maildir structure.


The following users are used by this setup:

The following groups are used by this setup:


Add the following lines to /etc/portage/package.use (create it if it doesn't exist) to set the USE flags to get the required features:

File: /etc/portage/package.use
mail-mta/postfix dovecot-sasl mysql -pam sasl
net-mail/dovecot mysql -pam pop3d
www-apps/postfixadmin mysql vhosts

This article will use webapp-admin to install PostfixAdmin. If you don't want to do this, remove the vhosts USE flag from the "postfixadmin" line above. In this case PostfixAdmin will be installed under /var/www/localhost/htdocs/.

Add the following lines to /etc/portage/package.keywords (create it if it doesn't exist) to unmask the relevent software versions:

File: /etc/portage/package.keywords

Install all of the software packages with: emerge -av postfix postfixadmin dovecot

Finally, start and then stop Postfix. This causes it to create the files it uses. If you don't do this, the cron jobs it sets up will chew up file handles unnecessarily: /etc/init.d/postfix start; /etc/init.d/postfix stop


This section will show you how to set up PostfixAdmin. This is done first because it doesn't depend on anything else and sets up the databases that will be used by Postfix and Dovecot.

Virtual Host Setup

This section will install PostfixAdmin and configure the Apache virtual host. This section does not deal with configuring SSL, although it is highly recommended that you only access PostfixAdmin over SSL.

Using webapp-config, install PostfixAdmin using the following command: webapp-config --install postfixadmin 2.1.0

Pay attention to any messages that webapp-config displays and follow any instructions you're given.

PostfixAdmin will now be installed to /var/www/

Note: If you want PostfixAdmin to be installed to a directory within the virtual host, use webapp-configs -d (--dir) option. See webapp-config --help for further help.

Now you need to tell Apache about the virtual host. To do so, put the following into a new file, /etc/apache2/vhosts.d/ (based on the Gentoo default virtual host):

File: /etc/apache2/vhosts.d/
<VirtualHost *:80>
    ServerName localhost
    DocumentRoot "/var/www/"

    <Directory "/var/www/localhost/htdocs">
        # Possible values for the Options directive are "None", "All",
        # or any combination of:
        #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
        # Note that "MultiViews" must be named *explicitly* --- "Options All"
        # doesn't give it to you.
        # The Options directive is both complicated and important.  Please see
        # for more information.
        Options Indexes FollowSymLinks

        # AllowOverride controls what directives may be placed in .htaccess files.
        # It can be "All", "None", or any combination of the keywords:
        #   Options FileInfo AuthConfig Limit
        AllowOverride All

        # Controls who can get stuff from this server.
        Order allow,deny
        Allow from all

    <IfModule alias_module>
        # Alias: Maps web paths into filesystem paths and is used to
        # access content that does not live under the DocumentRoot.
        # Example:
        #   Alias /webpath /full/filesystem/path
        # If you include a trailing / on /webpath then the server will
        # require it to be present in the URL.  You will also likely
        # need to provide a <Directory> section to allow access to
        # the filesystem path.

        # ScriptAlias: This controls which directories contain server scripts.
        # ScriptAliases are essentially the same as Aliases, except that
        # documents in the target directory are treated as applications and
        # run by the server when requested rather than as documents sent to the
        # client.  The same rules about trailing "/" apply to ScriptAlias
        # directives as to Alias.
        ScriptAlias /cgi-bin/ "/var/www/"

    <Directory "/var/www/">
        AllowOverride None
        Options None
        Order allow,deny
        Allow from all

    <IfModule mpm_peruser_module>
        ServerEnvironment apache apache

# vim: ts=4 filetype=apache

Finally, to apply the changes, restart Apache with: /etc/init.d/apache2 restart

MySQL Setup

This article will not go into the exact methods for creating users. There is plenty of documentation already available and many people use one of a number of tools to help them.

First create a database which will be used to store the mail account details. This article will use "postfixadmin" as the database name.

There are 2 MySQL users you need to create.

The first is the "postfixadmin" user who requires the following permissions: SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX on the "postfixadmin" database. This is the user PostfixAdmin will use to administrate the mail accounts.

The second is the "mailauth" user who requires only SELECT permissions on the "postfixadmin" database. This user is used by Postfix and Dovecot for looking up information.


Open up the file in the postfixadmin directory. The following settings are listed in the order that they appear.

First comment out the configured setting by placing a # in front of it to tell PostfixAdmin that we've configured it. Until you do this, PostfixAdmin will not run:

#$CONF['configured'] = false;

Tell PostfixAdmin what web address it will be accessed with:

$CONF['postfix_admin_url'] = '';

If your native language isn't English, you'll want to change the default_language setting. A list of language files in the languages/language.php file. For example, if you want PostfixAdmin in German:

$CONF['default_language'] = 'de';

Next set up the MySQL connection. This uses the MySQL database and user set up above. The password should be the same password you entered when creating the postfixadmin MySQL user.

$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfixadmin';
$CONF['database_password'] = 'password';
$CONF['database_name'] = 'postfixadmin';
$CONF['database_prefix'] = '';

You'll want to change the admin email address that PostfixAdmin uses. This is used as the From address when sending messages to new accounts.

$CONF['admin_email'] = '';

This setup will use mailboxes stored in the format <domain>/<username>, so change the domain_path and domain_in_mailbox settings to match those below.

$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';

This setup will use quotas, so tell PostfixAdmin to turn them on.

$CONF['quota'] = 'YES';

PostfixAdmin displays a couple of customizable links. You'll probably want to change these to link to your website.

$CONF['user_footer_link'] = "";

$CONF['show_footer_text'] = 'YES';
$CONF['footer_text'] = 'Example Webhosting';
$CONF['footer_link'] = '';

Finally, you can change the content of the email that is sent to new users.

$CONF['welcome_text'] = <<<EOM

Welcome to your new account.


You can now complete the setup of PostfixAdmin, creating the database, by visiting the setup page. For example:

At this point you'll be asked to set up a global admin user. Follow the instructions to do so. Remember the details as you'll need them to log in later.

Finally remove the setup.php file to stop others from being able to reset / change your database unexpectedly: rm /var/www/

You can now visit your PostfixAdmin install at the location you set it up. For example:

However, you should not set any domains or mailboxes up yet because Postfix and Dovecot have not been set up yet.


This section deals with configuring the Dovecot mail server.

SQL Configuration

The following configuration is done in /etc/dovecot/dovecot-sql.conf. You can find detailed information on MySQL's SELECT queries in the MySQL manual.

First set the database connection details. The password should be the same password you set when creating the mailauth SQL user above.

driver = mysql
connect = host=/var/run/mysql.sock user=mailauth password=password dbname=postfixadmin

Set the default password scheme. This tells Dovecot what format the passwords in the database are stored in.

default_pass_scheme = MD5

There are 2 different ways to configure Dovecot SQL. In this article you'll configure Dovecot to use a single SQL query instead of 2. However, this article will show you the query needed for 2-query authentication.

The following are in the same order as they are presented in the default configuration file.

First set the password_query use for 2-query authentication. Note that it's commented out by starting the line with a #

#password_query = SELECT username as user, password FROM mailbox WHERE username = '%u' AND active = 1

Next configure the user_query. You may want to double check these (user id's are listed in /etc/passwd and groups are listed in /etc/groups).

The quota parameter passes the PostfixAdmin configured quota to Dovecot.

The home value tells Dovecot where the users home directory is. This will be explained more in depth later.

In Dovecot 1.1, the quota specification has changed and uid/guid are now specified in the configuration file.

user_query = SELECT CONCAT('/var/mail/', maildir) AS home, 8 AS uid, 12 AS gid, CONCAT('maildir:storage=', quota) AS quota FROM mailbox WHERE username = '%u' AND active = 1
# For Dovecot 1.1 use:
#user_query = SELECT CONCAT('/var/mail/', maildir) AS home, CONCAT('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active = 1

Finally configure the query used for single query authentication. This combines the results passed by the above two queries into a single result. Note that in this query you must return userdb fields prefixed with "userdb_".

password_query = SELECT CONCAT('/var/mail/', maildir) AS userdb_home, 8 as userdb_uid, 12 as userdb_gid, username as user, password, CONCAT('maildir:storage=', quota) AS quota FROM mailbox WHERE username = '%u' AND active = 1
# For Dovecot 1.1 use:
#password_query = SELECT CONCAT('/var/mail/', maildir) AS userdb_home, username as user, password, CONCAT('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active = 1

General Configuration

The following configuration is all done in the /etc/dovecot/dovecot.conf file.

The Dovecot configuration file has a number of headers to help seperate the sections. Each of the subheadings here relates to a heading and are in the order they appear in the file.

All settings not mentioned here are left at their default values.

Basic settings

(This heading doesn't exist. All these settings appear before the first heading).

First configure the protocols that you want Dovecot to respond to. This article will simply use the default ports. If you want to use other ports, please consult Dovecot's documentation.

protocols = pop3 imap

By default Dovecot only listens on IPv6 interfaces. Many people are still using IPv4, so you probably want to listen on IPv4 interfaces too. To do so, change the listen line to:

listen = *, [::]

By default Dovecot disables plain text authentication on unencrypted (non-SSL/TLS) connections. It is highly recommended that you investigate setting up SSL/TLS connections, but for the purposes of this setup you can enable plain text authentication by setting:

disable_plaintext_auth = no

Mailbox locations and namespaces

The mail_location parameter tells Dovecot where mailboxes are stored and in what format. Thi article uses the Maildir (Qmail style) format. The location of indexes is also set.

mail_location = maildir:/var/mail/%d/%n/Maildir/:INDEX=/var/mail/%d/%n/indexes

For Dovecot 1.1 users, the mail_uid and mail_gid parameters specify the user and group that are used for mail storage.

mail_uid = mail
mail_gid = mail

Mail processes

The following settings set the user id and group id's that Dovecot is allowed to use for mail processes. This setup only allows the mail user and the mail group to be used. You should double check the id's are correct for your system.

first_valid_uid = 8
last_valid_uid = 8

first_valid_gid = 12
last_valid_gid = 12

IMAP specific settings

Enable the quota and imap_quota plugins by setting the following. This enables the use of quotas and the imap quota support so that clients can report quota usage.

protocol imap {
  mail_plugins = quota imap_quota

POP3 specific settings

Enable quota support for POP3 by setting the following.

protocol pop3 {
  mail_plugins = quota

LDA specific settings

Set the email address used as the From address for error message emails.

protocol lda {
  postmaster_address =

Enable the quota plugin.

  mail_plugins quota

Authentication settings

Set the list of allowed authentication mechanisms. For this setup you want the plain and login mechanisms. The plain mechanism allows clients to send passwords in plain text. While insecure, this method is supported by all clients. The login mechanism provides support for Outlook clients.

auth default {
  mechanisms = plain login

There are 2 "databases" you'll need to set. The database used for password queries (passdb) and the database used for user queries (userdb).

Note that all "userdb" and "passdb" sections other than those mentioned below must be commented out.

  passdb sql {
    args = /etc/dovecot/dovecot-sql.conf

Dovecot can use 2 queries to get the information it needs. If you wanted to do this, you would need to set up the userdb as follows and uncomment it (remove the # at the beginning of each line).

#  userdb sql {
#    args = /etc/dovecot/dovecot-sql.conf
#  }

Instead of using sql, this article will use the prefetch method to avoid an extra query to the database. This method requires no values to be set (because all the information comes from passdb).

  userdb prefetch {

Now set the authentication user to the one created earlier. This allows us to ensure we have a user that does not have access to anything else.

  user = nobody

Specify the sockets you want to allow for authentication mechanisms to use. For this setup you want a master socket for the Dovecot LDA and a client socket for Postfix.

  socket listen {
    master {
      path = /var/run/dovecot/auth-master
      mode = 0600
      user = mail
      group = mail
    client {
        # If you change the postfix queue_directory, you must also change this.
        path = /var/spool/postfix/private/auth
        mode = 0660
        user = postfix
        group = postfix


A small note about Postfix configuration: Postfix specifies (on man 5 postconf that only the last value specified in the /etc/postfix/ is used, so editing it's configuration is as easy as appending the values to the end of the file.

Local Aliases

Postfix needs to know where you want mail sent to local users (eg. mail sent by cron jobs is usually just sent to "root" - Postfix needs to be able to translate this to a "real" address).

Open up /etc/mail/aliases and uncomment and fill out the root and operator lines as in the example below:

File: /etc/mail/aliases
# Basic system aliases -- these MUST be present.
MAILER-DAEMON:      postmaster
postmaster:         root

# General redirections for pseudo accounts.
adm:                root
bin:                root
daemon:             root
exim:               root
lp:                 root
mail:               root
named:              root
nobody:             root
postfix:            root

# Well-known aliases -- these should be filled in!

# Standard RFC2142 aliases
abuse:              postmaster
ftp:                root
hostmaster:         root
news:               usenet
noc:                root
security:           root
usenet:             root
uucp:               root
webmaster:          root
www:                webmaster

# trap decode to catch security attacks
# decode:           /dev/null

Now run newaliases to generate the actual database. You may also want to symlink these files into the Postfix configuration directory to make them easier to find: ln -s /etc/mail/aliases /etc/postfix/; ln -s /etc/mail/aliases.db /etc/postfix/

Dovecot Integration - LDA

This setup uses Dovecot's deliver LDA (Local Delivery Agent).

First we need to tell Postfix about deliver. To do this, add the following line to /etc/postfix/

 dovecot   unix  -       n       n       -       -       pipe
   flags=DRhu user=mail:mail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}

To tell Postfix to actually use deliver, add the following to /etc/postfix/

 dovecot_destination_recipient_limit = 1
 virtual_transport = dovecot

Tip: You won't find dovecot_distination_recipient_limit in the Postfix documentation, instead see the documentation for transport_destination_recipient_limit

Dovecot Integration - Authentication

This setup uses Dovecot's SASL capability for Postfix authentication. Add the following settings to /etc/postfix/ to enable SASL and set it to the dovecot interface we configured earlier:

 smtpd_sasl_auth_enable = yes
 smtpd_sasl_type = dovecot
 smtpd_sasl_path = private/auth

MySQL Maps

The following files contain details that postfix will use to look up various details using the PostfixAdmin MySQL database.

Create each of the following files with the contents below in the /etc/postfix directory.

Most of the details here should be self explanatory. We use the same MySQL user as we did for dovecot since Postfix requires read only access to the same tables. The password is the same one you entered when creating the user.

File: /etc/postfix/
user = mailauth
password = password
hosts = localhost
dbname = postfixadmin
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'

File: /etc/postfix/
user = mailauth
password = password
hosts = localhost
dbname = postfixadmin
query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'

File: /etc/postfix/
user = mailauth
password = password
hosts = localhost
dbname = postfixadmin
query = SELECT CONCAT(maildir, 'Maildir/') AS maildir FROM mailbox WHERE username='%s' AND active = '1'

To tell Postfix about the maps that you've just set up, add the following to the bottom of /etc/postfix/

 virtual_alias_maps = mysql:/etc/postfix/
 virtual_mailbox_domains = mysql:/etc/postfix/
 virtual_mailbox_maps = mysql:/etc/postfix/

Relay (Backup MX) Domains

Warning: This section has been manually converted from old style map files and has not been tested

If you don't want your server to relay mail for other domains, you can skip this section.

Create the MySQL map file:

File: /etc/postfix/
user = mailauth
password = password
hosts = localhost
dbname = postfixadmin
query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '1' AND active = '1'

And then add the following to the bottom of /etc/postfix/

 relay_domains = mysql:/etc/postfix/

Other Settings

The following directory sets the mailbox base directory. This is prepended to all results returned by virtual_mailbox_maps.

virtual_mailbox_base = /var/mail

Add the following to set up the restrictions the Postfix will impose on mails:



smtpd_reject_unlisted_sender = yes


Checking Configuration

You can have Postfix perform a cursory check of your configuration by running postfix check. The only message you should expect to receive is the following one, which is regarding a file installed by portage:

 postfix/postfix-script: warning: not owned by postfix: /var/lib/postfix/./.keep_mail-mta_postfix-0

Setting up Services

Start all of the services with: /etc/init.d/dovecot start; /etc/init.d/postfix start

And add them to the default run level so they start on boot: rc-update add dovecot default; rc-update add postfix default

Setting up Mailboxes

Go to the URL you set up PostfixAdmin at and enter the global admin username and password you created when setting up PostfixAdmin.

This article will show you how to set up a simple domain with a single mailbox and a catch-all alias (ie. will go to the same account).


First you want to set up the domain, so from the drop-down menus along the top of the page, select Domain List and then New Domain.

Fill out the form as follows:

When you're done, click the Add Domain button.

You should now be able to see the domain in the "Domain List" and "Virtual List" screens.

Initial Mailbox

Now that you've created the domain, you want to create atleast one mailbox for it, called "postmaster" (since all domains should have atleast a postmaster mailbox).

Select Virtual List then, from the drop-down menu that appears, Add Mailbox.

To create the "postmaster" mailbox, fill out the form as follows:

When you're finished, click the Add Mailbox button.

Catch-all Alias

Now you have a domain with a mailbox, create an alias for it. In this case the alias will be a "catch all" alias the causes any email sent to an address for which there is not another alias or mailbox to be sent to the address specified in the catch all alias.

Select Virtual List then, from the drop-down menu that appears, Add Alias.

Fill out the form as follows:

Click the Add Alias button to add the alias.

Congratulations. Your new mail server now has a single domain with a single catch-all mailbox.


Now that you've set up your server with a mailbox, you'll want to test that everything works as expected.

Set up and fetch the mail for the mailbox. Using the example values above, the details you need to enter into your client are as follows:

First set up the account as an IMAP account. When you collect the mail, you should receive the "Welcome" message sent when you created the mailbox with PostfixAdmin.

Next, set up the account as a POP3 account. When you collect the mail, you should receive the "Welcome" message sent when you created the mailbox with PostfixAdmin.

Using an account hosted on another server (for example, a webmail account), send an email to your new mailbox (eg. Wait a couple of minutes and collect mail for the account. You should receive the email you just sent yourself.

Using the account on your new server, send an email to your webmail account and send a cc to an address other than postmaster at your new server (eg. Wait a couple of minutes and collect email on both accounts. You should received the email you sent yourself on both accounts.

If all these tests passed, then your server is working as expected. If any of these tests fail, then check the mail logs on your server and any bounce messages you receive for information on what went wrong.


Postfix Process Logging

You can increase the amount of logging that postfix processes do by adding "-v" or "-v -v" (for more verbosity) to the last parameter of the appropriate line in /etc/postfix/

See also

Retrieved from ""

Last modified: Tue, 19 Aug 2008 06:44:00 +0000 Hits: 3,458