本章讨论如何基于邮件的源(发件人,IP 地址等)或标题字符串来过滤邮件。采用两种邮件过滤机制,用映射表和 Sieve 服务器端规则 (SSR) 控制对 MTA 的访问。
使用映射表限制对 MTA 的访问,使得可以基于 From: 和 To: 地址、IP 地址、端口号和源通道或目标通道过滤邮件。映射表允许启用或禁用 SMTP 中继。Sieve 是一个邮件过滤脚本,允许基于标题中的字符串过滤邮件(不能基于邮件主体过滤邮件)。
如果要进行信封级别控制,请使用映射表来过滤邮件。如果要进行基于标题的控制,请使用 Sieve 服务器端规则。
本章分为两部分:
第 1 部分:映射表。允许管理员通过配置特定映射表来控制对 MTA 服务的访问。管理员可以控制通过 Messaging Server 发送和接收邮件的人员。
第 2 部分:邮箱过滤器。允许用户和管理员基于邮件标题中的字符串来过滤邮件并指定对已过滤的邮件的操作。使用 Sieve 过滤语言并可以在通道级别、MTA 级别或用户级别过滤。
第 1 部分包含以下各节:
您可以通过配置特定的映射表来控制对邮件服务的访问。通过这些映射表,您可以控制能够发送和/或接收邮件的人员。表 17–1 列出了本节中所说明的映射表。提供给 FROM_ACCESS、MAIL_ACCESS 和 ORIG_MAIL_ACCESS 映射的应用程序信息字符串包括在 HELO/EHLO SMTP 命令中声明的系统名称。此名称显示在字符串末尾,并以斜杠与字符串的其余部分(通常为 "SMTP")分隔开。这个声明的系统名称在阻止一些蠕虫和病毒时非常有用。
与所有映射表一样,访问控制映射表具有相同的通用格式(请参见映射文件)。这些访问控制映射表由映射表名称,后跟换行,再后跟一个或多个映射条目组成。映射条目由左侧的搜索模式和右侧的模板组成。搜索模式过滤特定邮件,模板指定对邮件所进行的操作。例如:
SEND_ACCESS *|Elvis1@sesta.com|*|* $Y *|Nelson7@sesta.com|*|* $Y *|AkiraK@sesta.com|*|* $Y *|*@sesta.com|*|* $NMail$ Blocked
在此示例中,将阻止所有来自 sesta.com 域的电子邮件,但 Elvis1、Nelson 和 AkiraK 中的电子邮件除外。
访问控制映射条目的搜索模式由多个搜索条件组成,搜索条件之间以垂直条 (|) 分隔。搜索条件的顺序取决于访问映射表,这将在后面的小节中介绍。例如,SEND_ACCESS 映射表具有以下搜索格式:
src-channel|from-address|dst-channel|to-address
其中,src-channel 是将邮件排队的通道;from-address 是邮件创始者的地址;dst-channel 是邮件要排队发送至的通道;to-address 是邮件要发送到的地址。在这四个字段中的任意一个字段中使用星号将使该字段匹配所有适当的通道或地址。
每当修改 mappings 文件之后,必须重新编译配置(请参见编译 MTA 配置)。
映射表 |
说明 |
---|---|
SEND_ACCESS(请参见SEND_ACCESS 和 ORIG_SEND_ACCESS 表) |
用于根据信封 From 地址、信封 To 地址、源通道和目标通道来阻止外来连接。执行重写、别名扩展等操作后将检查 To 地址。 |
ORIG_SEND_ACCESS(请参见SEND_ACCESS 和 ORIG_SEND_ACCESS 表) |
用于根据信封 From 地址、信封 To 地址、源通道和目标通道来阻止外来连接。执行重写之后,但在别名扩展之前检查 To 地址。 |
MAIL_ACCESS(请参见MAIL_ACCESS 和 ORIG_MAIL_ACCESS 映射表) |
用于根据在 SEND_ACCESS 和 PORT_ACCESS 表中找到的组合信息来阻止外来连接。即,将在 SEND_ACCESS 中找到的通道和地址信息与在 PORT_ACCESS 中找到的 IP 地址和端口号信息结合。 |
ORIG_MAIL_ACCESS(请参见MAIL_ACCESS 和 ORIG_MAIL_ACCESS 映射表) |
用于根据在 ORIG_SEND_ACCESS 和 PORT_ACCESS 表中找到的组合信息来阻止外来连接。即,将在 ORIG_SEND_ACCESS 中找到的通道和地址信息与在 PORT_ACCESS 中找到的 IP 地址和端口号信息结合。 |
FROM_ACCESS(请参见FROM_ACCESS 映射表) |
用于根据信封 From 地址来过滤邮件。To 地址为不相关的地址时使用该表。 |
PORT_ACCESS(请参见PORT_ACCESS 映射表) |
用于根据 IP 编号阻止外来的连接。 |
MAIL_ACCESS 和 ORIG_MAIL_ACCESS 映射是最常规的,这些映射不仅包含对 SEND_ACCESS 和 ORIG_SEND_ACCESS 可用的地址和通道信息,而且还包含可以通过 PORT_ACCESS 映射表获取的所有信息(包括 IP 地址和端口号信息)。
表 17–2 显示了与 SEND_ACCESS、ORIG_SEND_ACCESS、MAIL_ACCESS、ORIG_MAIL_ACCESS 和 FROM_ACCESS 映射表相关的访问映射标志。请注意,PORT_ACCESS 映射表支持一组略有不同的标志(请参见表 17–3)。
带有参数的标志必须按照表中所示的阅读顺序排列参数。例如:
ORIG_SEND_ACCESS tcp_local|*|tcp_local|* $N$D30|Relaying$ not$ allowed
在此示例中,正确的顺序是延迟时间段后跟拒绝字符串。请注意,标志本身可以按任何顺序排列。因此,以下条目具有相同的结果:
30|Relaying$ not$ allowed$D$N $N30|Relaying$ not$ allowed$D 30|$N$DRelaying$ not$ allowed |
标志 |
说明 |
---|---|
$A |
如果已使用 SASL,则设置该标志。请参见检查特殊标志 |
$B |
将邮件重定向到 bitbucket。 |
$D |
如果请求获得延迟传送收据,则设置该标志(在 FROM_ACCESS 中不可用)。请参见检查特殊标志。 |
$F |
如果请求获得失败传送收据,则设置该标志(在 FROM_ACCESS 中不可用)。请参见检查特殊标志。 |
$H |
将邮件保存为 .HELD 文件。 |
$S |
如果请求获得成功传送收据,则设置该标志(在 FROM_ACCESS 中不可用)。请参见检查特殊标志。 |
$T |
如果已使用 TLS,则设置该标志。请参见检查特殊标志 |
$U |
如果在 ORIG_SEND_ACCESS、SEND_ACCESS、ORIG_MAIL_ACCESS 和 MAIL_ACCESS 中使用,则从映射开始将获得一个整数变量,并相应地设置 MM_DEBUG 的值。此外,还将在可能的情况下启用通道级别调试。结果是基于源 IP 地址、原始地址和收件人地址等项目启用调试。 |
$Y |
允许访问。 |
$V |
导致对所有收件人执行强制放弃。 |
$Z |
导致对所有收件人执行强制放弃。 |
带有变量的标志,按照变量读取顺序+(请勿按字母顺序排列此表!) |
|
$Uinteger |
从映射一开始就采用整数参数,并相应地设置 MM_DEBUG。此外,还将在可能的情况下启用通道级别调试。结果是,现在可以基于源 IP 地址、原始地址和收件人地址等启用调试。 |
$Jaddress |
* 使用指定的 address 替换原始信封 From: 地址。 |
$Kaddress |
* ++ 使用指定的 address 替换原始 Sender: 地址。 |
$Iuser|identifier |
检查指定用户的组 ID。 |
$<string |
+++ 如果探测匹配,则将 string 发送到系统日志(UNIX user.notice 工具和严重性)或事件日志 (NT)。 |
$>string |
+++ 如果访问被拒绝,则将 string 发送到系统日志(UNIX user.notice 工具和严重性)或事件日志 (NT)。 |
$Ddelay |
延迟响应的间隔为 delay(单位为百分之一秒),正值将导致延迟应用于事务中的每个命令;负值将导致延迟只应用于地址移交(对于 FROM_ACCESS 表为 SMTP MAIL FROM: 命令;对于其他表为 SMTP RCPT TO: 命令)。 |
$Ttag |
使用 tag 前缀。 |
$Aheader |
将标题行 header 添加至邮件。 |
$Gconversion_tag |
如果在 ORIG_SEND_ACCESS、SEND_ACCESS、ORIG_MAIL_ACCESS 和 MAIL_ACCESS 中使用,此标志将从映射结果中读取值,并将该值视为要应用到当前收件人的一组转换标记。如果与 FROM_ACCESS 一起使用,转换标记将应用于所有收件人。在从映射读取的变量序列中,$G 位于 $A(标题地址)之后。请参见邮件转换标记 |
$Sx,y,z |
* 导致从映射结果中读取其他以 | 分隔的参数。此参数由一个到三个用逗号分隔的整数值组成。第一个值为事务建立一个新的最小 blocklimit,第二个值建立一个新的最小 recipientlimit,第三个值建立一个新的最小 recipientcutoff。在读取任何捕获参数后,将从映射结果中读取此参数。请参见指定绝对邮件大小限制。 |
$Xerror-code |
如果拒绝邮件,则发布指定的 error-code 扩展 SMTP 错误代码。 |
$,spamadjust_arg |
允许您从访问映射表执行筛选 spamadjust 操作。该参数与 spamadjust 参数的格式相同。另请注意,这些映射中有一些是基于各收件人而应用的,执行的任何 spamadjust 操作都适用于所有收件人。 |
$Nstring |
使用可选的错误文本 string 拒绝访问。 |
$Fstring |
$N string 的同义词;即,使用可选的错误文本 string 拒绝访问。 |
* 仅可用于 FROM_ACCESS 表。 + 要使用多个带有变量的标志,请用垂直条字符 | 分隔变量,并按照此表中列出的顺序放置变量。 ++ 要使 $K 标志在 FROM_ACCESS 映射表中生效,源通道必须包含 authrewrite 关键字。 +++ 处理有问题的发件人时,使用 $D 标志防止拒绝服务攻击是一个好方法。特别是,在任何 $> 条目或拒绝访问的 $< 条目中使用 $D 是一个很好的方法。 |
您可以使用 SEND_ACCESS 和 ORIG_SEND_ACCESS 映射表来控制其他人能否发送邮件、接收邮件,或同时控制这两方面。访问检查内容包括邮件的信封 From: 地址和信封 To: 地址、邮件进入的通道以及要尝试发出邮件的通道。
如果存在 SEND_ACCESS 或 ORIG_SEND_ACCESS 映射表,则对于通过 MTA 的每封邮件的每个收件人,MTA 将使用以下格式的字符串扫描表格(请注意垂直条字符 | 的使用):
src-channel|from-address|dst-channel|to-address
其中,src-channel 是将邮件排队的通道;from-address 是邮件创始者的地址;dst-channel 是邮件要排队发送至的通道;to-address 是邮件要发送到的地址。在这四个字段中的任意一个字段中使用星号将使该字段匹配所有适当的通道或地址。
此处的地址为信封地址,即信封 From: 地址和信封 To: 地址。如果是 SEND_ACCESS,则将在执行重写、别名扩展等操作后检查信封 To: 地址;如果是 ORIG_SEND_ACCESS,则将在执行重写之后,但在别名扩展之前检查最初指定的信封 To: 地址。
如果搜索字符串匹配某个模式(即,表中某个条目的左侧),则将检查映射的结果输出。如果输出包含标志 $Y 或 $y,则允许对该特定 To: 地址进行排队。如果输出包含 $N、$n、$F 或 $f 中的任意一个标志,则对该特定地址进行排队将被拒绝。在被拒绝的情况下,映射输出中可能提供可选的拒绝文本。此字符串将包括在 MTA 发布的拒绝错误中。如果没有输出字符串(除 $N、$n、$F 或 $f 标志以外),则将使用默认的拒绝文本。有关其他标志的描述,请参见访问控制映射表标志。
将 MTA 选项 ACCESS_ORCPT 设置为 1 时,将向传递给 SEND_ACCESS、ORIG_SEND_ACCESS、MAIL_ACCESS 和 ORIG_MAIL_ACCESS 映射表(包含原始收件人 [ORCPT] 地址)的探测值添加一个其他以垂直条分隔的字段。如果邮件没有 ORCPT 地址,则使用初始的、未经修改的 RCPT TO: 地址代替。默认值为 0,探测值位于末尾处:
src-channel|from-address|dst-channel|to-address|ORCPT_address
在以下示例中,从 UNIX 用户代理(例如 mail、Pine 等)发送的邮件源于本地通道 l,传送至 Internet 的邮件通过某种类型 TCP/IP 通道发出。假定不允许本地用户(邮寄主管除外)向 Internet 发送邮件,但可以从 Internet 接收邮件。则下面示例中所示的 SEND_ACCESS 映射表是可以实施此限制的一种方法。在此映射表中,假定本地主机名为 sesta.com。在通道名称 "tcp_*" 中使用了通配符,以便匹配所有可能的 TCP/IP 通道名称(例如 tcp_local)。
SEND_ACCESS *|postmaster@sesta.com|*|* $Y *|*|*|postmaster@sesta.com $Y l|*@sesta.com|tcp_*|* $NInternet$ postings$ are$ not$ permitted |
在拒绝邮件中,使用了美元符号,用以引用邮件中的空格。如果没有这些美元符号,拒绝邮件将提前结束,系统只能读取 "Internet",而不是 "Internet postings are not permitted"。请注意,此示例忽略了其他可能的“本地”邮件来源,例如来自基于 PC 的邮件系统或来自 POP 或 IMAP 客户机的邮件。
尝试发送邮件的客户机将决定是否把 MTA 拒绝错误文本实际提供给尝试发送邮件的用户。如果使用 SEND_ACCESS 拒绝外来 SMTP 邮件,MTA 将只发出一段包括可选拒绝文本的 SMTP 拒绝代码;SMTP 发送客户机将负责使用该信息构建要发送回原始发件人的退回邮件。
MAIL_ACCESS 映射表是 SEND_ACCESS 和 PORT_ACCESS 映射表的超集。它结合了 SEND_ACCESS 的通道和地址信息以及 PORT_ACCESS 的 IP 地址和端口号信息。同样,ORIG_MAIL_ACCESS 映射表是 ORIG_SEND_ACCESS 和 PORT_ACCESS 映射表的超集。MAIL_ACCESS 的探测字符串的格式为:
port-access-probe-info|app-info|submit-type|send_access-probe-info
同样,ORIG_MAIL_ACCESS 的探测字符串的格式为:
port-access-probe-info|app-info|submit-type|orig_send_access-probe-info
此处,如果邮件为外来 SMTP 邮件,则 port-access-probe-info 由 PORT_ACCESS 映射表探测中通常包含的所有信息组成;否则为空白。app-info 包含 HELO/EHLO SMTP 命令中所声明的系统名称。此名称显示在字符串末尾,并以斜杠与字符串的其余部分(通常为 "SMTP")分隔开。这个声明的系统名称在阻止一些蠕虫和病毒时非常有用。submit-type 可以为 MAIL、SEND、SAML 或 SOML 的其中之一,这取决于将邮件提交给 Messaging Server 的方式。通常情况下该值为 MAIL,表示它是作为邮件提交的;如果是向 SMTP 服务器提交广播请求(或组合的广播/邮件请求),该值可能会是 SEND、SAML 或 SOML。而对于 MAIL_ACCESS 映射,send-access-probe-info 由 SEND_ACCESS 映射表探测中通常包含的所有信息组成。同样,对于 ORIG_MAIL_ACCESS 映射,orig-send-access-probe-info 由 ORIG_SEND_ACCESS 映射表探测中通常包含的所有信息组成。
将 MTA 选项 ACCESS_ORCPT 设置为 1 时,将向传递给 SEND_ACCESS、ORIG_SEND_ACCESS、MAIL_ACCESS 和 ORIG_MAIL_ACCESS 映射表(包含原始收件人 [ORCPT] 地址)的探测值添加一个其他以垂直条分隔的字段。如果邮件不具有 ORCPT 地址,则使用原始、未经修改的 RCPT TO: 地址代替。默认值为 0,探测值位于末尾处。示例:
port-access-probe-info|app-info|submit-type|send_access-probe-info|ORCPT_address |
将外来 TCP/IP 连接信息与通道和地址信息包含在同一映射表中,可以更方便地实施某些类型的控制,例如强制允许在来自特定 IP 地址的邮件中显示哪些信封 From: 地址。这对限制电子邮件伪造,或鼓励用户正确配置其 POP 和 IMAP 客户机的 From: 地址很有用。例如,如果站点希望使信封 From: 地址 vip@siroe.com 只显示在来自 IP 地址 1.2.3.1 和 1.2.3.2 的邮件中,并且确保来自子网 1.2.0.0 中所有系统的邮件上的信封 From: 地址均来自 siroe.com,则可以使用 MAIL_ACCESS 映射表,如以下示例所示。
MAIL_ACCESS ! Entries for vip's two systems ! TCP|*|25|1.2.3.1|*|SMTP|MAIL|tcp_*|vip@siroe.com|*|* $Y TCP|*|25|1.2.3.2|*|SMTP|MAIL|tcp_*|vip@siroe.com|*|* $Y ! ! Disallow attempts to use vip's From: address from other ! systems ! TCP|*|25|*|*|SMTP|MAIL|tcp_*|vip@siroe.com|*|* \ $N500$ Not$ authorized$ to$ use$ this$ From:$ address ! ! Allow sending from within our subnet with siroe.com From: ! addresses ! TCP|*|25|1.2.*.*|*|SMTP|MAIL|tcp_*|*@siroe.com|*|* $Y ! ! Allow notifications through ! TCP|*|25|1.2.*.*|*|SMTP|MAIL|tcp_*||*|* $Y ! ! Block sending from within our subnet with non-siroe.com ! addresses ! TCP|*|25|1.2.*.*|*|SMTP|MAIL|tcp_*|*|*|* \ $NOnly$ siroe.com$ From:$ addresses$ authorized |
使用 FROM_ACCESS 映射表可控制哪些人员可以发送邮件,和/或使用已经验证的地址覆盖不确定的 From: 地址。
FROM_ACCESS 映射表的输入探测字符串与 MAIL_ACCESS 映射表的输入探测字符串类似,只是减少了目标通道和地址,但增加了已经验证的发件人信息(如果有)。因此,如果存在 FROM_ACCESS 映射表,则对于每次尝试的邮件提交,Messaging Server 将使用如下格式的字符串搜索表格(请注意垂直条字符 | 的使用):
port-access-probe-info|app-info|submit-type|src-channel|from-address|auth-from |
此处,如果邮件为外来 SMTP 邮件,则 port-access-probe-info 由 PORT_ACCESS 映射表探测中通常包含的所有信息组成;否则为空白。app-info 包含 HELO/EHLO SMTP 命令中所声明的系统名称。此名称显示在字符串末尾,并以斜杠与字符串的其余部分(通常为 "SMTP")分隔开。这个声明的系统名称在阻止一些蠕虫和病毒时非常有用。submit-type 可以为 MAIL、SEND、SAML 或 SOML 的其中之一,这取决于将邮件提交给 MTA 的方式。通常情况下该值为 MAIL,表示它是作为邮件提交的;如果是向 SMTP 服务器提交广播请求(或组合的广播/邮件请求),该值可能会是 SEND、SAML 或 SOML。src-channel 是邮件的来源通道(即对邮件进行排队);from-address 是不确定的邮件创始者的地址;auth-from 是已经验证的创始者地址(如果有此信息)或为空白(如果没有已经验证的信息)。
如果探测字符串匹配某个模式(即,表中某个条目的左侧),将检查映射的结果输出。如果输出包含标志 $Y 或 $y,则允许对该特定 To: 地址进行排队。如果输出包含 $N、$n、$F 或 $f 中的任意一个标志,则对该特定地址进行排队将被拒绝。在被拒绝的情况下,映射输出中可能提供可选的拒绝文本。此字符串将包括在 Messaging Server 发布的拒绝错误中。如果没有输出字符串(除 $N、$n、$F 或 $f 标志以外),则将使用默认的拒绝文本。有关其他标志的描述,请参见访问控制映射表标志。
除了基于创始者确定是否允许提交邮件以外,FROM_ACCESS 还可用于通过 $J 标志更改信封 From: 地址,或通过 $K 标志修改 authrewrite 通道关键字的效果(在接受的邮件上添加 Sender: 标题地址)。例如,使用此映射表,可以将原始信封 From: 地址简单替换为已验证的地址。
FROM_ACCESS *|SMTP|*|tcp_auth|*| $Y *|SMTP|*|tcp_auth|*|* $Y$J$3 |
使用 FROM_ACCESS 映射表修改某些源通道(将 authrewrite 设置为非零值)上的效果时,如果要按原样使用已验证的地址,则无需使用 FROM_ACCESS。
例如,如果在 tcp_local 通道上设置了 authrewrite 2,则无需使用以下 FROM_ACCESS 映射表,因为仅使用 authrewrite 就足以获得此效果(按原样添加已经验证的地址):
FROM_ACCESS *|SMTP|*|tcp_auth|*| $Y *|SMTP|*|tcp_auth|*|* $Y$K$3 |
但是,FROM_ACCESS 的真正目的在于允许进行更加复杂和细微的更改,如下面示例所示。如果要向外来邮件添加 Sender: 标题行(显示已经验证的 SMTP AUTH 提交者地址),则可以仅使用 authrewrite 关键字。但是,假设只有在已经验证的 SMTP AUTH 提交者地址与信封 From: 地址不同时,才将这样一个 Sender: 标题行添加到外来邮件(即如果地址匹配,则不必添加 Sender: 标题行),并进一步假设您不希望 SMTP AUTH 和信封 From: 地址仅仅因为信封 From: 包含可选子地址信息而被视为有所不同。
FROM_ACCESS ! If no authenticated address is available, do nothing *|SMTP|*|tcp_auth|*| $Y ! If authenticated address matches envelope From:, do nothing *|SMTP|*|tcp_auth|*|$2* $Y ! If authenticated address matches envelope From: sans ! subaddress, do nothing *|SMTP|*|tcp_auth|*+*@*|$2*@$4* $Y ! Fall though to... ! ...authenticated address present, but didn't match, so force ! Sender: header *|SMTP|*|tcp_auth|*|* $Y$K$3 |
分发程序可以基于 IP 地址和端口号选择性地接受或拒绝外来连接。分发程序启动时,将查找名为 PORT_ACCESS 的映射表。如果存在,分发程序将按以下格式格式化连接信息:
TCP|server-address|server-port|client-address|client-port
分发程序将尝试匹配所有 PORT_ACCESS 映射条目。如果映射结果包含 $N 或 $F,将立即关闭连接。映射的任何其他结果都表示可以接受连接。$N 或 $F 可以后跟一条拒绝消息(可选)。如果存在,该消息将在关闭连接之前被发送回连接。请注意,消息被发送回连接之前,其字符串将被附加一个 CRLF 结束符。
MMP 不使用 PORT_ACCESS 映射表。如果希望拒绝来自某些 IP 地址的 SMTP 连接并且您正在使用 MMP,则必须使用 TCPAccess 选项。请参见用 MMP 配置邮件访问。要通过映射表来控制 SMTP 连接,请使用 INTERNAL_IP 映射表(请参见允许为外部站点进行 SMTP 中继)。
如果映射探测匹配,则后跟可选字符串的标志 $< 可使 Messaging Server 将字符串发送至系统日志 (UNIX) 或事件日志 (NT)。如果访问被拒绝,则后跟可选字符串的标志 $> 可使 Messaging Server 将字符串发送至系统日志 (UNIX) 或事件日志 (NT)。如果设置了 LOG_CONNECTION MTA 选项的第 1 位和 $T 标志以拒绝连接,则再指定 $T 标志会将 "T" 条目写入连接日志。如果设置了 LOG_CONNECTION MTA 选项的第 4 位,则可将站点提供的文本包含在 PORT_ACCESS 条目中,以便包含在 "C" 连接日志条目中。要指定此类文本,可以在条目的右侧添加两个垂直条字符,后跟所需的文本。表 17–3 列出了可用的标志。
表 17–3 PORT_ACCESS 映射表
标志 |
说明 |
---|---|
$Y |
允许访问。 |
带有变量的标志按照变量的阅读顺序排序 + |
|
$< string |
如果探测匹配,将字符串发送到系统日志 (UNIX) 或事件日志 (NT)。 |
$> string |
如果访问被拒绝,将字符串发送到系统日志 (UNIX) 或事件日志 (NT)。 |
$N string |
使用可选的错误文本字符串拒绝访问 |
$F string |
$N string 的同义词;即,使用可选的错误文本 string 拒绝访问 |
$T text |
如果设置了LOG_CONNECTION MTA 选项的第 1 位(值 2)和 $N 标志(以便拒绝连接),则再设置 $T 标志会将 "T" 条目写入连接日志。T 日志条目将包含完整的映射结果字符串($N 及其字符串)。 |
+要使用多个带有变量的标志,请用垂直条字符 | 分隔变量,并按照此表中列出的顺序放置变量。 |
例如,除单独要拒绝的不包含说明文本的特定主机以外,以下映射将只接受来自单一网络的 SMTP 连接(到端口 25,常规 SMTP 端口):
PORT_ACCESS TCP|*|25|192.123.10.70|* $N500 TCP|*|25|192.123.10.*|* $Y TCP|*|25|*|* $N500$ Bzzzt$ thank$ you$ for$ playing. |
请注意,对 PORT_ACCESS 映射表做出任何更改之后,您将需要重新启动分发程序,以便分发程序能够看到这些更改。(如果您使用的是已编译的 MTA 配置,则需要先重新编译配置,以将更改并入已编译的配置中。)
PORT_ACCESS 映射表专用于执行基于 IP 的拒绝。要在电子邮件地址级别进行更加通用的控制,SEND_ACCESS 或 MAIL_ACCESS 映射表可能更加适用。
通过使用 Port Access 映射表中的共享库 conn_throttle.so,可以限制特定 IP 地址连接到 MTA 的频繁程度。限制特定 IP 地址的连接对于防止拒绝服务攻击中使用的过多连接可能会有用。
conn_throttle.so 是在 PORT_ACCESS 映射表中使用的共享库,它可限制特定 IP 地址过于频繁地连接到 MTA。所有配置选项都被指定为连接限制共享库的参数,如下所示:
$[msg_svr_base/lib/conn_throttle.so, throttle,IP-address ,max-rate]
IP-address 是远程系统的点分十进制地址。max-rate 是将对此 IP 地址强制实施的最大速率(连接次数/分钟)。
对于处罚性例程,可以使用例程名称 throttle_p 代替 throttle。如果某些连接在过去的连接次数太多,则 throttle_p 将在以后拒绝这些连接。如果最大速率为 100,并且在过去的一分钟里尝试的连接次数为 250,则不仅远程站点将在该分钟内最初 100 次连接之后被阻止,在接下的分钟内它们还会被阻止。换句话说,系统将在每分钟之后从尝试连接的总数中减去最大速率,只要连接的总数大于最大速率,就将阻止远程系统。
如果指定的 IP 地址没有超过最大每分钟连接速率,共享库调用将失败。
如果超过了该速率,调用将成功,但不会返回任何内容。这可以在 $C/$E 组合中来完成,如以下示例所示:
PORT_ACCESS TCP|*|25|*|* \ $C$[msg_svr_base/lib/conn_throttle.so,throttle,$1,10] \ $N421$ Connection$ not$ accepted$ at$ this$ time$E
其中,
$C 将继续执行从下一个表格条目开始的映射进程,并将此条目的输出字符串用作映射进程的新输入字符串。
$[msg_svr_base/lib/conn_throttle.so,throttle,$1,10] 是库调用, 其中 throttle 为库例程,$1 为服务器 IP 地址,而 10 为每分钟连接次数的阀值。
$N421$ Connection$ not$ accepted$ at$ this$ time 将拒绝访问并返回 421 SMTP 代码(瞬态负完成)以及消息 "Connection not accepted at this time"。
$E 将立即终止映射进程。它使用此条目的输出字符串作为映射进程的最终结果。
Messaging Server 将尽早检查访问控制映射。此操作的确切执行时间取决于所使用的电子邮件协议(当必须要检查的信息可用时)。
对于 SMTP 协议,在发送端能够发送收件人信息或邮件数据之前,将发生 FROM_ACCESS 拒绝。在发送端开始发送邮件数据之前,将发生 SEND_ACCESS 或 MAIL_ACCESS 拒绝。如果 SMTP 邮件被拒绝,Messaging Server 将永远不会接收或查看邮件数据,这就将执行此类拒绝的开销减至了最低。
如果有多个访问控制映射表,Messaging Server 将对所有这些映射表进行检查。即,FROM_ACCESS、SEND_ACCESS、ORIG_SEND_ACCESS、MAIL_ACCESS 和 ORIG_MAIL_ACCESS 映射表均可能生效。
imsimta test -rewrite 实用程序(特别是与 -from、-source_channel、-sender 和 -destination_channel 选项一起使用时)在测试访问控制映射时很有用。有关详细信息,请参见 《Sun Java System Messaging Server 6 2005Q4 Administration Reference》中的“imsimta test”。下面的示例显示了示例 SEND_ACCESS 映射表以及结果探测。
MAPPING TABLE: SEND_ACCESS tcp_local|friendly@siroe.com|l|User@sesta.com $Y tcp_local|unwelcome@varrius.com|l|User@sesta.com $NGo$ away! PROBE: $ TEST/REWRITE/FROM="friendly@siroe.com" - _$ /SOURCE=tcp_local/DESTINATION=l User@sesta.com ... Submitted address list: l User (SESTA.COM) *NOTIFY FAILURES* *NOTIFY DELAYS* Submitted notifications list: $ TEST/REWRITE/FROM="unwelcome@varrius.com" - _$ /SOURCE=tcp_local/DESTINATION=l User@sesta.com ... Submitted address list: Address list error -- 5.7.1 Go away! User@sesta.com Submitted notifications list: |
默认情况下,Messaging Server 被配置为阻止 SMTP 中继尝试,即拒绝从未经验证的外部源(外部系统是除服务器本身所在的主机以外的任何其他系统)向外部地址尝试提交邮件。此默认配置在阻止 SMTP 中继时相当主动,因为它将所有其他系统都认作外部系统。
当 IMAP 和 POP 客户机尝试通过 Messaging Server 系统的 SMTP 服务器将邮件提交到外部地址,而该地址未使用 SMTP AUTH (SASL) 进行验证时,系统将会拒绝这些提交尝试。因此,您可能要修改配置,以便它可以识别您自己的应始终从其接受中继的内部系统和子网。
至于哪些系统和子网将被识别为内部,这通常由 INTERNAL_IP 映射表控制,该表可在 msg_svr_base/config/mappings 中找到。
例如,在 IP 地址为 123.45.67.89 的 Messaging Server 上,默认的 INTERNAL_IP 映射表如下所示:
INTERNAL_IP $(123.45.67.89/32) $Y 127.0.0.1 $Y * $N |
此处,使用 $(IP-pattern/signicant-prefix-bits) 语法的初始条目指定,任何匹配 123.45.67.89 所有 32 位的 IP 地址均应为匹配项,并应被视为内部地址。第二个条目将回送 IP 地址 127.0.0.1 视为内部地址。最后一个条目指定所有其他 IP 地址均不被视为内部地址。请注意,每个条目前都必须至少有一个空格。
您可以通过在最后的 $N 条目之前指定其他 IP 地址或子网来添加其他条目。这些条目必须在左侧指定 IP 地址或子网(使用 $(.../...) 语法来指定子网),在右侧指定 $Y。或者您可以修改现有的 $(.../...) 条目,以接受更通用的子网。
例如,如果此同一样例站点具有一个 C 类网络(即,它拥有 123.45.67.0 的全部子网),则此站点可以通过更改匹配地址使用的位数来修改初始条目。在以下的映射表中,我们将 32 位更改为 24 位。这使 C 类网络上的所有客户机都可以通过此 SMTP 中继服务器来中继邮件。
INTERNAL_IP $(123.45.67.89/24) $Y 127.0.0.1 $Y * $N |
如果站点仅拥有 123.45.67.80-123.45.67.99 范围内的 IP 地址,则此站点将希望使用:
INTERNAL_IP ! Match IP addresses in the range 123.45.67.80-123.45.67.95 $(123.45.67.80/28) $Y ! Match IP addresses in the range 123.45.67.96-123.45.67.99 $(123.45.67.96/30) $Y 127.0.0.1 $Y * $N
请注意,imsimta test -match 实用程序在检查 IP 地址是否匹配特定 $(.../...) 测试条件时十分有用。imsimta test -mapping 实用程序更常用于检查 INTERNAL_IP 映射表是否对各种 IP 地址输入均返回了所需的结果。
修改 INTERNAL_IP 映射表之后,请确保发出 imsimta restart 命令(如果未使用已编译的配置运行)或后跟 imsimta restart smtp 的 imsimta cnbuild(如果使用已编译的配置运行),以便使更改生效。
有关映射文件和通用映射表格式的更多信息以及 imsimta 命令行实用程序的信息,请参见 Messaging Server Reference Manual。
所有内部 IP 地址均应按上述说明添加到 INTERNAL_IP 映射表中。如果有允许从其进行 SMTP 中继的友好或伙伴系统/站点,最简单的方法是将它们与您的真实内部 IP 地址一起包含到 INTERNAL_IP 映射表中。
如果不希望将这些系统/站点视为真实的内部系统/站点(例如,如果出于记录或其他控制目的,您希望区分真实内部系统与具有中继权限的友好非内部系统),则可以使用其他方法来配置系统。
一种方法是设置一个特殊的通道,用于接收来自此类友好系统的邮件。您可以通过创建与现有 tcp_internal 通道类似的、带有正式主机名 tcp_friendly-daemon 的 tcp_friendly 通道,以及创建与 INTERNAL_IP 映射表类似的、列出了友好系统 IP 地址的 FRIENDLY_IP 映射表来完成此设置。然后在当前重写规则之后:
! Do mapping lookup for internal IP addresses [] $E$R${INTERNAL_IP,$L}$U%[$L]@tcp_intranet-daemon
添加一个新的重写规则:
! Do mapping lookup for "friendly", non-internal IP addresses [] $E$R${FRIENDLY_IP,$L}$U%[$L]@tcp_friendly-daemon
另外一种方法是将以下形式的新条目添加到 ORIG_SEND_ACCESS 映射表的最后一个 $N 条目之上
tcp_local|*@siroe.com|tcp_local|* $Y
其中 siroe.com 是友好域的名称,并添加以下形式的 ORIG_MAIL_ACCESS 映射表:
ORIG_MAIL_ACCESS TCP|*|25|$(match-siroe.com-IP-addresses)|*|SMTP|MAIL| \ tcp_local|*@siroe.com|tcp_local|* $Y TCP|*|*|*|*|SMTP|MAIL|tcp_local|*|tcp_local|* $N
其中 $(...) IP 地址语法与上一节中所述的语法相同。只要地址正确,ORIG_SEND_ACCESS 检查就会成功,因此我们可以继续执行 ORIG_MAIL_ACCESS 检查,此检查更加严格,并且仅在 IP 地址与 siroe.com IP 地址对应时才会成功。
您可以使用访问控制映射来阻止别人通过您的 Messaging Server 系统中继 SMTP 邮件。例如,您可以阻止别人使用您的邮件系统向成百上千的 Internet 邮箱中继垃圾邮件。
默认情况下,Messaging Server 将阻止所有 SMTP 中继活动,包括本地 POP 和 IMAP 用户的中继。
阻止未经授权的中继但允许合法本地用户进行中继,这需要配置 Messaging Server 以使其知道如何区分这两类用户。例如,使用 POP 或 IMAP 的本地用户依赖于 Messaging Server 充当 SMTP 中继。
要阻止 SMTP 中继,您必须能够:
区分内部邮件和外部邮件
要启用由内部主机和客户机来进行 SMTP 中继,则必须将“内部”IP 地址或子网添加到 INTERNAL_IP 映射表。
为了阻止邮件中继活动,MTA 必须首先能够区分源自您的站点的内部邮件和源自 Internet 并通过您的系统传送回 Internet 的外部邮件。您要允许的是前一类邮件,要阻止的是后一类邮件。在入站 SMTP 通道(通常为 tcp_local 通道)上使用 switchchannel 关键字(默认设置)可以实现此区分。
switchchannel 关键字通过使 SMTP 服务器查找与外来 SMTP 连接关联的实际 IP 地址来进行工作。Messaging Server 将该 IP 地址和重写规则结合使用,以区分源自域内的 SMTP 连接和来自域外的连接。然后,此信息可用于在内部和外部通信之间分离邮件通信。
下面所述的 MTA 配置为默认设置,以便服务器可以区分内部和外部邮件通信。
在配置文件中,紧接本地通道之前,是带有 noswitchchannel 关键字的 defaults 通道:
! final rewrite rules defaults noswitchchannel ! Local store ims-ms ... |
外来 TCP/IP 通道指定了 switchchannel 和 remotehost 关键字,例如:
tcp_local smtp single_sys mx switchchannel remotehost TCP-DAEMON |
在外来 TCP/IP 通道定义之后,是一个具有不同名称的类似通道,例如:
tcp_intranet smtp single_sys mx allowswitchchannel routelocal tcp_intranet-daemon |
向通道重写地址时,routelocal 通道关键字会使 MTA 尝试将通过此通道的地址中的所有明确路由“短路”,从而阻止通过明确源路由的地址在内部 SMTP 主机间以循环方式进行的可能的中继尝试。
使用以上配置设置,域内生成的 SMTP 邮件将通过 tcp_intranet 通道进入。所有其他 SMTP 邮件将通过 tcp_local 通道进入。邮件将基于其进入的通道被区分为内部邮件和外部邮件。
这是如何起作用的?答案就是 switchchannel 关键字。该关键字被应用于 tcp_local 通道。邮件进入 SMTP 服务器时,该关键字使服务器查看与外来连接关联的源 IP 地址。服务器尝试对外来连接的真实 IP 地址进行反向指向信封重写,查找关联的通道。如果源 IP 地址匹配 INTERNAL_IP 映射表中的 IP 地址或子网,则调用该映射表的重写规则会将地址重写到 tcp_intranet 通道。
由于 tcp_intranet 通道标有 allowswitchchannel 关键字,因此邮件将被切换到 tcp_intranet 通道,并从该通道进入。如果邮件从其 IP 地址不在 INTERNAL_IP 映射表中的某个系统进入,则反向信封重写可能会重写到 tcp_local,也可能会重写到某些其他通道。但是,它不会重写到 tcp_intranet 通道,并且由于默认情况下,其他所有通道均被标记为 noswitchchannel,因此邮件也不会切换到其他通道,而是保留在 tcp_local 通道中。
请注意,使用字符串 "tcp_local" 的所有映射表或转换文件条目可能都需要根据用法更改为 "tcp_*" 或 "tcp_intranet"。
您的站点可能具有不属于您的物理网络的“本地”客户机用户。当这些用户提交邮件时,邮件提交将从外部 IP 地址进入—例如,任意 Internet 服务提供商。如果您的用户使用可以执行 SASL 验证的邮件客户机,则可以将他们已验证的连接与任意其他外部连接区分开。然后您可以允许已验证的提交,同时拒绝未验证的中继提交尝试。在入站 SMTP 通道(通常为 tcp_local 通道)中使用 saslswitchchannel 关键字,可以区分已验证的和未验证的连接。
saslswitchchannel 关键字使用变量来指定要切换到的通道;如果 SMTP 发件人验证成功,则他们提交的邮件会被视为进入指定的切换通道。
在配置文件中,添加带有独特名称的新 TCP/IP 通道定义,例如:
tcp_auth smtp single_sys mx mustsaslserver noswitchchannel TCP-INTERNAL
此通道应不允许常规通道切换(即,此通道上应具有先前默认行中明确或隐含指定的 noswitchchannel)。此通道上应具有 mustsaslserver。
修改 tcp_local 通道,在其中添加 maysaslserver 和 saslswitchchannel tcp_auth,如以下示例所示:
tcp_local smtp mx single_sys maysaslserver saslswitchchannel \ tcp_auth switchchannel |TCP-DAEMON |
使用此配置,那些可以使用本地密码进行验证的用户所发送的 SMTP 邮件将进入 tcp_auth 通道。从内部主机发送的未验证的 SMTP 邮件仍将进入 tcp_internal。所有其他 SMTP 邮件将进入 tcp_local。
现在要讨论此示例的要点:阻止未经授权的人员通过您的系统中继 SMTP 邮件。首先,请记住您要允许本地用户中继 SMTP 邮件。例如,POP 和 IMAP 用户依赖使用 Messaging Server 来发送其邮件。请注意,本地用户可能在物理上是本地(在这种情况下,其邮件从内部 IP 地址进入);也可能在物理上是远程,但可以将自身验证为本地用户。
您要阻止外部 Internet 上的任意人员使用您的服务器作为中继。使用以下各节所述的配置,您可以区分此类用户并正确地进行阻止。特别是,您要阻止邮件进入 tcp_local 通道和从同一通道返回。您可以使用 ORIG_SEND_ACCESS 映射表实现此目的。
通过 ORIG_SEND_ACCESS 映射表,可根据源通道和目标通道阻止通信。在此例中,将阻止来自 tcp_local 通道和返回该通道的通信。这可以通过以下 ORIG_SEND_ACCESS 映射表实现:
ORIG_SEND_ACCESS tcp_local|*|tcp_local|* $NRelaying$ not$ permitted
在此示例中,条目声明邮件不能进入 tcp_local 通道并从该通道直接返回。即,此条目不允许外部邮件进入您的 SMTP 服务器,并不允许外部邮件直接中继回 Internet。
使用 ORIG_SEND_ACCESS 映射表而非 SEND_ACCESS 映射表,以便阻止不会应用于最初匹配 ims-ms 通道的地址(但其可通过别名或邮件列表定义扩展回外部地址)。使用 SEND_ACCESS 映射表,需要很长的长度,才能允许外部人员发送到可扩展回外部用户的邮件列表,或发送到可将其邮件转发回外部地址的用户。
在 Messaging Server 中,有多种不同的方法可以确保所接受的要传送或转发的所有邮件均来自具有有效 DNS 名称的地址。最简单的方法是将 mailfromdnsverify 通道关键字放在 tcp_local 通道上。
Messaging Server 还提供了 dns_verify 程序,它使您可以使用 ORIG_MAIL_ACCESS 中的以下规则,确保接受的要传送和转发的所有邮件均来自具有有效 DNS 名称的地址:
ORIG_MAIL_ACCESS TCP|*|*|*|*|SMTP|MAIL|*|*@*|*|* \ $[msg_svr_base/lib/dns_verify.so, \ dns_verify,$6|$$y|$$NInvalid$ host:$ $$6$ -$ %e]
从句法上来说,以上示例中的换行符在此类映射条目中很显著。反斜杠字符是一种合法地继续到下一行的方法。
dns_verify 映像也可用于根据 RBL(Realtime Blackhole List,实时黑洞名单)、MAPS(Mail Abuse Prevention System,邮件滥用防止系统)、DUL(Dial-up User List,拨号用户列表 )或 ORBS(Open Relay Behavior-modification System,开放中继修改系统)列表检查外来连接,作为保护系统免受 UBE 影响的另一种尝试。使用新的 mailfromdnsverify 关键字,还可以使用一种单独的“更易于配置”的方法进行这样的检查,而不必执行 dns_verify 调用。这种更简单的方法是使用 dispatcher.cnf 文件中的 DNS_VERIFY_DOMAIN 选项。例如,在 [SERVICE=SMTP] 部分中,将选项的实例设置为要检查的各个列表:
[SERVICE=SMTP] PORT=25 ! ...rest of normal options... DNS_VERIFY_DOMAIN=rbl.maps.vix.com DNS_VERIFY_DOMAIN=dul.maps.vix.com! ...etc... |
在这种情况下,邮件在 SMTP 级别被拒绝(即,邮件在 SMTP 对话期间被拒绝),因此永远不会被发送到 MTA。这种简单方法的缺点在于,它将对所有正常的外来 SMTP 邮件(包括那些来自内部用户的邮件)执行检查。这种方法效率较低,并且在 Internet 连接性降低的情况下可能会发生问题。另一种方法是从 PORT_ACCESS 映射表或 ORIG_MAIL_ACCESS 映射表调用 dns_verify。在 PORT_ACCESS 映射表中,您可以使初始条目不检查本地内部 IP 地址或邮件提交者,而使较后的条目对其他所有人员执行所需的检查。或者,在 ORIG_MAIL_ACCESS 映射表中,如果只将检查应用于从 tcp_local 通道进入的邮件,则对于来自内部系统/客户机的邮件将跳过检查。使用了指向 dns_verify 的条目的示例,如下所示。
PORT_ACCESS ! Allow internal connections in unconditionally *|*|*|*|* $C$|INTERNAL_IP;$3|$Y$E ! Check other connections against RBL list TCP|*|25|*|* \ $C$[msg_svr_base/lib/dns_verify.so,\ dns_verify_domain_port,$1,rbl.maps.vix.com.]EXTERNAL$E ORIG_MAIL_ACCESS TCP|*|25|*|*|SMTP|*|tcp_local|*@*|*|* \ $C$[msg_svr_base/lib/dns_verify.so,\ dns_verify_domain,$1,rbl.maps.vix.com.]$E
dns_verify 程序支持基于 DNS 的数据库,该数据库用于确定可能发送未经许可的批量邮件的外来 SMTP 连接。某些公用 DNS 数据库不包含通常用于此用途的 TXT 记录。而是,他们只包含 A 记录。
在典型设置中,DNS 中针对特定 IP 地址找到的 TXT 记录包含一个在拒绝邮件时可返回 SMTP 客户机的错误消息。但是,如果未找到 TXT 记录,而是找到 A 记录,则 Messaging Server 5.2 之前的 dns_verify 版本将返回消息 "No error text available"
dns_verify 目前支持在无可用 TXT 记录时指定使用默认文本的选项。例如,以下 PORT_ACCESS 映射表显示了如何启用此选项:
PORT_ACCESS *|*|*|*|* $C$|INTERNAL_IP;$3|$Y$E \ TCP|*|25|*|* \ $C$[<msg_svr_base/lib/dns_verify.so \ ,dns_verify_domain_port,$1,dnsblock.siroe.com,Your$ host$ ($1)$ \ found$ on$ dnsblock$ list]$E * $YEXTERNAL
在此示例中,如果在对域 dnsblock.siroe.com 的查询中找到了远程系统,但没有可用的 TXT 记录,则系统将返回以下消息 "Your host a.b.c.d found on dnsblock list"
在映射表中使用大量条目的站点应考虑将其映射表组织为具有若干配备通用通配符的条目,以便可以调用通用数据库进行特定查找。 针对特定查找,使用若干映射表条目调用通用数据库比直接在映射表中使用大量的条目效率要高得多。
一个特例是某些站点希望对谁可以发送和接收 Internet 电子邮件进行基于单个用户的控制。使用诸如 ORIG_SEND_ACCESS 的访问映射表可以很方便地实现此类控制。对于这种用法,通过将大量特定信息(例如特定地址)存储在通用数据库中,同时结构化映射表条目以对通用数据库进行适当调用,可以显著提高效率和性能。
例如,请考虑下面所示的 ORIG_SEND_ACCESS 映射表。
ORIG_SEND_ACCESS ! Users allowed to send to Internet ! *|adam@siroe.com|tcp_local|* $Y *|betty@siroe.com|tcp_local|* $Y ! ...etc... ! ! Users not allowed to send to Internet ! *|norman@siroe.com|tcp_local|* $NInternet$ access$ not$ permitted *|opal@siroe.com|tcp_local|* $NInternet$ access$ not$ permitted ! ...etc... ! ! Users allowed to receive from the Internet ! tcp_*|*|*|adam@siroe.com $Y tcp_*|*|*|betty@siroe.com $Y ! ...etc... ! ! Users not allowed to receive from the Internet ! tcp_*|*|*|norman@siroe.com $NInternet$ e-mail$ not$ accepted tcp_*|*|*|opal@siroe.com $NInternet$ e-mail$ not$ accepted ! ...etc... |
与通过每个用户单独输入表中的此类映射表相比,下面示例中显示了一种更有效的设置(如果包含成百上千个用户条目,则更为有效),它显示了常规数据库的示例源文本文件和示例 ORIG_SEND_ACCESS 映射表。要将此源文件编译成数据库格式,请运行 imsimta crdb 命令:
% imsimta crdb input-file-spec output-database-spec
有关 imsimta crdb 实用程序的详细信息,请参阅 《Sun Java System Messaging Server 6 2005Q4 Administration Reference》中的“imsimta crdb”。
DATABASE ENTRIES SEND|adam@domain.com $Y SEND|betty@domain.com $Y ! ...etc... SEND|norman@domain.com $NInternet$ access$ not$ permitted SEND|opal@domain.com $NInternet$ access$ not$ permitted ! ...etc... RECV|adam@domain.com $Y RECV|betty@domain.com $Y ! ...etc... RECV|norman@domain.com $NInternet$ e-mail$ not$ accepted RECV|opal@domain.com $NInternet$ e-mail$ not$ accepted MAPPING TABLE ORIG_SEND_ACCESS ! Check if may send to Internet ! *|*|*|tcp_local $C${SEND|$1}$E ! ! Check if may receive from Internet ! tcp_*|*|*|* $C${RECV|$3}$E |
此示例中,在通用数据库中左侧任意字符串 SEND| 和 RECV| 的使用(以及由此在映射表生成的通用数据库探测中)提供了一种区分所生成的两类探测的方法。如图所示,用 $C 和 $E 标志环绕通用数据库探测在映射表调用通用数据库中很典型。
以上示例显示了根据通用数据库条目检查简单映射表探测的情况。具有复杂得多的探测的映射表也可以从使用通用数据库中受益。
邮箱过滤器(也称为 Sieve 过滤器),过滤在邮件标题中包含指定字符串的邮件并对这些邮件应用指定操作。管理员可以过滤通过通道或 MTA 传送到用户的邮件流。Messaging Server 过滤器存储在服务器上并由服务器评估,因此,这些过滤器有时称为服务器端规则 (SSR)。
本部分包含以下几个部分:
Messaging Server 过滤器基于 Sieve 过滤语言 (Draft 9 of the Sieve Internet Draft)。有关 Sieve 语法和语义的更多信息,请参见 RFC3028。此外,Messaging Server 还支持以下 Sieve 扩展:
jettison。与 discard 类似,它也可以无提示删除邮件,但不同的是,discard 只取消隐含保留而不进行其他任何操作,而 jettison 将强制执行 discard。这种行为差异仅在涉及到多个 Sieve 过滤器时才比较明显。例如,系统级别的 discard 可由明确指定 keep 的用户 Sieve 过滤器替换,而系统级别的 jettison 将替换用户 Sieve 执行的任何操作。
户主 Sieve 过滤器。提供了一个用户为另一个用户指定 Sieve 过滤器的方法。使用由以下 MTA 选项控制的用户条目中的两个 LDAP 属性:
LDAP_PARENTAL_CONTROLS—指定包含 Yes 或 No 字符串值的属性。Yes 表示将对此条目应用户主 Sieve,No 表示将不应用此类 Sieve。无默认值。
LDAP_FILTER_REFERENCE—指定包含 DN 的属性,该 DN 指向可以找到户主 Sieve 的目录条目。无默认值。
包含户主 Sieve 的条目必须包含由以下 MTA 选项指定的两个属性:
LDAP_HOH_FILTER—指定包含户主 Sieve 的属性。此选项的默认值为 mailSieveRuleSource。
LDAP_HOH_OWNER—指定包含户主拥有者的电子邮件地址的属性。此选项的默认值为 mail。
这两个属性必须同时存在才能使户主 Sieve 运行。
Sieve 过滤器由一个或多个条件操作组成,这些操作将根据邮件标题中的字符串应用于邮件。作为管理员,您可以创建通道级别的过滤器和 MTA 范围内的过滤器,用以防止传送不需要的邮件。用户可以使用 Messenger Express 为其自己的邮箱创建基于用户的过滤器。Messenger Express 联机帮助对此进行了详细的说明。
服务器按照以下优先级应用过滤器:
如果个人邮箱过滤器明确接受或拒绝一个邮件,则过滤器对该邮件的处理完成。但是如果收件人用户没有邮箱过滤器,或者用户的邮箱过滤器没有明确应用到问题邮件,Messaging Server 在下一步将应用通道级别的过滤器。设置基于用户的过滤器
如果通道级别的过滤器明确接受或拒绝一个邮件,则过滤器对该邮件的处理完成。否则,Messaging Server 接着将应用 MTA 范围内的过滤器(如果有)。
默认情况下,所有用户均没有邮箱过滤器。用户使用 Messenger Express 界面创建一个或多个过滤器时,他们的过滤器将存储在目录中,并在目录同步过程期间由 MTA 进行检索。
基于用户的邮件过滤器将应用于发往特定用户邮箱的邮件。只能使用 Messenger Express 创建基于用户的邮件过滤器。
通道级别的过滤器将应用于在通道内排队的每个邮件。此类过滤器的典型用途是阻止通过特定通道的邮件。
表 17–4 filter 通道关键字 URL-pattern 替换标记(不区分大小写)
标记 |
含义 |
---|---|
* |
执行组扩展。 |
** |
扩展属性 mailForwardingAddress。这可以是一个导致产生若干传送地址的多值属性。 |
$$ |
在 $ 字符中替换 |
$\ |
强制后续文本转为小写 |
$^ |
强制后续文本转为大写 |
$_ |
不对后续文本执行大小写转换 |
$~ |
在与地址本地部分关联的主目录的文件路径中替换 |
$1S |
与 $S 相同,但如果没有可用的子地址,则不插入任何内容 |
$2S |
与 $S 相同,但如果没有可用的子地址,则不插入任何内容,并删除前面的字符 |
$3S |
与 $S 相同,但如果没有可用的子地址,则不插入内容,并忽略后面的字符 |
$A |
在地址 local-part@ host.domain 中替换 |
$D |
在 host.domain 中替换 |
$E |
插入第二个备用属性 LDAP_SPARE_1 的值 |
$F |
插入传送文件的名称(mailDeliveryFileURL 属性) |
$G |
插入第二个备用属性 LDAP_SPARE_2 的值 |
$H |
在主机中替换 |
$I |
插入托管域(domainUidSeparator 指定的分隔符右侧 UID 的一部分)。如果没有可用的托管域,则失败 |
$1I |
与 $I 相同,但如果没有可用的托管域,则不插入任何内容 |
$2I |
与 $I 相同,但如果没有可用的托管域,则不插入任何内容,并删除前面的字符 |
$3I |
与 $I 相同,但如果没有可用的托管域,则不插入任何内容,并忽略后面的字符 |
$L |
在本地部分中替换 |
$M |
插入 UID,分流任何托管域 |
$P |
插入方法名称(mailProgramDeliveryInfo 属性) |
$S |
插入与当前地址关联的子地址。子地址是子地址分隔符(通常为 +)后原始地址的用户部分,但可由 MTA 选项 SUBADDRESS_CHAR 指定。如果没有给定子地址,则失败 |
$U |
插入当前地址的邮箱部分。这可以是 @ 符号左侧的全部地址,也可以是地址左侧、子地址分隔符 + 之前的部分。 |
使用 Sieve 编写过滤器。
将过滤器存储在位于以下目录的文件中:
../config/file.filter
该文件必须可全局读取并属于 MTA 的 UID。
将以下内容包括在通道配置中:
destinationfilter file:IMTA_TABLE:file.filter
重新编译配置并重新启动分发程序。
请注意,对过滤器文件所作的更改无需重新编译或重新启动分发程序。
destinationfilter 通道关键字将为排队到应用此关键字的通道的邮件启用邮件过滤。sourcefilter 通道关键字将为来自应用此关键字的通道队列的邮件启用邮件过滤。这些关键字都有一个必需参数,该参数指定了与通道关联的相应通道过滤器文件路径。
destinationfilter 通道关键字的语法为:
destinationfilter URL-pattern |
sourcefilter 通道关键字的语法为:
sourcefilter URL-pattern |
其中 URL-pattern 是一个 URL,指定了到问题通道的过滤器文件的路径。在以下示例中,channel-name 为通道的名称。
destinationfilter file:///usr/tmp/filters/channel-name.filter |
filter 通道关键字将为应用此关键字的通道启用邮件过滤。该关键字有一个必需参数,该参数指定了与通过通道接收邮件的每个信封收件人关联的过滤器文件路径。
filter 通道关键字的语法为:
filter URL-pattern |
URL-pattern 是一个 URL,在进行特殊替换序列处理后,将生成给定收件人地址的过滤器文件路径。URL-pattern 可以包含特殊替换序列,遇到此序列时,将使用源自问题收件人地址(local-part@host.domain)的字符串进行替换。表 17–4 中显示了这些替换序列。
fileinto 关键字指定在应用邮箱过滤器 fileinto 运算符后如何更改地址。以下示例指定了文件夹名称应作为子地址插入原始地址,替代原先存在的任何子地址:
fileinto $U+$S@$D |
MTA 范围内的过滤器将应用于排队到 MTA 的所有邮件。此类过滤器的典型用途是阻止未经许可的批量邮件或其他不需要的邮件,而不管邮件的目的地为何处。要创建 MTA 范围内的过滤器,请执行以下步骤:
使用 Sieve 编写过滤器
将过滤器存储在以下文件中:
../imta/config/imta.filter
此过滤器文件必须可全局读取。如果该文件存在,将自动进行使用。
重新编译配置并重新启动分发程序
使用已编译的配置时,MTA 范围内的过滤器文件将被包含到已编译的配置中。
默认情况下,通过邮箱过滤器放弃的邮件将立即从系统放弃(删除)。但是,用户初次设置邮箱过滤器(并可能犯错误)时,或出于调试目的,则使删除操作延迟一段时间可能会很有用。
要将邮箱过滤器放弃的邮件临时保留在系统中以待日后删除,请首先将 filter_discard 通道添加到 MTA 配置,并使用 notices 通道关键字指定删除邮件前保留邮件的时间长度(通常为天数),如以下示例所示:
filter_discard notices 7 FILTER-DISCARD
然后在 MTA 选项文件中设置选项 FILTER_DISCARD=2。filter_discard 队列区域中的邮件应被视为位于用户的个人垃圾箱文件夹的扩展部分中。因此,请注意对于 filter_discard 队列区域中的邮件,系统永远不会为其发送警告消息,也不会在用户请求退回或返回时,将此类邮件返回给其发件人。而对此类邮件采取的唯一操作是,在最终通知值过期,或使用诸如 imsimta return 之类的实用程序请求手动退回时,最终无提示地删除这些邮件。
在 Messaging Server 6 2004Q2 之前,由 FILTER_DISCARD MTA 选项控制 jettison 操作对 filter_discard 通道的使用。现在则由选项 FILTER_JETTISON 控制,该选项从 FILTER_DISCARD 设置中接受其默认值。而 FILTER_DISCARD 的默认值为 1(放弃将转至 bitbucket 通道)。
如果用户抱怨 Sieve 过滤器未按预期运行,则您可以采取一系列步骤来调试过滤器。下面对这些步骤进行了介绍。
要使 fileinto 过滤能够正常工作,请在 imta.cnf 文件中查看 ims-ms 通道是否标记如下:
fileinto $u+$s@$d
从用户 LDAP 条目中获取用户级别的过滤器。
用户级别的过滤器存储在 MailSieveRuleSource 属性下的 LDAP 条目中。要使用 ldapsearch 命令检索此过滤器,请记住它们是以 base64 编码的,因此您需要使用 -Bo 切换对输出进行解码。
./ldapsearch -D "cn=directory manager" -w password -b "o=alcatraz.sesta.com,o=isp" -Bo uid=test |
验证 MTA 是否可以看到用户过滤器。
发出命令:
# imsimta test -rewrite -filter -debug user@sesta.com
此命令应该输出您在前面步骤中检索的用户 Sieve 过滤器。如果未看见过滤器,则需要指出为什么 LDAP 条目未返回这些过滤器。如果 imsimta test -rewrite 输出显示过滤器,则表明 MTA 可看到用户过滤器。下一步将使用 imsimta test -expression 命令测试过滤器的解释。
创建文本文件(例如:temp.filter),该文本文件包含基于用户 mailSieveRuleSource: values 的 Sieve 语言语句。示例:
require "fileinto"; if anyof(header :contains ["To","Cc","Bcc","Resent-to","Resent-cc", "Resent-bcc"] "commsqa"){ fileinto "QMSG"; }
预期结果:如果 commsqa 是此邮件的收件人,则将邮件归档到名为 QMSG 的文件夹中。
创建名为 test.msg 的文本文件,该文件包含用户提供的 rfc2822 邮件文件的内容。
您可以使用用户邮件存储区域中的 .msg 文件,也可以创建名为 test_rfc2822.msg 的文本文件,该文件包含用户提供的 rfc2822 邮件文件的内容。
使用 imsimta test -exp 命令:
# imsimta test -exp -mm -block -input=temp.filter -message=test_rfc2822.msg |
检查输出。
imsimta test -exp 命令的最后几行将显示 Sieve 解释的结果。结果类似于:
Sieve Result: [] or this: Sieve Result: [action] |
其中,action 是在此邮件上应用 Sieve 过滤器后要执行的操作。
如果过滤器的条件匹配,则会得到显示为结果的某个操作。如果没有匹配项,Sieve 结果将为空白,原因是 Sieve 过滤器中存在逻辑错误或 .msg 文件不包含匹配信息。如果收到任何其他错误,则 Sieve 脚本文件中存在语法错误,您需要对其进行调试。
有关输出的更多信息,请参见imsimta test -exp 输出。
如果过滤器在语法上有效并且结果正确,则下一步将检查 tcp_local_slave.log 调试日志文件。
可能会出现正在测试的邮件文件与正在发送的邮件文件不相同的情况。查看正在接收的内容的唯一方法是:检查 tcp_local_slave.log 文件。此日志将向您显示正在发送到 MTA 的实际邮件以及如何将过滤器应用到该邮件。
有关获取 tcp_local_slave.log 调试文件的更多信息,请参见调试关键字中的 slave_debug 关键字。
完整的 imsimta test -exp 命令如下:
# imsimta test -exp -mm -block -input=temp.filter -message=rfc2822.msg
下面是一个输出示例:
# imsimta test -exp -mm -block -input tmp.filter -message=rfc2822.msg Expression: if header :contains ["to"] ["pamw"] (1) Expression: { Expression: redirect "usr3@sesta.com"; Expression: keep; Expression: } Expression: Expression: Dump: header:2000114;0 3 1 :contains 1 "to" 1 "pamw" if 8 ; Dump: redirect:2000121;0 1 1 "usr3@sesta.com" ; keep:2000117;0 (2) Dump: 0 Result: 0 Filter result: [ redirect "usr3@sesta.com" keep ] (3) |
1) Expression: 输出行显示正在从 tmp.filter 文本文件中读取并解析的过滤器。这些在调试脚本中不是特别有用。
2) Dump: 输出行是计算机解释 Sieve 语句的结果。不应看到有任何错误,并且输出看起来应与输入相匹配。例如 Dump 显示了文字 redirect, usr3@sesta.com,这与过滤器文件中的行 redirect "usr3@sesta.com"; 类似。
如果未显示此匹配文本,则应当引起注意,否则,它们在调试脚本时也不是特别有用。
3) 在输出的底部,您将看到 Filter result: 语句。如前面所述,可能有两种结果:
Sieve Result: [] 或:Sieve Result: [action]
其中 action 是 Sieve 脚本执行的操作。请注意,有时预期的结果为空。例如,对于 discard 过滤器,您应当测试该过滤器并不总是放弃测试的每个 .msg 文件。如果在方括号间存在某个操作,例如:
Filter result: [fileinto "QMSG" keep]
这表明 rfc2822.msg 文件中的文本与过滤器条件匹配。在此特定示例中,过滤器将把邮件归档到 QMSG 文件夹中,并在收件箱中保存一份副本。本示例中的结果操作是 fileinto 和 keep。
测试过滤器时,应当测试两种结果的各个 .msg 文件。应始终测试是否已过滤匹配过滤器的邮件,并测试是否未过滤不想匹配的邮件。
请记住,对于通配符匹配,您必须使用 :matches 测试而不是使用 :contains。例如,如果要匹配 from=*@sesta.com,则必须使用 :matches,否则测试会由于不满足测试条件而失败。
imsimta test -exp 将针对指定的 RFC2822 邮件测试 Sieve 语言语句,并将过滤器的结果发送到标准输出。
语法如下:
imsimta test -exp -mm -block -input=Sieve_language_scriptfile -message=rfc2822_message_file
其中,
-block 将整个输入视为一个 Sieve 脚本。默认情况下,将每行作为一个单独的脚本,并分别对其进行评估。仅在到达文件末端时评估 Sieve。
-input=Sieve_file 是包含 Sieve 脚本的文件。默认情况下,将从 stdin 中读取测试脚本行或脚本块。
-message=message_file 是一个文本文件,该文件包含要针对其测试 Sieve 脚本的 RFC 2822 邮件。这只能是 RFC 2822 邮件。而不能是队列文件(不是 zz*.00 文件)。
激活后,此命令将读取脚本信息,在测试邮件的上下文中评估该信息,并写出结果。结果显示将进行什么操作以及脚本中最终语句的评估结果。
其他有用的限定符包括:
-from=address 指定要在信封测试中使用的信封 from: 地址。默认情况下,使用由 RETURN_ADDRESS MTA 选项指定的值。
-output=file 将结果写入 file。默认情况下,将脚本测试结果写入 stdout 中。