- Sieve Scripting Cheat Sheet
-
The
require
statement specifies the extensions your script will use. Always ensure you list all necessary extensions to prevent runtime errors:require ["fileinto", "imap4flags", "vacation"];
-
Tests email addresses in headers. Useful attributes include
:all
,:localpart
,:domain
, and:comparator
. Comparators:i;ascii-casemap
,i;unicode-casemap
if address :all :comparator "i;unicode-casemap" :matches "From" "[email protected]" { ... }
-
Tests header fields with attributes like
:is
,:contains
, and:matches
.if header :contains "subject" "urgent" { ... }
-
Tests the size of the email using attributes
:over
or:under
if size :over 1M { ... }
-
Searches the email body. Available attributes include
:contains
and:matches
.if body :contains "keyword" { ... }
-
Tests the date of the email.
-
Attributes:
:value
,:zone
-
Some implementations use
currentdate
for dynamic checks:if currentdate :value "ge" "date" "2025-02-21" { ... }
-
Other implementations may require the date test directly on a header (typically "Date"). Be sure to check the required date format and timezone handling:
if date :value "ge" "2025-02-21" { ... }
-
Combine multiple tests to form more complex conditions:
if allof ( header :contains "subject" "urgent", size :over 1M ) { discard; }
-
Or to match any of several conditions:
if anyof ( header :contains "subject" "alert", header :contains "subject" "warning" ) { fileinto "Alerts"; }
-
Filters based on the SMTP envelope rather than header fields. This is useful when you want to filter by the actual sender:
if envelope :is "from" "[email protected]" { fileinto "Important"; }
-
These actions determine how the message is processed:
-
fileinto: Files the email into a specified folder.
fileinto "Inbox";
-
keep: Keeps the email in the inbox.
keep;
-
discard: Silently discards the email.
discard;
-
-
Manage email redirection and automated responses:
-
redirect: Sends the email to another address.
redirect "[email protected]";
-
reject: Rejects the email with a specified message.
reject "Your email was rejected.";
-
vacation: Sends an auto-reply. Attributes:
:days
,:subject
vacation :days 1 :subject "Out of Office" text: "Thank you for your email. I am currently out of the office and will get back to you shortly." ;
-
-
Manage email flags for further processing or visual cues:
addflag "\\Flag"; setflag "\\Flag"; removeflag "\\Flag";
- i;ascii-casemap: Case-insensitive ASCII comparison.
- i;unicode-casemap: Case-insensitive Unicode comparison.
- i;octet: Byte-by-byte comparison.
-
Allows you to include another Sieve script, which is useful for modularizing your filtering rules.
include :personal "other-script";
-
Tests environment variables, useful in some server-specific implementations.
if environment :matches "vnd.proton.spam-threshold" "*" { ... }
- The Sieve
redirect
command is used to forward incoming mail to another email address. Depending on your needs, you can forward the mail and either remove it from the original mailbox or keep a copy.
-
If you want to forward a copy of the email while leaving the original message in your mailbox, you need to enable the
copy
extension. This requires including it with therequire
statement, then using the:copy
option withredirect
:require ["copy"]; redirect :copy "[email protected]";
In this example, the :copy
option tells the mail server to send a copy of the message to the specified address without removing it from your mailbox.
-
If you simply want to forward the email without explicitly preserving a copy (which might result in the original being removed from your mailbox, depending on your server’s configuration), you can use the basic form of the
redirect
command:redirect "[email protected]";
- Testing: Always test your Sieve script in your specific environment. Some servers may have subtle differences in how forwarding is handled.
- Mail Loops: Be cautious of potential mail loops when forwarding messages. Ensure that the forwarded address is correctly configured to avoid continuous redirection.
- Privacy: Forwarding mail can inadvertently expose sensitive information. Make sure that forwarding aligns with your privacy and security policies.
-
The
variables
extension allows you to assign and reuse values within your script. This can simplify complex conditions.set "sender" "[email protected]"; if anyof ( address :all "From" "${sender}", envelope :is "from" "${sender}" ) { fileinto "From_Example"; }
-
Use the
relational
extension to perform numeric comparisons. Some implementations require explicit comparator requirements for numeric tests:if spamtest :value "ge" :comparator "i;ascii-numeric" "5" { ... }
-
Tests the spam score of the email, often used in conjunction with relational tests.
if spamtest :value "ge" :comparator "i;ascii-numeric" "5" { ... }
-
If supported, the
notify
extension can send alerts. This is useful for immediate notifications on incoming emails.notify "maildir" :options "silent" :message "You have a new email" "[email protected]";
- Some Sieve implementations support regular expression matching via non-standard extensions. Include a disclaimer that these features are implementation-specific and may not be portable across all servers.
- Testing: Use tools like
sieve-test
or similar utilities provided by your mail server to debug your scripts. - Variability: Note that different servers (e.g., Dovecot vs. Cyrus) may have subtle differences in supported extensions and syntax.
- Logging: If available, enable logging to diagnose issues with script execution.
-
Always list all extensions your script utilizes to avoid runtime errors:
require ["fileinto", "imap4flags", "vacation", "envelope", "variables", "relational"];
-
Greylisting with SQL Database: This script implements a simple greylisting filter using an SQL database.
require ["variables", "vnd.stalwart.expressions", "envelope", "reject"]; set "triplet" "${env.remote_ip}.${envelope.from}.${envelope.to}"; if eval "!query(\"SELECT 1 FROM greylist WHERE addr = ? LIMIT 1\", [triplet])" { eval "query(\"INSERT INTO greylist (addr) VALUES (?)\", [triplet])"; reject "422 4.2.2 Greylisted, please try again in a few moments."; }
-
Domain Blocklisting: This script implements a domain blocklisting filter during the EHLO phase.
require ["variables", "extlists", "reject"]; if string :list "${env.helo_domain}" "sql/blocked-domains" { reject "551 5.1.1 Your domain '${env.helo_domain}' has been blocklisted."; }
-
Message Modification: This example modifies the incoming message by replacing the content of all HTML parts with their uppercase version and adding a custom header to each part.
require ["envelope", "variables", "replace", "mime", "foreverypart", "editheader", "extracttext"]; if envelope :domain :is "to" "example.net" { set "counter" "a"; foreverypart { if header :mime :contenttype "content-type" "text/html" { extracttext :upper "text_content"; replace "${text_content}"; } set :length "part_num" "${counter}"; addheader :last "X-Part-Number" "${part_num}"; set "counter" "${counter}a"; } }
-
Spam Filtering with Numeric Score: This script discards emails with a spam score higher than or equal to 10.
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; }
-
Dynamic Folder Creation: This example dynamically creates folders based on the sender's email address.
require ["fileinto", "variables"]; if address :domain :matches "From" "*" { set "folder" "User.${1}"; fileinto "${folder}"; }
-
Quarantine and Notify: This example sends an email to a quarantine folder and notifies the user about it.
require ["fileinto", "notify"]; if allof (header :contains "subject" "spam", header :contains "X-Spam-Flag" "YES") { fileinto "Quarantine"; notify :message "An email was moved to Quarantine due to spam detection."; }
- When testing Sieve scripts for email filtering, consider the following tools and resources:
-
Dovecot Sieve Script Testing:
Dovecot’s documentation includes information on testing and debugging Sieve scripts. Although not a dedicated online tester, it provides guidelines and examples that you can replicate in your local environment.
Reference: Dovecot Sieve Documentation citeDovecotSieve -
Command-Line Tools:
Most Sieve implementations (e.g., Cyrus, Dovecot) include a command-line tool such assieve-test
that allows you to validate and debug your Sieve scripts locally. This is invaluable for catching syntax errors and testing script logic before deployment. -
Stalwart Labs Resources:
Stalwart Labs provides a range of documentation and community discussions on Sieve scripting. While not an online tester per se, these resources offer practical examples, troubleshooting tips, and sample scripts that can help you refine your filters.
Reference: Stalwart Labs - Sieve Scripting citeCyrusSieve -
GitHub Projects and Community Tools:
Search GitHub for community-driven projects related to Sieve script validation. These projects often provide test harnesses or simulation environments that allow you to run and debug your Sieve scripts in an online or local setup.
Note: These tools and resources are focused on the Sieve mail filtering language. They differ from tools used for physical sieve analysis, so ensure you’re referencing resources specific to email filtering when testing your Sieve scripts.
-
Stack Overflow: A community where you can ask questions and share knowledge about Sieve scripts and email filtering. Stack Overflow - Sieve
-
DirectAdmin Forums: A forum for discussing Sieve scripts and troubleshooting issues. DirectAdmin Forums
-
Stalwart Labs: A resource for Sieve scripting, including documentation and examples. Stalwart Labs
-
GitHub Discussions: A place to discuss Sieve scripting and related topics. GitHub Discussions
-
Protonmail Sieve filter (advanced custom filters)
-
GandiMail Sieve filtering documentation and tutorials Sample Sieve Filters for Email
-
Sieve Info Sieve Info
-
Sieve Tutorial Sieve Tutorial
-
Coderdose Setting up Email Filtering Sieve Scripts
-
Docker Mailserver Email Filtering with Sieve
- Extension Support: Not all servers support every extension. Check your server’s documentation to confirm compatibility.
- Date Formatting: Ensure you use the correct date format and consider timezone differences. Some servers may require additional timezone settings.
- Logical Operator Syntax: When using
allof
andanyof
, verify that your conditions are properly separated by commas and enclosed in parentheses. - Variable Scope: Variables in Sieve are limited in scope; reuse them carefully and ensure they are set before use.
- Debugging Tools: Use command-line tools or server logs to troubleshoot issues, especially for complex scripts.
- RFC 5228 - Sieve: A Mail Filtering Language citeRFC5228
- Dovecot Sieve Documentation citeDovecotSieve
- Cyrus Sieve Documentation citeCyrusSieve