Sun Java System Messaging Server 6 2005Q4 管理指南

第 11 章 配置重写规则

本章介绍如何在 imta.cnf 文件中配置重写规则。如果您还未阅读第 10 章,关于 MTA 服务和配置,则应该在阅读本章之前先阅读这一章。

本章包含以下各节:

Messaging Server 的地址重写工具是处理和更改地址的主机或域部分的主要工具。Messaging Server 提供了用于地址处理的其他工具,例如别名、地址反向数据库和专用映射表。但为了获得最佳性能,在可以执行地址操作时应使用重写规则。

开始之前

在对 imta.cnf 文件中的重写规则做出更改后,您必须重新启动仅在启动时装入一次配置数据的所有程序或通道,例如使用 imsimta restart 命令重新启动 SMTP 服务器。如果使用的是编译的配置,则必须重新编译然后再重新启动。

有关编译配置信息和启动程序的更多信息,请参见《Sun Java System Messaging Server 6 2005Q4 Administration Reference》

重写规则结构

重写规则显示在 MTA 配置文件 imta.cnf 的上半部分中。配置文件中的每个规则都以单行显示。各个规则之间允许有注释但不允许有空白行。重写规则以空白行结束,其后跟通道定义。以下示例显示了部分配置文件的重写规则部分。


! test.cnf - An example configuration file.
!
! This is only an example of a configuration file. It serves
! no useful purpose and should not be used in a real system.
!
a.com   $U@a-host
b.org   $U@b-host
c.edu   $U%c@b-daemon
d.com   $U%d@a-daemon

! Begin channel definitions

重写规则由两部分组成:模式,后跟等值字符串或模板。尽管每个部分内部不允许有空格但这两部分必须用空格分隔。重写规则的结构如下所示:


pattern template

pattern

表示要在域名中搜索的字符串。在表 11–3 中,模式为 a.comb.orgc.edud.com

如果模式与地址的域部分匹配,则重写规则适用于该地址。模式和模板必须用空白区域分隔。有关模式语法的更多信息,请参见重写规则模式和标记

template

为以下模板之一:

UserTemplate%DomainTemplate@ChannelTag[controls]
UserTemplate@ChannelTag[controls]
UserTemplate%DomainTemplate[controls]
UserTemplate@DomainTemplate@ChannelTag[controls]
UserTemplate@DomainTemplate@SourceRoute@ChannelTag[controls]

其中

UserTemplate 指定如何重写地址的用户部分。替换序列可用于表示原始地址的部分或数据库查找的结果。替换序列将被替换为其表示的内容以构造重写地址。在表 11–4 中,使用的是 $U 替换序列。有关更多信息,请参见模板替换和重写规则控制序列

DomainTemplate 指定如何重写地址的域部分。与 UserTemplate 相同,DomainTemplate 也可以包含替换序列。

ChannelTag 表示此邮件要发送到的通道。(所有通道定义必须包含通道标记和通道名称。通道标记通常显示在重写规则及其通道定义中。)

controls 使用控件可以限制规则的适用性。某些控件序列必须在规则的开始部分显示;其他控件必须在规则的结尾部分显示。有关控件的更多信息,请参见模板替换和重写规则控制序列

有关模板语法的更多信息,请参见重写规则模板

重写规则模式和标记

本节包含以下几个部分:

大多数重写规则模式包含仅与某一主机匹配的特定主机名,或与整个子域中的任何主机/域匹配的子域模式。

例如,以下重写规则模式包含将只与特定主机匹配的特定主机名:

host.siroe.com

下一个重写规则模式包含将与整个子域中的任一主机或域匹配的子域模式:

.siroe.com

但该模式将不会匹配确切的主机名 siroe.com;要匹配确切的主机名 siroe.com,需要单独的 siroe.com模式。

MTA 将尝试从特定主机名开始重写主机/域名,然后逐渐地将该名称一般化以使其不太特别。这意味着将优先使用较特定的重写规则模式,而不是较一般的重写规则模式。例如,假设在配置文件中存在以下重写规则模式:

hosta.subnet.siroe.com
.subnet.siroe.com
.siroe.com

基于不同的重写规则,地址 jdoe@hosta.subnet.siroe.com 将与 hosta.subnet.siroe.com 重写规则模式匹配;地址 jdoe@hostb.subnet.siroe.com 将与 .subnet.siroe.com 重写规则模式匹配;地址 jdoe@hostc.siroe.com 将与 .siroe.com 重写规则模式匹配。

特别是,包含子域重写规则模式的重写规则的使用对于 Internet 上的站点是常用的。此类站点通常具有许多用于其内部主机和子网的重写规则,并且还将顶层 Internet 域的重写规则包括在其文件 internet.rules (msg_svr_base/config/internet.rules) 的配置中。

为确保正确重写传送至 Internet 目的地(不是通过较具体的重写规则处理的内部主机目的地)的邮件并将其路由到外发 TCP/IP 通道,请确保 imta.cnf 文件包含:


!    Ascension Island
 .AC                      $U%$H$D@TCP-DAEMON
. [text
.     removed for
.             brevity]
!      Zimbabwe
 .ZW                      $U%$H$D@TCP-DAEMON

      

IP 域文字遵循类似的分层匹配模式,但是从右向左(而不是从左向右)匹配。例如,以下模式仅与 IP 文字 [1.2.3.4] 完全匹配:

[1.2.3.4]

下一个模式与 1.2.3.0 子网中的任何文字匹配:

[1.2.3.]

除了已经介绍的较为常用的几种主机或子域重写规则模式以外,重写规则还可以使用几种特殊的模式,表 11–1 中概述了这些模式,并在以下小节中将对此进行介绍。

表 11–1 重写规则的特殊模式摘要

模式 

说明/用法 

$* 

匹配任何地址。如果指定此规则,则将首先尝试该规则而不考虑其在文件中的位置。 

$% 

百分比黑客规则。与 A%B 格式的任何主机/域说明匹配。 

$! 

Bang 式样规则。与 B!A 格式的任何主机/域说明匹配。 

[ ] 

IP 文字全匹配规则。与任何 IP 域文字匹配。 

与任何主机/域说明匹配。例如,joe@[129.165.12.11]

除了这些特殊模式以外,Messaging Server 还包含标记的概念,标记可以在重写规则模式中出现。当某个地址可能被重写多次,并且根据以前的重写,必须通过控制与该地址匹配的重写规则在后续重写中进行区分的情况下,将使用这些标记。有关更多信息,请参见标记的重写规则集

与百分比黑客匹配的规则

如果 MTA 尝试重写 A%B 格式的地址时失败,则其将在失败并将该地址格式处理为 A%B@localhost 之前尝试一个附加规则。(有关这些地址格式的更多信息,请参见重写规则模板。)只有在包含百分比符号的本地部分以任何其他方法(包括以下介绍的全匹配规则)重写均失败时,该规则才有效。

百分比黑客规则可用于将某个特殊的内部含义指定到百分比黑客地址。

与 Bang 式样 (UUCP) 地址匹配的规则

如果 MTA 尝试重写 B!A 格式的地址时失败,则其将在失败并将该地址格式处理为 B!A@localhost 之前尝试一个附加规则。此附加规则是 bang 式样规则。其模式为 $!。该模式从不会更改。只有在包含感叹号的本地部分以任何其他方法(包括以下介绍的默认规则)重写均失败时,该规则才有效。

bang 式样规则可用于将 UUCP 式样地址强制路由至具有 UUCP 系统和路由的全面知识的系统。

与任何地址匹配的规则

如果其他规则均不匹配,并且在通道表格中找不到主机/域说明,则特殊模式 "."(单个句点)将与任何主机/域说明匹配。也就是说,当无法使用其他方法进行地址重写时,"." 规则将作为最后的解决方案。


注 –

关于替换序列,当全匹配规则匹配并且其模板已扩展时,则 $H 将扩展为完整主机名,$D 将扩展为单个句点 "."。因此,$D 在全匹配规则模板中的使用将受到限制!


标记的重写规则集

随着重写过程的继续,可能适合使用不同的规则集。这是通过使用重写规则标记来实现的。在配置文件或域数据库中查找当前标记之前,该标记已前置于每个模式。通过使用重写规则模板(下面将介绍)中的 $T 替换字符串,可以用匹配的任何重写规则更改该标记。

标记有些麻烦;设置标记之后,它们将不断应用到从单个地址提取的所有主机。这意味着在使用所有标记后,必须谨慎提供以正确的标记值开头的备用规则。实际上这几乎不是什么问题,因为标记通常只用于非常专用的应用程序中。重写地址完成后,标记将被重置为默认标记—空字符串。

依照约定,所有标记值均以垂直条 | 结束。该字符在标准地址中不使用,因此可以在模式的其余部分随意勾画标记。

重写规则模板

以下各节将详细介绍重写规则的模板格式。表 11–2 汇总了这些模板格式。

表 11–2 重写规则的模板格式摘要

模板 

用法 

A%B 

A 将变为新的用户/邮箱名称,B 将变为新的主机/域说明,再次重写。重复的重写模板 A%B

A@B 

将被视为 A%B@B。一般重写模板:A%B@C 或 A@B

A%B@C 

A 将是新的用户/邮箱名称,B 将是新的主机/域说明,路由到与主机 C 关联的通道。一般重写模板:A%B@C 或 A@B

A@B@C 

将被视为 A@B@C@C。指定的路由重写模板 A@B@C@D 或 A@B@C

A@B@C@D 

A 将是新的用户/邮箱名称,B 将是新的主机/域说明,插入 C 作为源路由,路由到与主机 D 关联的通道。指定的路由重写模板 A@B@C@D 或 A@B@C

一般重写模板:A%B@C 或 A@B

以下模板为最常用的模板格式。规则适用于地址的用户部分和地址的域部分。然后使用新地址将邮件路由到一个特定通道(由 ChannelTag 表示)。

UserTemplate%DomainTemplate@ChannelTag[controls]

下一个模板格式在应用方面与最常用的模板格式相同。但是,仅当 DomainTemplateChannelTag 相同时,才可使用此模板格式。

UserTemplate@ChannelTag[controls]

重复的重写模板 A%B

以下模板格式用于在应用规则后还需要附加重写的元规则。规则应用后,将在产生的新地址上重复整个重写进程。(所有其他重写规则格式会导致重写进程在规则应用后终止。)

UserTemplate%DomainTemplate[controls]

例如,以下规则可以从地址的结尾处删除出现的所有 .removable 域:

.removable $U%$H

使用这些重复规则时必须非常谨慎;使用疏忽可能会创建一个“规则循环”。因此,只有在绝对必要时才应使用元规则。确保使用 imsimta test -rewrite 命令来测试元规则。有关 test -rewrite 命令的更多信息,请参见《Sun Java System Messaging Server 6 2005Q4 Administration Reference》

指定的路由重写模板 A@B@C@D 或 A@B@C

以下模板格式与较常用的模板 UserTemplate%DomainTemplate@ChannelTag(注意第一个分隔符的区别)的工作方式相同,除了 ChannelTag 作为源路由被插入地址中。然后邮件将被路由到 ChannelTag

UserTemplate@DomainTemplate@Source-Route
    @ChannelTag[controls]

重写的地址变为 @route:user@domain。以下模板也有效:

UserTemplate@DomainTemplate@ChannelTag[controls]

例如,以下规则将把地址 jdoe@com1 重写到源路由的地址 @siroe.com:jdoe@com1。通道标记将变为 siroe.com

com1 $U@com1@siroe.com

重写规则模板中的大小写区分

与重写规则中的模式不同,模板中的字符大小写将被保留。当使用重写规则为区分字符大小写的邮件系统提供接口时,这是必要的。请注意类似 $U 和 $D 的替换序列(替换从地址提取的材料)也将保留字符的原始大小写。

在需要强制被替换的材料使用特定的大小写时(如在 UNIX 系统中强制邮箱为小写),在模板中可以使用特殊的替换序列以强制被替换的材料为所需的大小写。特别是,$\ 将强制后续被替换的材料为小写,$^ 强制后续被替换的材料为大写,而 $_ 则要求使用原始的大小写。

例如,您可以使用以下规则来强制 unix.siroe.com 地址的邮箱为小写:

unix.siroe.com    $\$U$_%unix.siroe.com

MTA 如何将重写规则应用到地址

以下步骤介绍 MTA 如何将重写规则应用到给定地址:

  1. MTA 从地址中提取第一个主机或域说明。

    一个地址可以指定多个主机或域名,如下例所示:

    jdoe%hostname@siroe.com.

  2. 识别了第一个主机或域名之后,MTA 将执行搜索,扫描其模式与主机或域名匹配的重写规则。

  3. 找到匹配的重写规则后,MTA 将根据该规则的模板部分重写地址。

  4. 最后,MTA 会将通道标记和与每个通道相关联的主机名进行比较。

    如果找到匹配,MTA 会将邮件加入关联的通道队列中;否则该重写过程失败。如果匹配的通道为本地通道,则会通过查找别名数据库和别名文件来进行地址的某个附加的重写。

在下个小节中将更加详细地介绍这些步骤。


注 –

使用不属于任何现有通道的通道标记将导致其地址与此规则匹配的邮件被退回。也就是使匹配的邮件无法路由。


步骤 1:提取第一个主机或域说明

重写地址的过程通过从地址中提取第一个主机或域说明开始。(建议不熟悉 RFC 822 地址约定的读者阅读该标准以便理解以下讨论内容。)扫描地址中的主机/域说明的顺序如下所示:

  1. 源路由中的主机(从左向右读取)

  2. 主机显示在 "at" 符号 (@) 的右侧

  3. 主机显示在最后单个百分比符号 (%) 的右侧

  4. 主机显示在第一个感叹号 (!) 的)

如果 bangoverpercent 关键字在正进行地址重写的通道上有效(即,如果尝试将邮件加入队列的通道自身被标上 bangoverpercent 通道关键字),则最后两个项目的顺序将被切换。

表 11–3 中显示了可以首先提取的一些地址和主机名的示例。

表 11–3 提取的地址和主机名

地址 

第一个主机域说明 

注释 

user@a

a

“简短格式”域名。 

user@a.b.c

a.b.c

全限定”域名 (fully qualified domain name, FQDN)。

user@[0.1.2.3]

[0.1.2.3]

“域文字”。 

@a:user@b.c.d

a

带有简短格式域名“路由”的源路由的地址。

@a.b.c:user@d.e.f

a.b.c

源路由的地址;路由部分被完全限定。 

@[0.1.2.3]:user@d.e.f

[0.1.2.3]

源路由的地址;路由部分是域文字。 

@a,@b,@c:user@d.e.f

a

带有 a 到 b 到 c 路由的源路由的地址。 

@a,@[0.1.2.3]:user@b

a

在路由部分中带有域文字的源路由的地址。 

user%A@B

B

此非标准的路由格式称为“百分比黑客”。

user%A

A

 

user%A%B

B

 

user%%A%B

B

 

A!user

A

“Bang 式样”寻址;通常用于 UUCP。 

A!user@B

B

 

A!user%B@C

C

 

A!user%B

B

nobangoverpercent 关键字处于活动状态;默认值。

A!user%B

A

bangoverpercent 关键字处于使用中。

RFC 822 不在地址中对感叹号 (!) 和百分比符号 (%) 进行解释。如果 at 符号不存在,百分比符号通常与 at 符号 (@) 的解释方法相同,因此 Messaging Server MTA 采用了该约定。

重复的百分比符号的特殊解释用于允许将百分比符号作为本地用户名的一部分;这在处理某些外部邮件系统地址时可能会十分有用。感叹号的解释符合 RFC 976 的“bang 式样”地址约定,因此可以在 Messaging Server MTA 中使用 UUCP 地址。

RFC 822 或 RFC 976 都没有指定这些解释的顺序,因此可以使用 bangoverpercentnobangoverpercent 关键字来控制执行重写的通道应用这些解释的顺序。尽管在某些情况下其他设置可能会很有用,但默认值更“标准”一些。


注 –

不建议在地址中使用感叹号 (!) 或百分比符号 (%)。


步骤 2. 扫描重写规则

从地址中提取出第一个主机或域说明后,MTA 将咨询重写规则以找出要执行的操作。将主机/域说明与每个规则的模式部分(即每个规则的左侧)进行比较。该比较不区分大小写。RFC 822 规定不区分大小写。MTA 不区分大小写,但在可能的情况下将保留大小写。

如果主机或域说明与任何模式均不匹配,即所谓的“与任何规则均不匹配”的情况,则主机或域说明的第一个部分(第一个句点前的部分,通常为主机名)将被删除并用星号 (*) 替换,然后将再次尝试查找生成的主机或域说明,但只在配置文件重写规则中查找(不查询域数据库)。

如果此操作失败,则会删除第一个部分并重复该过程。如果此操作也失败了,则会删除下一个部分(通常为子域),重写程序会再次尝试,首先带星号然后不带星号。包含星号的所有探测只在配置文件重写规则表中进行;不检查域数据库。此过程将继续,直到找到匹配或用尽整个主机或域说明。此过程的作用是尝试首先与最为特别的域匹配,然后逐渐与不太特别和比较一般的域匹配。

从倾向于算法的角度看,此匹配过程为:

例如,假设地址 dan@sc.cs.siroe.edu 将被重写。这将导致 MTA 按照给定的顺序查找以下模式:


sc.cs.siroe.edu
*.cs.siroe.edu
.cs.siroe.edu
*.*.siroe.edu
.siroe.edu
*.*.*.edu
.edu
*.*.*.*
.
 

步骤 3. 根据模板重写地址

主机/域说明与某个重写规则匹配后,将使用该规则的模板部分进行重写。模板指定了三个内容:

  1. 地址的新用户名。

  2. 地址的新的主机/域说明。

  3. 用于识别现有 MTA 通道(到达该地址的邮件应该发送到此通道)的通道标记。

步骤 4. 完成重写进程

主机/域说明重写后可能会出现下面两种情况之一。

重写规则失败

如果主机/域说明无法与任何重写规则匹配,并且不存在默认规则时,MTA 将使用“原样”说明;例如原始说明将成为新的说明和路由系统。如果地址中包含无意义的主机/域说明,则当路由系统不匹配与任何通道相关联的任何系统名时,将检测出该说明并将邮件退回。

重写后的语法检查

重写规则应用到地址后不进行任何附加的语法检查。这是有意的—这样可以使用重写规则将地址转换成不符合 RFC 822 的格式。但是,这也意味着配置文件中的错误可能会导致邮件为 MTA 留下不正确或非法的地址。

处理域文字

在重写过程中将对域文字进行特殊处理。如果地址的域部分中显示的域文字与某个重写规则模式不匹配,则该文字将被解释为由句点分隔并由方括号括起来的一组字符串。最右侧的字符串将被删除并会重复进行搜索。如果此操作不起作用则将删除下一个字符串,以此类推直到只剩下空括号。如果搜索空括号失败,则会删除整个域的文字并会对域地址的下一个部分(如果该部分存在)继续进行重写。域文字的内部处理中不使用星号;由星号替换整个域文字时,星号的数量与域文字中的元素的数量相对应。

与常规的域或主机说明类似,域文字也是按最特定到最不特定的顺序进行尝试。其模式匹配的第一个规则将是用于重写主机或域说明的规则。如果规则列表中有两个相同的模式,则会使用首先显示的模式。

例如,假设地址 dan@[128.6.3.40] 将被重写。重写程序将依次查找 [128.6.3.40][128.6.3.][128.6.][128.][] 以及 [*.*.*.*],最后是全匹配规则 "."

模板替换和重写规则控制序列

替换用于通过将字符串插入到重写的地址中来重写用户名或地址,替换的值由所用的特定替换序列确定。本节包含以下几个部分:

例如,在以下模板中,$U 是一个替换序列。该替换序列将导致被重写地址的用户名部分被替换为模板的输出。因此,如果 jdoe@mailhost.siroe.com 被此模板重写,则结果输出将为 jdoe@siroe.com$U 将在用户名部分替换原始地址的 jdoe

$U@siroe.com

控制序列为给定重写规则的适用性强加了附加条件。不仅重写规则的模式部分必须与要检查的主机或域说明匹配,而且要重写的地址的其他方面也必须满足由控制序列设置的条件。例如,$E 控制序列要求被重写的地址为信封地址,而 $F 控制序列要求其为正向指示地址。以下重写规则仅适用于(重写) 形式的信封 To: user@siroe.com 格式的信封 To: 地址:

siroe.com $U@mail.siroe.com$E$F

如果域或主机说明与某个重写规则的模式部分匹配,但不满足该规则的模板中由控制序列强加的所有条件,则该重写规则将失败,重写程序将继续查找其他适用的规则。

表 11–4 汇总了模板替换和控制序列。

表 11–4 重写规则模板替换和控制序列的摘要

替换序列 

替换 

$D

匹配的域说明的部分。 

$H

不匹配的主机/域说明的部分;模式中的点的左侧。 

$L

不匹配的域文字的部分;模式文字中的点的右侧。 

$U

原始地址中的用户名。 

$nA 

插入从位置 0 开始的当前地址左侧第 n 个字符,如果省略 n,则将插入整个地址。 

$nX 

插入从 0 开始的邮件主机左侧第 n 个组件,如果省略 n,则将插入整个邮件主机。 

$0U 

原始地址中的本地部分(用户名),减去任何子地址。 

$1U 

原始地址的本地部分(用户名)中的子地址(如果存在)。 

$$

插入文字美元符号 ($)。

$%

插入文字百分比符号 (%)。

$@

插入文字 at 符号 (@)。

$\

强制材料为小写。 

$^

强制材料为大写。 

$_

使用原始大小写。 

$=

强制后续替换字符经适当引用插入到 LDAP 搜索过滤器中。 

$W

在随机、唯一的字符串中替换。 

$]...[

LDAP 搜索 URL 查找。 

$(text)

常规数据库替换;如果查找失败则规则失败。 

${...}

将指定的映射应用于提供的字符串。 

$[...] 

调用用户提供的例程;在结果中替换。 

$&n

不匹配的(或通配的)主机的第 n 个部分,由 0 开始从左向右数。

$!n

不匹配的(或通配的)主机的第 n 个部分,由 0 开始从右向左数。

$*n

匹配模式的第 n 个部分,由 0 开始从左向右数。

$#n

匹配模式的第 n 个部分,由 0 开始从右向左数。

$nD

匹配的域说明的部分,保留从 0 开始的第 n 个最左侧部分 

$nH

不匹配的主机/域说明的部分,保留从 0 开始的第 n 个最左侧部分 

控制序列 

对重写规则的作用 

$1M 

只有当通道为内部重新处理通道时才适用。 

$1N 

只有当通道不是内部重新处理通道时才适用。 

$1~ 

执行所有待定通道匹配检查。如果检查失败将会成功地终止当前重写规则模板的处理。 

$A 

如果主机在符号的右侧则适用 

$B 

只适用于标题/主体地址 

$C channel

如果发送到 channel,则将失败

$E 

只适用于信封地址 

$F 

只适用于正向指引的(如 To:)地址 

$M channel

只在 channel 重写地址时适用

$N channel

如果 channel 重写地址,则将失败

$P 

如果主机在百分比符号的右侧则适用 

$Q channel

如果发送到 channel,则适用

$R 

只适用于反向指引的(如 From:)地址 

$S 

如果是源路由的主机则适用 

$Tnewtag

将重写规则标记设置为 newtag 

$Vhost

如果未在 LDAP 目录(在 DC 树中或作为虚拟域)中定义主机名则会失败。如果 LDAP 搜索超时,重写模式的剩余部分(紧跟主机名后面的字符之后)将会被 MTA 选项字符串 DOMAIN_FAILURE 替换。

$X 

如果主机在感叹号的左侧则适用 

$Zhost

如果在 LDAP 目录(在 DC 树中或作为虚拟域)中定义了主机名则会失败。如果 LDAP 搜索超时,重写模式的剩余部分(紧跟主机名后面的字符之后)将会被 MTA 选项字符串 DOMAIN_FAILURE 替换。

$?errmsg

如果重写失败,将返回 errmsg 而不是默认的错误消息。错误消息必须为 US ASCII。

$number?errmsg

如果重写失败,将返回 errmsg 而不是默认的错误消息,并将 SMTP 扩展错误代码设置为 ab.c

  • anumber/1000000(第一个数字)

  • b 为 (number/1000) 除以 1000 的余数(第 2 个到第 4 个数字的值)

  • cnumber 除以 1000 的余数(最后三个数字的值)。

    以下示例将错误代码设置为 3.45.89:

    $3045089?the snark is a boojum

用户名和子地址替换,$U、$0U、$1U

模板中出现的所有 $U 都将被原始地址的用户名(RFC 822 “本地部分”)替换。注意,a."b" 格式的用户名将被 "a.b" 格式的用户名替换,因为 RFC2822 不支持 RFC 822 的前一种语法,并期望后一种用法将来能成为强制性的语法。

模板中出现的所有 $0U 都将被原始地址的用户名替换,减去任何子地址和子地址指示字符 (+)。模板中出现的所有 $1U 都将被原始地址的子地址和子地址指示字符(如果存在)替换。因此请注意,$0U 和 $1U 是用户名的补充部分,$0U$1U 与简单 $U 等效。

主机/域和 IP 文字替换,$D、$H、$nD、$nH、$L

出现的所有 $H 都将被与规则不匹配的主机/域说明部分替换。出现的所有 $D 都将被与重写规则匹配的主机/域说明部分替换。$nH 和 $nD 字符是保留从 0 开始数的第 n 个最左侧部分的标准 $H 或 $D 部分的变体。即 $nH 和 $nD 分别省略了通常为 $H 或 $D 替换的最左侧的 n 部分(从 1 开始数)。特别是,$0H 与 $H 等效,$0D 与 $D 等效。

例如,假设地址 jdoe@host.siroe.com 与以下重写规则匹配:

host.siroe.com    $U%$1D@TCP-DAEMON

结果地址是 jdoe@siroe.comTCP-DAEMON 将用作外发通道。其中 $D 将在匹配的整个域 host.siroe.com 中进行替换,而 $1D 将在从第一部分(第一部分为 siroe)开始匹配的部分中进行替换,因此在 siroe.com 中进行替换。

$L 将替换与重写规则不匹配的域文字部分。

文字字符替换,$$、$%、$@

$、% 和 @ 字符通常是重写规则模板中的元字符。要执行此类字符的文字插入,请为其引上美元字符 $。即,$$ 扩展成单个美元符号 $;$% 扩展成单个百分比 %(这种情况下不将百分比解释为模板字段分隔符);$@ 扩展成单个 at 符号 @(也不解释为字段分隔符)。

LDAP 查询 URL 替换,$]...[

$]ldap-url[ 格式的替换被解释为 LDAP 查询 URL,并且 LDAP 查询的结果将被替换。使用标准 LDAP URL 时省略了主机和端口。而主机和端口在 msg.conf 文件(local.ldaphostlocal.ldapport 属性)中指定。

即,应该按如下所示指定 LDAP URL,其中方括号字符 [ ] 表示 URL 的可选部分:

ldap:///dn[?attributes[?scope?filter]]

dn 是必需的标识名,用于指定搜索基准。URL 的可选属性、范围和过滤器部分进一步完善了要返回的信息内容。对于重写规则,指定返回所需的属性可能是 mailRoutingSystem 属性(或某个类似的属性)。范围可以是任何基准(默认设置)、某个基准或子基准。所需的过滤器可能会要求返回其 mailDomain 值与要被重写的域匹配的对象。

如果 LDAP 目录模式包括属性 mailRoutingSystemmailDomain,则确定要将给定种类地址路由到哪个系统的可能的重写规则可能显示如下,其中 LDAP URL 替换序列 $D 用于将当前域名替换到构建的 LDAP 查询中:


.siroe.com \
  $U%$H$D@$]ldap:///o=siroe.com?mailRoutingSystem?sub? \
  (mailDomain=$D)

         

为了便于阅读,使用了反斜杠字符将单个逻辑重写规则行继续到第二个物理行。表 11–5 列出了 LDAP URL 替换序列。

表 11–5 LDAP URL 替换序列

替换序列 

说明 

$$

文字 $ 字符 

$~ account

用户帐户的主目录 

$A

地址 

$D

域名 

$H

主机名(全限定域名的第一部分) 

$L

用户名减去任何特殊的前导字符,如 ~ 或 _ 

$S

子地址 

$U

用户名 

MTA 现在高速缓存在重写规则和映射中查找到的 URL 结果。这一新的 URL 结果高速缓存由两个新的 MTA 选项控制,URL_RESULT_CACHE_SIZE(默认为 10000 个条目)和 URL_RESULT_CACHE_TIMEOUT(默认为 600 秒)。

常规数据库替换,$(...)

$(text) 格式的替换是经过特殊处理的。文本部分被用作访问特殊的常规数据库的密钥。该数据库包括在 /imta/config/imta_tailor 文件中通过 IMTA_GENERAL_DATABASE 选项指定的文件,此文件通常为 /imta/db/generaldb.db

该数据库通过 imsimta crdb 实用程序生成。如果在数据库中找到了“文本字符串”,则数据库中相应的模板将被替换。如果“文本字符串”与数据库中的任何条目均不匹配,则重写过程失败;这就相当于重写规则从未匹配过。如果替换成功,则从数据库中提取的模板将被重新扫描以进行附加替换。但是,提取的模板中的附加 $(text) 替换会被禁止以防止没完没了的递归引用。

例如,假设地址 jdoe@siroe.siroenet 与以下重写规则匹配:

.SIROENET $($H)

则将在常规数据库中查找文本字符串 siroe, 并且查找的结果(如果有)将用于重写规则的模板。假设查找 siroe 的结果是 $u%eng.siroe.com@siroenet.,则模板的输出将会是 jdoe@eng.siroe.com(即,用户名 = jdoe;主机/域说明 = eng.siroe.com),且路由系统将是 siroenet

如果常规数据库存在,则其应该是全局可读的以确保正常运行。

应用指定的映射,${...}

.SIROENET $($H) ${mapping,argument} 格式的替换用于查找并应用 MTA 映射文件中的映射。mapping 字段指定要使用的映射表的名称,而 argument 指定要传递给映射的字符串。若要重写成功,映射必须存在并必须在其输出中设置 $Y 标志;如果映射不存在或未设置 $Y,则重写将失败。如果重写成功,则映射的结果将合并到当前位置的模板中并重新扩展。

此机制允许 MTA 重写进程以各种复杂的方式进行扩展。例如,可以选择性地分析和修改地址的用户名部分,通常这并不是 MTA 重写过程所具有的功能。

用户提供的例程替换,$[...]

$[image ,routine,argument ] 格式的替换用于查找并调用用户提供的例程。在 UNIX 上运行时,MTA 使用 dlopendlsym 动态地装入并调用从共享库映像中指定的例程。则该例程被称为函数,带有以下变量列表:

status := routine (argument, arglength, result, reslength)

argumentresult 是 252 字节长的字符串缓冲区。在 UNIX 上,argumentresult 将作为指针传递到字符串(例如,在 C 中,作为 char*),arglengthreslength 是由引用传递的有符号型长整数。输入时,argument 包含重写规则模板中的变量字符串,arglength 是该字符串的长度。返回时,结果字符串应放在 result 中,而其长度应放在 reslength 中。然后该结果字符串将替换重写规则模板中的 "$[ image,routine,argument]"。如果重写规则失败则例程将返回 0,如果重写规则成功则例程将返回 -1。

此机制允许重写进程以各种复杂的方式进行扩展。例如,可以执行对某种类型的名称服务的调用并使用调用的结果来按某种方式改变地址。对主机 siroe.com 的正向定位地址(例如 To: 地址)的目录服务查找,可以使用以下重写规则并按如下方式执行。特定于方向和位置的重写规则 ($B, $E, $F, $R)中介绍的 $F 导致此规则仅用于正向定位地址:

siroe.com $F$[LOOKUP_IMAGE,LOOKUP,$U]

正向定位地址 jdoe@siroe.com 与该重写规则匹配时,将导致 LOOKUP_IMAGE(UNIX 上的共享库)被装入内存,并导致例程 LOOKUP 被调用(使用 jdoe 作为变量参数)。然后,例程 LOOKUP 可能会在结果参数中返回一个不同的地址(如 John.Doe%eng.siroe.com)和值 -1,以表示重写规则成功。结果字符串中的百分比符号(请参见重复的重写模板 A%BJohn.Doe@eng.siroe.com 将作为要被重写的地址。

在 UNIX 系统上,站点提供的共享库映像应该是全局可读的。

单个字段替换,$&、$!、$*、$#

单个字段替换从正被重写的主机/域说明中提取单个子域部分。表 11–6 中显示了可用的单个字段替换。

表 11–6 单个字段替换

控制序列 

用法 

$&n 

替换主机说明(不匹配或与某种通配符匹配的部分)中的第 n 个元素,n=0,1,2,...,9,。元素由点分隔;左侧的第一个元素为元素零。如果请求的元素不存在则重写失败。 

$!n 

替换主机说明(不匹配或与某种通配符匹配的部分)中的第 n 个元素,n=0,1,2,...,9,。元素由点分隔;右侧的第一个元素为元素零。如果请求的元素不存在则重写失败。 

$*n 

替换域说明(与模式中的显式文本匹配的部分)中的第 n 个元素,n=0,1,2,...,9,。元素由点分隔;左侧的第一个元素为元素零。如果请求的元素不存在则重写失败。 

$#n 

替换域说明(与模式中的显式文本匹配的部分)中的第 n 个元素,n=0,1,2,...,9,。元素由点分隔;右侧的第一个元素为元素零。如果请求的元素不存在则重写失败。 

假设地址 jdoe@eng.siroe.com 与以下重写规则匹配:

*.SIROE.COM     $U%$&0.siroe.com@mailhub.siroe.com

则从模板得到的结果将会是 jdoe@eng.siroe.com,并将 mailhub.siroe.com 用作路由系统。

唯一字符串替换

每次使用 $W 控制序列时均会插入一个由大写字母和数字组成的文本字符串,这些大写字母和数字都是唯一并且不可重复的。在必须构造非重复的地址信息时,$W 很有用。

特定于源通道的重写规则 ($M, $N)

重写规则可以只与特定的源通道一起使用。这在简短形式的名称具有两种含义时很有用:

  1. 当其在到达某个通道的邮件中显示时。

  2. 当其在到达另一个通道的邮件中显示时。

特定于源通道的重写与使用中的通道程序以及通道关键字 rulesnorules 相关联。如果在与正执行重写的 MTA 组件相关联的通道上指定了 norules,则将不会进行特定于通道的重写检查。如果在通道上指定了规则,则会强制进行特定于通道的规则检查。关键字 rules 是默认设置。

特定于源通道的重写和与给定地址匹配的通道不相关联。该重写仅取决于执行重写的 MTA 组件以及该组件的通道表格条目。

特定于通道的重写检查由规则模板部分中的 $N$M 控制序列触发。$N 或 $M 后面的字符,一直到 at 符号 (@)、百分比符号 (%) 或后面的 $N$M$Q$C$T$? 都被解释为通道名称。

例如,如果 channel 当前没有执行重写,则 $Mchannel 将导致规则失败。如果 channel 正在执行重写,则 $Nchannel 将导致规则失败。可以指定多个 $M$N 子句。如果多个 $M 子句中的任何一个子句匹配,则规则成功。如多个 $N 子句中的任何一个子句匹配,则规则将失败。

特定于目标通道的重写规则 ($C, $Q)

可以具有这样的重写规则,其应用程序取决于邮件要排入的通道。当某个主机有两个名称,一个由一组主机所知晓,一个由另一组主机所知晓时,该重写规则很有用。通过使用不同的通道将邮件发送给每个组,可以对地址进行重写以指代每个组所知晓的名称的主机。

特定于目标通道的重写与要处理邮件并将邮件移出队列的通道,以及该通道上的通道关键字 rulesnorules 关联。如果在目标通道上指定了 norules,则不会执行特定于通道的重写检查。如果在目标通道上指定了 rules,则会强制执行特定于通道的规则检查。关键字 rules 是默认设置。

特定于目标通道的重写和与给定地址匹配的通道不相关联。该重写仅取决于邮件的信封 To: 地址。将邮件加入队列时,首先重写其信封 To: 地址以确定邮件要加入队列的通道。在重写 信封 To: 地址过程中,将忽略所有 $C$Q 控制序列。重写了 信封 To: 地址以及确定了目标通道之后,$C$Q 控制序列才生效,因为与该邮件关联的其他地址已被重写。

特定于目标通道的重写检查由规则模板部分中的 $C$Q 控制序列触发。$C$Q 后面的字符,一直到 at 符号 (@)、百分比符号 (%) 或后面的 $N$M$C$Q$T$? 都被解释为通道名称。

例如,如果 channel 不是目标通道,则 $Qchannel 将会导致规则失败。再如,如果 channel 是目标通道,则 $Cchannel 将会导致规则失败。可以指定多个 $Q$C 子句。如果多个 $Q 子句中的任何一个子句匹配,则规则成功。如果多个 $C 子句中的任何一个子句匹配,则规则失败。

特定于方向和位置的重写规则 ($B, $E, $F, $R)

有时需要指定仅应用于信封地址或仅应用于标题地址的重写规则。如果被重写的地址不是信封地址,控制序列 $E 将强制使重写失败。如果被重写的地址不是来自邮件标题或主体的地址,控制序列 $B 将强制使重写失败。这些序列对重写没有其他作用并且可能会显示在重写规则模板中的任何位置。

地址也可以按方向分类。正向定位地址源自 To:、Cc:Resent-to: 或其他标题,或源自引用了目标的信封行。反向定位地址如 From:Sender:Resent-From:,指的是源。如果地址是正向定位的,则控制序列 $F 将导致应用重写。如果地址是反向指示的,则控制序列 $R 将导致应用重写。

特定于主机位置的重写 ($A, $P, $S, $X)

有时需要重写主机名在地址中出现的敏感位置。主机名可以显示在地址中几个不同的上下文中:

正常情况下,应该以相同的方式处理主机名,而不考虑其显示的位置。有些情况可能需要特殊处理。

四个控制序列用于根据地址中主机的位置来控制匹配。

如果主机的位置不是指定的位置,则规则将失败。这些序列可以组合成一个重写规则。例如,如果指定了 $S$A,规则将与在源路由中或 at 符号右侧指定的主机匹配。不指定这些序列相当于指定了所有序列;规则可以匹配而不考虑位置。

更改当前标记值,$T

$T 控制序列用于更改当前重写规则标记。在配置文件和域数据库中查找重写规则模式之前,所有重写规则模式都前置了重写规则标记。$T 后面的文本,一直到 at 符号、百分比符号、$N、$M、$Q、$C、$T 或 $? 均被视为新标记。

在处理特殊寻址形式(遇到某个组件时更改了地址的整个特征)时,标记很有用。例如,假设在源路由中找到特殊主机名 internet 时,应将其从地址中删除,并强制使结果地址与 TCP-DAEMON 通道匹配。

这可以通过类似以下规则(假定 localhost 为本地主机的正式名称)来实现:

internet               $S$U@localhost$Tmtcp-force|

mtcp-force|.           $U%$H@TCP-DAEMON

如果第一个规则在源路由中显示,则其将与特殊的主机名 internet 匹配。该规则强制 internet 与本地通道匹配,这将确保将 internet 从地址中删除。然后设置重写标记。重写将继续,但由于该标记的原因将不会有常规规则匹配。最后,将通过标记尝试使用默认规则,并且该组的第二个规则将激活,强制地址与 TCP-DAEMON 通道匹配而不考虑任何其他条件。

控制与重写相关联的错误消息 ($?)

重写和通道匹配失败时,MTA 将提供默认错误消息。在某些情况下,更改这些邮件的能力将很有用。例如,如果某人尝试将邮件发送到以太网路由器邮箱,则显示类似“我们的路由器无法接受邮件”的信息可能要比通常的“指定了非法的主机/域”更加明确。

如果规则失败,可以使用特殊控制序列来更改显示的错误消息。序列 $? 用于指定错误消息。如果此次重写的结果与任何通道均不匹配,则 $? 后面的文本,一直到 at 符号 (@)、百分比符号 (%)、$N、$M、$Q、$C、$T 或 $? 均被视为要打印的错误消息的文本。错误消息的设置具有“黏性”并将贯穿重写过程始终。

包含 $? 的规则与其他任何规则的操作方式相同。规则中只包含 $? (而没有任何其他符号)的特殊情况需要特别注意—重写过程将终止,而不更改地址的邮箱或主机部分,并按原样在通道表中查找主机。此查找将要失败,结果将返回错误消息。

例如,假设 MTA 配置文件中的最后一个重写规则如下所示:

. $?Unrecognized address; contact postmaster@siroe.com

此示例中,可能失败的任何不可识别的主机或域说明在失败过程中都会生成错误消息:Unrecognized address; contact postmaster@siroe.com

处理大量的重写规则

MTA 始终从 imta.cnf 文件中读取所有重写规则,并将他们以散列表的形式存储在内存中。使用编译的配置可以在每次需要信息时避开与读取配置文件相关联的系统开销;散列表仍用于存储内存中的所有重写规则。此方案适合于少量到中等数量的重写规则。但是,某些站点可能需要 10,000 个或更多的重写规则,这可能会消耗过分高的内存。

MTA 通过提供一个用于在辅助索引数据文件中存储大量重写规则的可选功能来解决此问题。每次读取常规配置文件时,MTA 都将检查域数据库的存在情况。如果此数据库存在,则当尝试与配置文件中找到的规则匹配失败时,将打开该数据库并进行咨询。只有在配置文件中未找到给定的规则时才检查域数据库,因此始终可以将规则添加到配置文件中以覆盖数据库中的规则。默认情况下,域数据库用于存储与托管域相关联的重写规则。IMTA_DOMAIN_DATABASE 属性存储在 imta_tailor 文件中。数据库的默认位置为 msg_svr_base/data/db/domaindb.db


注 –

请勿手动编辑此文件。


测试重写规则

可以使用 imsimta test -rewrite 命令测试重写规则。-noimage 限定符将允许您在重新编译新配置之前,测试对配置文件所做的更改。

您会发现使用此带有 -debug 限定符的实用程序来重写一些地址十分有用。此实用程序将向您显示如何逐步地重写地址。例如,发出以下命令:

% imsimta test -rewrite -debug joe@siroe.com

有关 imsimta test -rewrite 实用程序的详细说明,请参见《Sun Java System Messaging Server 6 2005Q4 Administration Reference》

重写规则示例

以下示例提供了重写规则样例以及规则如何重写样例地址。

假设系统 SC.CS.SIROE.EDU 的配置文件中包含以下示例中所示的重写规则:


sc                     $U@sc.cs.siroe.edu
sc1                    $U@sc1.cs.siroe.edu
sc2                    $U@sc2.cs.siroe.edu
*                      $U%$&0.cs.siroe.edu
*.cs                   $U%$&0.cs.siroe.edu
*.cs.siroe             $U%$&0.cs.siroe.edu
*.cs.siroe.edu         $U%$&0.cs.siroe.edu@ds.adm.siroe.edu
sc.cs.siroe.edu        $U@$D
sc1.cs.siroe.edu       $U@$D
sc2.cs.siroe.edu       $U@$D
sd.cs.siroe.edu        $U@sd.cs.siroe.edu
.siroe.edu             $U%$H.siroe.edu@cds.adm.siroe.edu
.edu                   $U@$H$D@gate.adm.siroe.edu
[]                     $U@[$L]@gate.adm.siroe.edu

表 11–7 显示了一些样例地址,以及如何根据重写规则来重写和路由这些地址。

表 11–7 样例地址和重写

初始地址 

重写为 

路由到 

user@sc 

user@sc.cs.siroe.edu 

sc.cs.siroe.edu 

user@sc1 

user@sc1.cs.siroe.edu 

sc1.cs.siroe.edu 

user@sc2 

user@sc2.cs.siroe.edu 

sc2.cs.siroe.edu 

user@sc.cs 

user@sc.cs.siroe.edu 

sc.cs.siroe.edu 

user@sc1.cs 

user@sc1.cs.siroe.edu 

sc1.cs.siroe.edu 

user@sc2.cs 

user@sc2.cs.siroe.edu 

sc2.cs.siroe.edu 

user@sc.cs.siroe 

user@sc.cs.siroe.edu 

sc.cs.siroe.edu 

user@sc1.cs.siroe 

user@sc1.cs.siroe.edu 

sc1.cs.siroe.edu 

user@sc2.cs.siroe 

user@sc2.cs.siroe.edu 

sc2.cs.siroe.edu 

user@sc.cs.siroe.edu 

user@sc.cs.siroe.edu 

sc.cs.siroe.edu 

user@sc1.cs.siroe.edu 

user@sc1.cs.siroe.edu 

sc1.cs.siroe.edu 

user@sc2.cs.siroe.edu 

user@sc2.cs.siroe.edu 

sc2.cs.siroe.edu 

user@sd.cs.siroe.edu 

user@sd.cs.siroe.edu 

sd.cs.siroe.edu 

user@aa.cs.siroe.edu 

user@aa.cs.siroe.edu 

ds.adm.siroe.edu 

user@a.eng.siroe.edu 

user@a.eng.siroe.edu 

cds.adm.siroe.edu 

user@a.cs.sesta.edu 

user@a.cs.sesta.edu 

gate.adm.siroe.edu—route inserted 

user@b.cs.sesta.edu 

user@b.cs.sesta.edu 

gate.adm.siroe.edu—route inserted 

user@[1.2.3.4] 

user@[1.2.3.4] 

gate.adm.siroe.edu—route inserted 

基本上,这些重写规则的意思是:如果主机名是我们的简短格式名称之一(scsc1sc2),或者是我们的完整名称(sc.cs.siroe.edu 等)之一,则将其扩展为完整名称并路由给我们。将 cs.cmu.edu 附加至一部分简短格式的名称并重试。将后面为 .cs 的一部分转换为后面为 .cs.siroe.edu 的一部分,并重试。同时将 .cs.siroe 转换为 .cs.siroe.edu 并重试。

如果名称为 sd.cs.siroe.edu(可能是我们直接连接至的某个系统),则执行重写并将其路由至那里。如果主机名为 .cs.siroe.edu 子域中的任何其他名称,则将其路由至 ds.cs.siroe.edu.cs.siroe.edu 子域的网关)。如果主机名为 .siroe.edu 子域中的任何其他名称,则将其路由至 cds.adm.siroe.edu.cs.siroe.edu 子域的网关)。如果主机名为 .edu 顶层域中的任何其他名称,则将其路由至 gate.adm.siroe.edu(假定其可以将邮件路由至正确的目标)。如果使用了域文字,则也将其发送到 gate.adm.siroe.edu

重写规则的大多数应用程序(如先前的示例)将不会以任何方式更改地址的用户名(或邮箱)部分。当 MTA 用于与不符合 RFC 822 的邮件程序(需要将主机/域说明部分加入到地址的用户名部分的邮件程序)配合共作时,将使用更改地址用户名部分的功能。确实要使用此功能时应格外谨慎。