Installing Dovecot and sieve on a vpopmail + qmail server

dovecot-2.2 has been released and the vpopmail driver is still broken. As Mike has already commented below, it is not worth sticking with the vpopmail authentication backend, when we can easily configure the sql driver via mysql. In addition, the sql driver also provides the iteration feature (not implemented by vpopmail), which is needed when purging the Track and the Junk mailboxes.

The sql driver (as far as my configuration is concerned) requires that the password is transmitted as plain text. This is not a problem because we are going to enable only SSL/TLS remote connections. Anyway we have to adjust roundcube so that it will not pass the password as CRAM-MD5.


Overview

Dovecot is an open source IMAP and POP3 email server for Linux/UNIX-like systems, written with security primarily in mind. Dovecot is an excellent choice for both small and large installations. It's fast, simple to set up, requires no special administration and it uses very little memory.

And I can say that this is really true, it's simple to configure, the project is alive and the documentation is exhaustive. In addition there is the support for vpopmail (while Courier IMAP no more).

I found Dovecot so friendly that I decided to switch off qmail-pop3d and use Dovecot not only as an IMAP but also as a POP3 server. I will show how to configure a secure connection as well.

If you want to support filters in your email you have to manage Sieve rules by means of the dovecot-managesieve plugin. When you create a filter with your webmail or email client, you write a Sieve script to customize how messages are delivered, e.g. whether they are forwarded, rejected or stored in special folders. But, in order to do so, Dovecot must also act as a Local Delivery Agent in place of vpopmail/vdelivermail, e.g. it must be Dovecot to store the email messages in the users' Maildirs. This guide will try to show how to accomplish this.

Installing

cd /usr/local/src
wget http://www.dovecot.org/releases/2.2/dovecot-2.2.2.tar.gz
tar xzf dovecot-2.2.2.tar.gz
chown -R root.root dovecot-2.2.2
cd dovecot-2.2.2

./configure \
--prefix=/usr/local/dovecot \
--with-vpopmail \
--with-sql \
--with-mysql \
--with-docs \
--with-ssl \
--without-shadow \
--without-pam \
--without-ldap \
--without-pgsql \
--without-sqlite

Install prefix . : /usr/local/dovecot
File offsets ... : 64bit
I/O polling .... : epoll
I/O notifys .... : inotify
SSL ............ : yes (OpenSSL)
GSSAPI ......... : no
passdbs ........ : static passwd passwd-file checkpassword sql vpopmail
: -shadow -pam -bsdauth -sia -ldap
userdbs ........ : static prefetch passwd passwd-file checkpassword sql vpopmail nss
: -ldap
SQL drivers .... : mysql
: -pgsql -sqlite
Full text search : squat
: -lucene -solr

Check if SSL was detected and if the sql/mysql authentication backend is supported. Compile:

make

If the old dovecot is running, stop it and delete the symbolic link before installing:

dovecotctl stop
rm /usr/local/dovecot
make install
cd /usr/local mv dovecot dovecot-2.2.2
ln -s dovecot-2.2.2 dovecot
This installs Dovecot in /usr/local/dovecot.

Configuring

Create the dovecot user and group and the log folder and the directory where to store runtime data.

groupadd dovecot
useradd -g dovecot dovecot
useradd -g dovecot dovenull

mkdir -p /usr/local/var/log/dovecot 
ln -s /usr/local/var/log/dovecot /var/log/
touch /var/log/dovecot/dovecot.log
chgrp vchkpw /var/log/dovecot/dovecot.log
chmod 660 /var/log/dovecot/dovecot.log

The config files must be copied from the share/doc to etc/dovecot folder

cd /usr/local/dovecot/etc/dovecot
cp -rp /usr/local/dovecot/share/doc/dovecot/example-config/* .

Adjust the MANPATH variable (add this line to your /etc/profile as well):

export MANPATH=$MANPATH:/usr/local/dovecot/share/man

Dowload my dovecot's config files

  • Download from here

If you don't want to have the trouble to modify your conf files and want to follow the directives of this guide you can download my config files and adjust them to your needs.

cd /usr/local/dovecot/etc
wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/dovecot.conf.tar.gz
tar xzf dovecot.conf.tar.gz
cd dovecot
chown -R root.root .

dovecot.conf

protocols = imap pop3
# delete IP6 addresses here
listen = *
dict {
  #quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
  #expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext
}
!include conf.d/*.conf
!include_try local.conf

Note that all conf.d/*.conf files will be included, so rename what is not needed.

10-auth.conf

disable_plaintext_auth = yes # we are going to configure SSL and the sql driver requires it
# To append @domain to username in plaintext logins
auth_default_realm = defaultdomain.net
auth_mechanisms = plain login # the sql drivers requires that the pwd is transmitted with no encryption
# !include auth-system.conf.ext # now commented
# !include auth-vpopmail.conf.ext # commented
!include auth-sql.conf.ext

auth-sql.conf.ext

passdb {
driver = sql
# Path for SQL configuration file, see example-config/dovecot-sql.conf.ext
args = /usr/local/dovecot/etc/dovecot/conf.d/dovecot-sql.conf.ext
}

userdb {
driver = sql
args = /usr/local/dovecot/etc/dovecot/conf.d/dovecot-sql.conf.ext
}

dovecot-sql.conf.ext

# This file is opened as root, so it should be owned by root and mode 0600.
#
# Database driver: mysql, pgsql, sqlite
driver = mysql

# Database connection string. This is driver-specific setting.
#
connect = host=[MySQL IP] dbname=vpopmail user=vpopmail password=[PASSWORD]

# Default password scheme.
#
default_pass_scheme = MD5-CRYPT

# passdb query to retrieve the password. It can return fields:
password_query = SELECT CONCAT(pw_name, '@', '%d') AS user, \
  pw_passwd AS password, \
  pw_dir as userdb_home, \
  89 AS userdb_uid, \
  89 AS userdb_gid \
  FROM `vpopmail` \
  WHERE pw_name = '%n' AND pw_domain = '%d'

# userdb query to retrieve the user information. It can return fields:
user_query = \
  SELECT pw_dir AS home, \
  89 AS uid, \
  89 AS gid \
  FROM vpopmail \
  WHERE pw_name = '%n' AND pw_domain = '%d'

# Query to get a list of all usernames.
iterate_query = SELECT CONCAT(pw_name,'@',pw_domain) AS username FROM `vpopmail`

Since this file stores the database password and is open only by root, you must secure the access priviledges:

chmod go-wrx dovecot-sql.conf.ext

10-director.conf

If you don't want to use the Director service rename the conf file, so that it will not be loaded:

mv 10-director.conf 10-director.conf.disabled

10-logging.conf

Set your log destination. I prefer to have a dedicated logfile for dovecot (default is syslog)

log_path = /var/log/dovecot/dovecot.log
plugin {
}

Logrotate

Save the below scriptlet as /etc/logrotate.d/dovecot:

cat > /etc/logrotate.d/dovecot << __EOF__
/var/log/dovecot/*.log {
missingok
notifempty
delaycompress
sharedscripts
postrotate
doveadm log reopen
endscript
}
__EOF__

10-mail.conf

We have to tell Dovecot which is the mailbox location. It will look for the Maildir in the home directory (%h):

mail_location = maildir:%h/Maildir
namespace inbox {
  inbox = yes
}

Set to 89 (vpopmail userid number) the mail_uid and mail_gid. The same for the valid first/last id as you want to manage only vpopmail users:

mail_uid = 89
mail_gid = 89

mail_privileged_group = 89
mail_access_groups = 89

first_valid_uid = 89
last_valid_uid = 89

first_valid_gid = 89
last_valid_gid = 89

Adjust the socket and the plugin folder:

auth_socket_path = /usr/local/dovecot/var/run/dovecot/auth-userdb
mail_plugin_dir = /usr/local/dovecot/lib/dovecot
mail_plugins = $mail_plugins quota

10-master.conf

Read carefully this before continuing.

#default_process_limit = 100
#default_client_limit = 1000

# Default VSZ (virtual memory size) limit for service processes. This is mainly
# intended to catch and kill processes that leak memory before they eat up
# everything.
#default_vsz_limit = 256M

# Login user is internally used by login processes. This is the most untrusted
# user in Dovecot system. It shouldn't have access to anything at all.
default_login_user = vpopmail

# Internal user is used by unprivileged processes. It should be separate from
# login user, so that login processes can't disturb other processes.
#default_internal_user = dovecot

service imap-login {
inet_listener imap {
#port = 143
}
inet_listener imaps {
#port = 993
#ssl = yes
}

# Number of connections to handle before starting a new process. Typically
# the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0
# is faster. <doc/wiki/LoginProcess.txt>
#service_count = 1

# Number of processes to always keep waiting for more connections.
#process_min_avail = 0

# If you set service_count=0, you probably need to grow this.
#vsz_limit = $default_vsz_limit
}

service pop3-login {
inet_listener pop3 {
#port = 110
}
inet_listener pop3s {
#port = 995
#ssl = yes
}
}

service lmtp {
unix_listener lmtp {
#mode = 0666
}

# Create inet listener only if you can't use the above UNIX socket
#inet_listener lmtp {
# Avoid making LMTP visible for the entire internet
#address =
#port =
#}
}

service imap {
# Most of the memory goes to mmap()ing files. You may need to increase this
# limit if you have huge mailboxes.
#vsz_limit = $default_vsz_limit

# Max. number of IMAP processes (connections)
#process_limit = 1024
}

service pop3 {
# Max. number of POP3 processes (connections)
#process_limit = 1024
}

service auth {
# auth_socket_path points to this userdb socket by default. It's typically
# used by dovecot-lda, doveadm, possibly imap process, etc. Users that have
# full permissions to this socket are able to get a list of all usernames and
# get the results of everyone's userdb lookups.
#
# The default 0666 mode allows anyone to connect to the socket, but the
# userdb lookups will succeed only if the userdb returns an "uid" field that
# matches the caller process's UID. Also if caller's uid or gid matches the
# socket's uid or gid the lookup succeeds. Anything else causes a failure.
#
# To give the caller full permissions to lookup all users, set the mode to
# something else than 0666 and Dovecot lets the kernel enforce the
# permissions (e.g. 0777 allows everyone full permissions).
unix_listener auth-userdb {
mode = 0600
user = vpopmail
group = vchkpw
}

# Postfix smtp-auth
#unix_listener /var/spool/postfix/private/auth {
# mode = 0666
#}

# Auth process is run as this user.
user = $default_internal_user
}

service auth-worker {
# Auth worker process is run as root by default, so that it can access
# /etc/shadow. If this isn't necessary, the user should be changed to
# $default_internal_user.
user = $default_internal_user
}

service dict {
# If dict proxy is used, mail processes should have access to its socket.
# For example: mode=0660, group=vmail and global mail_access_groups=vmail
unix_listener dict {
#mode = 0600
#user =
#group =
}
}

10-ssl.conf

Of course we want SSL support. First of all let's create a self-signed SSL certificate. Dovecot includes a script to build self-signed SSL certificates using OpenSSL; you can find it in doc/mkcert.sh:

cd /usr/local/src/dovecot/doc

mkcert.sh will create the SSL certificate. Before running mkcert.sh you have to customize the cert editing dovecot-openssl.cnf (in the same folder):

> nano dovecot-openssl.cnf

[ req ]
default_bits = 1024
encrypt_key = yes
distinguished_name = req_dn
x509_extensions = cert_type
prompt = no

[ req_dn ]
# country (2 letter code)
C=IT

# State or Province Name (full name)
ST=Italy

# Locality Name (eg. city)
L=MyLocality

# Organization (eg. company)
O=My Organization Name

# Organizational Unit Name (eg. section)
OU=IMAP server

# Common Name (*.example.com is also possible)
CN=mymailserver.net

# E-mail contact
emailAddress=postmaster@mymailserver.net

[ cert_type ]
nsCertType = server

Now we are ready to create the SSL certificate:

> sh mkcert.sh

and the files /etc/ssl/private/dovecot.pem and /etc/ssl/certs/dovecot.pem have been created. Remember their locations because you have to insert them in 10-ssl.conf:

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

15-lda.conf

As I already said dovecot will also act as an LDA because we want to manage sieve rules and filter our incoming emails.

postmaster_address = postmaster@yourdomain.net
hostname = mail.yourdomain.net

sendmail_path = /var/qmail/bin/sendmail
# the next two to auto create folders
lda_mailbox_autocreate = yes
lda_mailbox_autosubscribe = yes

protocol lda {
  # Space separated list of plugins to load (default is global mail_plugins).
  mail_plugins = $mail_plugins sieve quota autocreate # if you want to use sieve put sieve here
}

15-mailboxes.conf

##
## Mailbox definitions
##

# NOTE: Assumes "namespace inbox" has been defined in 10-mail.conf.
namespace inbox {

#mailbox name {
# auto=create will automatically create this mailbox.
# auto=subscribe will both create and subscribe to the mailbox.
#auto = no

# Space separated list of IMAP SPECIAL-USE attributes as specified by
# RFC 6154: \All \Archive \Drafts \Flagged \Junk \Sent \Trash
#special_use =
#}

# These mailboxes are widely used and could perhaps be created automatically:
mailbox Drafts {
special_use = \Drafts
auto = subscribe
}
mailbox Junk {
special_use = \Junk
auto = subscribe
}
mailbox Trash {
special_use = \Trash
auto = subscribe
}

# For \Sent mailboxes there are two widely used names. We'll mark both of
# them as \Sent. User typically deletes one of them if duplicates are created.
mailbox Sent {
special_use = \Sent
auto = subscribe
}
# mailbox "Sent Messages" {
# special_use = \Sent
# }

# If you have a virtual "All messages" mailbox:
#mailbox virtual/All {
# special_use = \All
#}

# If you have a virtual "Flagged" mailbox:
#mailbox virtual/Flagged {
# special_use = \Flagged
#}
}

20-imap.conf

protocol imap {
  mail_plugins = $mail_plugins imap_quota
}

20-lmtp.conf

I don't want the support for proxying to other LMTP/SMTP servers, so I disable lmtp:

mv 20-lmtp.conf 20-lmtp.conf.disabled

20-pop3.conf

protocol pop3 {
  mail_plugins = $mail_plugins quota
}

90-acl.conf

If no acl is needed you can disable it:

mv 90-acl.conf 90-acl.conf.disabled

90-plugin.conf

plugin {
# autocreate plugin
# This plugin allows administrator to specify mailboxes that must always 
# exist for all users. They can optionally also be subscribed. The 
# mailboxes are created and subscribed always after user logs in. 
# Namespaces are fully supported, so namespace prefixes need to be used 
# where necessary. 
  autocreate = Sent
  autocreate2 = Drafts
  autocreate3 = Junk
  autocreate4 = Trash
  #autocreate5 = ..etc..
  autosubscribe = Sent
  autosubscribe2 = Drafts
  autosubscribe3 = Junk
  autosubscribe4 = Trash
  #autosubscribe5 = ..etc
}

90-quota.conf

To enable maildir++ comment out this line (thanks to Nicolas for the hint!):

quota = maildir:User quota

Adjusting PATH and MANPATH

You may want to modify your environment variable as follows inside your /etc/profile:

export PATH=$PATH:/usr/local/dovecot/bin
export MANPATH=$MANPATH:/usr/local/dovecot/share/man

Comments

Dovecot-2.2.0 and Vpopmail

Hi Roberto
Thanks for your excellent guide.

I had no problems upgrading from dovecot 2.1.16 to 2.2.0
Instead of using the vpopmail auth driver, I am set up to use the sql driver. I appreciate this might not be what you are trying to achieve, but at least it will allow you to have vpopmail work with dovecot 2.2.0

My relevant configuration:

in /etc/dovecot/conf.d/10-auth.conf:
!include auth-sql.conf.ext

in /etc/dovecot/conf.d/auth-sql.conf.ext:
passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = prefetch
}

in /etc/dovecot/dovecot-sql.conf.ext:
driver = mysql
default_pass_scheme = MD5-CRYPT
password_query = SELECT CONCAT(pw_name, '@', '%d') AS user, \
  pw_passwd AS password, \
  pw_dir as userdb_home, \
  89 AS userdb_uid, \
  89 AS userdb_gid \
  FROM `vpopmail` \
  WHERE pw_name = '%n' AND pw_domain = '%d'

I haven't spent the time looking to see what has happened to the vpopmail auth driver.

Best wishes,
Michael Dick

Re: Dovecot-2.2.0 and Vpopmail

Hi Michael, thanks for your contribution.

of course the sql drivers works fine now as worked in the past. Anyway this is not the first time that the vpopmail breaks, so your comment is appreciated. Soon or later I should consider to expand this page with the sql driver method.


qmail & dovecot

Please be patient with me.....am a newbie...I've been trying to install qmail on my F16 64 bit home machine for the past 3 weeks but haven't managed to get it running yet but I'm very hopeful despite the many many frustrations. I wanted to know whether i install dovecot after the successful installation of qmail or do i start my dovecot installation 'independent' of the qmail installation. Thanks for the great piece by....

my answer is yes

Despite of the fact that you can have a dovecot successfull installation without qmail or another MTA, it doesn't make much sense having an imap server without the smtp service in order to transfer your emails around the world; at least you should have your MTA in another machine. So yes, you should install qmail firstly.

You may want to take a look at this article where is briefly explained how all things work together: http://wiki.dovecot.org/MailServerOverview


Pretty good post

Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I'll be subscribing to your feed and I hope you post again soon.

Thanks for this great HOWTO!

Thanks for this great HOWTO! Just tested it and it's ok!

some more features about quota

to makes IMAP quota working with maildir++, you should change these settings :

20-imap.conf

You should replace quota with imap_quota

90-quota.conf

You should uncomment this line:

quota = maildir:User quota

I tested it, and it's ok.

I tested it, and it's ok. Thanks for the contribution!


doveadm

First of all thanks for this HOWTO!

anyway i'm having a problem with the "doveadm -A" listing "ErrorUser listing returned failure doveadm",

"doveadm mailbox list -u user@domain" is working just fine.

did i miss something?

doveadm & vpopmail

If you are using vpopmail as a backend, I don't have an answer. It seems like the driver is not programmed to do the iteration..


doveadm expunge for vpopmail

I have found a way....this is how is working for me:
(this is just for "Trash" ...same for "Junk" ...just change mailbox param)
 
#!/bin/bash
# MySQL details

HOST="localhost";
USER="vpopmail";
PWD="vpopmailpasswod";

# Output sql to a file that we want to run
echo "USE vpopmail; select concat(pw_name,'@',pw_domain) as username from vpopmail;" > /tmp/query.sql;

# Run the query and get the results
results=`mysql -h $HOST -u $USER -p$PWD -N < /tmp/query.sql`;

# Loop through each row
for row in $results
do
/usr/local/dovecot/bin/doveadm expunge mailbox Trash -u $row savedbefore 30d
done

Excellent solution!

Can you believe it! I was facing the same problem with doveadm expunge and found out on google your excellent solution inside your comment of my own blog! Thank you..


networking

The exact same thing happened to me once, isn`t it great how networking works!