了解和替换 Microsoft Exchange

作者:Tom Adelstein

Linux 本身为主机提供了一套强大的互联网应用程序,而主机一直需要这些程序。IBM 的 eServer 战略似乎并不完整,因为它缺少一套强大的互联网工具,而 IBM 承诺为其所有品牌提供这些工具。在 2000 年年底,IBM 证明它可以在一台 S/390 主机上托管数千个 Linux 实例。

Understanding and Replacing Microsoft Exchange

图 1. 一台主机支持数千个 Linux 实例。

即便如此,IBM 意识到 Web 服务器和 GNU 应用程序并没有提供完整的价值主张。IBM 需要一个应用程序,使 Linux 成为一个能够更深入主流计算领域的主机。因此,他们向我们发出了邀请。

2001 年 4 月,当 IBM zSeries(S/390 的新名称)的销售经理拜访我们公司 Bynari, Inc. 时,我并不理解他的兴趣。在他访问之后,我完全明白了。Bynari, Inc. 成为 IBM 的第一个 Linux 影响力合作伙伴。

电子邮件,“杀手级应用”

最初,人们知道我们是因为我们使 Linux 和 UNIX 客户端能够与 Microsoft Exchange 服务器对话。为了扩大我们的市场,我找到了 Johnson 和 Mead 撰写的“Exchange 替换操作指南”(www.bynari.net/whitepapers_howto.html)。以他们的工作为指导,我们为我们的 Linux 客户端和 Microsoft Outlook 构建了一个服务器。我们的服务器及其 Outlook 配置指南受到了经销商渠道的欢迎。

当我们把我们的服务器代码移植到运行在 S/390 Multiprise 3000 上的 Linux 实例时,我们不认识 IBM 的任何人。当时在 Equant 工作的 Jimmy Lee 提供了资源,以验证我们是否能做到这一点。Equant 的 Gary Ernst 配置了 Linux 的 S/390 实例,并在使我们的服务器工作方面提供了帮助。

只要 Microsoft Outlook 具有仅限 Internet 邮件模式并提供对等文件夹共享,我们就有一个产品,允许 UNIX 和 Outlook 客户端安排会议和委派日历任务。我们的服务器扩展性很好,我们模仿了 Exchange 全局地址列表 (GAL),同时提供了用户空闲/忙碌时间的视图和一个像样的管理界面。

但是后来 Microsoft 发布了 Office XP,并在 Outlook 中做了重大更改。突然,我们的产品需要服务器端日历功能。我们担心 IBM 企业客户对 Outlook 低成本服务器解决方案日益增长的需求可能会减弱。因此,我们需要 Outlook 仅限 Internet 邮件模式下的对等日历共享,或者我们需要服务器端的东西。

创建解决方案的 45 天

随着 2001 年 1 月的 LinuxWorld 会议暨展览会的临近,IBM 继续营销我们的服务器,但对 Outlook XP 用户的需求有些视而不见。我知道我们必须做些什么,而且要快,否则就会失去 IBM 的信任。当时,最了解市场问题的人是 Mainline Information Systems 的 Roger Luca。

幸运的是,Roger 和我建立了良好的工作关系。在 Roger 担任销售和营销主管的情况下,Mainline 成为 IBM 大型机的最大经销商。他们也是我们在 IBM 之外的最大支持者。Roger 为我们提供了硬件资源,以帮助我们将服务器端日历功能构建到我们的产品中,并提供了人员来支持我们,以防我们遇到与硬件相关的问题。

让开发团队感到惊讶

想象一下,你完成了一整年的详尽开发。你安排了假期和其他计划的旅行。然后你的手机响了;你的老板让你参加一个重要的会议。这就是我们店里发生的事情。当我接听开发人员的电话时,我能听到他们声音中的恐惧。

我们在 2001 年 11 月 7 日会面,看看我们是否能在圣诞节前交付服务器端日历解决方案。Mainline 有几笔销售正在等待,他们需要这个功能。我的两个人同意和我一起工作以获得解决方案。

不适合胆小者的技术挑战

作为高级开发人员,我提供了项目框架。理论上,一个项目有各种各样的阶段和流程。为了缩短项目的生命周期,我制定了一个分为三个步骤的方法,即研究、发明和执行。我为每个阶段设定了一个里程碑。因此,我们没有从代码开始,而是开始浏览互联网和我们能找到的任何书籍。

经过一周的密集研究,我们发现了我们的挑战。我们必须弄清楚 Microsoft 的 DCE-RFC 协议是如何存储和移动日历事件的。我们必须解释存储的数据,提供一种我们可以存储在 IMAP 服务器上的格式,然后将数据以其熟悉的模式转发给 Outlook 客户端。我们还必须提供对这些信息存储的访问控制,以允许用户任命和委派对其日历的控制权给具有不同权限级别的其他用户。

我们又花了一个紧张的星期进行研究,并达成了一个共识。每一位专家、新闻组、Outlook 专家和尝试过的公司都说,不可能在 IMAP 服务器上创建 Microsoft Outlook 日历存储。以下是我们是如何做到的。

忘记传输,专注于数据

首先,我们观察到 Outlook 在 Microsoft Exchange 模型中完成了大约 95% 的工作。Exchange,顾名思义,是在 Outlook 用户之间或之中传输数据。即便如此,Exchange 控制了传输协议,这带来了问题。人们使用术语 MAPI 来描述 Exchange 协议,用于在 Outlook 用户之间传输数据。我不认为 MAPI 是合适的术语。

当拦截 Outlook 消息时,我们发现的是大量的二进制数据,而不是文本。我认出了这些数据,但不记得以前在哪里见过它。

Outlook 的不同面孔

Outlook 在两种不同的模式下运行:企业工作组模式和仅限 Internet 邮件模式。在企业工作组模式下,Microsoft 开启了 Outlook 的所有备受推崇的功能。在仅限 Internet 邮件模式下,Microsoft 使用完全不同且未公开的应用程序编程接口 (API),其功能集有限。如果没有 Exchange 服务器,Outlook 根本无法在企业工作组模式下运行,并且功能集有限。

在 Outlook 的工作组模式下,或者当连接到 Exchange 服务器时,其数据以二进制形式移动。这种二进制数据对于不知情的观察者来说变得无法识别。

在研究过程中,我在 SourceForge.net 上找到了一个开发人员站点,该站点正在将 Open DCE 移植到 Linux。我给其中一位开发人员发了电子邮件,他回信说 Open Group 贡献了代码。

我去了 Open Group 的网站,搜索了档案,找到一篇旧文章,提到 Microsoft 获得了 DCE 的许可。我们下载了 Open DCE 代码,并使用该引擎与 Outlook 和 Exchange 握手。因此,我们对传输协议有了更多的了解。我们也理解了二进制数据流的存在。

我们发现的是,当在企业工作组模式下使用 Exchange 和 Outlook 时,Microsoft 使用分布式计算环境 (DCE) 作为其传输。Microsoft 在 DCE 之上提供了一个编程接口,它称之为 MAPI。尽管如此,在 MAPI 之下存在一个基于开放标准的协议 (DCE),Microsoft 从 Open Group 购买并修改了该协议。

DCE 中的一个默认功能自动将 ASCII 文本转换为二进制对象。Microsoft 将二进制对象保持未公开状态。因此,大多数 MAPI 属性程序员标记最终都变成了他们无法识别的二进制代码。为了使事情变得更复杂一点,Microsoft 将二进制属性代码嵌入到大量的空二进制数据中,从而隐藏了它。

我们开始理解传输,但我们意识到 Outlook 向其他 Outlook 客户端发送 MIME 附件。这些附件并没有转换成二进制数据。我们得出结论,Outlook 也使用封装来传递附件,这引导我们找到了 TNEF 对象。

TNEF

Microsoft Exchange 使用许多它称之为“服务提供商”的程序,Linux 用户可能会称之为守护进程。Exchange 服务提供商处理对象,这些对象具有状态和行为。

传输中性封装格式 (TNEF) 是一种传递 ASCII 文本、其他文件和对象以及二进制消息数据的方法。二进制消息数据构成了每个 TNEF 对象的大部分。TNEF 将 MAPI 属性封装成一个二进制流,该二进制流随消息通过传输和网关。Outlook 可以解码封装以检索原始消息的所有属性。TNEF 对象隐藏在 MIME 中作为附件。

当我们找到创建日历事件的属性时,我们构建了一个 TNEF 编码器,并很快开始使用 SMTP 与 Outlook 客户端之间发送和接收日历事件。我们立即认识到,我们可以使用互联网传输协议并开启 Microsoft 的企业工作组模式,而无需 MAPI。当我们看到 Microsoft 知识库文章 Q197204 时,我们知道我们已经成功了,该文章说 Microsoft 不支持我们在工作组模式下的传输协议。

Exchange 客户端扩展

我们的主要目标是服务器端日历功能,我们需要创建一个消息存储来保存我们的 Outlook 客户端对象。由于我们使用了 IMAP 服务器,我们需要 IMAP 支持,而 Microsoft 在工作组模式下不提供 IMAP 支持。因此,我们必须找到一种方法将 IMAP 客户端支持添加到 Outlook。为现有 Outlook 客户端添加功能的推动者涉及到大多数人认为的插件。

当 Microsoft 首次发布 Exchange 时,Outlook 并不存在。相反,Microsoft 为其不同的 Windows 操作系统提供了一套 Exchange 消息客户端。Microsoft 还为其 Exchange 消息客户端提供了可扩展的架构。客户端扩展为开发人员提供了一种更改 Exchange 客户端默认行为的方法。当 Microsoft 发布 Outlook 时,它继续为 Exchange 客户端扩展架构提供支持,以兼容现有的客户端扩展 DLL。

客户端扩展允许人们更改客户端的默认行为。Microsoft 认为扩展的优势在于,它可以方便地将自定义功能和新行为直接集成到客户端中,而无需编写单独的 MAPI 应用程序。然而,我们将扩展视为在工作组模式下为 Outlook 添加 IMAP 客户端服务的一种方式。使用这种架构,我们在 Outlook 菜单中添加了命令,在工具栏中添加了自定义按钮,以及使用 IMAP 客户端服务预处理传出和传入消息的能力。

幸运的是,我们在前一年构建 Linux 客户端时已经编写了 IMAP 的客户端库。我们只需要将它们移植到 Windows。我们对函数调用、标头和协议的熟悉程度降低了我们的总体工作量。

一旦我们为客户端函数构建了 Microsoft DLL,我们就将其作为 Outlook 扩展添加进去。幸运的是,我们第一次尝试就成功了。通过为邮件和会议邀请选择富文本格式 (RTF),我们的 TNEF 对象将自己附加到消息中。由于 Outlook 创建了 TNEF 对象,因此它可以毫无问题地交换它们。

在这一点上,我们使用 Microsoft .pst 文件作为存储和交换空间,将我们的消息上传到我们的 IMAP 文件夹。在保持与 Exchange 连接并使用我们的服务器进行消息存储的情况下,我们注意到了两个系统之间的兼容性。我们将对象从 Exchange 文件夹拖放到我们的 IMAP 文件夹中。通过这样做,我们发现任务、日记条目、日历事件等等,都像从 Exchange 到达一样显示在 Outlook 中。日历也完美地工作。

Exchange

当你查看 Exchange 并研究其组件时,你会发现它们只有四个。第一个是信息存储或消息存储。存储保存单个用户消息,并具有与其关联的访问控制列表 (ACL) 引擎。与符合 RFC 的 IMAP 服务器类似,命名空间根据存储是属于单个用户还是文件夹是公共文件夹而有所不同。Microsoft 使用 Access 数据库来存储消息存储。Microsoft 的 Jet Engine 技术和 Access MDB 文件的局限性阻止了垂直可扩展性。

其次,Exchange 有一个目录。Microsoft 使用对象类和属性构建了他们的 Exchange 目录。Exchange 目录结构类似于符合 RFC 的 LDAP 协议。然而,Microsoft 添加了对象类,并更改了这些类和其他类中的属性名称。

接下来,Exchange 有一个邮件传输代理或 MTA。Microsoft 的 MTA 看起来类似于早期产品 Microsoft Mail 3.5 中使用的 MTA。Microsoft Mail MTA 需要连接器或网关,它们将其专有的邮件头重写为符合外部系统(如 Lotus Notes、X-400 和 RFC 822 互联网邮件标准)的邮件头。与 sendmail 和类似的互联网 MTA 不同,Exchange 的 MTA 缺少配置选项。

最后,Exchange 有一个名为系统助理的组件。助理处理 Exchange 中采取的每一个操作,从发送和接收电子邮件到填写来自 Exchange 目录的地址请求。在许多方面,系统助理类似于尝试提供进程间通信 (IPC),而 Microsoft 的操作系统缺乏 IPC。

使用 Berkeley DB 超越 Microsoft

我们的 Linux 服务器端解决方案包括类似于 Exchange 中发现的组件。第一个是 Cyrus IMAP 消息存储。Cyrus 存储保存单个用户消息,并具有与其关联的 ACL 引擎。命名空间根据存储是属于单个用户还是文件夹是公共文件夹而有所不同。Cyrus 使用 Sleepycat Software 的 Berkeley Database。Microsoft 的 Jet Engine 和 Access 数据库技术阻止了扩展,而 Berkeley DB 的高性能和可扩展性支持数千个同时用户处理高达 256 TB 的数据库。

其次,Linux 有一个目录。虽然 Microsoft 构建了他们的 Exchange 目录以类似于轻型目录访问协议 (LDAP),但 Linux 解决方案使用了 OpenLDAP 软件,这是 LDAP 的开源实现。为了适应 Outlook 客户端,我们添加了 Exchange 对象类及其不兼容的属性名称。我们索引了基于 Microsoft 的专有名称,并创建了一个高性能的全局地址列表。

与 Exchange 一样,Linux 解决方案也有一个 MTA,可以内部管理和配置,而不需要外部连接器。剑桥大学开发了我们使用的 Linux MTA,称为 Exim。Exim 有许多配置选项,包括文件查找、本地传递和正则表达式支持。在 Linux MTA 的上下文中,用户提供正则表达式来过滤传入和传出的内容。

替换 Exchange

在“Exchange 替换操作指南”中,Johnson 和 Mead 将添加服务器端消息传递和管理控制台的任务留给了下一代 Linux 开发人员。在本文中,我们解释了如何转换 Exchange 传输和消息存储。我们通过两个步骤完成此操作。首先,我们捕获 Outlook 消息并解码其 TNEF 对象。其次,我们使用 Exchange 客户端扩展架构在企业工作组模式下为 Outlook 添加 IMAP 功能。

这两个步骤可以允许程序员或经验丰富的管理员为 Outlook 创建替代服务提供商,并为许多传统的邮件客户端提供服务。Linux 邮件服务器不会根据用户使用的平台进行区分。人们可以使用 Netscape Mail、Outlook Express、Ximian Evolution、mutt 或 Pine 等等 MUA。

高度可扩展的 Linux 组件,如 Cyrus IMAP、OpenLDAP 和 Exim,可以在单个 Intel 平台上替换数十台 Exchange 服务器。Exchange 使用的接口层和过时的 DCE 组件不会阻碍 Linux。借助 zSeries 大型机上的 Linux,我们可以替换数百台 Exchange 服务器。

如果您正在寻找图形管理控制台,PHP Cyrus tools、cyrus_imap-sql、Webmin 和 Replex 等项目可以使服务器的管理变得简单。

总的来说,很少有人会认为用 Linux 替换 Exchange 是一件容易的任务。尽管如此,我们的开发团队证明了这是可以做到的。希望我们已经消除了 Exchange 服务器的大部分神秘感和恐吓感。

资源

Understanding and Replacing Microsoft Exchange
电子邮件: adelste@netscape.net

Tom Adelstein 在 Xandros, Inc. 工作,并领导该公司在德克萨斯州达拉斯的服务器部门。他目前的兴趣在于 Web 服务和支持 Xandros Linux Desktop 领域。Tom 欢迎您在 tadelstein@xandros.com 发表评论。

加载 Disqus 评论