diff options
Diffstat (limited to 'doc/wiki/Pigeonhole.Sieve.Examples.txt')
-rw-r--r-- | doc/wiki/Pigeonhole.Sieve.Examples.txt | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/doc/wiki/Pigeonhole.Sieve.Examples.txt b/doc/wiki/Pigeonhole.Sieve.Examples.txt new file mode 100644 index 0000000..fb578df --- /dev/null +++ b/doc/wiki/Pigeonhole.Sieve.Examples.txt @@ -0,0 +1,423 @@ +Pigeonhole Sieve examples +========================= + +Contents + + + 1. Pigeonhole Sieve examples + + 1. Mail filtering by various headers + + 2. Flagging or Highlighting your mail + + 3. Spam/Virus rules + + 1. Direct filtering using message header + + 2. Filtering using the spamtest and virustest extensions + + 4. Plus Addressed mail filtering + + 5. Vacation auto-reply + + 6. Include scripts + + 7. Archiving a Mailinglist by Date + + 8. Emulating lmtp_save_to_detail_mailbox=yes + + 9. Translation from Procmail + +Below are some simple Sieve code examples, more can be found at +http://sieve.info/examplescripts. + +Mail filtering by various headers +--------------------------------- + +Use if/elsif/else to store messages into various folders/subfolders: + + * ---%<---------------------------------------------------------------------- + require ["fileinto", "envelope"]; + if address :is "to" "dovecot@dovecot.org" { + fileinto "Dovecot-list"; + } elsif envelope :is "from" "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 "imap4flags"; +require "regex"; +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: + +---%<------------------------------------------------------------------------- +require ["envelope", "imap4flags"]; +if envelope "from" "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)./ + +Spam/Virus rules +---------------- + +Most spam and virus scanners add a special header to mail messages, so that +users can apply filtering accordingly. Depending on how the Sieve interpreter +is configured, filtering can either be performed by evaluating these headers +directly, or using the spamtest and virustest extensions. + +Direct filtering using message header +------------------------------------- + +Evaluating the headers directly is always possible as long as the headers are +actually added to the messages by the scanner software. For example, to +fileSpamAssassin-tagged mails into a folder called "Spam": + +---%<------------------------------------------------------------------------- +require "fileinto"; +if header :contains "X-Spam-Flag" "YES" { + fileinto "Spam"; +} +---%<------------------------------------------------------------------------- + +The following example discards SpamAssassin-tagged mails with level higher than +or equal to 10: + +---%<------------------------------------------------------------------------- +if header :contains "X-Spam-Level" "**********" { + discard; + stop; +} +---%<------------------------------------------------------------------------- + +Some spam scanners only produce a numeric score in a header. Then, the test +becomes more involved: + +---%<------------------------------------------------------------------------- +require ["comparator-i;ascii-numeric","relational"]; +if allof ( + not header :matches "x-spam-score" "-*", + header :value "ge" :comparator "i;ascii-numeric" "x-spam-score" "10" ) +{ + discard; + stop; +} +---%<------------------------------------------------------------------------- + +*NOTE:* Be very careful when matching against spam score headers using the +relational extension and the i;ascii-numeric comparator. This comparator can +only be used to match unsigned integers. Strings that do not begin with a digit +character represent positive infinity and will therefore always be larger than +any score mentioned in your rule! That is why the above example first checks +the minus sign explicitly. + +Filtering using the spamtest and virustest extensions +----------------------------------------------------- + +When the spamtest [http://tools.ietf.org/html/rfc5235#section-3.2] and +virustest [http://tools.ietf.org/html/rfc5235#section-3.3] extensions are +configured on the server ( <here> +[Pigeonhole.Sieve.Extensions.SpamtestVirustest.txt] is explained how), users +(and GUIs) can have a much easier way to filter spam and virus messages +respectively. To filter spam, the spamtest extension can for example be used as +follows: + +---%<------------------------------------------------------------------------- +require "spamtestplus"; +require "fileinto"; +require "relational"; +require "comparator-i;ascii-numeric"; + +/* If the spamtest fails for some reason, e.g. spam header is missing, file + * file it in a special folder. + */ +if spamtest :value "eq" :comparator "i;ascii-numeric" "0" { + fileinto "Unclassified"; + +/* If the spamtest score (in the range 1-10) is larger than or equal to 3, + * file it into the spam folder: + */ +} elsif spamtest :value "ge" :comparator "i;ascii-numeric" "3" { + fileinto "Spam"; + +/* For more fine-grained score evaluation, the :percent tag can be used. The + * following rule discards all messages with a percent score + * (relative to maximum) of more than 85 %: + */ +} elsif spamtest :value "gt" :comparator "i;ascii-numeric" :percent "85" { + discard; +} + +/* Other messages get filed into INBOX */ +---%<------------------------------------------------------------------------- + +The virustest extension can be used in a similar manner: + +---%<------------------------------------------------------------------------- +require "virustest"; +require "fileinto"; +require "relational"; +require "comparator-i;ascii-numeric"; + +/* Not scanned ? */ +if virustest :value "eq" :comparator "i;ascii-numeric" "0" { + fileinto "Unscanned"; + +/* Infected with high probability (value range in 1-5) */ +} if virustest :value "eq" :comparator "i;ascii-numeric" "4" { + /* Quarantine it in special folder (still somewhat dangerous) */ + fileinto "Quarantine"; + +/* Definitely infected */ +} elsif virustest :value "eq" :comparator "i;ascii-numeric" "5" { + /* Just get rid of it */ + discard; +} +---%<------------------------------------------------------------------------- + +Plus Addressed mail filtering +----------------------------- + +Using the subaddress [http://tools.ietf.org/html/rfc5233/] extension, it is +possible to match against the 'detail' part of an e-mail address, e.g. a +''+tag'' suffix to the local part of the address. This is for example useful +when you don't want just any +tag to create a directory, but you want to use +tagged addresses such as with amavisd-new. This example would place email +addressed to user+spam@example.com into user's Spam folder. + +---%<------------------------------------------------------------------------- +require ["fileinto", "envelope", "subaddress"]; +if envelope :detail "to" "spam"{ + fileinto "Spam"; +} +---%<------------------------------------------------------------------------- + +The following more advanced example uses the subaddress +[http://tools.ietf.org/html/rfc5233/] extension to handle recipient addresses +structured as 'sales+<name>@company.com' in a special way. The '<name>' part is +extracted from the address using variables +[http://tools.ietf.org/html/rfc5229/] extension, transformed into a format with +the first letter in upper case and subsequently used to create the folder name +where the message is stored. The folder name is structured as 'users/<name>'. +If the '+<name>' detail is omitted from the recipient address, the message is +filed in the 'sales' folder. + +---%<------------------------------------------------------------------------- +require ["variables", "envelope", "fileinto", "subaddress"]; + +if envelope :is :user "to" "sales" { + if envelope :matches :detail "to" "*" { + /* Save name in ${name} in all lowercase except for the first letter. + * Joe, joe, jOe thus all become 'Joe'. + */ + set :lower :upperfirst "name" "${1}"; + } + + if string :is "${name}" "" { + /* Default case if no detail is specified */ + fileinto "sales"; + } else { + /* For sales+joe@ this will become users/Joe */ + fileinto "users/${name}"; + } +} +---%<------------------------------------------------------------------------- + +To work with Postfix, this requires that the envelope "to" still contains the +full address, so pass it with the -a flag. + +---%<------------------------------------------------------------------------- +dovecot unix - n n - - pipe + flags=DRhu user=mail:mail argv=/usr/local/libexec/dovecot/dovecot-lda + -f ${sender} -d ${user}@${nexthop} -a ${original_recipient} +---%<------------------------------------------------------------------------- + +or + +---%<------------------------------------------------------------------------- +mailbox_command = /usr/lib/dovecot/dovecot-lda -a "$RECIPIENT" +---%<------------------------------------------------------------------------- + +Vacation auto-reply +------------------- + +Auto-responder functionality is implemented using the vacation +[http://tools.ietf.org/html/rfc5230/] extension. The following script sends +out-of-office replies when the message is not spam: + +---%<------------------------------------------------------------------------- +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 additional recipient addresses which are included in the auto +replying. + # If a mail's recipient is not the envelope recipient and it's 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"; +---%<------------------------------------------------------------------------- + +It's also possible to include the original subject using the variables +[http://tools.ietf.org/html/rfc5229/] extension: + +---%<------------------------------------------------------------------------- +require ["variables", "vacation"]; +# Store old Subject line so it can be used in vacation message +if header :matches "Subject" "*" { + set "subjwas" ": ${1}"; +} +vacation + :days 1 + :subject "Out of office reply${subjwas}" + :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 +--------------- + +It's possible to include other Sieve scripts in your script: + +---%<------------------------------------------------------------------------- +require ["include"]; +include :global "global-spam"; +include :personal "my-own-spam"; +---%<------------------------------------------------------------------------- + +The lookup directories can be specified with: + +---%<------------------------------------------------------------------------- +plugin { + # Directory for :personal include scripts. The default is to use home +directory. + sieve_dir = %h/sieve + + # Directory for :global include scripts (not to be confused with +sieve_global_path). + # If unset, the include fails. + sieve_global_dir = /etc/dovecot/sieve/ +} +---%<------------------------------------------------------------------------- + +Both 'sieve_dir' and 'sieve_global_dir' may also be overridden by <userdb extra +fields> [UserDatabase.ExtraFields.txt]. + +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. + +Archiving a Mailinglist by Date +------------------------------- + +You can archive messages from mailing lists in a date-structured folder tree as +follows: + +---%<------------------------------------------------------------------------- +require ["variables","date","fileinto","mailbox"]; + +# Extract date info +if currentdate :matches "year" "*" { set "year" "${1}"; } +if currentdate :matches "month" "*" { set "month" "${1}"; } + +# Archive Dovecot mailing list items by year and month. +# Create folder when it does not exist. +if header :is "list-id" "dovecot.dovecot.org" { + fileinto :create "INBOX.Lists.${year}.${month}.dovecot"; +} +---%<------------------------------------------------------------------------- + +For example, in March 2013 this puts messages from the Dovecot mailing list in +a folder called 'INBOX.Lists.2013.03.dovecot'. It combines the date +[http://tools.ietf.org/html/rfc5260#section-4] and variables +[http://tools.ietf.org/html/rfc5229/] extensions to extract the required date +strings. Using the ':create' argument for the 'fileinto' command, the indicated +folder is created automatically if it doesn't exist. The ':create' argument is +provided by the mailbox [http://tools.ietf.org/html/rfc5490#section-3] +extension. + +Emulating lmtp_save_to_detail_mailbox=yes +----------------------------------------- + +If you can't turn this option on, you can emulate the behaviour to some extent +with following code. + +---%<------------------------------------------------------------------------- +require ["variables", "fileinto", "envelope", "subaddress", "mailbox"]; + +if envelope :matches :detail "to" "*" { + # you can prefix with INBOX/ or INBOX. if necessary + # remove :create if you want to permit only existing mailboxes + fileinto :create "${1}"; +} +---%<------------------------------------------------------------------------- + +Translation 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 2019-06-19 12:42) |