X
    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.

PRE-REQ

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 @4.2.2.2 +short MX ${DOMAIN}|sort -n|cut -d' ' -f2)" )
## for NS in ${NSHOSTS[@]}; do printf "%-15s => %-s\n" "$(dig @4.2.2.2 +short A ${NS})" "${NS}"; done
## unset DOMAIN NSHOSTS

UPDATE THE SYSTEM

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

SET-UP SYSTEM USER

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"

INSTALL POSTFIX

## 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 =
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
         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_alias_maps=hash:/etc/postfix/vmail_aliases
virtual_mailbox_domains=hash:/etc/postfix/vmail_domains
virtual_mailbox_maps=hash:/etc/postfix/vmail_mailbox

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

INSTALL DOVECOT

## 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
info@mydomain.com:DOzcsKI8HY0bg8LAuz0DPKwS3WA=
## chown root: /etc/dovecot/passwd
## chmod 600 /etc/dovecot/passwd

START SERVICES

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

TEST THE SET-UP

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

ADD ANOTHER ACCOUNT

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
...
support@mydomain.com:DOzcsKI8HY0bg8LAuz0DPKwS3WA=

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.

admin:

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.