How to Install Dovecot IMAP Mail Server and Fetchmail on Debian

This article describes how to build a IMAP mail server based on Dovecot with Debian as operating system based on following versions:

  • Debian 10.x
  • Dovecot 2.3.4.x
  • Apache 2.4
  • Roundcube 1.4.8

In the configuration described below Dovecot only serves as a IMAP server for emails.

Emails will be fetched from remote IMAP servers via Fetchmail.

SMTP will not be provided by this server. Instead for sending emails external SMTP servers at your mail provider will be used. Exim4 will be configured to forward mails to such an external smarthost. All clients will connect directly to that external SMTP server. This simplifies installation, configuration and operation one does not have to care for a SMTP mail server.

Dovecot and Debian will be configured to use Maildir.

Exim4

Installation

# apt-get install exim4

Configure an External Smarthost for SMTP

# dpkg-reconfigure exim4-config

Werte können folgendermaßen gefüllt werden:

Einstellung Beispielwerte
Generelle E-Mail-Einstellungen Versand über Sendezentrale (Smarthost); Empfang über SMTP oder Fetchmail oder

Versand über Sendezentrale (Smarthost); Keine lokale E-Mail-Zustellung

E-Mail-Name des Systems mail.domain.tld
IP-Adressen, an denen eingehende SMTP-Verbindungen erwartet werden 127.0.0.1;::1
Weitere Ziele, für die die E-Mails angenommen werden sollen Feld leer lassen. -> Optional hier die Maildomäne eingeben?
Rechner, für die E-Mails weitergeleitet werden (Relay) Leer lassen, damit der Server nicht als Relay verwendet wird.
IP-Adresse oder Rechnername der Sendezentrale für ausgehende E-Mails SMTP Server des Externen Providers
Lokalen E-Mail-Namen in ausgehenden E-Mails verbergen Nein
Versandart bei lokaler E-Mail-Zustellung Maildir-Format im Home-Verzeichnis
Einstellungen auf kleine Dateien aufteilen (Splitkonfiguration) Nein

Wenn Einstellungen nicht auf kleine Dateien aufgeteilt werden, werden die Einstellungen aus /etc/exim4/*.conf -Dateien verwendet.

Passwörter für SMTP-authentifizierung eingeben in:

nano /etc/exim4/passwd.client

Format für Passwörter

<smarthostserver>:<username_für_anmeldung>:<passwort>

Send a test mail

echo This is a Text body | mail -s "<subject>" <recipient>


Reconfigure Debian for Maildir

Show Mail Status on Login

In order to get notifications about mail status when logging in the following changes have to be done:

Anpassungen /etc/pam.d/login

 # in /etc/login.defs to make sure that removing a user 
 # also removes the user's mail spool file.
 # See comments in /etc/login.defs
-session    optional   pam_mail.so standard
+session    optional   pam_mail.so dir=~/Maildir standard

Anpassungen /etc/pam.d/sshd

 # Print the status of the user's mailbox upon successful login.
-session    optional     pam_mail.so standard noenv # [1]
+session    optional     pam_mail.so dir=~/Maildir standard # [1]

Anpassungen /etc/pam.d/su

 # "nopen" stands to avoid reporting new mail when su'ing to another user
-session    optional   pam_mail.so nopen
+session    optional   pam_mail.so dir=~/Maildir nopen

Reconfigure Mutt

Reconfigure Mutt to Maildir:

Create new file /etc/Muttrc.d/my-mutt.rc.

set mbox_type=Maildir
set folder = '~/Maildir'
set record="+.Sent";
set postponed="+.Drafts"

For more details see Mutt

Install Roundcube

Install Apache

apt-get install apache2

Add VirtualHost to Apache

Create a new configuration file /etc/apache2/sites-available/roundcube.conf:

<VirtualHost *:80>
  DocumentRoot /var/www/roundcube
  ServerName roundcube.yourdomain.com

  RewriteEngine on
  RewriteCond %{SERVER_NAME} =roundcube.yourdomain.com
  RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

<Directory /var/www/roundcube>
  AllowOverride All
</Directory>

Enable VirtualHost in Apache:

a2ensite roundcube
systemctl reload roundcube

Add Let's Encrypt to VirtualHost

Install certbot if not already installed:

apt-get install certbot

Enable Let's Entrypt for new VirtualHost:

certbot --apache 

Follow instructions on screen.

For more details see Let's_encrypt

Add PHP Modules

apt-get install php-ldap

Enable Module Expires (needed for Roundcube):

a2enmod expires

Download Roundcube

Download to /var/www

wget https://github.com/roundcube/roundcubemail/releases/download/1.4.x/roundcubemail-1.4.x-complete.tar.gz

Extract with

tar xvf roundcubemail-1.4.x-complete.tar.gz

Rename folder roundcubemail-1.4.x to roundcube.

Follow INSTALL text file.

Create Database

Login to MariaDB as root and create database with following commands:

CREATE DATABASE roundcube CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER roundcube@localhost IDENTIFIED BY '<enter-password-here>';
GRANT ALL PRIVILEGES ON roundcube.* TO roundcube@localhost;

Create initial database tables with:

mysql -u -p roundcube < /var/www/roundcube/SQL/mysql.initial.sql

Installation

Open URL: https://roundcube.yourserver.com/installer

Follow instructions.

Values for config.inc.php:

$config['default_host'] = 'ssl://roundcube.yourdomain.com';
$config['default_port'] = 993;

Identity SMTP Plugin

This plugin enables to use different SMTP servers based on a given identity.

Source: https://github.com/deflomu/Roundcube-SMTP-per-Identity-Plugin

cd /var/www/roundcube/plugins
git clone git://github.com/deflomu/Roundcube-SMTP-per-Identity-Plugin identity_smtp

Alter configuration file /var/www/roundcube/config/config.inc.php.

Add identity_smtp:

$config['plugins'] = array( 
  ...,
  'identity_smtp',
);

Identity SMTP-Plugin requires a default SMTP server in the Roundcube configuration file:

$config['smtp_server'] = 'ssl://localhost';

Cronjob for Database Cleaning

Create a new file /etc/cron.d/roundcube:

# /etc/cron.d/roundcube: Housekeeping cronjob for Roundcube
#
# m h dom mon dow user     command
13  2  *   *   *  www-data /var/www/roundcube/bin/cleandb.sh

Reconfigure PHP

The maximum size of email attachments and other file uploads is controlled by PHP settings: upload_max_filesize and post_max_size. Read more about PHP settings at https://github.com/roundcube/roundcubemail/wiki/Installation#php-configuration.

Create new file /etc/php/x.x/fpm/conf.d/roundcube.ini:

[PHP]
upload_max_filesize = 50M
post_max_size = 50M

Security

Disable installer in config.inc.php by adding following line:

$config['enable_installer'] = false;

Move root of vhost to public_html:

<VirtualHost *:80>
  DocumentRoot /var/www/roundcube/public_html 
  ...
</VirtualHost>

Do the same in the vhost file for SSL created by certbot.

Install Dovecot Server

Install

apt-get install dovecot-imapd

Configure

Create configuration file /etc/dovecot/conf.d/99-my-dovecot.conf:

disable_plaintext_auth = yes
mail_location = maildir:~/Maildir
ssl = required
ssl_cert = </etc/letsencrypt/live/host.yourserver.tld/fullchain.pem
ssl_key = </etc/letsencrypt/live/host.yourserver.tld/privkey.pem

namespace inbox {
  mailbox Drafts {
    special_use = \Drafts
  }
  mailbox Junk {
    special_use = \Junk
  }
  mailbox Trash {
    special_use = \Trash
  }
  mailbox Sent {
    special_use = \Sent
  }
  mailbox Archive {
    special_use = \Archive
  }
}

For details see Dovecot-IMAP-Server_installieren_(Debian)

Test

See Dovecot-IMAP-Server_installieren_(Debian)#Zugriff_testen

IMAP Download via Fetchmail

For more details see Fetchmail (Debian)

Install Fetchmail

apt-get install fetchmail

Configure IMAP IDLE

Source: http://fnxweb.com/blog/2012/07/14/using-multiple-fetchmail-instances-for-instant-gratification/

The description above is altered to match Debian folders and security.

Files:

http://www.fnxweb.com/data/fetchmail-service --> Save as fetchmail-imap-idle at /usr/local/bin

http://www.fnxweb.com/data/fetchmail.service --> Save as fetchmail-imap-idle.service at /usr/local/bin

Add execute permissions:

chmod +x /usr/local/bin/fetchmail-imap-idle

Create symbolic link to fetchmail-imap-idle.service in /etc/systemd/system:

ln -s /usr/local/bin/fetchmail-imap-idle.service /etc/systemd/system/fetchmail-imap-idle.service

Place config files at: /etc/fetchmail.conf.d/*.conf

Each config file should contain only one IMAP connection.

Example /etc/fetchmail.conf.d/my-imap-account1-inbox.conf

poll host.domain.tld protocol IMAP
     user "<username@host.domain.tld>" with pass "<password>" is "<username@localhost>" here
     idle
     ssl

Avoid parameter fetchall in IMAP IDLE config files as this leads to somewhat intransparent behavior of the local dovecot LDA and emails don't appear at once rather than somewhat delayed.

Fix: Try to send another mail to remote mailbox. After that it seems that all missing mails appear magically in Dovecot mailbox.

Alter /usr/local/bin/fetchmail-imap-idle:

Change lines 10 and 11 as follows:

fetchmailuser=fetchmail
fetchmailgroup=nogroup

Alter paths and executable names in /etc/systemd/system/fetchmail.service as follows:

[Unit]
Description=A remote mail retrieval and forwarding utility
After=network-online.target sendmail.service 

[Service]
ExecStart=/usr/local/bin/fetchmail-imap-idle start
ExecReload=/usr/local/bin/fetchmail-imap-idle restart
ExecStop=/usr/local/bin/fetchmail-imap-idle stop
Type=forking
GuessMainPID=no

[Install]
WantedBy=multi-user.target

Activate service as follows:

systemctl enable fetchmail-imap-idle
systemctl start fetchmail-imap-idle

Configure Periodical Downloads via Cronjob

Create ~/.fetchmailrc which downloads all mails from INBOX folder at the specified host:

poll host.domain.tld protocol IMAP
     user "<username@host.domain.tld>" is "<username@localhost>" here
     ssl fetchall

...as well as other folders via MDA...

poll host.domain.tld protocol IMAP
     user "<username@host.domain.tld>" is "<username@localhost>" here
     folder Sent
     ssl fetchall
     mda "/usr/lib/dovecot/deliver -d <username@localhost> -m Sent"

Create password file ~/.netrc:

machine <host1.domain.tld>
login <username@host1.domain.tld>
password <pass>

machine <host2.domain.tld>
login <username@host2.domain.tld>
password <pass>

Create user specific cronjob with crontab -e and add following line:

*/3 * * * * fetchmail

Remove Unseen Flag in Sent Folder

When using Fetchmail to download Sent folder every downloaded mail will be flagged as unseen.

In order to mark them seen create following cronjob with crontab -e.

*/3 * * * * doveadm flags add -u <username@localhost> '\Seen' mailbox Sent unseen 

You can also chain doveadm to fetchmail which results in:

*/3 * * * * fetchmail && doveadm flags add -u <username@localhost> '\Seen' mailbox Sent unseen