You can support us by downloading this article as PDF from the Link below. Download the guide as PDF

Introduction

In order to set up a full simple mail server, this guide takes advantage of Postfix as an SMTP server, Dovecot to provide POP/IMAP functionality, and RoundCube as a webmail program or client so that users can check and receive email from their favorite web browsers.

To clear all the jargon, let us get to know what the compnents we are going to use are.

Dovecot: Dovecot is an open-source IMAP and POP3 email server for Linux/UNIX-like systems, written with security primarily in mind.
Postfix: Postfix is a free and open-source mail transfer agent (MTA) that routes and delivers electronic mail from one server to another over the internet.
Roundcube: Once the mails have been delivered into a mailbox, most users would need an easy to use interface to read their mails. Roundcube does this pretty well. It is a browser-based multilingual IMAP client with an application-like user interface. It provides full functionality you expect from an email client, including MIME support, address book, folder manipulation, message searching and spell checking.

Pre-requisites for Production use

In order to use the server for production use, you must ensure you have the following

  • You must have a Fully Qualifed Domain Name (FQDN)
  • Create A and MX Records for your Domain in a Public Domain Name Server. These records must point to the Public IP of your server.

Now that we are on the same page, it is time we get into the part where they all come and work together. The order is a bit mixed up but please understand and make sure each configuration is correct.

Step 1: Update, set your hostname and disable SELinux

This is to ensure we start with the latest packages which ensures all previous patches are applied and hence beginning with a secure and an upto date system.

$ sudo dnf update
$ sudo hostnamectl set-hostname mail.example.com

# Disable SELinux
sudo sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config
sudo reboot

Step 2: Install postfix, Apache and PHP

We need a Mail Transfer Agent to handle the sending and delivery of mails from our mail server. Luckily, postfix does that quite well. To install postfix, run the command below once your server is back up.

sudo dnf install postfix postfix-mysql httpd vim policycoreutils-python-utils epel-release -y

PHP will be used by Roundcube to render the pages on your browser and hence the need to install it. Get it installed by following instructions in the guide below.

How To Install PHP 7.4 on CentOS 8 / RHEL 8

After PHP is installed, add extra PHP packages like so:

sudo dnf install -y php-common php-json php-xml php-mbstring php-mysqlnd

Step 3: Install and configure MySQL

We shall need a database to store and retrieve important data for both Roundcube and Postfix. Install MariaDB by following this guide:

How To Install MariaDB 10.x on CentOS 8 / RHEL 8

After MariaDB is installed, we shall continue to configure it by creating a MariaDB username and database for the Roundcube installation. Additionally, we shall create Postfix Mail accounts databse. Log into the MariaDB client with the command:

mysql -u root -p

Supply your root password and create a database for Postfix Mail accounts as shown below

create database postfix_accounts;

Create a user with full rights for the mail accounts database we just created.

grant all on postfix_accounts.* to [email protected] identified by 'StrongPassword';
flush privileges;

Create a table in the database that will store the domains you would wish to host in the server.

CREATE TABLE `postfix_accounts`.`domains_table` ( `DomainId` INT NOT NULL AUTO_INCREMENT , `DomainName` VARCHAR(50) NOT NULL , PRIMARY KEY (`DomainId`)) ENGINE = InnoDB;

Create a table in the database that will hold user accounts

CREATE TABLE `postfix_accounts`.`accounts_table` ( 
    `AccountId` INT NOT NULL AUTO_INCREMENT,  
    `DomainId` INT NOT NULL,  
    `password` VARCHAR(300) NOT NULL,  
    `Email` VARCHAR(100) NOT NULL,  
    PRIMARY KEY (`AccountId`),  
    UNIQUE KEY `Email` (`Email`),  
    FOREIGN KEY (DomainId) REFERENCES domains_table(DomainId) ON DELETE CASCADE 
) ENGINE = InnoDB;

Create a table in the database that will hold email aliases data.

An alias basically allows emails sent to one account to be redirected to another account once it reaches the mail server. For example, if you would wish all [email protected] emails to be sent to [email protected], you create an alias to accomplish that functionality.

CREATE TABLE `postfix_accounts`.`alias_table` (
    `AliasId` INT NOT NULL AUTO_INCREMENT, 
    `DomainId` INT NOT NULL, 
    `Source` varchar(100) NOT NULL, 
    `Destination` varchar(100) NOT NULL, 
    PRIMARY KEY (`AliasId`), 
    FOREIGN KEY (DomainId) REFERENCES domains_table(DomainId) ON DELETE CASCADE
) ENGINE = InnoDB;

Add records to the tables we have just created in Postfix Mail Accounts database.

We will now add our domain, some accounts and an alias.

INSERT INTO `postfix_accounts`.`domains_table` (DomainName) VALUES ('example.com');  
INSERT INTO `postfix_accounts`.`accounts_table` (DomainId, password, Email) VALUES (1, ENCRYPT('Password', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '[email protected]');  
INSERT INTO `postfix_accounts`.`accounts_table` (DomainId, password, Email) VALUES (1, ENCRYPT('Password', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '[email protected]');  
INSERT INTO `postfix_accounts`.`alias_table` (DomainId, Source, Destination) VALUES (1, '[email protected]', '[email protected]');

You can use names and passwords(strong) you prefer for:

postfix_admin user and postfix_accounts database name

Create a database for Roundcube which we shall install later

Now that we are in the database, we can as well add roundcube’s DB as follows.

create database roundcube;

Create a user with full rights for the database we just created.

grant all on roundcube.* to [email protected] identified by 'StrongPassword';
flush privileges;

You can use names and passwords(strong) you prefer for:

roundcube_admin user and roundcube database name.

After that is done, log out of the database and hop onto the next step.

quit;

Step 4: Configure Postfix

Let us now configure Postfix to ensure it will be able to recieve and deliver mails from our server. Its configuration files are found under /etc/postfix.

Configure the master configuration file

sudo vim /etc/postfix/master.cf

Uncomment the following lines in the file. Ensure that the lines beginning with -o maintains the indentation.

submission inet n       -       n       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt   ## Comment this if you have no SSL(not recommended)
  -o smtpd_tls_auth_only=yes            ## Comment this if you have no SSL(not recommended)
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
  -o smtpd_reject_unlisted_recipient=no
pickup    unix  n       -       n       60      1       pickup
cleanup   unix  n       -       n       -       0       cleanup
qmgr      unix  n       -       n       300     1       qmgr
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
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       n       -       -       smtp
relay     unix  -       -       n       -       -       smtp

showq     unix  n       -       n       -       -       showq
error     unix  -       -       n       -       -       error
retry     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
dovecot   unix  -       n       n       -       -       pipe
    flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}

We shall install and configure dovecot later on.

Save the file after you have made the changes above.

Open main.cf file

The /etc/postfix/main.cf file has main configuration options for Postfix installation.

sudo vim /etc/postfix/main.cf

Make the following changes:

Configure Hostname

Uncomment the myhostname line and replace host.domain.tld with the server’s hostname.

myhostname = mail.example.com

Configure your Domain

Add your domain to the mydomain line as below:

mydomain = example.com   ## Input your unique domain here

Uncomment or add the following lines so that they do not have a # sign in-front of them

myorigin = $myhostname
inet_interfaces = all
inet_protocols = all
mydestination = $myhostname, localhost.$mydomain, localhost
smtpd_recipient_restrictions = permit_mynetworks
home_mailbox = Maildir/

Add the following configuration lines to the end of the file. As you can notice, other configurations are SSL related. If you have SSL files, copy them in a suitable location and add them as illustrated. In case you have no SSL, simply comment (add # in front) on those options so as to deactivate them.

append_dot_mydomain = no
biff = no
config_directory = /etc/postfix
dovecot_destination_recipient_limit = 1
message_size_limit = 4194304
smtpd_tls_key_file = /etc/postfix/ssl/yourkey.key           ##SSL Key
smtpd_tls_cert_file = /etc/postfix/ssl/yourcertificate.crt  ##SSL Cert
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_security_level=may
virtual_transport = dovecot
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth

Add the following configuration as well which gives Postfix access to the account-related data we created and stored in the database in Step 3.

virtual_mailbox_domains = mysql:/etc/postfix/database-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/database-users.cf
virtual_alias_maps = mysql:/etc/postfix/database-alias.cf

Now let us add database configurations to those specific files as shown below. Note that the databases and tables will be created later in the next step of this guide.

Allow Postfix to access domains from the database

$ sudo vim /etc/postfix/database-domains.cf

user = postfix_admin
password = StrongPassword
hosts = 127.0.0.1
dbname = postfix_accounts
query = SELECT 1 FROM domains_table WHERE DomainName='%s'

Allow Postfix to access user accounts from the database

$ sudo vim /etc/postfix/database-users.cf

user = postfix_admin
password = StrongPassword
hosts = 127.0.0.1
dbname = postfix_accounts
query = SELECT 1 FROM accounts_table WHERE Email='%s'

Allow Postfix to access email aliases from the database

$ sudo vim /etc/postfix/database-alias.cf

user = postfix_admin
password = StrongPassword
hosts = 127.0.0.1
dbname = postfix_accounts
query = SELECT Destination FROM alias_table WHERE Source='%s'

Change ownership and permissions of the files we created above

Change the permissions to these files

sudo chmod 640 /etc/postfix/database-domains.cf
sudo chmod 640 /etc/postfix/database-users.cf
sudo chmod 640 /etc/postfix/database-alias.cf

And the ownership to the files like so

sudo chown root:postfix /etc/postfix/database-domains.cf
sudo chown root:postfix /etc/postfix/database-users.cf
sudo chown root:postfix /etc/postfix/database-alias.cf

Since we have made new changes we need to restart Postfix to load the new configs.

sudo systemctl restart postfix

Test Postfix settings we made

Now that our database is set-up, let us test if the configuration we made on Postfix are working. You should see a 1 if successful and an alias email address in the last one.

sudo postmap -q example.com mysql:/etc/postfix/database-domains.cf
1
sudo postmap -q [email protected] mysql:/etc/postfix/database-users.cf
1
sudo postmap -q [email protected] mysql:/etc/postfix/database-users.cf
1
sudo postmap -q [email protected] mysql:/etc/postfix/database-alias.cf
[email protected]

Step 5: Install and configure Dovecot

As it had been covered before, Dovecot is an open source IMAP and POP3 email server for Linux/UNIX-like systems. These protocols offers mail users the ability to retrieve mails from the server to their local mail clients and to delete mails from the server. Install Dovecot like so:

sudo dnf install dovecot dovecot-mysql -y

After it is successfully installed, let us add a user and group that will be responsible for handling mails in the system.

sudo groupadd -g 6000 vmail 
sudo useradd -g vmail -u 6000 vmail -d /home/vmail -m


Dovecot has a number of configuration files. Let us edit them step by step ensuring every configuration is accurately captured.

Open main dovecot configuration file and make sure the lines below have no # sign in from of them

$ sudo vim /etc/dovecot/dovecot.conf

listen = *, ::
protocols = imap pop3 lmtp
!include conf.d/*.conf
!include_try local.conf
log_path = /var/log/dovecot.log  ##Add this for logs

Next, open /etc/dovecot/conf.d/10-auth.conf file and make sure the lines below are without comments. You will notice that #!include auth-system.conf.ext is enabled by default. Comment it out leaving !include auth-sql.conf.ext only enabled.

$ sudo vim /etc/dovecot/conf.d/10-auth.conf

disable_plaintext_auth = yes
auth_mechanisms = plain login
!include auth-sql.conf.ext     ## Only enable authentication through SQL and leave other authentication methods disabled

After that, we need to add configurations to the file we enabled above. That is /etc/dovecot/conf.d/auth-sql.conf.ext.

These are the few special variables used

As you can see from the configuration below, we will be storing emails in /home/vmail/.

$ sudo vim /etc/dovecot/conf.d/auth-sql.conf.ext

passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = static     ## Don't forget to change this
  args = uid=vmail gid=vmail home=/home/vmail/%d/%n/Maildir
}

Create the /home/vmail/domain directory (/home/vmail/%d/)

sudo mkdir /home/vmail/example.com

Let us add database details we configured for postfix in the file we included in “args” in the file above

$ sudo vim /etc/dovecot/dovecot-sql.conf.ext

driver = mysql
connect = "host=127.0.0.1 dbname=postfix_accounts user=postfix_admin password=StrongPassword"
default_pass_scheme = SHA512-CRYPT
password_query = SELECT Email as User, password FROM accounts_table WHERE Email='%u';

Now we are going to configure Mailbox locations and namespaces

Open this file /etc/dovecot/conf.d/10-mail.conf and make sure the settings are altered to be similar to the configuration below

$ sudo vim /etc/dovecot/conf.d/10-mail.conf

mail_location = maildir:/home/vmail/%d/%n/Maildir
namespace inbox {
  inbox = yes
}
mail_privileged_group = mail
mbox_write_locks = fcntl

Next, open up /etc/dovecot/conf.d/10-master.conf and make the following changes to it then save.

$ sudo vim /etc/dovecot/conf.d/10-master.conf

service imap-login {
  inet_listener imap {
    port = 143
  }
  inet_listener imaps {
  }
}
service pop3-login {
  inet_listener pop3 {
    port = 110
  }
  inet_listener pop3s {
  }
}
service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
   mode = 0600
   user = postfix
   group = postfix
  }
}
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
  unix_listener auth-userdb {
   mode = 0600
   user = vmail
  }
  user = dovecot
}
service auth-worker {
  user = vmail
}
service dict {
  unix_listener dict {
  }
}

vmail user is responsible for handling mails in teh server. Therefore, the user needs access to the location of the mails. Give vmail user the permissions it requires as below:

sudo chown –R vmail:vmail /home/vmail

Give vmail and dovecot users permission to read Configuration files.

sudo chown -R vmail:dovecot /etc/dovecot 
sudo chmod -R o-rwx /etc/dovecot 

In /etc/dovecot/conf.d/10-ssl.conf, there are SSL configurations you can make optionally. If you have no intections of using any SSL for Dovecot, open the file and set ssl as no

$ sudo vim /etc/dovecot/conf.d/10-ssl.conf

ssl = no

##If you want to use SSL here use ssl = required then add the files like:

ssl = required
ssl_cert = </etc/pki/dovecot/certs/dovecot.pem
ssl_key = </etc/pki/dovecot/private/dovecot.pem

Step 6: Install and configure Roundcube

And now onto our web-based client to enable users to view their mails. You can download the latest stable release of Roundcube from their official webpage.

VER="1.4.5"
wget https://github.com/roundcube/roundcubemail/releases/download/$VER/roundcubemail-$VER-complete.tar.gz

Uncompress the downloaded file and change the name of the resulting directory

tar xvzf roundcubemail-$VER-complete.tar.gz
mv roundcubemail-$VER roundcube

Now move the new directory to the document root of Apache, change its ownership to apache and restart Apache web server.

sudo mv roundcube /var/www/html/
sudo chown -R apache:apache /var/www/html/
sudo systemctl restart httpd

Load Roundcube on your favorite browser to complete installation

Open your browser and enter the following url

http://IP/FQDN/roundcube/installer

In case the installer does not load, make sure your web-server is running and you have enabled port 80 on the firewall

sudo systemctl status httpd

sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --reload

Follow the screenshots below to complete the setting up of Roundcube

Make sure all the PHP checks are OK.

Scroll down and click “Next” if everything is working fine.

On the next page, look for “Database Setup” and fill in the Roundcube Database details we created earlier. After that, you can add other configs on the page as you like then scroll to the bottom and click “CREATE CONFIG

On the “Create config” part look for “Create Config” and click on it which will lead to a page like below where you will be required to either download and transfer a config file or create it manually. Choose the one that you are comfortable with. Note that this file might automatically be saved to /var/www/html/roundcube/config/. If not, just proceed with the steps.

Initialize the Database

If you downloaded the file, transfer it to your server and copy it in the directory named in the instructions. Click “CONTINUE” after that.

sudo cp config.inc.php /var/www/html/roundcube/config/
sudo chown apache:apache /var/www/html/roundcube/config/config.inc.php

Edit the config file to include smtp hosts, ports and method of logging in

$ sudo vim /var/www/html/roundcube/config/config.inc.php

$config['default_host'] = 'localhost';  ## If SSL is configured, use: $config['default_host'] = 'ssl//mail.example.com';
$config['support_url'] = '';
$config['defautl_port'] = 143;
$config['smtp_server'] = 'localhost';   ## If SSL is confgured, use: $config['smtp_server'] = 'tls//mail.example.com'; 
$config['smtp_port'] = 587;
$config['smtp_user'] = '%u';
$config['smtp_pass'] = '%p';
$config['smtp_auth_type'] = 'LOGIN';
$config['debug_level'] = 1;
$config['smtp_debug'] = true;
$config['plugins'] = array('virtuser_query');                                                                    
$config['virtuser_query'] = "SELECT Email FROM postfix_accounts.accounts_table WHERE Email = '%u'"; ## Enables Roundcube to use authentication for virtual users for outgoing mail

Everything should be okay till this point. At the bottom of the page, you will see a banner that advises you to remove the whole installer directory after successfully setting up Roundcube.

Step 7: Open all of the needed ports on the firewall

In case your firewall is running, allow the following ports

  • HTTPS: 443
  • SMTP: 25
  • POP3: 110
  • IMAP: 143
  • SMTP Secure: 465
  • MSA: 587
  • IMAP Secure: 993
  • POP3 Secure: 995
sudo firewall-cmd --permanent --add-port={443,25,110,143,465,587,993,995}/tcp
sudo firewall-cmd --reload

Step 8: Testing our Mail server

After everything is set-up and ready to go, it is time to test whether we are capable of sending and receiving emails.

Load your browser and enter https://IP-or-FQDN/roundcube

Input any email account we configured earlier and its corresponding password.

After logging in, test if you can send and receive mails from your local domain and external as well if the requirements are met for that.

Conclusion

Setting up a simple mail server can be as quick as it has been in this guide. If it is sitting in the cloud with a valid FQDN and Mail Exchange records well configured, then you should be able to send and receive emails to whomever you wish. For now, we appreciate you for visiting. Other guides are listed below for your consideration.

Install and Setup iRedMail Mail Server on Debian 10 (Buster)

How To Add Domains and User Accounts to iRedMail Mail Server

Secure iRedMail Server with Let’s Encrypt SSL Certificate

How To Install iRedMail Mail Server on CentOS 7

You can support us by downloading this article as PDF from the Link below. Download the guide as PDF