As we have shown two weeks ago, email can be a very convenient tool for decent communication and in the future we will show that it can also be very secure tool if you need to send confidential information and verify its source using digital signature. But before we venture into that quadrant of space-time, we need to have a solid infrastructure in place. We start building such infrastructure with creating email server that can host virtual domains with multiple mailboxes and aliases. We will also ensure the mailboxes are accessible using common protocols and it is possible to easily administer the whole solution.
For our setup we use the postfix as mail transfer agent, dovecot as mail delivery agent and postfixadmin – running on top of the Apache web server – for administering the domains and accounts. In order to secure all TLS communication for all protocols, Let’s Encrypt certificate authority client acme.sh is used.
As we are a bunch of lazy sysadmins, we want to leverage web browser for any administration of the solution we design. We do not have any really specific needs, all we know is that any software we are about to install on the web server is written in PHP. Therefore we use standard Apache HTTP server with PHP module installed. Installing on CentOS is just a matter of:
yum install httpd php56 systemctl enable httpd systemctl start httpd
We also want to use trusted TLS certificates from the start and so we install the shell implementation of Let’s Encrypt’s ACME protocol client, ACME.sh:
git clone https://github.com/Neilpang/acme.sh.git cd ./acme.sh ./acme.sh --install . /root/.acme.sh/acme.sh.env
And we issue certificates for the domain name of our newly installed server. Also, after issuing the certificates, we change the SELinux context if we are using SELinux in enforcing mode:
acme.sh --issue -d mailserver.trustica.cz --apache chcon -t cert_t -R /root/.acme.sh/
With newly issued certificates we configure TLS in Apache HTTP server by adding the following lines to appropriate HTTPS VirtualHost definition:
SSLCertificateFile /root/.acme.sh/mailserver.trustica.cz/mailserver.trustica.cz.cer SSLCertificateKeyFile /root/.acme.sh/mailserver.trustica.cz/mailserver.trustica.cz.key SSLCertificateChainFile /root/.acme.sh/mailserver.trustica.cz/fullchain.cer
After all these changes, we just restart the Apache HTTP server:
systemctl restart httpd
And we are done with web server and TLS certificates.
Domains, mailboxes and aliases configuration will be stored in SQL database in our solution. This is how combination of postfixadmin, postfix and your IMAP server of choice works. We use MariaDB – as there is no need for advanced database features. Just a bunch of tables with our data will suffice. Installation of MariaDB is as simple as:
yum install mariadb-server systemctl enable mariadb systemctl start mariadb mysql_secure_installation
Now we are ready to install postfixadmin. The current version at the time of writing this article is 3.0.2 and before installation it is the most natural way to just unpack the distribution archive to the web server root directory:
wget https://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-3.0.2/postfixadmin-3.0.2.tar.gz tar -xzf postfixadmin-3.0.2.tar.gz -C /var/www/html mv /var/www/html/postfixadmin-3.0.2 /var/www/html/postfixadmin
And before running the installation script, we create the database and database user for postfixadmin:
CREATE DATABASE postfixadmin; GRANT ALL PRIVILEGES ON postfixadmin.* TO 'postfixadmin'@'localhost' IDENTIFIED BY '********************'; FLUSH PRIVILEGES; quit
Before installing postfixadmin, we need to fix access rights to the templates compilation directory:
cd /var/www/html/postfixadmin/ chown apache:apache templates_c chcon -t httpd_sys_rw_content_t postfixadmin/templates_c/
Now we can configure the postfixadmin database access in
/var/www/html/postfixadmin/config.inc.php and then we can continue with its installation using the provided installation script by pointing our browser to an URL like
If everything went fine, we create our first super admin by issuing:
bash /var/www/html/postfixadmin/scripts/postfixadmin-cli admin add firstname.lastname@example.org --password ******************** --password2 ******************** --superadmin 1 --active 1
At this moment we are able to configure domains, mailboxes and aliases. We are also able to create super administrators or domain administrators and let them do their work. Now on to actual mail delivery and reading.
As mentioned earlier, we will use postfix mail server and our IMAP server of choice is dovecot. We install postfix with MariaDB/MySQL support from the “centosplus” repository:
yum --enablerepo=centosplus install postfix
Then we create required table lookup configuration files as mentioned in postfixadmin installation guide. We place them in
/etc/postfix/sql directory. If we need more hardening the security of our solution, we also create separate SQL user for postfix, which has only read access to required tables. Remember, the postfixadmin user needs read and write access!
As we are creating solution for handling virtual domains and mailboxes, we use single system account for all mailboxes. It can be created by:
groupadd -g 5000 vmail useradd -g vmail -u 5000 vmail -d /home/vmail -m
The constant id 5000 was chosen because it does not collide with any system identifiers or possible users created normally.
/etc/postfix/main.cf, we enable the SQL table lookups:
virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf virtual_alias_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf svirtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
Now we only enable
virtual_transport to go through
dovecot service in the same configuration file and add TLS certificates:
smtpd_tls_cert_file = /root/.acme.sh/mailserver.trustica.cz/mailserver.trustica.cz.cer smtpd_tls_cert_file = /root/.acme.sh/mailserver.trustica.cz/fullchain.cer smtpd_tls_key_file = /root/.acme.sh/mailserver.trustica.cz/mailserver.trustica.cz.key
After all these changes, we can start the postfix mail server:
systemctl enable postfix systemctl start postfix
Installing dovecot IMAP server is pretty easy, just issue:
yum install dovecot dovecot-mysql
We enable the required protocols in main configuration file:
protocols = imap pop3 lmtp
Then we also configure the virtual mailboxes location on the filesystem:
mail_location = maildir:/home/vmail/%d/%n/Maildir mail_privileged_group = mail mail_uid = vmail mail_gid = mail first_valid_uid = 5000 last_valid_uid = 5000 first_valid_gid = 5000 last_valid_gid = 5000
We also need to configure MariaDB access using the same configuration we gave to postfix and then – once again – use the same TLS certificates:
ssl = yes ssl_cert = </root/.acme.sh/mailserver.trustica.cz/fullchain.cer ssl_key = </root/.acme.sh/mailserver.trustica.cz/mailserver.trustica.cz.key
Then we just fiddle with filesystem access rights and SELinux labels to ensure postfix and dovecot behave and start dovecot:
systemctl enable dovecot systemctl start dovecot
And that is basically all. The overview of the solution we have just installed is depicted in picture 1 below.
Picture 1: overall schema of our newly installed mail server.
As we can see, this does not include all functionality we would like to see from our robust solution. Next week, we are about to finish this series by implementing all features mentioned in our previous email rant. See you next week!
1. The Postfix Home Page, Wietse Venema, available online at http://www.postfix.org/
2. Dovecot, Secure IMAP server, available online at https://www.dovecot.org/
3. postfix.admin, Web based administration interface, available online at http://postfixadmin.sourceforge.net/
4. Apache HTTP server project, available online at https://httpd.apache.org/
5. Let’s Encrypt, Free SSL/TLS Certificates, available online at https://letsencrypt.org/
6. acme.sh, A pure Unix shell script implementing ACME client protocol, Neil Pang, available online at https://github.com/Neilpang/acme.sh
7. PHP: Hypertext Preprocessor, available online at https://secure.php.net/
8. CentOS Project, available online at https://www.centos.org/
9. Security-Enhanced Linux. (2017, December 18). In Wikipedia, The Free Encyclopedia. Retrieved 22:49, January 20, 2018, from https://en.wikipedia.org/w/index.php?title=Security-Enhanced_Linux&oldid=816052642
10. SQL. (2018, January 19). In Wikipedia, The Free Encyclopedia. Retrieved 22:50, January 20, 2018, from https://en.wikipedia.org/w/index.php?title=SQL&oldid=821325981
11. RFC 1730: INTERNET MESSAGE ACCESS PROTOCOL – VERSION 4, Network Working Group, December, 1994, available online at https://tools.ietf.org/html/rfc1730
12. MariaDB Foundation, official web available online at https://mariadb.org/