本页,连同 Sieve 脚本和 SecurityGateway Sieve 扩展命令页,提供了有关 Sieve 邮件过滤语言及其在 SecurityGateway 中应用的基本纲要。本页的第一部分概述了 Sieve 脚本的基本组成部分。下一部分概述了该语言的多种结构单元。然后是所支持的标准控制、测试和操作命令的列表。最后,在页面下方提供了多个脚本范例供审阅。
|
要了解有关 Sieve 邮件过滤语言的更详尽说明,应在线查看 IETF 网站的权威文档: 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) 和 Spamtest and VirusTest Extensions (RFC-3685)。 还可访问 www.mdaemon.com/Support/ 了解 SecurityGateway 的最新技术支持和帮助选项,包括: 电话支持、邮件支持、知识库、常见问题解答和社区论坛等。 |
Sieve 脚本有四个基本组成部分:
1.需求—该部分用于声明给定脚本所需的 Sieve 扩展命令。如果脚本中要使用可选的扩展命令,则必须使用 require 控制命令在脚本开头列出所需的那些扩展命令。require 命令的参数末尾需添加分号。
示例:
require "securitygateway";
-and-
require ["securitygateway", "fileinto"];
2.条件—在脚本的这一部分中可说明在邮件中要查找的内容特定类型以及测试并比较这些内容的方式。
示例:
if size :over 1M
-and-
if header :contains ["to", "cc"] "Frank Thomas"
3.操作—该部分为当指定条件为“True”时要实施的操作和要执行的命令。每一操作必须后接分号,且每一组操作必须包含在大括号内(即 "{" 和 "}")。
示例:
if size :over 1M { discard; }
-and-
if header :contains ["to", "cc"] "Frank Thomas" {
bayes-learn "spam";
fileinto "spam";
}
4.注释—可以在 Sieve 脚本中包含注释供自己参考,以提醒自己该脚本的功能等等。有两种注释可供使用: 单行注释和多行注释。单行注释以 "#" 开头并一直延续到行末(即至下一个 CRLF)。多行注释以 "/*" 开头,可跨越多行文本,然后以 "*/" 结尾。
示例:
# 删除超过 1 mb 的邮件
if size :over 1M { discard; }
-and-
if header :contains "from" "Frank Thomas" {
/* Frank Thomas 常常给我们发送垃圾邮件,因此该脚本
自动将自他那儿收到的所有内容移入
用户隔离队列。*/
fileinto "spam";
}
字符串
文本字符串开头和结尾使用单个双引号。例如: "Frank Thomas".
要在用引号括起来的字符串中包含反斜杠或双引号,必须在该字符前添加另一个反斜杠。因此,在用引号括起来的字符串中,\\ 将被视为 \ 且 \" 将被视为 "。字符串中的其他字符无需换码。
字符串列表
每当您希望在脚本中使用一组字符串时,请用逗号分隔各条用引号括起来的字符串,并将该组字符串用方括号括起来。
示例:
if header :contains ["to", "cc"] ["me@xyz.com", "you@xyz.com", "us@xyz.com"]
如果 To 或 CC 报头包含以上三条地址中的任一条,该测试结果即为 True。
报头
报头名中不得包含冒号。
示例:
if header :is "to:" (无效)
if header :is "to"(有效)
测试列表
类似于字符串列表,脚本中可包含一组测试(用小括号括起来)。当使用 allof 或 anyof 测试命令时,有时必须包含小括号,因为它们分别是逻辑“与”和逻辑“或”语句。
示例:
if anyof (size :over 1M, header :contains "subject" ["big file", "mega file"])
{
discard;
}
参数和匹配类型
大多数命令带有一个或多个参数,以便您指定如何操作。参数类型有多种,如位置参数、标记参数和可选参数。举例来说,标记参数和匹配类型参数前加有冒号。:contains、:is、:matches、:over 和 :under 都属于标记参数。某些标记参数仅限于特定命令。有关不同类型参数的更多信息,请参见: RFC-5228。
操作
每一操作必须后接分号,且每一组操作必须包含在大括号内。
示例:
if header :contains ["to", "cc"] "Frank Thomas" {
bayes-learn "spam";
fileinto "spam";
}
Sieve 语言中使用三种控制命令:
require
在脚本开头使用该控制命令来声明在脚本中所用的可选扩展命令。
示例:
require ["securitygateway", "fileinto"];
if / elsif / else
if 命令是核心控制命令。尽管理论上有三条相互关联的命令,但 elsif 和 else 的使用不能独立于 if。当在脚本中遇到 if 命令时,将评估该测试条件以判断它是否为 true。如果为真,则将执行与之相关的操作。
如果 if 测试结果为 false,则评估第一条 elsif 测试。如果 elsif 为 true,则执行与该测试相关的操作。如果 elsif 测试仍为假,则继续对下一条 elsif 进行评估,依次类推,直到其中一条为真。
如果 if 和所有 elsif 测试都为 false,并有一条 else 命令,则将执行该命令的操作。
stop
stop 控制命令终止所有处理。
这些是在 SecurityGateway 的 Sieve 应用中支持的标准测试命令。然而,body 和 envelope 命令是扩展命令,因此每当您希望在脚本中加以使用时,就必须将其包括在 require 控制命令中。此外,在 securitygateway 扩展命令中还包括了大量其他的测试命令,在 SecurityGateway Sieve 扩展命令页上对之作了概述。
address
使用该命令,可以只对报头中的邮件地址而不是可能包含的短语或名称进行测试。例如,如果 "to" 报头包含 "Frank Thomas" <frank@example.com>,那么 header :is "to" "frank@example.com" 的测试结果为 false。但是 address :is "to" "frank@example.com" 的测试结果为真,因为在该评估中只考虑地址。
使用该命令时还有三个可选标记参数: ":localpart",":domain" 和 ":all"。:localpart 参数只评估地址的左半部分(例如 "frank@example.com" 中的 "frank"),:domain 参数只使用地址的域部分(例如 "example.com"),而 :all 使用整个地址。若未包含以上参数,则默认使用 :all。
示例:
require "fileinto";
if address :domain :is "from" "spammer.com" {
fileinto "spam";
}
allof
该测试为逻辑“与”,表示所有的评估条件都必须为真才能执行操作。
示例:
if allof (header :contains "from" "J.Lovell", header :contains "to" "Bubba")
{
fileinto "spam";
}
anyof
该测试为逻辑“或”,表示若评估条件部分为真就能执行相关操作。
示例:
if anyof (size :over 1M, header :contains "subject" "big file attached")
{
reject "I don't want messages that claim to have big files.";
}
body
body 测试命令是可选的扩展命令,因而在要使用它的脚本开头必须添加 require "body" 这个控制命令。该命令比较邮件正文。有关该命令的更多信息,请参阅: Sieve's Body Extension (RFC-5173)。
示例:
require ["body", "fileinto"];
if body :text :contains "secret formula" {
fileinto "admin";
}
envelope
envelope 命令是可选的扩展命令,因而在要使用它的脚本开头必须添加 require "envelope" 控制命令。当 "from" 或 "to" 分别用作命令参数时,该命令比较信封部分的 SMTP 发件人和收件人。
示例:
require "envelope";
if envelope :is "from" "MrsFrank@company.com" {
redirect "frankshome@example.com";
}
exists
若邮件中存在参数中所列报头,该测试为真。列出的所有报头必须全都存在,否则该测试为假。
示例:
if exists "x-custom-header" {
redirect "admin@example.com";
}
-and-
if not exists ["from", "date"] {
discard;
}
false
该测试评估结果始终为“FALSE”。
header
当指定报头的数值匹配参数所设置的条件时,该报头测试评估结果为 true。当未指定匹配类型参数时,默认使用 :is。
示例:
require "fileinto"
if header :is "x-custom-header" "01" {
fileinto "admin";
}
not
将该命令随其他测试一起使用意味着测试结果必须求反才能执行该测试的相应操作。例如,测试 if not exists ["from", "date"] { discard; } 表示如果邮件既不包含 "from" 也不包含 "date" 报头,则执行 discard 操作。如果省略 not 命令,则表示当这些报头果真存在时删除该邮件。
size
size 命令接受标记参数 ":over" 和 ":under",且其后必须跟一个数值。该参数用于指定邮件大小必须大于还是小于指定数值才能使测试结果为真。可在数值后使用 M 表示兆字节,K 表示千字节,或不带任何字母表示字节。
示例:
if size :over 500K {
discard;
}
spamtest
spamtest 命令是可选的 Sieve 扩展命令,相关论述包含在 Spamtest and VirusTest Extensions (RFC-3685) 这篇文档中,位于 ietf.org。请查看该文档了解有关该扩展命令的信息。
true
该测试评估结果始终为“TRUE”。
virustest
virustest 命令是可选的 Sieve 扩展命令,相关论述包含在 Spamtest and VirusTest Extensions (RFC-3685) 这篇文档中,位于 ietf.org。请查看该文档了解有关该扩展命令的信息。
vnd.mdaemon.ai.prompt
用于 AI 分类, 此测试调用预先配置的 AI 提示(在安全 > AI 分类 > AI 提示定义),它将邮件内容发送到 AI 服务并接收分类响应。
语法: vnd.mdaemon.ai.prompt [MATCH-TYPE] <prompt-name> <expected-response>
•提示词名称 (字符串) - 配置的 AI 提示的名称
•期待的响应 (字符串) - 要与 AI 的响应匹配的值
支持的匹配类型:
•:is - 精确字符串匹配 (默认)
•:contains - 子字符串匹配
•:matches - 通配符模式匹配 (使用 * 和 ?)
需要: vnd.mdaemon.ai
有效时间: DATA 事件及以后(邮件内容可用后)
性能考虑因素
重要事项: AI 提示执行是同步的,在邮件处理期间发生。为了避免延迟邮件投递:
•设计提示快速返回 - 使用简洁的提示和高效的 AI 模型
•配置合适的超时值 - 在 AI 模型设置中设置超时值以防止无限期阻塞
•避免思考模式 - 不要使用具有扩展的“思考”或“推理”模式(例如 o1、o3、o1-pro)的 AI 模型,因为它们会大幅度增加响应时间
•使用选择性条件 - 与其他 Sieve 测试相结合,以限制何时调用 AI:
require ["vnd.mdaemon.ai", "spamtest"];
# 仅在通过基本垃圾邮件检查的邮件上运行 AI
if allof(spamtest :value "lt" :comparator "i;ascii-numeric" "5",
not header :contains "subject" "unsubscribe") {
if vnd.mdaemon.ai.prompt :is "PhishingCheck" "YES" {
discard;
}
}
配置要求
在 Sieve 规则中使用此测试之前,您必须在 SecurityGateway 的 web 界面中配置以下内容:
1.AI 模型 (安全 > AI 分类 > AI 模型)
o配置与 OpenAI 兼容的 AI 服务的连接
o设置终端 URL、模型名称和身份验证令牌
o配置超时设置
2.AI 提示词 (安全 > AI 分类 > AI 提示词)
o创建具有唯一名称的提示(在 Sieve 规则中引用)
o将提示词与配置的 AI 模型关联
o使用邮件变量来定义提示词模板
o配置相应分析
Sieve 测试中指定的提示词名称必须与已配置的 AI 提示词的名称完全匹配。
示例:
网络钓鱼检测
检测和隔离复杂的网络钓鱼尝试:
require "vnd.mdaemon.ai";
if vnd.mdaemon.ai.prompt :is "PhishingCheck" "YES" {
quarantine "AI detected potential phishing attempt";
}
使用通配符进行内容分类
按类别和文件将邮件分类到适当的文件夹中:
require ["vnd.mdaemon.ai", "fileinto"];
if vnd.mdaemon.ai.prompt :matches "CategoryClassifier" "SPAM*" {
fileinto "Junk";
} elsif vnd.mdaemon.ai.prompt :matches "CategoryClassifier" "MARKETING*" {
fileinto "Marketing";
}
优先级检测
标记紧急邮件以便立即得到关注:
require ["vnd.mdaemon.ai", "imap4flags"];
if vnd.mdaemon.ai.prompt :contains "UrgencyLevel" "HIGH" {
addflag "\\Flagged";
addheader "X-Priority" "1";
}
情绪分析
基于 AI 检测到的情绪来路由邮件:
require "vnd.mdaemon.ai";
if vnd.mdaemon.ai.prompt :is "SentimentAnalysis" "NEGATIVE" {
addheader "X-Customer-Sentiment" "Negative";
redirect "customer-support@example.com";
}
合规检测
识别可能包含敏感信息的邮件:
require "vnd.mdaemon.ai";
if vnd.mdaemon.ai.prompt :contains "ComplianceCheck" "PII" {
addheader "X-Contains-PII" "Yes";
redirect "compliance@example.com";
}
vnd.mdaemon.display_name_protection
显示名保护 测试邮件发件人的显示名称(来自发件人报头)是否类似于受保护的用户名,这表明可能存在显示名称伪装攻击。相似性阈值参数 (0.0-1.0) 控制相似性敏感性,其中较高的值需要更接近的匹配。默认值是 1.0。如果发件人的显示名称与高于阈值且未排除的受保护用户名匹配,则返回 true,反之则返回 false。
该测试包括两层排除检查:
•域级别的发件人排除列表: 无论相似性如何,此列表中的发件人的邮件都不会被标记为显示名称欺诈。支持通配符模式 (例如 *@company.com 和 user*@domain.com)。此列表在“不检查从下方列出的电子邮件地址发送的邮件”下的“显示名称欺诈”设置中配置。
•按用户的个人地址列表: 如果发件人位于受保护用户的个人地址列表中,则测试不会为该特定收件人标记邮件。
语法: vnd.mdaemon.display_name_protection [:nicknames] [threshold]
•在 DATA 事件和以后有效(在邮件报头可用后)
•:nicknames (可选): 指定时,启用昵称/细微变化检测。常见的名字变体被视为匹配(例如“Bob Smith”匹配“Robert Smith”、“Matt Jones”匹配“Matthew Jones”)。这有助于检测使用非正式名称变体的伪装尝试。
•阈值 (可选): 一个介于 0.0 和 1.0 之间的十进制值,表示相似性阈值(默认值: 1.0). 更高的值要求更接近的匹配才被认为是欺诈。
示例
使用默认阈值拒收显示名称具有欺诈性的邮件:
require "securitygateway";
if vnd.mdaemon.display_name_protection {
reject "Display name spoofing detected";
}
启用昵称检测来捕获非正式名称变体:
require "securitygateway";
if vnd.mdaemon.display_name_protection :nicknames "0.85" {
reject "Display name spoofing detected";
}
使用更严格的阈值 (0.90) 和隔离而不是拒收:
require "securitygateway";
if vnd.mdaemon.display_name_protection "0.90" {
fileinto "spam";
}
使用昵称检测对使用免费电子邮件的外部发件人应用更严格的策略:
require "securitygateway";
if allof (vnd.mdaemon.sender_is_free_email,
vnd.mdaemon.display_name_protection :nicknames "0.85") {
reject "Potential impersonation from free email provider";
}
为边缘案例添加警告报头:
require "securitygateway";
if vnd.mdaemon.display_name_protection ".75" {
addheader "X-Possible-Spoofing" "Display name similarity detected";
}
vnd.mdaemon.sender_is_free_email
测试邮件发件人的电子邮件地址(来自发件人报头)是否来自 Gmail、Yahoo、Hotmail、Outlook 和 ProtonMail 等免费电子邮件供应商。如果发件人的域匹配任何已知的免费电子邮件供应商,则返回 true,否则返回 false。
语法: vnd.mdaemon.sender_is_free_email
•在 DATA 事件和以后有效(在邮件报头可用后)
•无参数。
公认的免费电子邮件供应商
该测试识别主要的免费电子邮件供应商,包括:
•Gmail (gmail.com、googlemail.com )
•Yahoo Mail (yahoo.com 和地区变体)
•Outlook/Hotmail (hotmail.com、outlook.com、live.com、msn.com )
•ProtonMail (protonmail.com、proton.me)
•iCloud (icloud.com、me.com、mac.com )
•AOL (aol.com )
•等等 (GMX、Mail.com、Zoho、Yandex、Mail.ru、FastMail、Tutanota 等)
示例
标记来自免费电子邮件供应商的邮件以供额外审查:
require "securitygateway";
if vnd.mdaemon.sender_is_free_email {
addheader "X-Free-Email-Provider" "Yes";
}
对使用免费电子邮件的外部发件人应用更严格的策略:
require "securitygateway";
if allof (vnd.mdaemon.sender_is_free_email,
not vnd.mdaemon.display_name_spoofed "0.90") {
reject "Potential impersonation from free email provider";
}
这些是 SecurityGateway 支持的标准操作命令。fileinto 和 reject 命令是扩展命令,因此每当您希望在脚本中加以使用时,就必须将其包括在 require 控制命令中。securitygateway 扩展命令中还提供了许多其他操作命令,在 SecurityGateway Sieve 扩展命令 这个页面上对其作了概述。
fileinto
fileinto 操作命令是可选的扩展命令,因而在要使用它的脚本开头必须添加 require "fileinto" 这个控制命令。该命令接受两个参数: "spam" 和 "admin"。"spam" 将邮件移入用户隔离,而 "admin" 将它移入管理员隔离。
示例:
require "fileinto";
if header :contains "from" "Frank Thomas" {
fileinto "spam";
}
discard
该操作导致邮件被自动删除,而不会发送投递状态通知和任何其他消息。
示例:
if size :over 2M { discard; }
keep
该操作导致邮件被保存到默认位置。
redirect
该命令把邮件改投到相关参数中指定的地址,而不会更改邮件正文和现有报头。该命令还支持可选的 :copy 扩展参数,它将邮件的副本发送到指定地址而不是重新投递该邮件。因而在将副本发送到指定地址以外,还可执行其他操作。
示例:
require "copy";
if header :contains "subject" "Response to XYZ" {
redirect :copy "offers@example.com";
bayes-learn "ham";
}
reject
reject 操作命令是可选的扩展命令,因而在要使用它的脚本开头必须添加 require "reject" 控制命令。该命令导致在 SMTP 处理过程中邮件被拒绝,并附带 5xx 响应代码和参数中指定的可选短消息。
require "reject";
if size :over 5M {
reject "No way! This message is too big for me to accept.";
}
vnd.mdaemon.securewebmsg
使用这个操作命令来使用 SecurityGateway 的安全通信 web 门户来发送邮件。它将发送给外部收件人的出站邮件转换为通过门户投递的安全网络邮件。邮件不是直接通过 SMTP 发送,而是存储在 SecurityGateway 的数据库中,收件人会收到一封通知电子邮件,其中包含通过 web 浏览器安全访问邮件的链接。此操作为针对没有安全电子邮件基础设施的外部各方的敏感通信,提供端到端的加密和安全投递。典型使用: 数据泄露防护, 安全地发送机密/敏感信息,并满足合规要求。
该操作在内容过滤器和数据泄露防护规则 (“作为安全 web 邮件发送”操作)中可用,以及可以在手动创建的 Sieve 脚本中可用。
语法: vnd.mdaemon.securewebmsg
参数: 无
需要: securitygateway
有效时间: 邮件处理期间的任何时间。
工作方式
将此操作应用于邮件时:
•该操作仅影响发送给外部(非本地)收件人的邮件。正常投递指向本地用户的邮件。
•收件人会收到一封通知电子邮件,其中包含安全链接,以便通过 SecurityGateway 的门户网站访问完整邮件。
•如果外部用户账户不存在(如果为域启用了自动创建),则会自动为收件人创建外部用户账户。
•收件人使用身份验证(电子邮件验证、密码或多重身份验证,具体取决于配置)通过 web 浏览器访问邮件。
•邮件内容加密存储在 SecurityGateway 的数据库中,并通过 HTTPS 传输。
配置要求
在使用该操作前,必须配置安全邮件门户:
启用安全通信 - 为发件域启用安全邮件投递 (设置/用户 > 安全通信 > 配置)
外部用户设置 - 配置外部用户创建策略和身份验证要求
门户访问 - 确保外部收件人可以访问 SecurityGateway 门户网站
通知模板 - 定制通知电子邮件模板 (可选)
示例
require ["securitygateway","reject","fileinto","envelope","body","regex"];
if allof(header :matches "subject" "[Secure Message]*")
{
vnd.mdaemon.securewebmsg;
}
敏感关键字的自动安全投递
通过安全门户自动发送包含敏感关键字的邮件:
require "securitygateway";
if header :contains "subject" ["confidential", "private", "sensitive"] {
vnd.mdaemon.securewebmsg;
}
基于收件域的安全投递
通过安全门户将所有邮件发送到特定的外部域:
require "securitygateway";
if address :domain :is "to" ["competitor.com", "external-partner.net"] {
vnd.mdaemon.securewebmsg;
}
针对大附件的安全投递
对带有大附件的邮件使用安全门户,以避免电子邮件大小限制:
require ["securitygateway", "fileinto"];
if size :over 10M {
vnd.mdaemon.securewebmsg;
}
由合规驱动的安全投递
与内容分析相结合,为受监管的数据实施安全投递:
require "securitygateway";
# Send messages containing potential PII via secure portal
if header :contains "X-Contains-PII" "Yes" {
vnd.mdaemon.securewebmsg;
}
针对特定发件人的安全投递
对来自特定内部用户的邮件强制安全投递:
require "securitygateway";
if address :is "from" ["ceo@example.com", "legal@example.com", "hr@example.com"] {
vnd.mdaemon.securewebmsg;
}
结合其他操作
您可以将安全 web 邮件与其他操作相结合:
require "securitygateway";
if header :contains "subject" "confidential" {
addheader "X-Sensitive-Content" "Yes";
vnd.mdaemon.securewebmsg;
}
拒绝主题中包含 "[SPAM]" 的任何邮件
require "reject";
if header :contains "subject" "[SPAM]"
{
reject "I don't want your spam";
}
拒绝发往特定实名的任何邮件
require ["securitygateway","reject"];
if header :contains "to" "Real Name"
{
bayes-learn "spam";
reject "I don't want your spam";
}
定制贝叶斯自动学习
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 匹配
require ["securitygateway"];
if not lookup "rblip" "all" {greylist;}
收到大型邮件时通知管理员
require ["securitygateway"];
if size :over 1M
{
alert text:
收件人: admin@company.mail
发件人: postmaster@$RECIPIENTDOMAIN$
主题: SecurityGateway 内容过滤器邮件
X-Attach-Msg: No
$RECIPIENT$ 收到超过 1MB 的邮件。
.
;
}
当主题以“[Secure Message]”开头时作为安全邮件发送
require ["securitygateway","reject","fileinto","envelope","body","regex"];
if allof(header :matches "subject" "[Secure Message]*")
{
vnd.mdaemon.securewebmsg;
}