Part 2: How to Install Dovecot IMAP server on Ubuntu and Enable TLS Encryption

This is part 2 of building your own secure email server on Ubuntu 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 Geary.

To be able to send email using desktop email client, we need to do a little bit configuration on Postfix. To receive email using desktop email client, we can install an open source IMAP server named Dovecot on Ubuntu 16.04 or 14.04 server. And to encrypt our communications, we need a TLS certificate.

Securing Email Server Traffic with TLS Certificate

Please note that when we configure our desktop email client, using 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 Ubuntu 16.04 server from official PPA.

sudo apt install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt update
sudo apt 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.

If you use Apache web server, you need to install the Apache plugin. (The following command will install Apache web server if it’s not already on your system.)

sudo apt install python3-certbot-apache

If you use Nginx web server, then install the Nginx plugin. (The following command will install Nginx web server if it’s not already on your system.)

sudo apt 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/apache2/sites-available/mail.your-domain.com.conf

Then paste the following text into the file.

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

        DocumentRoot /var/www/mail.your-domain.com
</VirtualHost>

Save and close the file. Then create the web root directory.

sudo mkdir /var/www/mail.your-domain.com

Set www-data (Apache user) as the owner of the web root.

sudo chown www-data:www-data /var/www/mail.your-domain.com -R

Enable this virtual host.

sudo a2ensite mail.your-domain.com.conf

Reload Apache for the changes to take effect.

sudo systemctl reload apache2

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 --email your-email-address -d mail.your-domain.com

Substitute the red text with your actual data. You should see the following which means the certificate is successfully obtained. You can also see the directory under which your cert is stored.

obtain-a-ssl-certificate-from-lets-encrypt

Obtaining TLS Certificate with Nginx Web Server

You need to have a 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;
      server_name mail.your-domain.com;

      root /var/www/mail.your-domain.com/;

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

Save and close the file. Then create the web root directory.

sudo mkdir /var/www/mail.your-domain.com/

Set www-data (Nginx user) as the owner of the web root.

sudo chown www-data:www-data /var/www/mail.your-domain.com -R

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 --email your-email-address -d mail.your-domain.com

You should see the following which means the certificate is successfully obtained. You can also see the directory under which your cert is stored.

postfix tls letsencrypt

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 -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. The submission daemon listens on TCP port 587. STARTTLS is used to encrypt communications between email client and the submission daemon.

Save and close the file. Next, we need to let Postfix know where TLS certificate and private key are. Edit main.cf file.

sudo nano /etc/postfix/main.cf

Edit the TLS parameter as follows:

smtpd_tls_cert_file=/etc/letsencrypt/live/mail.your-domain.com/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.your-domain.com/privkey.pem
smtpd_tls_security_level=may 
smtpd_tls_protocols = !SSLv2, !SSLv3 !TLSv1
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache

smtp_tls_security_level = may
smtp_tls_loglevel = 1
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

Your Let’s Encrypt certificate and private key are stored under /etc/letsencrypt/live/mail.your-domain.com/ directory. Save and close the file. Then reload Postfix.

sudo postfix reload

If you run the following command, you will see port 587 is now open.

sudo netstat -lnpt

starttls-587-port

Installing Dovecot IMAP Server

Enter the following command to install Dovecot core package and the IMAP daemon package on Ubuntu server.

sudo apt install dovecot-core dovecot-imapd

Check Dovecot version:

sudo dovecot --version

Sample output:

2.2.22 (fe789d2)

Configuring Dovecot

First, edit main config file.

sudo nano /etc/dovecot/dovecot.conf

Add the following line to enable IMAP protocol.

protocols = imap

Configuring Mailbox Location

By default, Postfix uses mbox format to store emails. Each user’s emails is 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

The config file for mailbox location is /etc/dovecot/conf.d/10-mail.conf.

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

The default configuration is as follows, which is fine for a small email server.

mail_location = mbox:~/mail:INBOX=/var/mail/%u

We need to add the following line in the file. (On Ubuntu 18.04, this line is already in the file.)

mail_privileged_group = mail

After that, 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 common authentication mechanism you probably want to add.

auth_mechanisms = plain login

Configuring SSL/TLS Encryption

Next, edit SSL/TLS config file.

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

Change ssl = no to ssl = required.

ssl = required

Then specify the location of your SSL/TLS cert and private key. Don’t leave out < 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

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
    }
}

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). If there’s a configuration error, dovecot will fail to restart. We also need to restart Postfix to allow the LOGIN authentication mechanism.

sudo systemctl restart postfix

Configure Desktop Email Client

Now open up your desktop email client such as Mozilla Thunderbird and add a mail account.

  • In the incoming server section, select IMAP protocol, enter mail.your-domain.com as the server name, choose port 993 and SSL/TLS. 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.

postfix dovecot letsencrypt

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

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.

Install the Dovecot LMTP Server.

sudo apt install dovecot-lmtpd

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 {
   group = postfix
   mode = 0600
   user = postfix
  }
}

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

Wrapping Up

I hope this article helped you set up Postfix and Dovecot on Ubuntu server. In part 3, I will show you how to set up SPF and DKIM with Postfix to improve email deliverability. If you want to access emails via Webmail, then I recommend RainLoop Webmail, which is lightweight, fast and has a modern interface. Roundcube is also a popular open source webmail client.

Rate this tutorial
[Total: 45 Average: 3.7]

report this ad

28 Responses to “Part 2: How to Install Dovecot IMAP server on Ubuntu and Enable TLS Encryption

  • Bummer, got all the way through this and Thunderbird cannot connect to it.

  • jubakala
    11 months ago

    Finally, a tutorial that tells everything that’s needed, not only parts of it. And finally, after about 12 hours of trying, I have a working email-server. So THANKS a lot!

  • This is THE best postfix/dovecot tutorial on the web. Thank you very much for posting. You covered a lot of material in great detail, but there are still a few parts that I’m unclear on.

    When adding your mail account to your mail client, how do you know what the password is? We didn’t set a password for SMTP authentication in the walkthrough. If my Ubuntu user account is ‘admin’, and my email is [email protected], do I just use my local ‘admin’ account password to connect my mail client to my new email account?

    What if, in my specific case, my local Ubuntu login is ‘admin’, but I want the email address “[email protected]” to be the default for all incoming and outgoing mail? Do I need to create a “user1” local user account on Ubuntu? I’ve send some test emails from the “[email protected]” account and the SPF/DKIM checks are failing. DKIM only passes the check when I send mail from my “[email protected]” account.

    • Well, I continued working at it and I answered one of my questions. Yes, each email account has to have a local user account on the Ubuntu server in order to have email. I have successfully added my accounts on my Android email application. Still looking into the other issue about the “[email protected]” failing DKIM (and therefore getting detected as spam).

    • So after some research and trial/error since my last post, I’m still having problems with DKIM. When I email the port25.com test system from the user account that I followed this guide from, I get a pass on everything. When I email from another user on the system and get a report form port25.com, everything except DKIM passes.

      If I send mail from my root account, DKIM passes. I just can’t figure out what it is about this specific user account that’s causing it to fail. And of course, it happens to be the account that I primarily want to use to send and receive mail. Without DKIM passing, I’ve noticed that Google sends my messages straight to the spam box.

    • Aha! I figured out why my single user account was failing DKIM, and I understand why:

      DKIM takes the message content and hashes it with the private key, then puts this in the email header. I was using an additional postfix configuration option called smtp_generic_maps to “rewrite” how my sender address would appear in the recipients inbox. DKIM did not like this modification and that is what was causing the DKIM check to fail on messages from this specific user. Hopefully this helps somebody else!

      Simply comment out the smtp_generic_maps parameter in your /etc/postfix/main.cf file if you’re having this problem.

      Thanks again for the wonderful guide!

  • M Aprian
    9 months ago

    After doing this part, I can send email but cannot receive email. Can you help me? 🙁

    • M Aprian
      9 months ago

      SOLVED!! I made a little mistake, sorry

      This is the best guide for mail servers (for me now), THANKS YOU

  • Great tutorial, worked perfectly, thanks!

  • Hello,

    In the command:
    sudo certbot –nginx –agree-tos –redirect –hsts –email your-email-address -d mail.your-domain.com

    What is the “your-email-address” I should provide ?

    Kind regards,
    Daniel

  • Hello,

    My domain is not a .com one, it is a .co.uk (let’s say test.co.uk)

    How should I replace “your-domain” in:
    “sudo nano /etc/nginx/conf.d/mail.your-domain.com.conf” ?

    Kind regards,
    Daniel

  • Hello,
    ive got problem with letssencrypt

     ./letsencrypt-auto --apache --agree-tos --redirect --hsts --email kontakt.*****@gmail.com -d mail.*****.pl
    Requesting to rerun ./letsencrypt-auto with root privileges...
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Plugins selected: Authenticator apache, Installer apache
    Obtaining a new certificate
    Performing the following challenges:
    http-01 challenge for mail.*****.pl
    Waiting for verification...
    Cleaning up challenges
    Failed authorization procedure. mail.kosmetykifm.pl (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://mail.*****.pl/.well-known/acme-challenge/9dbq8iQ0Pqo3RX6NEgPiKZ1Q5-r9oKN4AJmoAWt9GjU: "\n\n\n  <meta char"
    
    IMPORTANT NOTES:
     - The following errors were reported by the server:
    
       Domain: mail.*****.pl
       Type:   unauthorized
       Detail: Invalid response from
       http://mail.*****.pl/.well-known/acme-challenge/9dbq8iQ0Pqo3RX6NEgPiKZ1Q5-r9oKN4AJmoAWt9GjU:
       "\n\n\n  <meta char"
    
       To fix these errors, please make sure that your domain name was
       entered correctly and the DNS A/AAAA record(s) for that domain
       contain(s) the right IP address.
    

    any ideas what to do?

  • Daniel Orkan
    8 months ago

    Hello Xiao,

    Thank you very much for the guide, all works for me.
    Also, thank you for the support !!!

    Kind regards,
    Daniel Orkan

  • Once again. Well done. Got everything working perfectly. I couldn’t find the “buy me a beer” link, but thanks for a very thorough job. Have you done an article on virtual mailboxes yet?

  • melvin ramsey
    4 months ago

    I cannot thank you enough.
    Beautifully written article.

  • Biiiiig thank you, Xiao!!!

  • Hello,
    great set of tutorial! Thank you very much. I managed to setup postfix/dovecot thanks to you.
    However, there was one problem, I had to figure out myself and that you might want to add to your tutorial: Ubuntu 18.04 firewall ufw blocks all the ports, so it is important, to configure and open them, if ufw is active. for me, looks like this: “ufw status verbose”

    To                         Action      From
    --                         ------      ----
    25/tcp (Postfix)           ALLOW IN    Anywhere                  
    143/tcp (Dovecot IMAP)     ALLOW IN    Anywhere                  
    993/tcp (Dovecot Secure IMAP) ALLOW IN    Anywhere                  
    587                        ALLOW IN    Anywhere                  
    25/tcp (Postfix (v6))      ALLOW IN    Anywhere (v6)             
    143/tcp (Dovecot IMAP (v6)) ALLOW IN    Anywhere (v6)             
    993/tcp (Dovecot Secure IMAP (v6)) ALLOW IN    Anywhere (v6)             
    587 (v6)                   ALLOW IN    Anywhere (v6)    

    Best regards and thank you again for good documentation.

  • before “sudo certbot –apache –agree-tos –redirect –hsts –email your-email-address -d mail.your-domain.com”
    need to do “sudo apt-get update && sudo apt-get dist-upgrade”, cause some certbot python packages need to be upgraded. You got the error, while otbain certificates, if you dont upgrade some packages. Sorry for bad english.

  • Luke Taaffe
    2 months ago

    You absolute boss.

    I’ve rarely found a tutorial which just works.. for something so complicated and head spinning as well.
    Kudos mate, really.

  • I can’t seem to receive any external mail (ie: from gmail) – but everything else seems to be working well. Any thoughts?

    • found the solution – just needed to run this:

      sudo iptables -A INPUT -p tcp --dport 143 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
      • WRONG PORT LISTED ABOVE:

        sudo iptables -A INPUT -p tcp --dport 587 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

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.
  • If my answer helped you, please consider supporting this site. Thanks :)