Postfix, Dovecot and roundcube – Part 01

postfix dovecot logo

postfix, dovecot and roundcube on CentOS 6

Hi there people. I know it’s not my thing to post tutorials one after another but I could not resist. This one is big and is divided into few parts (as you can tell ;)). In this tutorial, I will walk you through creating a perfect mail server on a CentOS 6.5 box using the best MTA out there, that is, postfix, dovecot roundcube. Before moving forward, make sure your server’s hostname is a FQDN. Once you are sure of that, continue with the below.

From here, you have three options to save the users and their respective emails on the server which are mentioned below:

1. On the physical system: You will create physical user accounts on the system for each user who will be using the email service on your server.

2. In MySQL database: User data along with their passwords will be saved in MySQL database and users will be authenticated from there.

3. Virtual users: In this setup, you will create a list of virtual users on the server and their mailboxes will be defined in a directory (one directory per user). This is the setup we are going with in this series.

UPDATE THE SYSTEM:

# yum update -y

CREATE SYSTEM USER:

Create the following group and user that will be used by the services


# groupadd virtmail -g  2100

# useradd virtmail -r -g  2100 -u 2100 -d /var/virtmail -m

GET POSTFIX UP AND RUNNING:

Remove any other MTA from the server if any


# yum remove sendmail exim -y

# yum install postfix -y

Edit postfix configuration file and add/append the following:


# 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/aliases
alias_database = $alias_maps

inet_interfaces = all
inet_protocols = ipv4

mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain

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/examples
readme_directory = /usr/share/doc/postfix-2.6.6/README_FILES

relay_domains = *
virtual_alias_maps=hash:/etc/postfix/virtmail_aliases
virtual_mailbox_domains=hash:/etc/postfix/virtmail_domains
virtual_mailbox_maps=hash:/etc/postfix/virtmail_mailbox

virtual_mailbox_base = /var/virtmail
virtual_minimum_uid = 2100
virtual_transport = virtual
virtual_uid_maps = static:2100
virtual_gid_maps = static:2100

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 virtmail-mailbox file which will hold the user’s mailboxes

vim /etc/postfix/virtmail_mailbox

#user                                 #Mailbox Directory
aman.hanjrah@techlinux.net            techlinux.net/aman.hanjrah/
a.hanjrah@techlinux.net               techlinux.net/a.hanjrah/
a.hanjrah@seconddomain.com            seconddomain.com/a.hanjrah/
aman.hanjrah@seconddomain.com         seconddomain.com/aman.hanjrah/

The above will create the directories at: ‘/var/virtmail/techlinux.net/aman.hanjrah’ and ‘/var/virtmail/seconddomain.com/a.hanjrah’, for examples.

Next, we will add the virtual domains on this server, create a file named virtmail_domains

# vim /etc/postfix/virtmail_domains
techlinux.net          OK
seconddomain.com       OK

Create the virtual aliases (virtmail_aliases) file which will hold the records for aliases, but they would be virtual, as

# vim /etc/postfix/virtmail_aliases
aman.hanjrah@techlinux.net          aman.hanjrah@techlinux.net
a.hanjrah@seconddomain.com          anything@foobar.tld

Virtual aliases works in the same way as aliases work, they forward the message to another account if defined.

Next, hash the above three files using postmap, any changes to these files will not work unless you hash them

# postmap /etc/postfix/virtmail_domains
# postmap /etc/postfix/virtmail_mailbox
# postmap /etc/postfix/virtmail_aliases
# touch /etc/postfix/aliases

Open the submission port/service

# vim +/submission /etc/postfix/master.cf

submission inet n       -       n       -       -       smtpd

INSTALL DOVECOT

Install dovecot if you haven’t done that already and edit the configuration file


#yum install dovecot

# vim /etc/dovecot/dovecot.conf
listen = *
ssl = no
protocols = imap lmtp
disable_plaintext_auth = no
auth_mechanisms = plain login

mail_access_groups = virtmail
default_login_user = virtmail

first_valid_uid = 2100
first_valid_gid = 2100

mail_location = maildir:/var/virtmail/%d/%n

passdb {
    driver = passwd-file
    args = scheme=SHA1 /etc/dovecot/passwd
}
userdb {
    driver = static
    args = uid=2100 gid=2100 home=/var/virtmail/%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 = virtmail
}

Next, create a ‘passwd’ file which will store all the usernames and passwords for authentication. We will generate hashed values instead of plain text passwords

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

save the generated password in following file

# vim /etc/dovecot/passwd

aman.hanjrah@techlinux.net:3HnLMO2nL2GakCuqdvJExfmDI+8=

Setup permissions on ‘passwd’ file

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

START SERVICES AND MAKE THEM TO START ON BOOT

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

This completes the basic email server setup which is without any SSL certificates or spam filters, in the coming articles, we will set that up to create a simple yet robust email server.

ADD ANOTHER ACCOUNT

In order to add another account, just edit the files ‘/etc/postfix/virtmail_mailbox‘ and ‘/etc/postfix/virtmail_aliases‘ and fill in the details just as you did previously. In addition to that, generate a hashed password using ‘doveadm’ and make an entry for this newly created mailbox account in: ‘/etc/dovecot/passwd‘.

Do not forget to run the folowing otherwise the new account will not be operational:

# postmap /etc/postfix/virtmail_mailbox
# postmap /etc/postfix/virtmail_aliases

INSTALLING WEBMAIL USING ROUNDCUBE

Roundcube is my favorite web client among others such as squirrelmail and horde, because of it’s speed and features available through plugins. Here, we will install it on our server so that you can access it using a browser and check/send/draft etc. an email just like you do with GMAIL or any other email service providers. As roundcube is a web based email client, it requires a web server, MySQL database (or a variant) and PHP in order to get going. In this setup, I already have web server, MySQL server and PHP installed on my server and all I need to do is add a server block to the web server’s configuration file and point that domain to server’s IP address. For example, if I will be using ‘virtmail.techlinux.net’, then I will be adding a server block for this domain in my web server’s configuration file and point ‘virtmail.techlinux.net’ to my server’s IP address. Having done that, let’s get roundcube up and running.

 

1. Download the latest roundube archive using wget and save it in /tmp, after that extract it in the document root of, for example, virtmail.techlinux.net, as:


# wget -c "http://sourceforge.net/projects/roundcubemail/files/latest/download?source=files" > /tmp/roundcube.tar.gz

# tar -xvzf /tmp/roundcube.tar.gz -C /usr/share

# cd /usr/share

# mv -v roundcube* roundcubemail

# chown -cR root: roundcubemail/

# chown -cR nginx: roundcubemail/temp/

# chown -cR nginx: roundcubemail/logs/

 

2. Create the database and grant privileges to this database, make sure you use a strong password as:


# mysql -uroot -p

mysql> create database roundcube;

mysql> grant all privileges on roundcube.* to 'round_user'@'localhost' identified by 'strong_password';

mysql> flush privileges;

mysql> exit;

 

Next, create the necessary tables for roundcube:


# mysql -u round_user -p roundcube < /usr/share/roundcubemail/mysql.initial.sql

 

3. Copy the ‘config.inc.php.sample’ file to ‘config.inc.php’ inside the directory structure (/usr/share/roundcubemail/config/) and edit it as:


# vim /usr/share/roundcubemail/config/config.inc.php

change

$config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail'; 

with

$config['db_dsnw'] = 'mysqli://round_user:strong_password@localhost/roundcubemail';

change

$config['smtp_server'] = '';

with

$config['smtp_server'] = 'localhost';

 

4. Save and close the above file. Also, remove the ‘installer’ directory as we do not need it, we did the configuration manually.


# rm -rf /usr/share/roundcubemail/installer

 

5. Finally, restart the web service. I am using ‘nginx’, so I will do the following, in case you are using some other web server, restart the service accordingly:


# /etc/init.d/nginx restart

 

You can now access your webmail client (roundcube) by accessing the URL:

http://server’sIPaddress/roundcubemail

OR

http://virtmail.techlinux.net (in case you have added a domain/subdomain)

NOTE: In order to receive emails, you need to set a reverse DNS entry as well otherwise the sending SMTP server will not know the location of your server (newly configured ;)) and incoming emails will never make to the inbox of your user’s mailbox.

Now you have the basic webmail server which work with your own domain name.

Next related articles will walk you through configuring SSL certificates for encrypted connections in Postfix, Dovecot and nginx along with how to configure OpenDKIM signatures and SPF records so that the probability of your emails be increased to land in receiver’s inbox instead of SPAM/JUNK folder. That might take some time 😉

Till then, enjoy!

10 thoughts on “Postfix, Dovecot and roundcube – Part 01

      1. Jan 4 22:48:26 elqotravel postfix/trivial-rewrite[4987]: warning: do not list domain elqotravel.com in BOTH mydestination and virtual_mailbox_domains

        Jan 4 22:55:10 elqotravel postfix/local[5051]: 665BD8F41C1B: to=, relay=local, delay=0.19, delays=0.1/0/0/0.09, dsn=5.1.1, status=bounced (unknown user: “novri”)

        1. You are listing your domain name at two locations, one is the value of “$mydestinations” inside ‘main.cf’ and another is “virtual_mailbox_domains” file. I would recommend you to remove the domain name from main.cf and then restart the postfix service.

  1. Receiving emails works in a different manner. You would need to setup rDNS from your domain panel. Another point that might be creating the problem is the firewall. Check if you have port number 25 is open for inbound connections. Yet another thing is MX records. I would recommend check them one by one so as to be sure if everything is in place. Following discusses the use of MX records:
    http://rimuhosting.com/support/settingupemail.jsp?mta=&t=dns#dns

  2. Hi ! Thank you for this tutorial.

    I have an issue with dovecot. When i check the status (service dovecot status) i have this error :

    master: Error: setrlimit(RLIMIT_NPROC, 4090): Operation not permitted

    1. Hi,
      I’ve been very busy lately. Are you using Red Hat/CentOS etc. (derivative of RedHat)? If yes, I suspect it is the SELinux which is prohibiting the Dovecot binary to start. Try disabling it and Dovecot should start like a charm. And if it does, find a way to allow it from SELinux, I wish I could help you with SELinux but I am not well versed with it.

      If it would not work, then you might need to increase the value of ‘data’ from: ‘/etc/security/limits.conf’ file. It should be something like:

      * hard data 384000

      Hope that helps.

Leave a Reply

Your email address will not be published. Required fields are marked *