Install Dovecot + IMAP + TLS
From:       https://www.linuxbabe.com/mail-server/secure-email-server-ubuntu-postfix-dovecot


Needs more work
Open Ports in FW


Part 2: Install Dovecot IMAP server on Ubuntu & Enable TLS Encryption
Last Updated: December 2nd, 2022 Xiao Guoan (Admin) 319 Comments Mail Server This is part 2 of building your own secure email server on Ubuntu from scratch 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 the Ubuntu server. And to encrypt our communications, we need a TLS certificate.
Open Ports in Firewall
Ubuntu doesn’t enable firewall by default. If you have enabled the UFW firewall, then you need to run the following command to open email related ports in irewall. sudo ufw allow 80,443,587,465,143,993/tcp If you use POP3 to fetch emails (I personally don’t), then also open port 110 and 995. sudo ufw allow 110,995/tcp Securing Email Server Traffic with TLS Certificate When we configure our desktop email clients, It’s always a good idea to enable TLS encryption to prevent hackers from snooping on our emails. 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 server from the default software repository. sudo apt update sudo apt dist-upgrade 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 installed 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 installed 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. ServerName mail.your-domain.com DocumentRoot /var/www/html/ Save and close the file. Enable this virtual host. sudo a2ensite mail.your-domain.com.conf Then disable the default virtual host, because it might interfere with other virtual hosts. sudo a2dissite 000-default Reload Apache for the changes to take effect. sudo systemctl reload apache2 Once the virtual host is created and enabled, run the following command to obtain Let’s Encrypt TLS certificate. sudo certbot certonly -a apache --agree-tos --no-eff-email --staple-ocsp --email you@example.com -d mail.your-domain.com Where: -a apache: Use the Apache plugin for authentication --agree-tos: Agree to terms of service. --no-eff-email: Don’t receive emails from EFF foundation. --staple-ocsp: Enables OCSP Stapling. A valid OCSP response is stapled to the certificate that the server offers during TLS. --email: Enter your email address, which is used for important notifications and account recovery. -d: domain, aka your mail server hostname. 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. postfix-tls-letsencrypt-certbot If there’s a problem when trying to obtain the TLS certificate, please read the following article to learn how to troubleshoot. How to Fix Common Let’s Encrypt/Certbot Errors 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. Make sure the /usr/share/nginx/html/ directory exists on your server. sudo mkdir -p /usr/share/nginx/html/ Reload Nginx for the changes to take effect. sudo systemctl reload nginx Once the virtual host is created and enabled, run the following command to obtain Let’s Encrypt certificate with Nginx plugin. sudo certbot certonly -a nginx --agree-tos --no-eff-email --staple-ocsp --email you@example.com -d mail.your-domain.com Where: -a nginx: Use the Nginx plugin for authentication --agree-tos: Agree to terms of service. --no-eff-email: Don’t receive emails from EFF foundation. --staple-ocsp: Enables OCSP Stapling. A valid OCSP response is stapled to the certificate that the server offers during TLS. --email: Enter your email address, which is used for important notifications and account recovery. -d: domain, aka your mail server hostname. You should see the following which means the certificate is successfully obtained. You can also see the directory under which your cert is stored. dovecot-tls-letsencrypt-certbot If there’s a problem when trying to obtain the TLS certificate, please read the following article to learn how to troubleshoot. How to Fix Common Let’s Encrypt/Certbot Errors Enable Submission Service in 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 encryption. The submission daemon listens on TCP port 587. STARTTLS is used to encrypt communications between email client and the submission daemon. Microsoft Outlook mail client only supports submission over port 465. If you are going to use Microsoft Outlook, 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 Enable Submission Service in Postfix 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 specify the location of TLS certificate and private key in Postfix configuration file. Edit main.cf file. sudo nano /etc/postfix/main.cf Edit the TLS parameter as follows. Remember to replace mail.your-domain.com with your real hostname. #Enable TLS Encryption when Postfix receives incoming emails 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_loglevel = 1 smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache #Enable TLS Encryption when Postfix sends outgoing emails smtp_tls_security_level = may smtp_tls_loglevel = 1 smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache #Enforce 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 Your Let’s Encrypt certificate and private key are stored under /etc/letsencrypt/live/mail.your-domain.com/ directory. postfix tls parameters Save and close the file. Then restart Postfix. sudo systemctl restart postfix If you run the following command, you will see Postfix is now listening on port 587 and 465. sudo ss -lnpt | grep master postfix master submission port 587 smtps port 465 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 If you use POP3 to fetch emails, then also install the dovecot-pop3d package. sudo apt install dovecot-pop3d Check Dovecot version: dovecot --version Sample output: 2.3.16 (7e2e900c1a) Enabling IMAP/POP3 Protocol Edit the main config file. sudo nano /etc/dovecot/dovecot.conf Add the following line to enable IMAP protocol. protocols = imap ubuntu dovecot enable IMAP protocol If you use POP3 to fetch emails, then also add POP3 protocol. protocols = imap pop3 Save and close the file. Configuring Mailbox Location By default, Postfix and Dovecot use mbox format to store 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 The default configuration uses mbox mail format. mail_location = mbox:~/mail:INBOX=/var/mail/%u Change it to the following to make Dovecot use the Maildir format. Email messages will be stored under the Maildir directory under each user’s home directory. mail_location = maildir:~/Maildir We need to add the following line in the file. (On Ubuntu 18.04 and 20.04, this line is already 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 adduser dovecot mail Using Dovecot to Deliver Email to Message Store Although we configured Dovecot to store emails in Maildir format, by default, Postfix uses its built-in local delivery agent (LDA) to move inbound emails to the message store (inbox, sent, trash, Junk, etc), and it will be saved in mbox format. We need to configure Postfix to pass incoming emails to Dovecot, via the LMTP protocol, which is a simplified version of SMTP, so incoming emails will saved in Maildir format by Dovecot. LMTP allows for a highly scalable and reliable mail system. It also allows us 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 { mode = 0600 user = postfix group = postfix } } dovecot lmtp ubuntu 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 incoming 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. 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. Then find the following line, #auth_username_format = %Lu Uncomment it and change its value to %n. auth_username_format = %n By default, when Dovecot tries to find or deliver emails for a user, it uses the full email address. Since in this part, we only set up canonical mailbox users (using OS users as mailbox users), Dovecot can’t find the mailbox user in full domain format (username@your-domain.com), so we need to set auth_username_format = %n to drop the domain part, then Dovecot should be able to find the mailbox user. This also allows us to use the full email address (username@your-domain.com) to log in. ubuntu dovecot auth_username_format 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 Change ssl = yes to ssl = required to enforce encryption. ssl = required Then find the following lines. ssl_cert = Account Settings -> Account Actions -> Add Mail Account to add a mail account. 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. ubuntu postfix dovecot letsencrypt Hint 1: You can also use port 993 with SSL/TLS encryption for IMAP, and use port 465 with SSL/TLS encryption for SMTP. You should NOT use port 25 as the SMTP port in mail clients to submit outgoing emails. Hint 2: If you use Microsoft 365 Outlook email client, then you shouldn’t enable Secure Password Authentication (SPA), which is a proprietary Microsoft protocol. Your password is already encrypted by TLS. 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: user1@your-domain.com, and the password for the email address is the same password for the user1 user. To create a local Unix account, run sudo adduser user1 Note: Dovecot doesn’t allow you to log in with the root account. You need to create separate user accounts. You can list all available mailbox users with: sudo doveadm user '*' It’s recommended to restart Dovecot after adding users, so Dovecot can recognize new mailbox users. sudo systemctl restart dovecot Troubleshooting Tips As a rule of thumb, you should always check the mail log (/var/log/mail.log) on your mail server when an error happens. The following is a list of specific errors and troubleshooting tips. Can’t login from Mail Clients If you can’t log into your mail server from a desktop mail client, scan your mail server to find if the ports (TCP 587, 465, 143, and 993) 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/mail.log), which may give you some clues. If Dovecot fails to start, the error might not be logged to the /var/log/mail.log file, you can run the following command to see what’s wrong. sudo journalctl -eu dovecot For example, some folks may have the following error in the journal. doveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-master.conf line 78: Unknown setting Most of the time, it’s a simple syntax error, like a missing curly bracket. Open the configuration file, go to the specified line and fix the error. If you find the following error message in the mail log 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 Then open the Dovecot TLS configuration file. sudo nano /etc/dovecot/conf.d/10-ssl.conf Add the following line in this file. ssl_dh = : Relay access denied; from= to= proto=ESMTP helo= You can display the current value of $mydestination with: postconf mydestination Some folks might not have the main domain name in the list like so: mydestination = $myhostname, localhost.$mydomain, localhost Then run the following command to add the main domain name to the list. sudo postconf -e "mydestination = yourdomain.com, \$myhostname, localhost.\$mydomain, localhost" Reload Postfix for the changes to take effect. sudo systemctl reload postfix User Doesn’t Exist If you see the following error message in the mail log (/var/log/mail.log), it’s likely that you forgot to set auth_username_format = %n In /etc/dovecot/conf.d/10-auth.conf file. mail postfix/lmtp[2256]: 68E00FC1A5: to=, relay=mail.example.com[private/dovecot-lmtp], delay=509, delays=509/0.03/0.03/0.02, dsn=5.1.1, status=bounced (host mail.example.com[private/dovecot-lmtp] said: 550 5.1.1 User doesn't exist: user1@example.com (in reply to RCPT TO command)) iOS Mail App If you use the iOS Mail app to log into your mail server and encounter the following error. ios the mail server is not responding You can try to fix it by enforcing SSL encryption, for both SMTP and IMAP. ios mail enforce SSL encryption Fun fact: It seems the iOS Mail app has difficulty in supporting STARTTLS on IMAP port 143, but it supports STARTTLS on the submission port 587. If you encounter the “No password provided” error in the iOS Mail app, it’s likely that you have a typo when entering the username in the Mail account settings, or you didn’t enable SSL in the Mail account settings. ios mail no password provided Unable to Receive Email From Gmail, Hotmail, Yahoo Mail, etc If you can’t receive emails from Gmail, Hotmail, Yahoo Mail, etc, here are the possible causes: Your MX record is wrong, or not propagated to the Internet yet. Your mail server hostname doesn’t have DNS A record, or is not propagated to the Internet yet. Your firewall doesn’t allow incoming connections to port 25. Maybe your mail server is behind a NAT? Postfix isn’t listening on the public IP address. Check the mail log (/var/log/mail.log) to find out if there are other errors in your Postfix and Dovecot configuration. You can use the Network Tools Email Checker to test if your SMTP server is reachable from the Internet. Just enter your domain email address and click the Go button. As you can see from the screenshot below, it successfully found my domain’s MX record and my SMTP server is reachable from the Internet. email checker If your SMTP servers isn’t reachable from the Internet, then you have a problem in the first 4 items. If your SMTP server is reachable from the Internet, but you still can’t receive emails, check the mail log (/var/log/mail.log) to find out if there is any errors in your Postfix and Dovecot configuration. 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 apache2 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. Dovecot Automatic Restart If for any reason your Dovecot process is killed, you need to run the following command to restart it. sudo systemctl restart dovecot Instead of manually typing this command, we can make Dovecot automatically restart by editing the dovecot.service systemd service unit. To override the default systemd service configuration, we create a separate directory. sudo mkdir -p /etc/systemd/system/dovecot.service.d/ Then create a file under this directory. sudo nano /etc/systemd/system/dovecot.service.d/restart.conf Add the following lines in the file, which will make Dovecot automatically restart 5 seconds after a failure is detected. [Service] Restart=always RestartSec=5s Save and close the file. Then reload systemd for the changes to take effect. sudo systemctl daemon-reload To check if this would work, kill Dovecot with: sudo pkill dovecot Then check Dovecot status. You will find Dovecot automatically restarted. systemctl status dovecot Next Step
I hope this article helped you set up Postfix and Dovecot on Ubuntu server. In part 3, I will show you how to create virtual mailboxes. If you prefer to use MariaDB/MySQL database server, then follow this PostfixAdmin tutorial.
  • Part 3: PostfixAdmin – Create Virtual Mailboxes on Ubuntu Mail Server (MariaDB/MySQL)
As always, if you found this post useful, subscribe to our newsletter to get more tips and tricks. Take care 🙂