Dovecot Sieve plugin ==================== 1. Dovecot Sieve plugin 1. Introduction 2. Getting the sources 3. Compiling 4. Configuring 5. Per-user Sieve script location 6. Script compiling and errors 7. How to stop using sieve 8. Features 1. CMUSieve Plug-in 2. New Sieve Plug-in 9. ManageSieve server 10. Validate your script 11. v1.0 namespaces and fileinto 12. Vacation auto-reply 13. Example scripts 1. SpamAssassin tagged mail filtering 2. Mail filtering by various headers 3. Flagging or Highlighting your mail 4. Vacation auto-reply 5. Include scripts 14. French Howto 15. Migration from Procmail Introduction ------------ The Dovecot Sieve plug-in provides mail filtering facilities at time of final message delivery using the Sieve (RFC 5228 [http://www.ietf.org/rfc/rfc5228.txt]) language. By writing Sieve scripts, users can customize how messages are delivered, e.g. whether they are forwarded or stored in special folders. The Sieve language is meant to be simple, extensible and system independent. And, unlike most other mail filtering script languages, it does not allow users to execute arbitrary programs. This is particularly useful to prevent virtual users from having full access to the mail store. The intention of the language is to make it impossible for users to do anything more complex (and dangerous) than write simple mail filters. This wiki page explains how to use the Sieve language with Dovecot. It is implemented as a plug-in to the deliver [http://wiki.dovecot.org/LDA] LDA. Currently, two concurrent implementations of the Sieve plug-in are available. The original plug-in called *CMUSieve* uses the Sieve interpreter from the Cyrus project and has been available for Dovecot versions ranging from v1.0 to the latest v1.2. Recently, a fully rewritten implementation was released for Dovecot v1.2. This new plug-in is simply called *Sieve*. The main reason for rewriting the Sieve engine is to provide more reliable script execution and to provide better error messages to users and system administrators. Getting the sources ------------------- Both implementations of the Sieve plug-in are distributed in a separate package: * You can get the CMUSieve plug-in from Dovecot's download page [http://www.dovecot.org/download.html]. * You can get the new Sieve plug-in at this web page [http://www.rename-it.nl/dovecot/1.2/]. The tarballs for the Sieve releases are called dovecot-1.2-sieve-x.y.z.tar.gz in which the x.y.z represents the particular version. Alternatively, you can obtain the latest versions from Mercurial repositories: * The CMUSieve plug-in has different repositories for the available Dovecot versions: * For v1.0: 'http://hg.dovecot.org/dovecot-sieve-1.0' * For v1.1 and v1.2: 'http://hg.dovecot.org/dovecot-sieve-1.1' * The repository of the new Sieve plugin is: 'http://hg.rename-it.nl/dovecot-libsieve' In Ubuntu, starting from version 7.10 Gutsy, the CMUSieve plug-in already comes with Dovecot regular install. In this case you do not have to download additional packages. Simply skip "Compiling" section and proceed to "Configuring". This is also true for Debian Etch. Compiling --------- Compilation is identical among the CMUSieve and the new Sieve plug-in. Use '--with-dovecot=' to point to 'dovecot-config' file's directory. There are two possibilities where this could exist: 1. If you configured Dovecot with '--enable-header-install', you'll have 'dovecot-config' installed in '$prefix/lib/dovecot/' directory. 2. Compiled Dovecot sources' root directory. So for example: ---%<------------------------------------------------------------------------- ./configure --with-dovecot=/usr/local/lib/dovecot make sudo make install ---%<------------------------------------------------------------------------- If you downloaded the sources using Mercurial, you will need to execute './autogen.sh' first to build the automake structure in your source tree. This process requires autotools and libtool to be installed. Binaries for command line tools like 'sievec' and 'sieved' are built only if you use method 2, because they need to link with Dovecot's libraries. These two tools can be used to compile and decompile Sieve scripts. You probably do not need these, except when using the Python server (it uses 'sievec' to verify uploaded scripts). The new Sieve implementation has a few additional tools that can be used to verify and debug scripts from the command line (refer to the README file for more information). Configuring ----------- First, you'll need to make sure you're using Dovecot's [LDA.txt] to deliver incoming mail to users' mailboxes. Then you need to enable the Sieve plugin in your 'dovecot.conf'. The CMUSieve plugin is called 'cmusieve' and the new Sieve plugin is called 'sieve'. The CMUSieve plugin is for example enabled as follows: ---%<------------------------------------------------------------------------- protocol lda { .. # If there is no user-specific Sieve-script, global Sieve script is # executed if set. (v1.0.1 and older used "global_script_path") # (e.g. /etc/dovecot/default.sieve) #sieve_global_path = # Support for dynamically loadable plugins. mail_plugins is a space separated # list of plugins to load. mail_plugins = cmusieve # ... other plugins like quota } ---%<------------------------------------------------------------------------- In this context /sieve_global_path/ refers to a *filename*, and not a directory. Per-user Sieve script location ------------------------------ By default Dovecot looks for user's Sieve script from '.dovecot.sieve' file in user's home directory. This requires that the [VirtualUsers.txt] is set for the user. If you want to store the script elsewhere, you can override the default by returning 'sieve' setting containing path to the file. This can be done in two ways: 1. Define 'sieve' setting in plugin section of 'dovecot.conf'. 2. Return 'sieve' extra field from [UserDatabase.ExtraFields.txt]. For example to create a Sieve script file named '.sieve' in '/var/sieve-scripts', use: ---%<------------------------------------------------------------------------- plugin { # NOTE: %variable expansion works only with Dovecot v1.0.2+ sieve = /var/sieve-scripts/%u.sieve } ---%<------------------------------------------------------------------------- You may use templates like %u in the example. See all [Variables.txt]. A relative path (or just a filename) will be interpreted to point under the user's home directory. Script compiling and errors --------------------------- When the Sieve script is executed for the first time (or after it has been changed), it's compiled into into a binary form. This is where the CMUSieve plug-in and the new Sieve plug-in differ: * For CMUSieve, the binary is stored by appending "c" letter after the script name (e.g. ".dovecot.sievec"). If there are errors in the script, the error messages are stored into a ".err" file (e.g. ".dovecot.sieve.err"). This means that deliver must have write access to the directory where the script is stored. Global scripts have the same problem. Either allow deliver to write to the global script's directory, or compile the script before deliver sees it. Scripts can be compiled using the 'sievec' tool. * The new Sieve implementation uses the '.svbin' extension to store compiled Sieve scripts (e.g. ".dovecot.svbin"). If there are errors or warnings in the script, the messages are appended to a ".log" file (e.g. ".dovecot.sieve.log") until it grows too large. When that happens, the old log file is rotated to a ".log.0" file and an empty log file is started. Currently, scripts included using the include extension are compiled into the main binary, meaning that the plug-in only needs write access to the directory where the main script is located. This is also where the log file is always written. Messages that could be of interest to the system administrator are also written to the Dovecot logging facility (usually syslog). How to stop using sieve ----------------------- A user may want to stop using his/her own sieve (and maybe return to using global sieve script). Or the administrator may want to disable global sieve. To stop using sieve, both the .sieve source file and the compiled .sieve *c* file must be deleted(or renamed). Features -------- Both implementations of the Sieve plug-in support various extensions to the Sieve language. You can find more information about these at the Sieve Mail Filtering Language Charter [http://www.ietf.org/html.charters/sieve-charter.html] or the Sieve.info wiki page [http://www.sieve.info/]. *NB: Sieve doesn't support running external programs*. CMUSieve Plug-in ---------------- The CMUSieve plugin v1.0.x code is taken from Cyrus IMAP v2.2.12. The CMUSieve plugin v1.1.x code is taken from Cyrus IMAP v2.3.8. Whatever information you can find about those versions of Cyrus Sieve, it should also apply to these plug-ins. The supported Sieve features are: * fileinto * reject * envelope * vacation * imapflags (old draft specification) * notify (old draft specification) * regex * subaddress * relational * copy (v1.1 only) * body (v1.1 only) * include (v1.1 only) New Sieve Plug-in ----------------- The new Sieve plug-in aims to at least match the extensions supported by the CMUSieve plug-in: * fileinto * reject * envelope * vacation * imap4flags * regex * subaddress * relational * copy * body * include * encoded-character * variables In this respect the notify extension is notably missing. This is currently under development. Note that the CMUSieve plug-in implements an older specification that calls this extension *notify* and not *enotify* as it is called nowadays. Something similar is true for the *imapflags* extension which is now called *imap4flags*. The most valuable extension that the new Sieve implementation adds to the list is the *variables* extension. As the name implies, this adds support for variables to the language. ManageSieve server ------------------ To give users the ability to upload their own Sieve scripts to your server, i.e. without the need for shell or FTP access, you can use the Manage ''Sieve protocol. Two alternatives are available for Dovecot: * Python implementation: http://woozle.org/~neale/src/pysieved/ * [ManageSieve.txt] Validate your script -------------------- Use the following page to validate your sieve rules: http://libsieve-php.sourceforge.net/ v1.0 namespaces and fileinto ---------------------------- Dovecot v1.0's deliver doesn't support namespaces, so if you have a namespace prefix configured for IMAP, you must not use it with *fileinto* command. This also means that delivering mails to multiple namespaces isn't possible. v1.1's deliver supports namespaces and the namespace prefixes must be used with *fileinto* commands. Vacation auto-reply ------------------- Vacation uses envelope sender and envelope recipient. They're taken from: * v1.0: * Envelope sender: Return-Path: header in the message. * Envelope recipient: -d parameter to deliver. If -d isn't given (delivering to system users), the $USER environment is used. * v1.1: * Envelope sender: -f parameter to deliver if given, otherwise Return-Path: header in the message. * Envelope recipient: -a parameter to deliver if given, otherwise -d parameter to deliver. If neither is given (delivering to system users), the $USER environment is used. The vacation replies are sent to the envelope sender. List of autoreplied senders is stored in '.dovecot.lda-dupes' file in user's home directory. When you're testing the vacation feature, it's easy to forget that the reply is sent only once in the number of configured days. If you've problems getting the vacation reply, try deleting this file. If that didn't help, make sure the problem isn't related to sending mails in general by trying the "reject" Sieve command. The automatic replies aren't sent if any of the following is true: * Auto-Submitted: header exists with any value except "no" * Precedence: header exists with value "junk", "bulk" or "list" * The envelope sender * begins with "MAILER-DAEMON" (case-insensitive) * begins with "LISTSERV" (case-insensitive) * begins with "majordomo" (case-insensitive) * begins with "owner-" (case-sensitive) * contains the string "-request" anywhere within it (case-sensitive) * The envelope sender and envelope recipient are the same * The envelope recipient is not found in the message To:, Cc: or Bcc: fields. A bare username without a domain gets canonicalised by the libsieve code to "@unspecified-domain", which means it is highly unlikely to pass the last two tests in the list above. Example scripts --------------- Below are some simple Sieve code examples, more can be found from http://libsieve.sourceforge.net/script1.php and http://wiki.fastmail.fm/index.php?title=SieveExamples. SpamAssassin tagged mail filtering ---------------------------------- Redirect tagged mails into mbox folder "spam": ---%<------------------------------------------------------------------------- require "fileinto"; if header :contains "X-Spam-Flag" "YES" { fileinto "spam"; } ---%<------------------------------------------------------------------------- Discard tagged mails: ---%<------------------------------------------------------------------------- if header :contains "X-Spam-Flag" "YES" { discard; } ---%<------------------------------------------------------------------------- Mail filtering by various headers --------------------------------- Use if/elsif/else to store messages into various folders/subfolders: * ---%<---------------------------------------------------------------------- require "fileinto"; if address :is "to" "dovecot@dovecot.org" { fileinto "Dovecot-list"; } elsif address :is "Return-path" "owner-cipe-l@inka.de" { fileinto "lists.cipe"; } elsif anyof (header :contains "X-listname" "lugog@cip.rz.fh-offenburg.de", header :contains "List-Id" "Linux User Group Offenburg") { fileinto "ml.lugog"; } else { # The rest goes into INBOX # default is "implicit keep", we do it explicitly here keep; } ---%<---------------------------------------------------------------------- "anyof" means logical OR, "allof" is AND. Forward mails with "order" or "buy" in their subject to another address: * ---%<---------------------------------------------------------------------- if header :contains "subject" ["order", "buy"] { redirect "orders@company.dom"; } ---%<---------------------------------------------------------------------- Message-ID and recipient of forwarded message are stored in a '.dovecot.lda-dupes' at users home directory to prevent mail loops. Flagging or Highlighting your mail ---------------------------------- Some mail readers use these flags: ---%<------------------------------------------------------------------------- require "imapflags"; if anyof (exists "X-Cron-Env", header :regex ["subject"] [".* security run output", ".* monthly run output", ".* daily run output", ".* weekly run output"]) { addflag "$label1"; # ie 'Important'/red label within Thunderbird # Other flags: # addflag "$label1"; # Important: #ff0000 => red # addflag "$label2"; # Work: #ff9900 => orange # addflag "$label3"; # personal: #009900 => green # addflag "$label4"; # todo: #3333ff => blue # addflag "$label5"; # later: #993399 => violet # } ---%<------------------------------------------------------------------------- Local copy of your emails: ---%<------------------------------------------------------------------------- if address ["Return-Path"] ["my_address@my_domain.com"] { setflag "\\seen"; } ---%<------------------------------------------------------------------------- /Useful, when you want sieve to manage your incoming *and* outgoing email (you must ask your mail reader to Bcc your mail to your dovecot in this case)./ More flags fun can be found here: Vacation auto-reply ------------------- ---%<------------------------------------------------------------------------- require ["fileinto", "vacation"]; # Move spam to spam folder if header :contains "X-Spam-Flag" "YES" { fileinto "spam"; # Stop here so that we do not reply on spams stop; } vacation # Reply at most once a day to a same sender :days 1 :subject "Out of office reply" # List of recipient addresses which are included in the auto replying. # If a mail's recipient is not on this list, no vacation reply is sent for it. :addresses ["j.doe@company.dom", "john.doe@company.dom"] "I'm out of office, please contact Joan Doe instead. Best regards John Doe"; ---%<------------------------------------------------------------------------- Include scripts --------------- With v1.1 it's possible to include other Sieve scripts in your script: ---%<------------------------------------------------------------------------- require ["include"]; include :global "global-spam.sieve"; include :personal "my-own-spam.sieve"; ---%<------------------------------------------------------------------------- If you want to use global scripts, you'll need to set up the global script directory: ---%<------------------------------------------------------------------------- protocol lda { # .. sieve_global_dir = /etc/dovecot/sieve/ } ---%<------------------------------------------------------------------------- Personal scripts are looked up from 'sieve_dir' if it's returned in [UserDatabase.ExtraFields.txt], or home directory if not. If neither is known, the include fails. It's not currently possible to use subdirectories for the scripts. Having a '/' character in the script name always fails the include. This is just an extra check to avoid potential problems with including scripts within mail directories. French Howto ------------ http://casys.crevetor.org/index.php/Filtres_côté_serveur Migration from Procmail ----------------------- There exists a script which attempts to translate simple Procmail rules into Sieve rules:http://www.earth.ox.ac.uk/~steve/sieve/procmail2sieve.pl (dovecot.org mirror [http://dovecot.org/tools/procmail2sieve.pl]) Here's the original post announcing it: http://dovecot.org/list/dovecot/2007-March/020895.html (This file was created from the wiki on 2009-01-05 04:42)