Skip to main content
Version: 0.16

Examples

This section collects example Sieve scripts that can serve as a starting point for custom rules. Each example is stored as a SieveSystemScript record (found in the WebUI under Settings › Sieve › System Scripts) and invoked from the relevant SMTP stage by setting the stage's script expression to the script's name.

Greylisting

The following script implements a greylisting filter backed by an SQL store. Install it as a system script and reference it from the script field on the MtaStageRcpt singleton (found in the WebUI under Settings › MTA › Session › RCPT TO Stage) so that it runs at the RCPT TO stage.

{
"name": "greylist",
"description": "Greylisting filter backed by SQL",
"isActive": true,
"contents": "require [\"variables\", \"vnd.stalwart.expressions\", \"envelope\", \"reject\"];\n\nset \"triplet\" \"${env.remote_ip}.${envelope.from}.${envelope.to}\";\n\nif eval \"!query(\\\"SELECT 1 FROM greylist WHERE addr = ? LIMIT 1\\\", [triplet])\" {\n eval \"query(\\\"INSERT INTO greylist (addr) VALUES (?)\\\", [triplet])\";\n reject \"422 4.2.2 Greylisted, please try again in a few moments.\";\n}\n"
}

The script field on MtaStageRcpt then selects the script by name:

{
"script": {"else": "'greylist'"}
}

Domain blocklisting

The following script rejects messages whose HELO/EHLO domain is found in an SQL-backed list. Install it as a system script and reference it from the script field on the MtaStageEhlo singleton (found in the WebUI under Settings › MTA › Session › EHLO Stage).

{
"name": "is-blocked",
"description": "Reject blocklisted HELO domains",
"isActive": true,
"contents": "require [\"variables\", \"extlists\", \"reject\"];\n\nif string :list \"${env.helo_domain}\" \"sql/blocked-domains\" {\n reject \"551 5.1.1 Your domain '${env.helo_domain}' has been blocklisted.\";\n}\n"
}

The referenced sql/blocked-domains list is defined as a StoreLookup against the SQL store, using the query SELECT 1 FROM blocked_domains WHERE domain=? LIMIT 1.

The script field on MtaStageEhlo then selects the script:

{
"script": {"else": "'is-blocked'"}
}

Message modification

The following script modifies the incoming message, replacing the contents of each HTML MIME part with its uppercase form and adding a custom header to every part. Install it as a system script and reference it from the script field on the MtaStageData singleton (found in the WebUI under Settings › MTA › Session › DATA Stage).

{
"name": "modify-message",
"description": "Uppercase HTML parts and annotate each MIME part",
"isActive": true,
"contents": "require [\"envelope\", \"variables\", \"replace\", \"mime\", \"foreverypart\", \"editheader\", \"extracttext\"];\n\nif envelope :domain :is \"to\" \"example.net\" {\n set \"counter\" \"a\";\n foreverypart {\n if header :mime :contenttype \"content-type\" \"text/html\" {\n extracttext :upper \"text_content\";\n replace \"${text_content}\";\n }\n set :length \"part_num\" \"${counter}\";\n addheader :last \"X-Part-Number\" \"${part_num}\";\n set \"counter\" \"${counter}a\";\n }\n}\n"
}

The script field on MtaStageData then selects the script:

{
"script": {"else": "'modify-message'"}
}