SMTP 服务设计

 

上一次修改主题: 2006-07-19

核心 SMTP 协议引擎是在 SMTPSvc.dll 中实现的。后者位于 \WINDOWS\system32\inetsrv 目录中。该协议引擎作为不受管理的代码在 IIS Inetinfo 进程中运行,它在会话层处理传入和传出 SMTP 连接。下图显示出 SMTP 服务位于国际标准化组织 (ISO) 制定的开放系统互连 (OSI) 模型中的会话层、表示层和应用层中。

85ff238c-4cd4-447d-ae68-f648fbf0cac7

note注意:
不受管理的代码指的是直接由操作系统在 Microsoft .NET Framework 公共语言运行库 (CLR) 外部执行的代码。不受管理的代码提供它自己的内存管理、类型检查和安全支持。受管理的代码从公共语言运行库中接收这些服务。

Internet 信息服务 (IIS) 集成

由于邮局协议版本 3 (POP3) 服务、Internet 邮件访问协议版本 4 (IMAP4) 服务和 Exchange 路由引擎服务 (RESvc) 等其他服务也在 IIS 中运行,因此 SMTP 服务在 Inetinfo 进程中运行这一事实意味着,Exchange Server 2003 传输子系统与这些服务共享 IIS 资源。Inetinfo.exe 是核心 IIS 进程,而且 IIS Admin 服务控制 Inetinfo.exe。Exchange Server 2003 服务依存关系中对此进行了说明。

异步线程执行

SMTP 服务与 Inetinfo 进程中的其他所有服务共享的最重要资源之一是异步线程队列 (ATQ)。这是一个线程池,IIS 用它来处理所有传入的网络连接请求。线程是进程内部的代码执行实例。进程由虚拟地址空间、处理器上下文和至少一个线程组成。线程是使用操作系统的 CreateThread() 方法创建而成,它在调用进程(即 IIS Inetinfo 进程)的虚拟地址空间内部运行。

在异步处理中,每个线程都在 Inetinfo 进程中运行,而不必等待其他线程完成其处理。在同步处理中,线程以同步方式顺序运行(通过函数调用来阻止代码在函数完成前执行)。为了同步异步线程(例如,为了避免由于对特定资源的并发访问而产生的冲突),操作系统提供同步对象。例如,Windows 套接字的事件对象就是特定资源的同步对象。SMTP 服务使用事件对象来接收有关传入 SMTP 连接的通知。Windows 套接字是 IP 地址与端口号组合。到达 SMTP 协议引擎的默认端口是 TCP 端口 25。通过与运行 SMTP 服务的 Exchange 服务器的 IP 地址组合,该端口号形成了默认 SMTP 虚拟服务器的套接字,例如: 192.168.1.100:25.

note注意:
Exchange 服务器中仅存在默认的 SMTP 虚拟服务器。默认的 SMTP 虚拟服务器针对服务器的所有 IP 地址在 TCP 端口 25 上接受传入连接。可以从 Exchange 系统管理器“常规”选项卡中的“默认 SMTP 虚拟服务器”属性中更改此配置。

处理传入的 SMTP 连接

Inetinfo 进程按如下过程处理传入的 SMTP 连接:

  1. SMTP 服务启动时,Inetinfo 进程在 TCP/IP 中初始化 SMTP 虚拟服务器的套接字,以侦听传入连接请求。为了通过同一虚拟服务器支持多个并发连接,Inetinfo 进程针对重叠的 I/0 操作在非阻塞模式下初始化套接字。默认情况下,SMTP 虚拟服务器可以接受几乎无限多的传入网络连接次数(尽管实际的物理限制大约为 5000)。

    note注意:
    在 Microsoft Windows Server 2003 中,服务器只能处理大约 2,000 个并发连接。在 Windows Server 2003 Service Pack 1 中,默认值从 2,000 增加到 5,000,借助元数据库中的设置甚至可以增加更多。
  2. Inetinfo 进程创建一个同步对象,以便通知操作系统它希望通过套接字接收传入连接的网络事件通知。ATQ 与该同步对象关联,这样,当同步对象发出信号,指出有传入的网络连接时,该线程池中的线程便可以得到通知。

  3. TCP/IP 传输堆栈接收传入的 SMTP 连接,并将该事件通知给 Inetinfo 进程。现在 ATQ 中的线程可以运行,以读取 SMTP 套接字中的数据。

    note注意:
    Inetinfo 进程可以在 ATQ 中创建其他线程,以确保有足够多的线程可用来侦听传入连接请求。若要优化 IIS 性能,可以通过下列注册表参数来指定可在系统中创建的线程的最大数目:

    位置

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\InetInfo\Parameters

    PoolThreadLimit

    类型

    REG_DWORD

    数值数据

    0 - 4,294,967,295 (unlimited)

    描述

    PoolThreadLimit 是包含所有 IIS 池线程的硬限制。

  4. IIS 线程运行 SMTPSvc.dll 中的代码,并使用如下所示的服务器问候语(名为 SMTP 标语)响应传入的客户端请求:220 server01.TailspinToys.com Microsoft ESMTP MAIL Service, Version:6.0.3790.0 ready at Sun, 21 Mar 2004 23:48:47 +0100

  5. 当远程 SMTP 主机传输邮件时,SMTP 会话继续。每次收到 SMTP 命令时,ATQ 中的线程都会运行 SMTPSvc.dll 中的 SMTP 协议代码,并会触发 SMTP 服务中的事件,这些事件将导致其他 DLL 中的代码运行。例如,NTFS 存储驱动程序将文件形式的邮件写入到文件系统上的虚拟 SMTP 服务器 \Queue 文件夹中。

  6. 处理完当前的 SMTP 命令后,Inetinfo 进程会将用于执行 SMTP 处理的线程重新放回到 ATQ 中,以侦听新的传入命令或新的连接请求。IIS 反复使用现有的线程,这样可以避免每次收到新的命令或新的连接请求时都创建新线程,从而减少了开销。

  7. 远程主机发出 Quit 命令,SMTP 服务释放连接。

    note注意:
    ATQ 中的非活动线程的生存时间 (TTL) 是 24 小时。为了响应传入的连接请求,在 Inetinfo 进程的 ATQ 中每一时刻都至少有两个线程。

限制 SMTP 线程数

默认情况下,SMTP 服务最多可以使用 ATQ 中可用线程的 90%。由于SMTP 服务是与运行在同一服务器上的其他 IIS 服务(如文件传输协议 (FTP)、POP3、RESvc 和 IMAP4 服务)共享该线程池的,因此较高的 SMTP 负载可能导致 Inetinfo 进程中出现性能瓶颈。这可能导致 FTP、POP3、RESvc 或 IMAP4 服务失败。

为避免这种情况,可以限制 SMTP 服务能够使用的线程百分比,这样可以保留足够多的线程供其他 IIS 服务使用。这是通过下列注册表参数来完成的。

位置

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\SMTPSVC\Queuing

MaxPercentPoolThreads

类型

REG_DWORD

数值数据

默认为 0x5A (90%)

描述

限制 SMTP 服务能够使用的 ATQ 线程百分比。推荐设置为:

MaxPercentPoolThreads = 90/( 2*SMTP 虚拟服务器实例数 )

如果有足够的内存可供更多线程使用,则还可以使用下列注册表参数来增加 Inetinfo 进程中的总线程数。

位置

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\SMTPSVC\Queuing

AdditionalPoolThreadsPerProc

类型

REG_DWORD

数值数据

默认为 0x5A (90%)

描述

确定Inetinfo 进程在 SMTP 服务启动时在每个处理器上创建的额外池线程数。推荐设置为:

AdditionalPoolThreadsPerProc = ((9/(MaxPercentPoolThreads/100))-4)/2

note注意:
如果 AdditionalPoolThreadsPerProcvalue 大于 200,则必须增加 HKEY_LOCAL_MACHINE\ System\CurrentControlSet\Services\InetInfo\Parameters\ 下面的 PoolThreadLimit 参数的值。应将 PoolThreadLimit 至少设置为与 AdditionalPoolThreadsPerProc 相等。

基于组件对象模型的 SMTP 扩展

SMTP 协议支持在一个会话期间发送多个邮件。在传递或中继某个邮件时,可以传输下一个邮件。SMTP“邮件数据结束”指示符(一个回车换行符接一个句点,再接另一个回车换行符)或每个邮件的最终 BDAT 数据块会通知接收方 SMTP 服务去处理特定邮件的收件人和数据。此处理称为传输处理,因为它将邮件传递到本地 Exchange 存储,或者将它转发到收件人的主服务器(如果收件人的邮箱不驻留在本地服务器上)。SMTP 服务还可以将邮件中继给外部收件人。例如,当 Exchange 用户使用 Internet 客户端向外部收件人发送邮件时,就执行了邮件中继。

通过 SMTP 收到的邮件传递给高级排队引擎 (Phatq.dll)。之后,SMTP 服务用来将邮件传递给高级排队引擎的线程返回到 ATQ。高级排队引擎使用它自己的线程池来处理排队的邮件。该线程池与用来处理 SMTP 协议操作的线程池是分开的。可以在高级排队引擎中阅读有关高级排队引擎的详细内容。

SMTP 传输子系统中的事件

当线程运行 Smtpsvc.dll 中的协议代码或者 Phatq.dll 中的传输代码时,会触发导致其他 DLL 中的代码运行的事件。此事件体系结构完全基于 COM。SMTP 使用 Microsoft 服务器扩展对象 COM 库 (Seo.dll) 来触发 SMTP 事件,并使用 COM 激活来实例化针对每个特定事件注册的事件接收器。SMTP 事件可以表明 SMTP 协议命令已传输或已到达、邮件已提交到 SMTP 传输子系统中,等等。SMTP 协议扩展、分类程序和路由引擎等事件接收器在 SMTP 服务中注册特定的事件。

在 Exchange 2003 的 SMTP 传输子系统中可能发生下列类型的事件:

  • SMTP 协议事件   这些事件是特定于 SMTP 的事件。事件接收器可以通过这些事件来修改、禁用或添加入站命令和出站命令以及对这些命令的响应,从而修改 SMTP 协议引擎的行为。例如,Exchange Server 2003 的 X-LSA Sink 协议事件接收器实现额外的 SMTP 命令 X-LINK2STATE,以便在路由组之间传输链接状态信息,这一点已在邮件路由体系结构中进行了说明。协议事件接收器还可以用来修改标准的 SMTP 命令和 ESMTP 命令(如 EHLO),以拓宽 SMTP 协议的功能。SMTP 协议扩展中介绍了协议事件接收器。
  • SMTP 存储事件 这些事件使得存储事件接收器(即存储驱动程序实现)可以将邮件内容永久地保存在文件系统目录或 Exchange 存储中。例如,在 Exchange Server 2003 的传输子系统中,存储事件用于执行本地传递,向 Exchange 收件人传递邮件。SMTP 服务存储驱动程序中介绍了存储驱动程序。
  • SMTP 传输事件:当邮件到达服务器,再经过核心传输子系统,然后交付给 Exchange 收件人或者中继到其他 SMTP 主机时,这些事件就会发生。在 Exchange Server 2003 中,传输事件用于执行邮件分类和邮件路由。邮件路由体系结构中介绍了路由引擎。SMTP 传输组件中介绍了分类程序事件接收器。
  • SMTP 系统事件 这些事件转换为对充当系统组件的接收器的调用。例如,SMTP Eventlog 接收器是一个系统组件,它注册系统事件,以便将内部处理信息写入到应用程序事件日志中。

63542692-4837-4238-9e02-d0bc7583ff71

note注意:
使用 SMTP 事件接收器,非 Microsoft 供应商可以实现对 SMTP 传输子系统的自定义扩展,如邮件筛选器和防病毒扫描程序。SMTP 事件接收器不支持 COM+ 应用程序。

事件发送器和事件通知

当某个事件发生时,充当事件发送器的 SMTP 服务线程检查事件注册(作为事件绑定存储在 IIS 元数据库中),确定是否有任何接收器与该事件关联。事件发送器确定所有要运行的已注册的事件接收器并确定它们何时运行。运行顺序依赖于在事件绑定信息中指定的接收器优先级。事件将按顺序通知给各个接收器。优先级最低的接收器最先运行。

对于每个接收器,都会发生下列过程:

  1. 事件发送器将接收器的事件注册与事件条件进行比较。如果条件满足,便执行接收器。

    note注意:
    某些 SMTP 事件(例如,存储事件)没有事件条件。
  2. 事件发送器在必要的情况下使用事件接收器 COM 类的类 ID (CLSID) 创建接收器的实例。

    note注意:
    可以缓存接收器以避免在处理后续事件时也执行此步骤。
  3. 事件发送器调用 COM 的 IUnknown::QueryInterface 方法,以获取事件接收器的相应事件通知接口。大多数接收器都使用活动模板库 (ATL) 来实现接收器接口。

  4. 事件发送器通过调用接收器接口上的相应事件方法来运行接收器。对于传输事件,事件发送器将邮件以 MailMsg 对象的形式传递到事件接收器。该对象包含整个邮件以及传输信封字段。可以通过接收器来修改邮件和信封字段。

  5. 接收器在完成处理后将事件状态标志返回给事件发送器。事件发送器检查此标志以确定是否通知后续接收器。例如,事件接收器可能指示事件发送器跳过所有余下的接收器,以停止所有进一步的邮件处理。
    事件接收器使用下列返回代码来指示是否通知后续接收器:

    • S_OK 调用优先级相同或更低的其他接收器。
    • S_FALSE 不调用优先级相同或更低的其他接收器。
      note注意:
      SMTP 协议事件接收器可能还返回 MAILTRANSPORT_S_PENDING 值,这表示处理将通过调用 NotifyAsyncCompletion 方法异步完成。协议事件接收器可以调用 NotifyAsyncCompletion 方法,以通知入站协议事件发送器异步处理已完成,并传递处理结果。
  6. 对于传输事件,则在通知了每一个接收器后,或者在一个接收器指示跳过余下的接收器后,才会检查邮件的状态信封字段,以确定下一个操作。邮件可能被传递到相应的位置,也可能被丢弃,也有可能被放入文件系统上的 SMTP 虚拟服务器 \Badmail 文件夹中。

note注意:
在 SMTP 服务中,事件发送器的角色由协议引擎和高级排队引擎承担。协议引擎发送协议事件。高级排队引擎发送传输事件。协议引擎和高级排队引擎也发送存储事件和系统事件。

管理接口

管理 Exchange Server 2003 服务器上的 SMTP 协议设置和 SMTP 虚拟服务器的主要工具是 Exchange 系统管理器,具体地说是 Exchange SMTP 管理单元 (\Programme\Exchsrvr\bin\SMTPMgr.dll)。在 Exchange 系统管理器中的每个服务器对象下,可在 SMTP 容器中的“协议”下找到该管理单元。可以控制适用于入站邮件传输的大部分 SMTP 设置以及相对较少的出站邮件设置。使用 Exchange 系统管理器,还可以在 Exchange 服务器上创建更多的 SMTP 虚拟服务器。每个 SMTP 虚拟服务器都代表 SMTP 服务的一个实例,并通过 IP 地址与 TCP 端口号的唯一组合定义。每个 SMTP 虚拟服务器都触发它自己的事件,并管理它自己的一组事件接收器。有关配置虚拟 SMTP 服务器的详细信息,请参阅 Exchange Server 2003 Transport and Routing Guide(英文)。

note注意:
在运行 Exchange Server 2003 的服务器上创建多个 SMTP 虚拟服务器对改善系统性能没有帮助。每个 SMTP 虚拟服务器都是多线程的,并且可以并发地处理大量的连接。例如,每个 SMTP 域的并发传出连接的默认最大数目为 100,而并发传出连接总数的最大值为 1,000。

配置设置和事件绑定

Exchange Server 2003 的 SMTP 传输子系统依赖下列三个配置信息库:

  • Active Directory Exchange 系统管理器主要通过 Active Directory 存储配置信息,并从中检索配置信息。例如,收件人属性和限制以及 Exchange 组织的路由拓扑(包括所有路由组和邮件连接器)都在 Active Directory 中定义。SMTP 传输子系统中的组件与 Active Directory 进行通信以获取此信息,Exchange Server 2003 与 Active Directory 中对此进行了说明。
  • IIS 元数据库 Windows Server 2003 附带的 SMTP 服务核心组件不能识别 Active Directory。例如,应用于 SMTP 虚拟服务器的任何设置都必须从 Active Directory 传输到 IIS 元数据库。这是元数据库更新服务的任务。元数据库更新服务注册到配置域控制器中,Exchange Server 2003 使用配置域控制器来接收所有有关 Exchange 配置更改的通知。通知发生在更改后的 15 秒内。只要更改一复制到配置域控制器中,IIS 元数据库更新服务就会立即将更改复制到 IIS 元数据库中。
  • 注册表 可用于配置 SMTP 传输子系统的大多数配置设置都存储在 Active Directory 中或 IIS 元数据库中。但是,影响 SMTP 服务的几个系统参数(如 MaxPercentPoolThreads or AdditionalPoolThreadsPerProc)存储在注册表数据库中的下列项下: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\SMTPSVC.
    另一个重要的项是:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\InetInfo,该项包含驻留 SMTP 服务的 Inetinfo 进程的配置参数。几个重要的注册表参数已在此部分前面介绍。
    由于所有 SMTP 事件接收器都是 COM 组件,因此它们必须在 HKEY_CLASSES_ROOT 注册表部分中注册。可以使用 Regsvr32.exe 来手动注册或注销 COM 组件。

Active Directory 中的配置信息

Exchange 系统管理器在 Active Directory 的配置目录分区中存储 SMTP 虚拟服务器的配置设置。每个虚拟服务器都通过一个单独的配置对象来表示。该对象的位置与 Exchange 系统管理器中所显示的配置对象层次结构匹配,并且公用名与虚拟服务器在 IIS 元数据库中的数字对应。例如,默认 SMTP 虚拟服务器是 IIS 中的第一台 SMTP 虚拟服务器,因此,默认 SMTP 虚拟服务器的配置对象在 Active Directory 中的对应公用名 (CN) 是 1(例如,CN=1,CN=SMTP,CN=Protocols,CN=SERVER01,CN=Servers,CN=First administrative Group,CN=Administrative Groups,CN=TailspinToys,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=TailspinToys,DC=com)。

表 6.1 列出了 Exchange Server 2003 在 Active Directory 中为 SMTP 虚拟服务器存储的重要配置信息。若要了解如何通过编程的方式管理 Active Directory 中的 SMTP 虚拟服务器设置,请参阅 Setting Message Restriction on an SMTP Virtual Server Using ADSI(英文)。

SMTP 虚拟服务器的重要 Active Directory 属性

Active Directory 属性 描述

msExchServerBindings

为安全套接字层 (SSL) 连接指定 Internet 协议 (IP) 端口绑定。

msExchAuthenticationFlags

指出该 SMTP 虚拟服务器接受哪些类型的身份验证。

msExchMaxIncomingConnections

指定该 SMTP 虚拟服务器可以接受的入站连接的最大数目。

msExchLogType

指定该 SMTP 虚拟服务器用于协议日志记录的日志格式。

msExchAccessSSLFlags

指出该 SMTP 虚拟服务器支持的加密通道类型。

msExchServerAutoStart

指定何时启动虚拟服务器。如果设定为 true,则将在操作系统启动时启动虚拟服务器。

msExchNTAuthenticationProviders

指定可以用来通过该 SMTP 虚拟服务器身份验证的 Security Support Provider Interface (SSPI) 数据包列表。Exchange Server 2003 支持通过通用安全服务应用程序编程接口 (GSSAPI) 以及旧版 Microsoft Windows NT LAN Manager Authentication Protocol (NTLM) 执行 Kerberos 身份验证。

msExchIncomingConnectionTimeout

指定所允许的传入连接的最长闲置时间(超过该时间后,连接将被取消)。

msExchSmtpMaxOutgoingConnections

指定该 SMTP 虚拟服务器可以容纳的出站连接的最大数目。

msExchSmtpOutgoingConnectionTimeout

指定所允许的传出连接的最长闲置时间(超过该时间后,连接将被取消)。

msExchSmtpMaxOutgoingConnectionsPerDomain

指定从该 SMTP 虚拟服务器到特定域的出站连接的最大数目。

msExchSmtpOutgoingPort

指定 SMTP 虚拟服务器用来与远程 SMTP 主机联系的出站连接端口号。

msExchSmtpOutgoingSecurePort

指定在使用了传输层安全性 (TLS) 来保护传输通道的情况下,SMTP 虚拟服务器用来与远程 SMTP 主机联系的出站连接端口号。

msExchSmtpMaxHopCount

指定由该 SMTP 虚拟服务器传输的邮件最多可经过多少个跃点到达最终目标。

msExchSmtpMaxMessageSize

指定由该 SMTP 虚拟服务器传递的邮件所允许的最大邮件大小。

msExchSmtpMaxSessionSize

指定在一个 SMTP 会话中可以传输的最大数据量 (KB)。

msExchSmtpMaxRecipients

指定由该 SMTP 虚拟服务器传输的邮件最多可具有的收件人数。

msExchSmtpLocalQueueExpirationTimeout

指定该 SMTP 虚拟服务器必须在什么时间将未送达的本地邮件过期。

msExchSmtpLocalQueueDelayNotification

指定该 SMTP 虚拟服务器必须在什么时间生成传递状态通知,以通知发件人本地邮件未到达其目标。

msExchSmtpRemoteQueueExpirationTimeout

指定该 SMTP 虚拟服务器必须在什么时间将未送达的出站邮件过期。

msExchSmtpRemoteQueueDelayNotification

指定该 SMTP 虚拟服务器必须在什么时间生成传递状态通知,以通知发件人出站邮件未传输。

msExchSmtpSmartHost

对通过此 SMTP 虚拟服务器传输的出站邮件指定智能主机路由路径。

msExchSmtpSmartHostType

指定智能主机类型。

msExchSmtpMaxOutboundMsgPerDomain

指定该 SMTP 虚拟服务器在一次会话中可以为每个域传输的出站邮件的最大数目。

msExchSmtpOutboundSecurityFlag

指定通过该 SMTP 虚拟服务器建立出站连接时使用的身份验证。

msExchSmtpInboundCommandSupportOptions

控制在入站连接上支持哪些 SMTP 命令。通过更改这一值,可以禁用 8BITMIME、BDAT、CHUNKING 和 PIPELINING 等功能。

msExchSmtpRelayForAuth

确定在中继邮件时是否要求进行身份验证。

msExchSmtpPerformReverseDnsLookup

指定是否为邮件的传递执行反向域名系统 (DNS) 查找。

msExchSmtpDoMasquerade

指定是否对未送达报告 (NDR) 使用虚拟域。如果已设置,将使用虚拟域。这样,NDR 将返回给指定的备用域,而不是电子邮件的发出域。

msExchSmtpBadMailDirectory

指定文件系统上存储死信(包含在 BadMail 文件夹中的电子邮件)的位置。

msExchSmtpSendBadmailTo

指定死信将发送到的地址。

msExchSmtpFullyQualifiedDomainName

为该 SMTP 虚拟服务器指定完全限定的域名 (FQDN)。

msExchSmtpPickupDirectory

指定从中获取邮件的目录。

msExchSmtpQueueDirectory

指定邮件在其中排队的目录。

msExchSmtpRemoteQueueRetries

为远程邮件传递指定第一次、第二次、第三次和后续重试。

msExchSmtpRelayIpList

为中继限制指定 IP 地址列表。

msExchBridgeheadedLocalConnectorsDNBL

指定SMTP 虚拟服务器路由组中的连接器列表,该 SMTP 虚拟服务器充当这些连接器的本地桥头。

msExchBridgeheadedRemoteConnectorsDNBL

指定远程路由组中的连接器列表,该 SMTP 虚拟服务器充当这些连接器的远程桥头。

note注意:
元数据库更新服务将所有这些配置设置都复制到 IIS 元数据库中。

元数据库中的 SMTP 配置设置

IIS 元数据库是配置信息和架构信息存储,具有层次结构,用于配置 IIS 资源。IIS 4.0 和 IIS 5.0 的元数据库配置和架构存储在二进制文件 (MetaBase.bin) 中,该文件不易于阅读或编辑。必须使用 MetaEdit 工具才能够查看和编辑 IIS 4.0 和 IIS 5.0 的元数据库。可以从 https://go.microsoft.com/fwlink/?LinkId=47942 中下载 MetaEdit 2.2。

在 IIS 6.0 中,早期的二进制文件被可扩展标记语言 (XML) 格式文件(名为 MetaBase.xml 和 MBSchema.xml)所取代。IIS 配置信息存储在 MetaBase.xml 文件中,而元数据库架构则存储在 MBSchema.xml 文件中。当 IIS 启动时,这些文件被元数据库存储层读取,然后通过管理基本对象 (ABO) 写入到内存中的元数据库中,如下图所示。

6584201d-0104-4f3a-ba55-5103964c2762

SMTP 配置项

本地 Administrators 组的成员可以查看并修改 MetaBase.xml 文件,这些文件是位于 \Windows\System32\Inetsrv 文件夹中的纯文本文件。应用于 SMTP 服务及其 SMTP 虚拟服务器的元数据库条目以 IisSmtp 开头。

配置条目中的 Location 属性指定配置对象的层次结构。例如,在 Location ="/LM/SmtpSvc/1" 中,LM 代表本地计算机,SmtpSvc 代表总的 SMTP 服务,而数字 (1) 代表默认 SMTP 虚拟服务器。枚举数“1”对应默认 SMTP 虚拟服务器对象在 Active Directory 中的 CN 属性。

下图根据每个 IIsSmtp 元数据库条目的 Location 属性,显示了 SMTP 虚拟服务器配置条目的层次结构。

cdea405a-905c-4da1-bc76-d6101615e059

应用于 SMTP 服务的参数通常在元数据库的 SmtpSvc 节点中进行注册。当搜索 Location ="/LM/SmtpSvc" 时,可以找到该节点。以下部分是该项的简化列表:

<IIsSmtpService Location ="/LM/SmtpSvc"

    ConnectionTimeout="600"

    DefaultDomain="server01.TailspinToys.com"

    DomainRouting=""

    EnableReverseDnsLookup="FALSE"

    FullyQualifiedDomainName="server01.TailspinToys.com"

    ...

    SmtpRemoteProgressiveRetry="15,30,60,240"

    SmtpRemoteRetryThreshold="3"

    >

    <Custom

        Name="AuthFlags"

        ID="6000"

        Value="AuthBasic | AuthAnonymous | AuthNTLM"

        Type="DWORD"

        UserType="IIS_MD_UT_SERVER"

        Attributes="INHERIT"

    />

    ...

    <Custom

        Name="UnknownName_61537"

        ID="61537"

        Value="0"

        Type="DWORD"

        UserType="IIS_MD_UT_SERVER"

        Attributes="NO_ATTRIBUTES"

    />

</IIsSmtpService>

在 SmtpSvc 节点下,您会找到在运行 Exchange Server 2003 的服务器上创建的每个 SMTP 虚拟服务器的配置设置。SMTP 虚拟服务器继承为 SMTP 服务配置的常规设置,并且可以覆盖这些设置。下面是默认 SMTP 虚拟服务器的配置部分的示意性列表。请注意 Location 信息。

<IIsSmtpServer Location ="/LM/SmtpSvc/1"

    ... property definitions that apply only to the

      particular virtual server ...

    >

    <Custom

        ... custom property defintion...

    />

</IIsSmtpServer>

note注意:
当比较 SMTP 虚拟服务器在 IIS 元数据库中的参数名称与 SMTP 虚拟服务器在 Active Directory 中的属性时,您会找到相近的匹配。例如,元数据库参数 PickupDirectory 对应 Active Directory 属性 msExchSmtpPickupDirectory。

直接编辑元数据库

由于 MetaBase.xml 是一个文本文件,因此 Administrators 组的成员可以使用常用的文本工具(如记事本)直接编辑元数据库。但是,当 IIS 运行时,该文件保持打开和锁定状态。要支持直接编辑,必须在 IIS 管理器中启用“允许直接编辑配置数据库”功能。有关如何启用对 IIS 元数据库的直接编辑的详细说明,请参阅如何在 IIS 管理器中启用“启用直接元数据库编辑”功能

本地域注册

在元数据库中的每个 SMTP 虚拟服务器节点下,可以找到重要的子节点,如 Domain (Location ="/LM/SmtpSvc/1/Domain") 节点和 EventManager (Location ="/LM/SmtpSvc/1/EventManager") 节点。域节点包含域定义,域定义决定了 SMTP 虚拟服务器应执行的路由操作。例如,根据收件人策略的规定,SMTP 服务必须接受发送到所有本地 SMTP 域的邮件,但可能必须拒绝任何将邮件中继到非本地域的尝试。元数据库更新服务将所有 SMTP 虚拟服务器的收件人策略中的域信息复制到 IIS 元数据库中。

note注意:
域定义还包含指向 Active Directory 站点的条目。域名 705260ab-46c4-454d-bfdd-96b9c605364c._msdcs.fabrikam.com 就是一个这样的示例。这些条目的路由操作导致 SMTP 虚拟服务器将邮件放入 \Drop 目录中,这样 Active Directory 便可以从中检索邮件。为避免出现目录复制问题,请不要更改或删除这些域条目。Active Directory 使用 SMTP 服务在站点之间复制目录更改。

事件接收器注册

EventManager 节点下面的条目是事件注册。要使 SMTP 服务能够使用事件接收器,事件接收器必须在 IIS 元数据库中注册,这样,SMTP 服务才能够创建这些接收器,并在相关事件发生时运行这些接收器。IIsConfigObjects 在 IIS 元数据库中定义事件绑定。例如:

<IIsConfigObject    Location ="/LM/SmtpSvc/1/EventManager/

EventTypes/{283430C9-1850-11D2-9E03-00C04FA322BA}/

Bindings/{A928AD15-1610-11D2-9E02-00C04FA322BA}/

SinkClass"

>

<Custom

Name="MD_0"

ID="0"

Value="Exchange.Router"

Type="STRING"

UserType="UNKNOWN_UserType"

Attributes="NO_ATTRIBUTES"

/>

</IIsConfigObject>

这种绑定将特定事件的 GUID(如 283430C9-1850-11D2-9E03-00C04FA322BA)与事件接收器(如 Exchange Router 接收器)关联。绑定信息 {A928AD15-1610-11D2-9E02-00C04FA322BA} 中的第二个 GUID 条目是该特定事件绑定条目的标识符 (ID)。事件绑定 ID 在元数据库中必须是唯一的,但是就像本节前面的图 6.4 中所显示的那样,特定的事件可以有多个关联的事件接收器。

事件绑定参数是在元数据库层次结构中的每个事件接收器节点下定义的。当前的列表定义 SinkClass 值,该值在 SMTP 传输 OnGetMessageRouter 事件与 Exchange.Router 接收器类之间创建关联关系。还有更多的绑定条目,这些条目可用于为 Exchange Router 等事件接收器定义显示名称,以及定义事件接收器优先级等其他参数。下表列出了可以指定的事件绑定参数。

事件绑定信息

属性描述 属性描述

ID

唯一标识绑定的 GUID。此信息是必需的。

DisplayName

绑定的用户友好名(可选)。

SinkClass

事件接收器类的程序标识符 (ProgID)。

启用

指示绑定当前是否启用的标志。如果未指定该标志,将启用事件接收器。此参数是可选的。

MaxFirings

禁用绑定之前,接收器可以接收的事件通知数。此参数是可选的。

EventBindingProperties

为整个绑定定义的其他属性字典(或哈希)。此参数是可选的。

SinkProperties

接收器属性保留用于特定的接收器实现。当接收器得到事件通知时,事件发送器将接收器属性集合传递给事件接收器。例如,用于将放弃声明添加到邮件中的事件接收器,此事件接收器可能通过接收器属性来接收放弃声明文本。

SourceProperties

源属性是由特定的事件发送器实现来定义的。例如,入站和出站协议事件发送器使用 Rule 和 Priority 属性来确定接收器何时得到事件通知。除 OnTransportSubmission 事件以外的大多数传输事件接收器都不使用 Rule 源属性。所有协议事件和传输事件都支持 Priority 源属性的使用。

下列源属性用于协议事件和传输事件的事件绑定:

  • Rule 标识接收器绑定的协议筛选器的字符串。发送器将规则用作决定是否通知接收器的条件或条件集合。这些规则是 SMTP 协议命令规则,如 EHLO。规则可能包含条件,如 EHLO=*.contoso.com。多个规则用分号分隔。
  • Priority 接收器的通知优先级(相对于已注册接收事件通知的其他接收器)。值从 0(最高)到 32767(最低)。此属性是可选的。默认优先级为 24575。优先级相同的接收器的运行顺序不定。

服务器扩展对象

事件绑定中的 GUID 确保在事件类型与事件接收器之间建立唯一的关联,但是这些标识符可能会令人产生疑问,因为它们在逻辑上并不是显而易见的。例如,若要了解什么事件对应上表中列出的事件接收器,必须在注册表中的 HKEY_CLASSES_ROOT\Component Categories 下搜索 GUID 283430C9-1850-11D2-9E03-00C04FA322BA。之后才能查明该 GUID 标识 SMTP Transport OnGetMessageRouter 事件类型。本绑定定义示例中的第二个 GUID A928AD15-1610-11D2-9E02-00C04FA322BA 是 Exchange Router 类(在 Reapi.dll 中实现)的 CLSID。该 COM 组件的注册表项为 HKEY_CLASSES_ROOT\CLSID\{A928AD15-1610-11d2-9E02-00C04FA322BA}}。但是,该 CLSID 仅用于在元数据库中为事件绑定创建唯一的 ID。问题在于SinkClass 值,此值定义事件类型与事件接收器类之间的关联。

幸运的是,并非必须使用 GUID 才能管理事件接收器绑定。您可以改用 Seo.dll 中实现的服务器扩展对象。Microsoft 已开发了一个脚本,该脚本证明了可以使用服务器扩展对象来管理 SMTP 服务的事件绑定。该脚本名为 SMTPReg.vbs,您可以在 smtpreg.vbs Event Management Script(英文)中找到它。例如,通过将 SMTPReg.vbs 与下列命令结合起来使用,可以将 IIS 元数据库中的所有 SMTP 事件绑定写入到名为 Event_Bindings.txt 的文件中:cscript smtpreg.vbs /enum > Event_Bindings.txt.下面的列表显示的是 Exchange Router 绑定条目的输出:

    ---------

    | Binding |

    ---------

        Event: SMTP Transport OnGetMessageRouter

        ID: {A928AD15-1610-11D2-9E02-00C04FA322BA}

        Name: Exchange Router

        SinkClass: Exchange.Router

        Enabled: True

        SourceProperties: {

            priority = 8192

        }