Please enable JavaScript to view this site.

SecurityGateway for Email Servers v10.5

Navigation: Security > Sieve Scripts

Creating Sieve Scripts

Scroll Prev Top Next More

This page, along with the Sieve Scripts and SecurityGateway Sieve Extensions pages, provides a basic outline of the Sieve email filtering language and its implementation within SecurityGateway. The first section of this page outlines the basic parts of a Sieve Script. The next section outlines various structural elements of the language. Then there are lists of the standard Control, Test, and Action commands that are supported. And last, there are several sample scripts provided at the bottom of the page for your review.

For a more extensive look at the Sieve email filtering language, you should review the authoritative documents online at the IETF web site: Sieve: An Email Filtering Language (RFC-5228), Sieve's Copy Extension (RFC 3894), Sieve's Body Extension (RFC-5173), Sieve's Reject Extension (RFC-5429), Sieve's Variables Extension (RFC-5229), and Spamtest and VirusTest Extensions (RFC-3685).

You can also visit www.mdaemon.com/Support/ for SecurityGateway's latest technical support and help options, including: telephone support, email support, a Knowledge Base, Frequently Asked Questions, community forums, and more.

Parts of a Sieve Script

A Sieve Script has four basic parts:

1.Requirements—this part is used to declare the Sieve extensions that are required for a given script. When commands belonging to optional extensions will be used in a script, you MUST use the require control command to list those required extensions at the beginning of the script. A semicolon is required at the end of the require command's arguments.

Examples:

require "securitygateway";

-and-

require ["securitygateway", "fileinto"];

2.Conditions—this part of a script is where you declare the specific types of things you are looking for in a message and how you will be testing and comparing those things.

Examples:

if size :over 1M

-and-

if header :contains ["to", "cc"] "Frank Thomas"

3.Actions—these are the actions that will be taken and commands that will be executed when the designated conditions are True. Each Action must be followed by a semicolon and each block of actions must be contained in curly braces (i.e. "{" and "}").

Examples:

if size :over 1M { discard; }

-and-

if header :contains ["to", "cc"] "Frank Thomas" {

bayes-learn "spam";

fileinto "spam";

}

4.Comments—you can include comments in your Sieve scripts for your own reference, to remind you what the script does, and the like. There are two types of comments that you can use: single-line comments and multi-line comments. Single-line comments start with "#" and continue to the end of the line (i.e. until the next CRLF). Multi-line comments start with "/*", can span multiple lines, and then end with "*/".

Examples:

# discards messages over 1 mb

if size :over 1M { discard; }

-and-

if header :contains "from" "Frank Thomas" {

/* Frank Thomas sends mostly spam to us, so this script

will automatically move everything we get from him to

the user quarantine. */

fileinto "spam";

}

Structural Elements

Strings

Text strings start and end with a single double-quote. For example: "Frank Thomas".

To include a backslash or double-quote within a quoted string the character must be preceded by another backslash. So, \\ will be treated as \ and \" will be treated as " in a quoted string. No other characters should be escaped in strings.

String Lists

Whenever you wish to use a groups of strings in a script, separate each quoted string with a comma and enclose the set in square brackets.

Example:

if header :contains ["to", "cc"] ["me@xyz.com", "you@xyz.com", "us@xyz.com"]

The result of this test is True if either the To or CC header contains any of the three addresses.

Headers

Do not include a colon in header names.

Example:

if header :is "to:" (invalid)

if header :is "to" (valid)

Test Lists

Similar to string lists, you can include a group of tests in a script by enclosing the group in parentheses. This is sometimes necessary when using the allof or anyof Test commands, since those are logical "AND" and logical "OR" statements respectively.

Example:

if anyof (size :over 1M, header :contains "subject" ["big file", "mega file"])

{

discard;

}

Arguments and Match Types

Most commands take one or more arguments in order for you to specify what to do. There are several types of arguments, such as positional arguments, tagged arguments, and optional arguments. Tagged arguments and Match Type arguments, for example, are preceded by a colon. :contains, :is, :matches, :over, and :under are all examples of tagged arguments. Some tagged arguments are limited to specific commands. For more on the different types of arguments, see: RFC-5228.

Actions

Each action must be followed by a semicolon and each block of actions must be enclosed in curly braces.

Example:

if header :contains ["to", "cc"] "Frank Thomas" {

bayes-learn "spam";

fileinto "spam";

}

Control Commands

There are three control commands used in the Sieve language:

require

This control command is used at the beginning of a script to declare which optional extensions will be used in the script.

Example:

require ["securitygateway", "fileinto"];

if / elsif / else

The if command is the core control command. Although there are technically three interrelated commands, elsif and else cannot be used independently of if. When if is encountered in a script, the test condition will be evaluated to see if it is true. If it is, then the actions associated with it will be executed.

If the if test is false then the first elsif test will be evaluated. If the elsif is true then the actions associated with that test will be executed. If the elsif test proves to be false as well, then the process will continue with the next elsif, and so on until one of them is true.

If the if and all elsif tests are false, and if there is an else command, then that command's actions will be executed.

stop

The stop control command ends all processing.

Test Commands

These are the standard Test commands supported in SecurityGateway's implementation of Sieve. The body and envelope commands are extensions, however, so you must include them in the require control command whenever you wish to use either of them in a script. Further, there is a significant number of additional Test commands included in the securitygateway extension outlined on the SecurityGateway Sieve Extensions page.

address

With this command you can test on only an email address in a header rather than on the included phrase or name it might contain. For example, if the "to" header contained "Frank Thomas" <frank@example.com>, then the result of the the test header :is "to" "frank@example.com" would be false. But the test address :is "to" "frank@example.com" would be true because only the address is considered in the evaluation.

There are also three optional tagged arguments you can use with this command: ":localpart", ":domain", and ":all". The :localpart argument evaluates only the left part of the address (e.g. "frank" in "frank@example.com"), the :domain argument only uses the domain portion of the address (e.g. "example.com"), and :all uses the entire address. If none of these arguments are included then :all is used by default.

Example:

require "fileinto";

if address :domain :is "from" "spammer.com" {

fileinto "spam";

}

allof

This test is a logical "AND", meaning that ALL of the conditions being evaluated must be true in order for the action be taken.

Example:

if allof (header :contains "from" "J.Lovell", header :contains "to" "Bubba")

{

fileinto "spam";

}

anyof

This test is a logical "OR", meaning that if ANY of the conditions being evaluated are true then the associated action will be taken.

Example:

if anyof (size :over 1M, header :contains "subject" "big file attached")

{

reject "I don't want messages that claim to have big files.";

}

body

The body test command is an optional extension and therefore you must use the require "body" control command at the beginning of any script that will use it. This command compares against the message's body. For more on this command, see: Sieve's Body Extension (RFC-5173).

Example:

require ["body", "fileinto"];

if body :text :contains "secret formula" {

fileinto "admin";

}

envelope

The envelope command is an optional extension and therefore you must use the require "envelope" control command at the beginning of any script that will use it. This command compares against the SMTP MAIL From and RCPT To envelope parts when "from" or "to" is used respectively as the command's argument.

Example:

require "envelope";

if envelope :is "from" "MrsFrank@company.com" {

redirect "frankshome@example.com";

}

exists

This test is true if the headers listed in the argument exist within the message. All listed headers must exist or the test is false.

Example:

if exists "x-custom-header" {

redirect "admin@example.com";

}

-and-

if not exists ["from", "date"] {

discard;

}

false

This test always evaluates to "FALSE".

header

The header test evaluates to true when the value of the named header matches the conditions set by the argument. When no Match Type argument is specified, :is will be used by default.

Example:

require "fileinto"

if header :is "x-custom-header" "01" {

fileinto "admin";

}

not

Using this command with another test means that the result of the test must be reversed in order for the test's action to be taken. For example, the test if not exists ["from", "date"] { discard; } means that if a message does NOT contain both "from" and "date" headers then the discard action will be taken. If the not command were omitted then that would mean the message would be discarded if the headers DID exist.

size

The size command accepts the tagged arguments ":over" and ":under",  which must be followed by a numerical value. These arguments are used to designate whether a message's size must be higher or lower than the specified value in order for the test to be TRUE. You can use an M after the value to indicate megabytes, a K for kilobytes, or no letter for bytes.

Example:

if size :over 500K {

discard;

}

true

This test always evaluates to "TRUE".

spamtest

The spamtest command is an optional Sieve extension discussed in the Spamtest and VirusTest Extensions (RFC-3685) document at ietf.org. See that document for information on this extension.

virustest

The virustest command is an optional Sieve extension discussed in the Spamtest and VirusTest Extensions (RFC-3685) document at ietf.org. See that document for information on this extension.

Action Commands

These standard Action commands are supported by SecurityGateway. The fileinto and reject commands are extensions, so you must include them in the require control command whenever you wish to use either of them in a script. There are many other action commands available via the securitygateway extension outlined on the SecurityGateway Sieve Extensions page.

fileinto

The fileinto action command is an optional extension and therefore you must use the require "fileinto" control command at the beginning of any script that will use it. This command accepts two arguments: "spam" and "admin". "spam" moves the message to the User quarantine and "admin" moves it to the Administrative quarantine.

Example:

require "fileinto";

if header :contains "from" "Frank Thomas" {

fileinto "spam";

}

discard

This action causes a message to be silently deleted, without sending a delivery status notification are any other message.

Example:

if size :over 2M { discard; }

keep

This action causes the message to be saved to the default location.

redirect

This command redirects the message to the address specified in the associated argument, without changing the message's body or existing headers. This command also supports the optional :copy extension, which will cause a copy of the message to be sent to the specified address rather then redirecting the message. This allows other actions to be performed in addition to sending a copy to the specified address.

Example:

require "copy";

if header :contains "subject" "Response to XYZ" {

redirect :copy "offers@example.com";

bayes-learn "ham";

}

reject

The reject action command is an optional extension and therefore you must use the require "reject" control command at the beginning of any script that will use it. This command causes the message to be refused during the SMTP process with a 5xx response code and an optional short message specified in the argument.

require "reject";

if size :over 5M {

reject "No way! This message is too big for me to accept.";

}

vnd.mdaemon.securewebmsg

Use this action command to use SecurityGateway's Secure Messaging web portal to send a message.

Example:

require ["securitygateway","reject","fileinto","envelope","body","regex"];

if allof(header :matches "subject" "[Secure Message]*")

{

vnd.mdaemon.securewebmsg;

}

Sample Sieve Scripts

 

Reject any message with subject containing "[SPAM]"

require "reject";

if header :contains "subject" "[SPAM]"

{

reject "I don't want your spam";

}

Reject any message to a specific real name

require ["securitygateway","reject"];

if header :contains "to" "Real Name"

{

bayes-learn "spam";

reject "I don't want your spam";

}

Custom Bayes Auto Learning

require ["securitygateway","comparator-i;ascii-numeric"];

if allowlisted

{

bayes-learn "ham";

}

elsif anyof(blocklisted,spamtotal :value "gt" :comparator "i;ascii-numeric" "20.0")

{

bayes-learn "spam";

}

Greylist DNSBL matches

require "securitygateway"];

if not lookup "rblip" "all" {greylist;}

Notify admin when large message is received

require ["securitygateway"];

if size :over 1M

{

alert text:

To: admin@company.mail

From: postmaster@$RECIPIENTDOMAIN$

Subject: SecurityGateway Content-Filter Message

X-Attach-Msg: No

$RECIPIENT$ received a message larger that 1MB.

.

;

}

Send as a secure message when subject starts with "[Secure Message]"

require ["securitygateway","reject","fileinto","envelope","body","regex"];

if allof(header :matches "subject" "[Secure Message]*")

{

vnd.mdaemon.securewebmsg;

}