History / Status



First things first. If you are a novice at linux I recommend that you should get help with setting this up. This is an advanced email server configuration. This configuration will allow you to serve multiple domains on one server. You will get the following features:

  • Postfix: the workhorse behind the mail delivery
  • smtp authentication
  • secure smtp using TLS
  • Dovecot: imap and pop3 mailbox service
  • secure imap and pop3
  • mysql: haldle all the virtual domains and users
  • PostfixAdmin: GUI for domain administration
  • squirrelmail: web mail access

Lets get started

Books You May Find Helpful

The following books may be helpful for some people.

The Accidental Administrator: Linux Server Step-by-Step Configuration Guide
Learning the bash Shell: Unix Shell Programming (In a Nutshell (O'Reilly))

Installing CentOS

Start with my HOWTO: CentOS 5.x base server. That howto will get CentOS installed and ready for this howto. Please note, if you don't follow that howto then you won't get the correct version of postfix. I have Postfix with mysql support in my repo.

Installing The Software

We'll start with the yum installs.
> yum -y install dovecot squirrelmail cyrus-sasl-devel cyrus-sasl-sql subversion

Postfix.Admin doesn't have an rpm so we need to download it and put it where we want it. Wouldn't you know it but the 2.1.0 release has problems with mysql 5. So we need to download the verson from svn.
> svn co https://postfixadmin.svn.sourceforge.net/svnroot/postfixadmin/trunk postfixadmin
> mv postfixadmin /usr/share/

Configuring The Server

Configuring Postfix Admin

Create the apache config file for postfixadmin and restart apache.

alias /mailadmin /usr/share/postfixadmin
<Directory "/usr/share/postfixadmin">
  AllowOverride AuthConfig

> service httpd restart

Now we need to setup the mysql database for mysqladmin. We only need to create the database and user. The setup file will create the rest.
> mysql -u root -p -e "CREATE DATABASE postfix;"
> mysql -u root -p -e "CREATE USER postfix@localhost IDENTIFIED BY 'choose_a_password';"
> mysql -u root -p -e "GRANT ALL PRIVILEGES ON postfix . * TO postfix@localhost;"

Now its time to setup the config file. Don't forget to set your password. Find the following items and change them.
> cd /usr/share/postfixadmin
> nano -w config.inc.php

// Postfix Admin Path
// Set the location to your Postfix Admin installation here.
$CONF['postfix_admin_url'] = '/mailadmin/';

// Database Config
// mysql = MySQL 3.23 and 4.0
// mysqli = MySQL 4.1
// pgsql = PostgreSQL
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfixadmin';
$CONF['database_password'] = 'postfixadmin';
$CONF['database_name'] = 'postfix';
$CONF['database_prefix'] = '';

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

Next we need to run the setup.php script in a web browser. Enter the url in your browser. Ex.

If everything shows OK then create the admin user using the form displayed. When done delete the setup.php file.
> rm /usr/share/postfixadmin/setup.php

Log into the web interface and follow the directions.

NOTE: Don't forget to remove /usr/lib/postfixadmin/setup.php. Postfixadmin will complain until you do.

Configuring Postfix

Here we go with more config files. You'll have to be sure to change some settings to match your host. The config files will have sections commented out. Don't worry about it. These sections are for spam/virus/sympa configuration. Just copy and past to create the config files. What ever you see here replaces what already exists.

The main postfix config files.

# postfix config file

# uncomment for debugging if needed

# postfix main
mail_owner = postfix
setgid_group = postdrop
delay_warning_time = 4

# postfix paths
html_directory = no
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
queue_directory = /var/spool/postfix
sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
manpage_directory = /usr/share/man
sample_directory = /usr/share/doc/postfix-2.2.2/samples
readme_directory = /usr/share/doc/postfix-2.2.2/README_FILES

# network settings
inet_interfaces = all
mydomain = yourdomain.com
myhostname = host.yourdomain.com
mynetworks =,,
mydestination = $myhostname, 
relay_domains = $mydestination

# mail delivery
recipient_delimiter = + 

# mappings
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
#local_recipient_maps = 

# virtual setup
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual_alias_maps.cf,
virtual_gid_maps = static:89
virtual_mailbox_base = /home/vmail
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual_mailbox_maps.cf
virtual_minimum_uid = 89
virtual_transport = virtual
virtual_uid_maps = static:89

# debugging
debug_peer_level = 2
debugger_command =
         xxgdb $daemon_directory/$process_name $process_id & sleep 5

# authentication
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
broken_sasl_auth_clients = yes

# tls config
smtp_use_tls = yes
smtpd_use_tls = yes 
smtp_tls_note_starttls_offer = yes 
smtpd_tls_key_file = /etc/postfix/ssl/smtpd.pem
smtpd_tls_cert_file = /etc/postfix/ssl/smtpd.pem
smtpd_tls_CAfile = /etc/postfix/ssl/smtpd.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom

# rules restrictions 
# smtpd_client_restrictions = reject_rbl_client zen.spamhaus.org
smtpd_helo_restrictions = permit_sasl_authenticated,
smtpd_sender_restrictions = reject_non_fqdn_sender, 
smtpd_recipient_restrictions = permit_sasl_authenticated, 
smtpd_helo_required = yes
unknown_local_recipient_reject_code = 550
disable_vrfy_command = yes
smtpd_data_restrictions = reject_unauth_pipelining


# Postfix master process configuration file.  For details on the format
# of the file, see the Postfix master(5) manual page.
# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
smtp      inet  n       -       n       -       -       smtpd
#  -o content_filter=smtp-amavis:
#  -o receive_override_options=no_address_mappings
#submission inet n      -       n       -       -       smtpd
#       -o smtpd_etrn_restrictions=reject
#       -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#smtps    inet  n       -       n       -       -       smtpd
#  -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes
#submission   inet    n       -       n       -       -       smtpd
#  -o smtpd_etrn_restrictions=reject
#  -o smtpd_enforce_tls=yes -o smtpd_sasl_auth_enable=yes
#628      inet  n       -       n       -       -       qmqpd
pickup    fifo  n       -       n       60      1       pickup
  -o content_filter= 
  -o receive_override_options=no_header_body_checks
cleanup   unix  n       -       n       -       0       cleanup
qmgr      fifo  n       -       n       300     1       qmgr
#qmgr     fifo  n       -       n       300     1       oqmgr
tlsmgr    unix  -       -       n       1000?   1       tlsmgr
rewrite   unix  -       -       n       -       -       trivial-rewrite
bounce    unix  -       -       n       -       0       bounce
defer     unix  -       -       n       -       0       bounce
trace     unix  -       -       n       -       0       bounce
verify    unix  -       -       n       -       1       verify
flush     unix  n       -       n       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
smtp      unix  -       -       n       -       -       smtp
# When relaying mail as backup MX, disable fallback_relay to avoid MX loops
relay     unix  -       -       n       -       -       smtp
        -o fallback_relay=
#       -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq     unix  n       -       n       -       -       showq
error     unix  -       -       n       -       -       error
discard   unix  -       -       n       -       -       discard
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       n       -       -       lmtp
anvil     unix  -       -       n       -       1       anvil
scache    unix  -       -       n       -       1       scache
# ====================================================================
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.
# Many of the following services use the Postfix pipe(8) delivery
# agent.  See the pipe(8) man page for information about ${recipient}
# and other message envelope options.
# ====================================================================
# maildrop. See the Postfix MAILDROP_README file for details.
# Also specify in main.cf: maildrop_destination_recipient_limit=1
maildrop  unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient}
# The Cyrus deliver program has changed incompatibly, multiple times.
old-cyrus unix  -       n       n       -       -       pipe
  flags=R user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -m ${extension} ${user}
# Cyrus 2.1.5 (Amos Gouaux)
# Also specify in main.cf: cyrus_destination_recipient_limit=1
cyrus     unix  -       n       n       -       -       pipe
  user=cyrus argv=/usr/lib/cyrus-imapd/deliver -r ${sender} -m ${extension} ${user}
# See the Postfix UUCP_README file for configuration details.
uucp      unix  -       n       n       -       -       pipe
  flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
# Other external delivery methods.
ifmail    unix  -       n       n       -       -       pipe
  flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp     unix  -       n       n       -       -       pipe
  flags=Fq. user=foo argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient
# spam/virus section
#smtp-amavis  unix  -    -       y       -       2       smtp
#  -o smtp_data_done_timeout=1200
#  -o disable_dns_lookups=yes
#  -o smtp_send_xforward_command=yes
# inet n  -       y       -       -       smtpd
#  -o content_filter=
#  -o smtpd_helo_restrictions=
#  -o smtpd_sender_restrictions=
#  -o smtpd_recipient_restrictions=permit_mynetworks,reject
#  -o mynetworks=
#  -o smtpd_error_sleep_time=0
#  -o smtpd_soft_error_limit=1001
#  -o smtpd_hard_error_limit=1000
#  -o receive_override_options=no_header_body_checks
#  -o smtpd_bind_address=
#  -o smtpd_helo_required=no
#  -o smtpd_client_restrictions=
#  -o smtpd_restriction_classes=
#  -o disable_vrfy_command=no
#  -o strict_rfc821_envelopes=yes

The postfix / mysql config files.

hosts = localhost
user = postfix
password = postfix
dbname = postfix
table = alias
select_field = goto
where_field = address


hosts = localhost
user = postfix
password = postfix
dbname = postfix
table = domain
select_field = domain
where_field = domain
additional_conditions = and backupmx = '0' and active = '1'


hosts = localhost
user = postfix
password = postfix
dbname = postfix
table = mailbox
select_field = maildir
where_field = username

Now for the sasl auth configuration.

pwcheck_method: auxprop
mech_list: PLAIN LOGIN
auxprop_plugin: sql
sql_verbose: yes
sql_engine: mysql
sql_hostnames: localhost
sql_user: postfix
sql_passwd: postfix
sql_database: postfix
sql_select: select password from mailbox where username = '%u@%r'

Now generate an SSL certificate for postfix to have TLS support.
> mkdir /etc/postfix/ssl
> cd /etc/postfix/ssl
> openssl req -new -x509 -nodes -out smtpd.pem -keyout smtpd.pem -days 3650

We need to touch a file. So type the follwoing.
> touch /etc/postfix/virtual_regexp

Finally we'll configure the mail store directory. We put it in the /home directory to make backups and other item easy. So type the following.
> mkdir /home/vmail
> chmod 770 /home/vmail
> chown postfix:postfix /home/vmail

Configuring Dovecot

Lets start off with the main config file. Just replace the default one with whats below.

# Dovecot config file
auth default {
  userdb sql {
    args = /etc/dovecot-mysql.conf
  passdb sql {
    args = /etc/dovecot-mysql.conf
first_valid_uid = 89
default_mail_env = maildir:/home/vmail/%d/%n
protocols =  imaps imap pop3s pop3
ssl_cert_file = /etc/postfix/ssl/smtpd.pem
ssl_key_file = /etc/postfix/ssl/smtpd.pem

Next we configure Dovecot to access mysql. Create the following file.

driver = mysql
connect = host=localhost dbname=postfix user=postfix password=yourpassword
default_pass_scheme = PLAIN
password_query = SELECT password FROM mailbox WHERE username = '%u'
user_query = SELECT maildir, 89 AS uid, 89 AS gid FROM mailbox WHERE username = '%u'

Finally set Dovecot to boot at startup.

Configuring SquirrelMail

We should next give our users a web interface to their mail. This is an optional install.

Lets start configurating SquirrelMail. Luckilly squirrelMail has a configuration utility. So type: > /usr/share/squirrelmail/config/conf.pl

Here's the settings to be changed

  • Under server settings change sendmail to SMTP
  • Under update IMAP settings change the software to dovecot.
  • Other config changes are optional.

Now go to your browser and test squirrelmail. the url is http://yourdomein.com/webmail/src/configtest.php

You should now be able to login to your mailserver. The usr would be 'host.domain.com/webmail'. Remember your username is in the format: user@domain.com

Configuring the Little Things That Drive You MAD

Be sure your /etc/hosts looks similar to the following.

# Do not remove the following line, or various programs
# that require network functionality will fail.       localhost   host.domain.com

Preparing and Testing the Postoffice

First things first. Reboot the system. If everything went well we all should be at the same point.

No errors? Lets keep going.

Setup a test domain and account. Setup your favorit mail client and send some test emails.

Notes About Security And Clear Text Passwords

My howto has been written to use clear text passwords. This can and does cause security problems. There are 2 issues at hand: Database security and sending of clear text passwords through the internet.

Lets start with database security. With my configuration passwords are stored in clear text in the database. As long as the database is kept secure passwords in the clear won't cause a problem. If you want the passwords encrypted then all the software must be configured for it.

Now for the problem of clear text passwords over the internet. If you use SSL/TLS then the passwords are encrypted in the SSL connection. POPS, IMAPS and SMTPS all use SSL/TLS connection. So as long as your client supports secure connections to the mail server your clear text passwords will be secure.


With a bit of work you come out with a robust server.


Add Comment 
Sign as Author 
Enter code 575

Eesnaslp?07 February 2014, 03:56

It's quite a few rows of information products., <a href="http://www.mymoag.com">garcinia cambogia extract side effects</a>, rcrgu,

Steve?22 April 2013, 21:03

Wow this page is a lifesaver. All the other guides about how to set up a mail system bombard you with 10 different options (which all do the same thing) for each step. Choose 1 wrong option and nothing works. This guide just says "Hey... Set it up this way and it will work." Many settings have changed since this was written but most are obvious, just checking maillog after trying to connect can tell you what's wrong in most cases. The biggest problems are with Dovecot. First of all you need to yum install dovecot-mysql in addition to dovecot, because mysql support has been separated out. Also, the dovecot.conf syntax has totally changed and should now look like this:

  1. Dovecot config file

userdb {

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

first_valid_uid = 89 protocols = imap pop3 ssl_cert = </etc/postfix/ssl/smtpd.pem ssl_key = </etc/postfix/ssl/smtpd.pem mail_location = maildir:/home/vmail/%n@%d mail_uid = postfix

and in /etc/dovecot-mysql.conf I had to change default_pass_scheme from PLAIN to CRYPT because my installation was hashing the passwords, that must be the default in the current version.

Hope that helps. By the way, I used this on an Amazon EC2 instance with the Amazon Linux AMI 2013-03.

kirik?31 March 2013, 09:32

where is the SQL SYNTAX to create tables inside "postfix" Database???

rcamp?01 May 2012, 14:40

PLEASE NOTE: Doesn't work with centos 6. I will post a new howto soon. Lots of changes including quota support and roundcubemail.

Nate?10 February 2012, 14:20

Forgot to mention another small error I had hit with dovecot when following this guide.

If when starting dovecot service you get: >service dovecot start Starting Dovecot Imap: If you have trouble with authentication failures, enable auth_debug setting. See http://wiki.dovecot.org/WhyDoesItNotWork This message goes away after the first successful login. Error: socket() failed: Address family not supported by protocol Fatal: listen(::, 993) failed: Address family not supported by protocol [FAILED]

You need to add 'listen = *' in your dovecot.conf file. That should fix that issue.

Nate?10 February 2012, 14:16

I saw this issue listed in a previous comment a while back, but no solution ever posted. If you are getting permission denied on the smtpd.pem file when starting dovecot, check if SELinux is still running. I was receiving the following error: > service dovecot start Starting Dovecot Imap: Error: ssl_cert_file: Can't use /etc/postfix/ssl/smtpd.pem: Permission denied Fatal: Invalid configuration in /etc/dovecot.conf


Check selinux with command 'sestatus'. If current mode says enforcing, try command "setenforce 0" and then try start dovecot. If it does, you need to update selinux policy (don't ask me!) or make sure selinux is disabled (my solution). To disable SELinux after a reboot make sure to edit /etc/selinux/config and change ENFORCING to DISABLED. My mistake was I set the conf file to disable SELinux and assumed it was off when it was still active since I hadn't rebooted. I usually do at during my server builds to update the kernel, but this particular build I couldn't. 'setenforce 0' fixed the issue to change the current selinux mode.

Another small error with the guide. 'default_mail_env' in dovecot.conf is now 'mail_location' in later versions Not sure which version, but mine threw an error at that one.

Thanks for the great guide!

Armand Groenewald?17 February 2011, 06:34

This has been the best mail how to that i have seen! thank you! in three months... i could not get anything right... and now all is fine

also remember to yum install mysql-server php-imap php-mysql

/etc/ini.d/httpd restart

and for postfix yum install --enablerepo=centosplus --disablerepo=base postfix


Armand Groenewald?17 February 2011, 06:34

This has been the best mail how to that i have seen! thank you! in three months... i could not get anything right... and now all is fine

also remember to yum install mysql-server php-imap php-mysql

/etc/ini.d/httpd restart

and for postfix yum install --enablerepo=centosplus --disablerepo=base postfix


rcamp?29 October 2010, 11:36

Postfix admin 2.3 has had some config changes. Please read the postfixadmin docs for config file setup. I'll update the howto after doing a clean run and incorporating everyone's comments.

Bob?25 October 2010, 07:08

the virtual_regexp file is empty so I'm thinking that is why it's not puting mail in my box... So what is supposed to be in there?

Glidic Anthony?27 April 2010, 12:18

Sorry it's my bad... Do you know how to add quota by user?

Glidic Anthony?20 April 2010, 11:27

this a great tutorial but i think they have a problem. When i send a mail to test@pornshop.ca postfix create a mailbox /home/vmail/test@pornshop.ca or dovecot search the mail in /home/vmail/pornshop.ca/test

jarrod?26 February 2010, 15:56

All around, this is a great tutorial. As another commenter pointed out, though, you must pay careful attention to the Postfix and Dovecot config files. I got tripped up because I did not assign the correct uid and gid (in main.cf, dovecot.conf, and dovecot-mysql.conf), as well as several permissions issues on random files and directories. System: CentOS 5.4, Postfix 2.4, Webmin 1.5, Squirrelmail 1.4.8, MySQL 5.1.43, Dovecot 1.0.7. For the record, though, this is my first server setup ever, as well as my first mail server, so I can attest to the fact that this will work for a beginner (with substantial effort). Now I have to work the kinks out of the dovecot configuration...

jajajajajajajaja spic?22 February 2010, 12:52

wtf is a domein

chris Mottershead?03 January 2010, 17:00

i have followed the above and it seems to be accepting email for the domains i setup but when i log in as a user there is no email there despite me sending email from my gmail account, i dont get non delivery reports either. please help

justo?09 December 2009, 12:20

good work men.

London?12 November 2009, 16:24


Tom?07 November 2009, 11:47

Is it possible to supply some details as to how to configure the software to use encrypted passwords in the database?


London?05 November 2009, 18:39

ohno this howto very easy

sns?13 October 2009, 12:21

For postfix with mysql try this

yum --enablerepo=centosplus upgrade/install postfix*

failed what help ?13 October 2009, 09:40

Starting Dovecot Imap: Error: Can't use SSL certificate /etc/postfix/ssl/smtpd.pem: Permission denied

13 October 2009, 01:50
 /etc/init.d/dovecot restart

Stopping Dovecot Imap: [FAILED] Starting Dovecot Imap: Error: Can't use SSL certificate /etc/postfix/ssl/smtpd.pem: Permission denied Fatal: Invalid configuration in /etc/dovecot.conf


arnat ?11 August 2009, 18:11

Thank You for this Howto Thank You very much

arnat ?28 July 2009, 05:08

maillog error

 warning: process /usr/libexec/postfix/cleanup pid 9568 exit status 1

warning: /usr/libexec/postfix/cleanup: bad command startup -- throttling

help me please

Gabriel?22 May 2009, 23:42

By the way, Postfix from CentOS 5 repo doesn't come with MySQL support. You need to enable the CentOS Plus repository to install it with MySQL support.

You may refer to the INSTALLATION NOTES from <a href="http://www.chrisgountanis.com/technical/34-technical/59-isp-style-virtual-mail-system.html">here</a>.

randell?26 February 2009, 21:06

Thank You for this Howto.. :)

rcamp?25 February 2009, 08:33

howto has been updated

marcogomez?24 February 2009, 02:35

Sorry, the last comment was for readers of the article, not the author. i think the author is very knowledgeable :)

marcogomez?22 February 2009, 00:52

Overall , many many thanx for this article.

Last comment - pay attention to the settings in postfixadmin.

marcogomez?21 February 2009, 02:34

Another error;

smtpd_client_restrictions = reject_rbl_client zen.spamhaus.org

and not sb1.spamhaus.org

postfix throws up error message "SPAMHAUS BLOCKLIST ADDRESS IS WRONG MUST FIX"

marcogomez?20 February 2009, 19:31

Is there a mistake with the the virtual_regexp entry in main.cf?

Maillog shows this error?

Feb 21 10:37:45 fwgw postfix/cleanup[1739]: fatal: open /etc/postfix/virtual_regexp: No such file or directory Feb 21 10:37:46 fwgw postfix/master[28641]: warning: process /usr/libexec/postfix/cleanup pid 1739 exit status 1 Feb 21 10:37:46 fwgw postfix/master[28641]: warning: /usr/libexec/postfix/cleanup: bad command startup -- throttling

rcamp?20 January 2009, 15:53

Start with my base server howto. Postfix gets installed there. I compiled it with mysql support and added it to my repo

Joe?20 January 2009, 14:34

Where is the installation of postfix? The one part of this tutorial that I needed was getting postfix-mysql installed on CentOS 5, and you don't have anythign about it at all.

nobody?22 December 2008, 01:45

Too bad didn't work for me

nobody?21 December 2008, 03:06

Wow! This is exactly what I'm looking for almost a week. Thanks a lot! I'll try this at once.

Custom Search