Part 2: Install Dovecot IMAP Server on CentOS 8/RHEL 8 & Enable TLS Encryption

This is part 2 of building your own email server from scratch on CentOS 8/RHEL 8 tutorial series. In part 1, we showed you how to set up a basic Postfix SMTP server. In this tutorial, we are going to configure our email server so that we can receive and send emails using a desktop email client like Mozilla Thunderbird or Microsoft Outlook.

To be able to send emails using a desktop email client, we need to enable the submission service in Postfix. To receive emails using a desktop email client, we can install an open-source IMAP server named Dovecot on CentOS 8/RHEL 8 server. And to encrypt our communications, we need a TLS certificate.

Open Ports in Firewall

Run the following commands to open email related ports in firewall.

sudo firewall-cmd --permanent --add-service={http,https,smtp-submission,smtps,imap,imaps}

If you use POP3 to fetch emails (I personally don’t), then also add the pop3 and pop3s service.

sudo firewall-cmd --permanent --add-service={pop3,pop3s}

Reload firewalld for the change to take effect.

sudo systemctl reload firewalld

Securing Email Server Traffic with TLS Certificate

When we configure a desktop email client, enabling encryption is always a good idea. We can easily obtain a free TLS certificate from Let’s Encrypt. Issue the following commands to install Let’s Encrypt client (certbot) on CentOS 8/RHEL 8 from the EPEL repository.

sudo dnf install epel-release -y

sudo dnf install certbot

If you don’t have a web server running yet, I recommend you install one (Apache or Nginx), because it’s easier to obtain and install TLS certificate with a web server than using other methods. And in a later tutorial, I will show you how to set up webmail, which requires running a web server.

Apache

If you prefer Apache, run the following command to install it.

sudo dnf install httpd

Start Apache and enable auto-start at boot time.

sudo systemctl start httpd

sudo systemctl enable httpd

Install the Certbot Apache plugin.

sudo dnf install python3-certbot-apache

Nginx

If you prefer Nginx, run the following command to install it.

sudo dnf install nginx

Start Nginx and enable auto-start at boot time.

sudo systemctl start nginx

sudo systemctl enable nginx

Install the Certbot Nginx plugin.

sudo dnf install python3-certbot-nginx

Obtaining TLS Certificate with Apache Web Server

You need to have an Apache virtual host for mail.your-domain.com before obtaining Let’s Encrypt TLS certificate. Create the virtual host file:

sudo nano /etc/httpd/conf.d/mail.your-domain.com.conf

Then paste the following text into the file.

<VirtualHost *:80>        
        ServerName mail.your-domain.com

        DocumentRoot /var/www/html/
</VirtualHost>

Save and close the file. Reload Apache for the changes to take effect.

sudo systemctl reload httpd

Once virtual host is created and enabled, run the following command to obtain and install Let’s Encrypt TLS certificate.

sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d mail.your-domain.com

After a while, you should see the following lines which means the certificate is successfully obtained. You can also see the directory under which your cert is stored.

centos postfix dovecot tls certbot

Obtaining TLS Certificate with Nginx Web Server

You need to have an Nginx virtual host for mail.your-domain.com before obtaining Let’s Encrypt TLS certificate. Create the virtual host file:

sudo nano /etc/nginx/conf.d/mail.your-domain.com.conf

Next, paste the following text into the file.

server {
      listen 80;
      listen [::]:80;
      server_name mail.your-domain.com;

      root /usr/share/nginx/html/;

      location ~ /.well-known/acme-challenge {
         allow all;
      }
}

Save and close the file. Reload Nginx for the changes to take effect.

sudo systemctl reload nginx

Once virtual host is created and enabled, run the following command to obtain and install Let’s Encrypt certificate with Nginx plugin.

sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d mail.your-domain.com

After a while, you should see the following which means the certificate is successfully obtained. You can also see the directory under which your cert is stored.

centos postfix dovecot tls certbot

Configuring Postfix

To send emails from a desktop email client, we need to enable the submission service of Postfix so that the email client can submit emails to Postfix SMTP server. Edit the master.cf file.

sudo nano /etc/postfix/master.cf

In submission section, uncomment or add the following lines. Please allow at least one whitespace (tab or spacebar) before each -o.  In postfix configurations, a preceding whitespace character means that this line is continuation of the previous line. (By default the submission section is commented out. You can copy the following lines and paste them into the file, so you don’t have to manually uncomment or add new text.)

submission     inet     n    -    y    -    -    smtpd
 -o syslog_name=postfix/submission
 -o smtpd_tls_security_level=encrypt
 -o smtpd_tls_wrappermode=no
 -o smtpd_sasl_auth_enable=yes
 -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
 -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
 -o smtpd_sasl_type=dovecot
 -o smtpd_sasl_path=private/auth

The above configuration enables the submission daemon of Postfix and requires TLS encryption. So later on our desktop email client can connect to the submission daemon in TLS encryption. The submission daemon listens on TCP port 587. STARTTLS is used to encrypt communications between email client and the submission daemon.

Microsoft Outlook only supports submission over port 465. If you are going to use Microsoft outlook mail client, then you also need to enable submission service on port 465 by adding the following lines in the file.

smtps     inet  n       -       y       -       -       smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
  -o smtpd_sasl_type=dovecot
  -o smtpd_sasl_path=private/auth

Save and close the file.

Hint: The SMTP protocol is used when an email client submits emails to an SMTP server.

Next, we need to run the following two commands to specify the location of TLS certificate and private key in Postfix configuration file. Your Let’s Encrypt certificate and private key are stored under /etc/letsencrypt/live/mail.your-domain.com/ directory.

sudo postconf "smtpd_tls_cert_file = /etc/letsencrypt/live/mail.your-domain.com/fullchain.pem"

sudo postconf "smtpd_tls_key_file = /etc/letsencrypt/live/mail.your-domain.com/privkey.pem"

If you want to log TLS connections in the mail log (/var/log/maillog), then run the following two commands.

sudo postconf "smtpd_tls_loglevel = 1"

sudo postconf "smtp_tls_loglevel = 1"

To disable insecure SSL/TLS versions, open the Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Add the following lines at the bottom of the file. (In Nano text editor, you can quickly go to the bottom of a file by pressing Ctrl+W, then Ctrl+V.)

#Force TLSv1.3 or TLSv1.2
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

Save and close the file. Then reload Postfix for the changes to take effect.

sudo systemctl restart postfix

If you run the following command, you will see Postfix is now listening on port 587 and 465.

sudo netstat -lnpt | grep master

enable submission service in postfix 587 465

Installing Dovecot IMAP Server

Enter the following command to install Dovecot on CentOS 8/RHEL 8 server.

sudo dnf install dovecot

Check Dovecot version:

dovecot --version

Sample output:

2.3.8 (9df20d2db)

Start Dovecot and enable auto-start at boot time.

sudo systemctl start dovecot

sudo systemctl enable dovecot

Configuring Dovecot

First, edit main config file.

sudo nano /etc/dovecot/dovecot.conf

Add the following line to enable IMAP protocol.

protocols = imap

If you want to use POP3 to fetch emails, then also add the POP3 protocol.

protocols = imap pop3

Save and close the file.

Configuring Mailbox Location

mbox is the traditional and default format for storing emails. Each user’s emails are stored in a single file /var/mail/username. You can run the following command to find the mail spool directory.

postconf mail_spool_directory

Sample output:

mail_spool_directory = /var/mail

However, nowadays it’s almost always you want to use the Maildir format to store email messages. The config file for mailbox location is /etc/dovecot/conf.d/10-mail.conf.

sudo nano /etc/dovecot/conf.d/10-mail.conf

Add the following line to use the Maildir format. Email messages will be stored under the Maildir directory under each user’s home directory.

mail_location = maildir:~/Maildir

We also need to add the following line in the file.

mail_privileged_group = mail

Save and close the file. Then add dovecot to the mail group so that Dovecot can read the INBOX.

sudo gpasswd -a dovecot mail

Configuring Authentication Mechanism

Edit the authentication config file.

sudo nano /etc/dovecot/conf.d/10-auth.conf

Uncomment the following line.

disable_plaintext_auth = yes

It will disable plaintext authentication when there’s no SSL/TLS encryption. And if you want to use full email address ([email protected]) to login, add the following line in the file.

auth_username_format = %n

Otherwise, you are able to login with username only (without @your-domain.com). Next, find the following line.

auth_mechanisms = plain

This line only enables the PLAIN authentication mechanism. LOGIN is another authentication mechanism you probably want to add to support older email clients.

auth_mechanisms = plain login

Save and close the file.

Configuring SSL/TLS Encryption

Next, edit SSL/TLS config file.

sudo nano /etc/dovecot/conf.d/10-ssl.conf

You can find the following line, which requires email clients to communicate with Dovecot with TLS encryption.

ssl = required

Then find the following two lines.

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

We need to replace values with the location of your SSL/TLS cert and private key. Don’t leave out the < character. It’s necessary.

ssl_cert = </etc/letsencrypt/live/mail.your-domain.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.your-domain.com/privkey.pem

Next, find the following line and uncomment it. (Remove the beginning # character.)

#ssl_dh = </etc/dovecot/dh.pem

Find the following line.

#ssl_min_protocol = TLSv1

This specifies the minimum TLS versions used by Dovecot. TLSv1.0 and TLSv1.1 are insecure. so uncomment this line and change the value to TLSv1.2, which will force Dovecot to use TLSv1.2 or TLSv1.3.

ssl_min_protocol = TLSv1.2

Then find the following line.

#ssl_prefer_server_ciphers = no

It’s a good practice to prefer the server’s order of ciphers over client’s, so uncomment this line and change the value to yes.

ssl_prefer_server_ciphers = yes

Save and close the file. Now we need to generate the Diffie-Hellman parameter with:

sudo openssl dhparam -out /etc/dovecot/dh.pem 4096

If your mail server has a single CPU core, then this is going to take a long time (about 10 minutes). If you can’t wait, you can generate the DH parameters on your local Linux computer, then upload the file to the /etc/dovecot/ directory on the mail server.

SASL Authentication Between Postfix and Dovecot

Edit the following file.

sudo nano /etc/dovecot/conf.d/10-master.conf

Change service auth section to the following so that Postfix can find the Dovecot authentication server.

service auth {
    unix_listener /var/spool/postfix/private/auth {
      mode = 0660
      user = postfix
      group = postfix
    }
}

Postfix SMTP Auth

Save and close the file.

Auto-create Sent and Trash Folder

Edit the below config file.

sudo nano /etc/dovecot/conf.d/15-mailboxes.conf

To auto-create a folder, simply add the following line in the mailbox section.

auto = create

Example:

 mailbox Trash {
    auto = create
    special_use = \Trash
 }

Some common folders you will want to create includes: Drafts, Junk, Trash and Sent. These folders will be created at the user’s home directory. After you save and close all above config files, restart Dovecot.

sudo systemctl restart dovecot

Dovecot will be listening on port 143 (IMAP) and 993 (IMAPS), as can be seen with:

sudo netstat -lnpt | grep dovecot

centos dovecot imap server

If there’s a configuration error, dovecot will fail to restart, so it’s a good idea to check the status of Dovecot.

systemctl status dovecot

We also need to restart Postfix to allow the LOGIN authentication mechanism.

sudo systemctl restart postfix

Using Dovecot to Deliver Email to Message Store

By default, Postfix uses its builtin local delivery agent (LDA) to move inbound emails to the message store (inbox, sent, trash, Junk, etc). We can configure it to use Dovecot to deliver emails, via the LMTP protocol, which is a simplified version of SMTP. LMTP allows for a highly scalable and reliable mail system. This step is required if you want to use the sieve plugin to filter inbound messages to different folders.

Edit the Dovecot main configuration file.

sudo nano /etc/dovecot/dovecot.conf

Add lmtp to the supported protocols.

protocols = imap lmtp

Save and close the file. Then edit the Dovecot 10-master.conf file.

sudo nano /etc/dovecot/conf.d/10-master.conf

Change the lmtp service definition to the following.

service lmtp {
 unix_listener /var/spool/postfix/private/dovecot-lmtp {
   mode = 0600
   user = postfix
   group = postfix
  }
}

dovecot-lmtp-centos

Save and close the file. Next, edit the Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Add the following lines at the end of the file. The first line tells Postfix to deliver emails to local message store via the dovecot LMTP server.  The second line disables SMTPUTF8 in Postfix, because Dovecot-LMTP doesn’t support this email extension.

mailbox_transport = lmtp:unix:private/dovecot-lmtp
smtputf8_enable = no

Save and close the file. Finally, restart Postfix and Dovecot.

sudo systemctl restart postfix dovecot

Configure Desktop Email Client

Fire up your desktop email client such as Mozilla Thunderbird and add a mail account. If Thunderbird found your mail server configuration like below, simply click Done button and you will be able to read and send emails.

mozilla thunderbird set up an existing email account

If Thunderbird didn’t found your mail server configuration, then click Manual config button to enter your mail server details.

  • In the incoming server section, select IMAP protocol, enter mail.your-domain.com as the server name, choose port 143 and STARTTLS. Choose normal password as the authentication method.
  • In the outgoing section, select SMTP protocol, enter mail.your-domain.com as the server name, choose port 587 and STARTTLS. Choose normal password as the authentication method.

centos 8 postfix dovecot

Hint: You can also use port 993 with SSL/TLS encryption for IMAP, and use port 465 with SSL/TLS encryption for SMTP

You should now be able to connect to your own email server and also send and receive emails with your desktop email client!

We use local Unix accounts as email addresses, as we did in part 1. For example, if you have a user called user1 on your Ubuntu server, then you have an email address: [email protected], and the password for the email address is the same password for the user1 user.

Troubleshooting Tips

If you can’t log into your mail server from a desktop mail client, scan your mail server to find if the ports are open. Note that you should run the following command from another Linux computer or server. If you run it on your mail server, then the ports will always appear to be open.

sudo nmap mail.your-domain.com

And check if Dovecot is running.

systemctl status dovecot

You can also check the mail log (/var/log/maillog), which may give you some clues.

Auto-Renew TLS Certificate

You can create Cron job to automatically renew TLS certificate. Simply open root user’s crontab file.

sudo crontab -e

If you use Apache web server, add the following line at the bottom of the file.

@daily certbot renew --quiet && systemctl reload postfix dovecot httpd

If you are using Nginx web server, then add the following line.

@daily certbot renew --quiet && systemctl reload postfix dovecot nginx

Reloading Postfix, Dovecot and the web server is necessary to make these programs pick up the new certificate and private key.

Next Step

I hope this article helped you set up Postfix and Dovecot on CentOS 8/RHEL 8 server. In part 3, I will show you how to create virtual mailboxes on CentOS 8/RHEL 8 with PostfixAdmin.

Rate this tutorial
[Total: 4 Average: 5]

18 Responses to “Part 2: Install Dovecot IMAP Server on CentOS 8/RHEL 8 & Enable TLS Encryption

  • Great instruction, thank you!

    However, there is one error causing my thunderbird unable to read email (sending is fine). The mail log (/var/log/maillog) says user doesn’t exists, although it does. I change the following parameter (in /etc/dovecot/conf.d/10-auth.conf) and it works!

    auth_username_format = %Ln

  • Kristen
    1 month ago

    The newest version of Dovecot on CentOS 8 is now:

     # dovecot --version
    2.3.8 (9df20d2db) 

    This caused a problem with the SSL connection from mail clients as SSL is no longer used.
    Looking at /var/log/maillog I find this:

    Dovecot: imap-login: Error: Failed to initialize SSL server context: Can't load DH 
    parameters: error:1408518A:SSL routines:ssl3_ctx_ctrl:dh key too small:

    There are instructions as to resolving this issue as stated:
    “dd if=/var/lib/dovecot/ssl-parameters.dat bs=1 skip=88 | openssl dhparam -inform der > /etc/dovecot/dh.pem”
    But this fails. The problem being that dh.pem is too small. It should be noted that ssl-parameters.dat is no longer required.
    Final resolution is to use a physical computer and issue this command:

    openssl dhparam 4096 > dh.pem

    In my case I used

    scp dh.pem [email protected]:dh.pem

    and then moved that file to /etc/dovecot/dh.pem.
    Next

    chown root:root dh.pem

    Finally, restart dovecot with systemctl restart dovecot.service

    • This was helpful. However, in my case I am using Let’s Encrypt. After the update from Dovecot 2.2 to 2.3.8, I just did the following:

       gzip /var/lib/dovecot/ssl-parameters.dat
      systemctl restart dovecot

      Since it seemed that dovecot was still referencing the ss-parameters.dat file. After removing it from the equation, mail resumed working again.

  • Great guide, thanks!

    I have an issue of “connect to mail.mydomain[private/dovecot-lmtp]: No such file or directory” in the maillog. So postfix can not deliver the mail to dovecot.

    Thanks

    • Sam, in your /etc/dovecot/conf.d/10-master.conf file, check the ‘service lmtp’ section to make sure it is correct. A misconfiguration there will cause that error.

    • If you don’t know where’s wrong, you can add the following line in the /etc/dovecot/dovecot.conf file,

      mail_debug=yes

      then restart dovecot, so dovecot will produce debugging message in the /var/log/maillog file.

    • Thanks, all good now. It is the service lmtp.

  • Big thanks for such a great manual, all works great except one thing.
    I have such error:

    postfix/smtpd[21850]: warning: cannot get RSA certificate from file "/etc/letsencrypt/live/mail.myrealdomain.com/privkey.pem": disabling TLS support
    postfix/smtpd[21850]: warning: TLS library problem: error:0909006C:PEM routines:get_name:no start line:crypto/pem/pem_lib.c:745:Expecting: TRUSTED CERTIFICATE:
    postfix/smtpd[21850]: warning: TLS library problem: error:140DC009:SSL routines:use_certificate_chain_file:PEM lib:ssl/ssl_rsa.c:622:

    Trying different things like deleting privacy.pem and creating new one. When I testing privacy.pem all looks good.

  • Hello Xiao ports 465 and 578 not listen after doing this:

    Add the following lines at the bottom of the file. (In Nano text editor, you can quickly go to the bottom of a file by pressing Ctrl+W, then Ctrl+V.)

    #Force TLSv1.3 or TLSv1.2
    smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
    smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
    smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
    smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
    Save and close the file. Then reload Postfix for the changes to take effect.

    sudo systemctl restart postfix
    If you run the following command, you will see Postfix is now listening on port 587 and 465.

    sudo netstat -lnpt | grep master

  • Xiao question very important : Can anyone hack my mail server? postfix? vps? how I can found out I been hacked ? thanks

  • Thank You Xiao

  • Abu Yusfan
    3 weeks ago

    Hi Xiao,
    what a great toturial ever i found. could we follow your tutorial series but postfix and dovecot installed on different servers? lets say postfix on server a and dovecot for server b?
    thanks.

  • This confused me. Is it 0666 or 0600? Your quoted code says 0600 but the example image says 0666.

    I’m commenting issues I had because I ended up having to rebuild my server after being DDoS’d (configuration maybe) and likely misconfigured. Couldn’t reboot my CentOS without entering rescue kernel. I was almost 100% completed with this tutorial but I couldn’t get my primary email account setup. Sucks. I wish you added more information about setting up the initial email account as opposed to it being inherited from the centOS user account. When I tried in thunderbird it found the settings but just wouldn’t login. I went over the permissions a million times. I’m hoping to maybe start from scratch in-case I missed something. Email servers ARE A PAIN. Let me tell you, anyone who wants to do this. I’ve been building sites for 15 years and feel like I have a good grasp of CentOS, and the ever-changing landscape is inevitable it feels like. Bandwidth, CPU, script-kiddies, etc. It’s a lot to juggle.

    • It should be 0600.

      I don’t think this configuration will make you rebuild the email server. If you don’t want to build an email server from scratch, you can use iRedMail to set up a full-featured mail server quickly and easily.

      • Anthony
        5 days ago

        Not this configuration specifically, but something went wrong on my side while I followed the tutorial. I have root login and password authentication shut off with sshd reloaded, but I can see cross-site attacks from Chinese IP addresses in the logs for days following the mail installation. Most of them are referencing the cgi-bin, and I haven’t figured out what happened yet.

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.


The maximum upload file size: 2 MB.
You can upload: image.