User Tools

Site Tools



With Dovecot you have the possibility utilize server-side filtering. This is very useful if you have a limited imap client, for instance an Android phone, where you do not have the option to make filtering/sorting rules. It also saves you a lot of data by only downloading messages from the inbox that is intended for the inbox. If you subscribe to just a handful of mailinglists you will soon know how much noise it makes in the inbox.

This description assumes you've got Dovecot and Postfix up and running already and only needs to change some settings to extend your setup.

create vmail user

We will need a user on the system that is not postfix, root or dovecot. Neither of these will not work as the software has limitation (security) inside of them.

What we will do is create vmail as a user and a group, and give it full ownership of the virtual directories where the mails are stored. Please take a note of the uid and gid as this number will be populated inside different configuration files later on.

groupadd -g 99 vmail
useradd -g 99 -d /usr/local/virtual/ -s /bin/false -u 99 vmail
chown -R vmail.vmail /usr/local/virtual/
chgrp vmail /etc/dovecot/dovecot.conf


To get the sql part inline with the vmail user you will have to make sure that its uid and gid is returned for every query the daemon makes against mysql.

Therefor align it like this:

user_query = SELECT maildir, 99 AS uid, 99 AS gid FROM mailbox WHERE username = '%u' AND active = '1'


To make use of sieve scripts we need a LDA that has that capability. When using Postfix out of the box this is not the case. Postfix uses the “virtual” transport daemon for sending the mails inside our virtual maildir. This LDA hasn't got what we need thus we exchange it with the “deliver” that comes with Dovecot. To enable the Dovecot LDA insert the following into /etc/postfix/

dovecot   unix  -       n       n       -       -       pipe
    flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ${recipient}

Note the user parameter running the command as vmail.

If you have a content filter running also, like Dspam, this will not interfere as the content filter is getting the mail before “deliver” sends the mail into the maildir.


Now we need to tell Postfix to use the Dovecot LDA and to map the uid and gid to our newly created vmail user.

Insert/change these settings:

dovecot_destination_recipient_limit = 1
virtual_gid_maps = static:99
virtual_minimum_uid = 99
virtual_transport = dovecot
virtual_uid_maps = static:99


Next thing up is the Dovecot configuration itself. We again need to align the uid and gid to match our vmail user and to enable the LDA.

Change to:

first_valid_uid = 99
first_valid_gid = 99
mail_uid = 99
mail_gid = 99

protocol lda {
  # Address to use when sending rejection mails.
   postmaster_address =
   auth_socket_path = /var/run/dovecot/auth-master
   mail_plugins = sieve

socket listen {
    master {
      # Master socket provides access to userdb information. It's typically
      # used to give Dovecot's local delivery agent access to userdb so it
      # can find mailbox locations.
      path = /var/run/dovecot/auth-master
      mode = 0600
      # Default user/group is the one who started dovecot-auth (root)
      user = vmail
      group = vmail

plugin {
 sieve = /usr/local/virtual/%d/%n/.dovecot.sieve

In the “protocol lda” section we enable the sieve plugin, now Dovecot knows that it should start looking for a sieve script. In the plugin section we specify where this script can be found. We make use of variables that more or less corresponds to the mail_location setting so we can have different script per mail user.

Now restart Dovecot and Postfix to enable the new configuration:

sudo invoke-rc.d dovecot restart
sudo invoke-rc.d postfix restart

Sieve script

Imap servers can be configured in different ways not making it obvious on how the notation of the destination folder should be. Here telnet is your friends.

telnet 143

. login secretpassword 
. OK User logged in

. list "" "*"
* LIST (\HasChildren) "." "INBOX" 
* LIST (\HasNoChildren) "." "INBOX.Drafts" 
* LIST (\HasNoChildren) "." "INBOX.Sent Items" 
* LIST (\HasNoChildren) "." "INBOX.Trash" 
* LIST (\HasNoChildren) "." "INBOX.test1" 
* LIST (\HasNoChildren) "." "INBOX.test2"
* LIST (\HasNoChildren) "." "test3"  
. OK Completed (0.460 secs 7 calls)

Here we've telnet'et to the imap server and logged in. Remember the dot in front of the login command (. login) it must be there. Type in the username and password seperated with a space/blank to login. If you've typed correctly you can now run the list command to get your folders. Again remember the dot in front of the command (. list).

With this result you can see that to get a mail into the test1 folder you address it like “INBOX.test1” and to get a mail into test3 you use just “test3”.


Here is an example of how a sieve script could look like. This script will look the mail address “” in to, cc and bcc field of the mailbody and move it into the OpenVPN folder:

require "fileinto";
if address :is ["To", "Cc", "Bcc"] "" {
  fileinto "OpenVPN";


Dovecot supports the managesieve api/plugin which is used to simplify management of sieve scripts. Instead of hacking around with files on the server managesieve opens a way to allow users to securely upload scripts through the imap daemon. Very handy :-)

To make this work the following steps must be executed.

Dovecot configuration

To enable the managesieve in dovecot add the word “managesieve” to the protocols line in dovecot.conf:

protocols = imap imaps managesieve

Now configure the settings for managesieve by adding this to the configuration file:

protocol managesieve {
listen = *:2000
managesieve_logout_format = bytes ( in=%i : out=%o )
managesieve_implementation_string = dovecot

This tells dovecot to open a port on 2000/tcp on all interfaces and define the logging format when scripts are uploaded. The “managesieve_implementation_string = dovecot” is to make the implementation more compatible with sieve clients.

The final setting in dovecot.conf:

plugin {
 sieve = /usr/local/virtual/%d/%n/.dovecot.sieve
 sieve_dir = /usr/local/virtual/%d/%n/sieve

Here we say that the sieve script file (“.dovecot.sieve”) is to be placed in the root folder of the users maildir and that the uploaded scripts are to be placed in the subfolder “sieve”. What will happen is that the “.dovecot.sieve” file will be turned into a symbolic link pointing to real scriptfile inside the sieve directory. If the sieve folder doesn't exist it will automatically be created the first time a script is stored.

Roundcube sieverules

To build the sieve scripts we can now use a client. Making the task of building a rule more user friendly finding a gui enabled client is a good idea. What you can choose is using a plugin to Roundcube webmail called “sieverules” (download it here:

Download the plugin and extract it into the Roundcube plugin directory, like this “/var/www/roundcube/plugins”. Enable the plugin inside the configuration file by adding/setting the value:

$rcmail_config['plugins'] = array('sieverules');

If other plugins already is used you just append 'sieverules' to the list with comma as a separator.

This particular plugin requires a PHP library called php5-idn (because it supports IDN domain names). This must be installed to make the plugin work:

sudo apt-get install php5-idn

Inside /etc/php5/conf.d you will find the file idn.ini that looks like this:

Remove the hash mark and bounce the webserver to enable the needed IDN support.

The “sieverules” plugin has a lot of configuration options that you can play with but the default should get you going out-of-the-box. If you encounter errors or problems you can find a nice error log in the Roundcube logs directory.

With the sieverules plugin enabled you will find a new tab inside Settings:

Click the Filter tab and start building some nice filtering rules:

The above rule will look like this in the sieve script file:

## Generated by Roundcube Webmail SieveRules Plugin ##
require ["fileinto"];

# rule:[google]
if anyof (address :contains "From" "")
	fileinto "Google";
indexes/postfix-dovecot-sieve.txt · Last modified: d/m/Y H:i by domingo