Categories Tutorials

Mailserver with virtual users and domains using Postfix and Dovecot on a CentOS 6 VPS

The following article will show you how to install and run simple POP3/IMAP/SMTP mail server in your CentOS VPS using virtual users and domains with Postfix and Dovecot

What is Postfix? It is a drop in replacement for the old and mature Sendmail. Postfix also attempts to be very fast, easy to administer, and secure.

What is Dovecot? It is an open source IMAP and POP3 server for *NIX-like systems, written primarily with security in mind.


You may want to check if your hostname/domainname is a valid FQDN (fully qualified domain name) and it has a valid MX DNS record.

## if ! type -path "dig" > /dev/null 2>&1; then yum install bind-utils -y; fi
## DOMAIN=mydomain.com
## NSHOSTS=( "$(dig @ +short MX ${DOMAIN}|sort -n|cut -d' ' -f2)" )
## for NS in ${NSHOSTS[@]}; do printf "%-15s => %-s\n" "$(dig @ +short A ${NS})" "${NS}"; done


## screen -U -S mailserver-screen
## yum update


create group used for virtual mailboxes

## groupadd vmail -g 2222

create user used for virtual mailboxes

## useradd vmail -r -g 2222 -u 2222 -d /var/vmail -m -c "mail user"


## yum remove exim sendmail
## yum install postfix cronie

edit postfix main.cf configuration file

## cp /etc/postfix/main.cf{,.orig}
## vim /etc/postfix/main.cf
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
mail_owner = postfix
unknown_local_recipient_reject_code = 550
alias_maps = hash:/etc/postfix/aliases
alias_database = $alias_maps

inet_interfaces = all
inet_protocols = ipv4
mydestination = $myhostname, localhost.$mydomain, localhost

debug_peer_level = 2
debugger_command =
         ddd $daemon_directory/$process_name $process_id & sleep 5

sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /usr/share/doc/postfix-2.6.6/samples
readme_directory = /usr/share/doc/postfix-2.6.6/README_FILES

relay_domains = *

virtual_mailbox_base = /var/vmail
virtual_minimum_uid = 2222
virtual_transport = virtual
virtual_uid_maps = static:2222
virtual_gid_maps = static:2222

smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = /var/run/dovecot/auth-client
smtpd_sasl_security_options = noanonymous
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
smtpd_sasl_local_domain = $mydomain
broken_sasl_auth_clients = yes

smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

create vmail_domains configuration file. this is where you add your virtual domains.

## vim /etc/postfix/vmail_domains
mydomain.com            OK
my-otherdomain.com      OK

create vmail_mailbox configuration file. this is where you define your mailboxes.

## vim /etc/postfix/vmail_mailbox
info@mydomain.com           mydomain.com/info/
info@my-otherdomain.com     my-otherdomain.com/info/

create vmail_aliases configuration file. this is where you define your virtual aliases.

## vim /etc/postfix/vmail_aliases
info@mydomain.com           info@mydomain.com
info@my-otherdomain.com     foo@bar.tld

hash the configuration files

## postmap /etc/postfix/vmail_domains
## postmap /etc/postfix/vmail_mailbox
## postmap /etc/postfix/vmail_aliases
## touch /etc/postfix/aliases
## vim +/submission /etc/postfix/master.cf
submission inet n       -       n       -       -       smtpd


## yum install dovecot

edit dovecot dovecot.conf configuration file

## cp /etc/dovecot/dovecot.conf{,.orig}
## vim /etc/dovecot/dovecot.conf
listen = *
ssl = no
protocols = imap lmtp
disable_plaintext_auth = no
auth_mechanisms = plain login
mail_access_groups = vmail
default_login_user = vmail
first_valid_uid = 2222
first_valid_gid = 2222
#mail_location = maildir:~/Maildir
mail_location = maildir:/var/vmail/%d/%n

passdb {
    driver = passwd-file
    args = scheme=SHA1 /etc/dovecot/passwd
userdb {
    driver = static
    args = uid=2222 gid=2222 home=/var/vmail/%d/%n allow_all_users=yes
service auth {
    unix_listener auth-client {
        group = postfix
        mode = 0660
        user = postfix
    user = root
service imap-login {
  process_min_avail = 1
  user = vmail

create virtual user’s configuration file passwd. this is where usernames and password hashes will be stored.

## touch /etc/dovecot/passwd
## doveadm pw -s sha1 | cut -d '}' -f2

## vim /etc/dovecot/passwd
## chown root: /etc/dovecot/passwd
## chmod 600 /etc/dovecot/passwd


## chkconfig postfix on
## chkconfig dovecot on
## service postfix restart
## service dovecot restart


Open your favorite e-mail client and configure it to use the newly created info@mydomain.com account. Try to send/receive an email. If you experience any issues, check if there’s something logged in /var/log/maillog

you can also use swaks to test your smtp server, for example:

swaks --to support@mydomain.com --from email@address.net

more information about swaks you can find at man swaks


set-up account’s mailbox

## vim /etc/postfix/vmail_mailbox
support@mydomain.com           mydomain.com/support/

set-up account’s alias(es)

## vim /etc/postfix/vmail_aliases
support@mydomain.com           support@mydomain.com

postmap configuration files and restart postfix

## postmap /etc/postfix/vmail_mailbox
## postmap /etc/postfix/vmail_aliases
## service postfix restart

generate password hash and add username:password-hash to passwd file.

## doveadm pw -s sha1 | cut -d '}' -f2
## vim /etc/dovecot/passwd

This is a simple, but yet very robust mail server set-up on a CentOS 6 VPS which supports SMTP and IMAP without SSL, webmail, anti-spam, anti-virus, filter rules, opendkim etc. However, in the next few related articles, we will be adding additional features to the set-up to make it even yet more powerful, so stay tuned.

Of course, if you are one of our Linux VPS Hosting customers, you don’t have to do any of this, simply ask our admins, sit back and relax. Our admins will set this up for you immediately.

PS. If you liked this post please share it with your friends on the social networks using the buttons on the left or simply leave a reply below. Thanks.


View Comments

  • I am also having trouble with receiving mail. It doesn't seem like nobody ever gets a working solution cause they don't know how to reply. Anyways, if I could get some help that'd be great. Currently my mail_location is set to: 'mail_location = maildir:/var/vmail/%d%n' When I send test emails from gmail to server email, it doesn't return with any error at all. This here is out of the /var/log/maillog: Oct 13 12:45:44 localhost postfix/smtpd[981]: initializing the server-side TLS engine Oct 13 12:45:44 localhost postfix/smtpd[981]: connect from unknown[unknown] Oct 13 12:45:44 localhost postfix/smtpd[981]: lost connection after CONNECT from unknown[unknown] Oct 13 12:45:44 localhost postfix/smtpd[981]: disconnect from unknown[unknown] There is nothing out of the ordinary in the entire log, as I just cleared it to, so I can be more precise to see how the logs are performing upon me sending an email from gmail. Currently in cloudflare, here is what I got setup: http://i.imgur.com/HDrvJbd.png I have followed all 6 tutorials on the web mail setup exactly. Please if you could, inform me on what I can do to resolve this issue. Added: So I got a relay message back from Google now, this is what it displays: http://puu.sh/cbsm1/d5e22b04fd.png

  • Thanks for your great tutorial. Best one I've seen so far. I've set up everything and seems to be working fine. I want to retrieve my mails using gmail pop3 but I get a connection refused error on gmail. I assume because pop3 isn't added on the dovecoat protocols. When I add it and try again I get a 'authentication failed' on gmail. Any idea what am doing wrong?

  • Jan 31 15:44:34 xxxxxx postfix/qmgr[24552]: E7E343A479: from=, size=3100, nrcpt=2 (queue active) Jan 31 15:44:34 xxxxxxx postfix/local[24706]: E7E343A479: to=, relay=local, delay=0.63, delays=0.57/0.03/0/0.03, dsn=2.0.0, status=sent (delivered to mailbox) Jan 31 15:44:34 xxxxxxx postfix/local[24707]: E7E343A479: to=, relay=local, delay=0.7, delays=0.57/0.05/0/0.07, dsn=2.0.0, status=sent (delivered to mailbox) mail is delivering. but not fetching new mails via thunderbird

    • Re-check your Dovecot and Postfix configuration and the location of your emails. Check your ‘mail_location’ and check if the email is stored there. Thanks.

  • sir plz help me to fetch email via thunderbird. postfix shows that mail delivered to mailbox. postconf -n and dovecot.conf are pasted below. i can't findout anything wrong... postconf -n alias_database = $alias_maps alias_maps = hash:/etc/postfix/aliases broken_sasl_auth_clients = yes command_directory = /usr/sbin config_directory = /etc/postfix daemon_directory = /usr/libexec/postfix data_directory = /var/lib/postfix debug_peer_level = 2 html_directory = no inet_interfaces = all inet_protocols = ipv4 mail_owner = postfix mailq_path = /usr/bin/mailq.postfix manpage_directory = /usr/share/man mydestination = $myhostname, localhost.$mydomain, localhost newaliases_path = /usr/bin/newaliases.postfix queue_directory = /var/spool/postfix readme_directory = /usr/share/doc/postfix-2.6.6/README_FILES relay_domains = * sample_directory = /usr/share/doc/postfix-2.6.6/samples sendmail_path = /usr/sbin/sendmail.postfix setgid_group = postdrop smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination smtpd_sasl_auth_enable = yes smtpd_sasl_local_domain = $mydomain smtpd_sasl_path = /var/run/dovecot/auth-client smtpd_sasl_security_options = noanonymous smtpd_sasl_tls_security_options = $smtpd_sasl_security_options smtpd_sasl_type = dovecot smtpd_tls_cert_file = /etc/pki/tls/certs/plusmail.in.crt smtpd_tls_key_file = /etc/pki/tls/private/plusmail.in.key smtpd_tls_loglevel = 3 smtpd_tls_received_header = yes smtpd_tls_session_cache_timeout = 3600s smtpd_use_tls = yes tls_random_source = dev:/dev/urandom unknown_local_recipient_reject_code = 550 virtual_alias_maps = hash:/etc/postfix/gmail_aliases virtual_gid_maps = static:2222 virtual_mailbox_base = /var/gmail virtual_mailbox_domains = hash:/etc/postfix/gmail_domains virtual_mailbox_maps = hash:/etc/postfix/gmail_mailbox virtual_minimum_uid = 2222 virtual_transport = virtual virtual_uid_maps = static:2222 dovecot conf listen = * ssl = yes ssl_cert = </etc/pki/tls/certs/plusmail.in.crt ssl_key = </etc/pki/tls/private/plusmail.in.key protocols = imap lmtp pop3 disable_plaintext_auth = no auth_mechanisms = plain login mail_access_groups = gmail default_login_user = gmail first_valid_uid = 2222 first_valid_gid = 2222 #mail_location = maildir:~/Maildir mail_location = maildir:/var/gmail/%d/%n #mail_location=mbox:/mail:INBOX=/var/gmail/%d/%n passdb { driver = passwd-file args = scheme=SHA1 /etc/dovecot/passwd } userdb { driver = static args = uid=2222 gid=2222 home=/var/gmail/%d/%n allow_all_users=yes } service auth { unix_listener auth-client { group = postfix mode = 0660 user = postfix } user = root } service imap-login { process_min_avail = 1 user = gmail }

  • Great tutorial. Probably the best anyone can find for setting up email server on the web. Small error on your part. You have left out `vim /etc/postfix/vmail_domains` and `postmap /etc/postfix/vmail_domains` command for the section "Add another account" and this is what is causing many people commenting about various issues, and you keep saying they should check their setting .. Please include that to avoid further confusion. Once again, best guide ever.

    • Thank you for your kind words Simon. We left out the lines you mentioned because we assume that the user following this article has already configured the virtual domains that he needs in the /etc/postfix/vmail_domains file. Of course it goes without saying that a new virtual domain needs to be added along with the email account and alias before postmapping the configuration files.

  • on a bare install of CentOS 7, I struggled for hours with this: Nov 20 01:59:36 post dovecot: imap(xxxx@xxxx.com): Error: user xxxx@xxxx.com: Initialization failed: Initializing mail storage from mail_location setting failed: mkdir(/var/vmail/xxxx.com/xxxx) failed: Permission denied (euid=2222(vmail) egid=2222(vmail) missing +w perm: /var/vmail, euid is not dir owner) The permissions were in fact correct, the users and groups created correctly. I thought to myself, what could happen with permissions here that I don't understand (I've been at this *nix game a while. ) Turns out, I had to disable SElinux. Hope this helps someone. Thanks for the great tutorials!

    • I prefer to leave selinux enabled. To fix this problem I did: ## chcon -R system_u:object_r:mail_spool_t:s0 /var/vmail

    • This tutorial is very very good!!! help me a lot. I successfully run the service on Centos 6.5, but when I move on to Centos 6.7 I got the permission denied problem. @Mack Allison, Thanks your for big help by pointing out the solution of SELinux. Disabled SELinux or set it to permissive mode both can fix the problem. Thanks to both of you!

  • Great information there, I just had a small issue that mentioned above in the commends, The mail_location must be same in configs. I had to change mail_location = maildir:/var/vmail/%d/%n in file /etc/dovecot/conf.d/10-mail.conf to be able to read messages via thunderbird or any other client.

  • Excellent! Thank you so much - I have tried a number of similar articles and blogs trying to get virtual users and domains setup properly between postfix and dovecot, and yours is the one that filled in the gaps, and at the same time is the simplest! BTW, works fine on CentOS 7 too, except change the chkconfig and service commands to systemctl, but fine apart from that.