AlphaMail 是可扩展且易于访问的 Web 邮件

作者:Tony Kay

AlphaMail 是俄勒冈大学创建的高性能、功能丰富的开源 Web 邮件系统。该界面包括索引中的消息片段、UTF8 组合以及用于附件的众多查看器(例如图像图标预览和来自 tarball 的文件列表)。它还试图在理想的功能和过多的界面噪音之间取得平衡。它的创建是为了解决其他开源和商业 Web 邮件系统存在的一些问题。

性能

AlphaMail 解决的首要问题是性能。几乎所有 Web 邮件系统(例如 Horde 的 IMP Web 邮件客户端和 SquirrelMail)都从 Web 服务器内部使用 IMAP,这无法持久化 IMAP 会话。

IMAP 协议旨在优化通过持久访问的访问,因此这是一个固有的且公认的问题。这个问题通常通过维护持久连接的 IMAP 代理来缓解。此解决方案的问题是多方面的。

一个问题是 Web 邮件客户端本身的代码不能依赖 IMAP 连接的状态,并且必须重复命令,就好像每次鼠标单击都是一个新的 IMAP 会话一样。这是一个问题,因为 IMAP 协议中新会话所需的事件序列包括身份验证和选择所需的文件夹。几个 IMAP 服务器的基准测试表明,即使文件夹已经过身份验证和选择(即通过代理),重复文件夹选择命令也可能导致显着的额外服务器负载。

这些低效率可以通过改进 IMAP 服务器和代理算法来解决,但另一个问题是棘手的:代理无法改进协议。Web 邮件客户端正在使用 IMAP 这一事实迫使其表现得像一个完整的独立客户端。如果开发人员想要添加复杂的功能,例如会话视图(类似于 Google 邮件),这需要在多个文件夹中进行复杂的消息交叉引用,那么协议本身就成为主要的障碍。

AlphaMail 通过包含一个中间件层来解决这些问题,该中间件层为 Web 应用程序使用简化且可扩展的协议,并负责优化对邮件服务器的访问。该协议支持高度专业的命令,允许 Web 代码直接请求页面所需的信息,而无需对 IMAP 连接的状态做任何假设。

这还有一个额外的优点,即中间件层中的 IMAP 协议处理可以用高性能语言(在本例中为 C++)编写,可以缓存结果并优化交互。中间件程序被称为 imap_webcache,因为它缓存了邮件交互的数据和网络连接。

可访问性

下一个关注点是可访问性。高等教育、政府和许多其他环境中的信息系统必须支持每个人的访问。AlphaMail 仍在积极调整以方便残疾人访问,但它已经针对其他访问问题进行了优化。例如,站点安全策略可能要求或建议社区成员禁用经常出现在 US-CERT 咨询中的浏览器功能,例如 JavaScript。我能找到的唯一不需要 JavaScript 甚至基本功能的 Web 电子邮件是 SquirrelMail,但从性能角度来看,它被认为风险太高。

AlphaMail 包括 JavaScript 增强功能,但这些增强功能具有传统的 CGI 替代方案,如果浏览器上禁用 JavaScript,这些替代方案将变为活动状态。系统的所有关键功能都可以在任何浏览器上运行,而与功能和设置无关。

安装

AlphaMail 支持 GNU autoconf,并且已在许多 Linux 变体、FreeBSD、Solaris 和 Darwin (OS X) 上干净地构建。最容易安装的平台是通过 yum(1) 的 Fedora Core 5,如 AlphaMail 主页上所述。

我强烈建议在测试机器上使用 Fedora Core 5,以避免在初始试运行时解决依赖项的麻烦。实际构建与您期望的几乎一样,但解决运行时依赖项可能具有挑战性。

如果您决定从源代码构建,首先您需要安装 Boost C++ 库(请参阅资源)。

安装 Boost

您需要 Boost Jam 实用程序(通常命名为 bjam)以及版本 1.33 或更高版本的 Boost C++ 库。Jam 有点像 GNU autoconf 和 make 的组合。按照 Boost 网站上的说明了解详细信息,但本质上,解压文件并运行

# bjam install

在极少数情况下,您可能想要传递选项(例如安装前缀)。如果您有特殊需要,请参阅 Boost 网站上的入门指南。

从源代码构建 AlphaMail

构建非常符合您的期望

# ./configure
# make
# make install

configure 脚本检查您的系统是否存在依赖项,并告诉您缺少或过时的内容。只要您安装了 Boost,即使 Perl 依赖项未满足,您也应该能够完成所有三个步骤。

请注意,某些版本的 g++ 存在一个错误,会导致编译器在构建 imap_webcache 时进入无限循环。源代码中的两个文件(IMAPFolder_rules.cc 和 RFC2822.cc)可能会触发此错误,但即使使用好的编译器,这些文件也需要大量时间和空间来构建,因此预计编译会运行几分钟。

在某些系统上,文件位置可能会出现问题。例如,在 Red Hat Enterprise Linux 系统上,Kerberos 依赖项会导致 OpenSSL 代码编译失败,这可以通过传递 CXXFLAGS 的值来纠正

# CXXFLAGS="-I/usr/kerberos/include" ./configure

与任何其他 GNU autoconf 系统一样,如果配置脚本未能完成,请检查 config.log。

安装运行时依赖项

在大多数发行版上,最大的困难不是构建 AlphaMail,而是满足所有先决条件。许多发行版都带有旧版本的 mod_perl、libapreq 和其他 Perl 模块。

在处理其他 Perl 依赖项之前,请确保您已安装 libapreq2 和 mod_perl >= 2.0,因为其中一些依赖于其中一个或两个。完成此操作后,您应该能够使用您的软件包管理器或 cpan(1) 安装剩余的 Perl 依赖项。

如果模块的打包版本不存在或太旧,则需要使用 cpan(1)。请参阅侧边栏,了解如何避免在使用 cpan(1) 时与发行版的软件包管理器发生打包冲突。

使用 cpan(1) 时避免软件包管理冲突

许多 Linux 管理员不喜欢使用 cpan(1),因为 cpan 实用程序安装的文件与发行版的软件包管理器安装的文件之间存在竞争。因此,在生产系统中,最好将 Perl 模块安装在软件包管理器看不到的地方。

AlphaMail 在 /usr/local/lib/alphamail 中查找自己的库(如果您在构建期间选择了默认前缀),您可以在那里安装 Perl 依赖项,而无需更改系统的运行时配置。

首先,设置您的环境以指示您希望 Perl 在其他位置查找(这仅在构建期间需要,运行时系统在启动期间已包含此路径)

# export PERL5LIB=/usr/local/lib/alphamail

如果您在配置期间使用备用前缀,请更改此处的 /usr/local 部分以匹配。

接下来,运行 cpan(1) 并(重新)配置它

# cpan
cpan> o conf makepl_arg 
 ↪'PREFIX=/tmp/unneeded LIB=/usr/local/lib/alphamail'

PREFIX 参数告诉构建过程通用安装前缀是什么;而 LIB 告诉它在哪里安装实际的模块代码。我使用 /tmp/unneeded 作为 PREFIX,并在之后删除文件,因为 AlphaMail 只需要库。如果您需要手册页或这些模块附带的其他额外内容,请将 PREFIX 设置为类似 /usr/local 的内容。

如果您想保存 cpan 设置以供将来会话使用,请执行

cpan> o conf commit

现在,安装或升级必要的 Perl 模块(在您运行配置时列出)

cpan> install Time::HiRes
...

如果您想在您自己的脚本中使用这些模块(或需要更改 AlphaMail 脚本查找它们的位置),请在文件顶部附近添加以下行

use lib qw(/usr/local/lib/alphamail);
配置

构建指示您使用 alphamail_genconfig 实用程序创建模板配置文件。此脚本提示您输入基本安装所需的所有配置选项,并在您提供的位置创建必要的文件。

您需要一个特殊的沙箱用户,并了解您的 Web 服务器作为哪个用户运行,然后才能开始配置。我建议为前者创建一个名为 sandbox 的用户。不应启用此用户的登录。

配置将询问安装前缀,即您传递给 configure 的任何内容。这通常是 /usr/local,脚本将在继续之前验证正确性。

系统会要求您为要使用 AlphaMail 访问的每个 IMAP 服务器提供 IMAP 前缀和分隔符。一些 IMAP 服务器使用斜杠 (/) 作为分隔符;其他服务器使用点 (.)。前缀是用户放置所有其他邮件文件夹的子文件夹。例如,如果用户具有 shell 访问权限,并且他们的邮件文件夹存储在他们的主目录中,那么策略可能是将所有邮件文件夹放在名为 mail 的目录中,在这种情况下,前缀可能是 mail。

重要的是要注意,某些 Web 服务器(例如 Cyrus)使用 INBOX 作为前缀,点 (.) 作为分隔符。以下过程可以帮助您确定要使用什么。首先,从命令行连接到 IMAP 服务器,使用

# openssl s_client -connect imap.example.com:993 # For SSL

# telnet imap.example.com 143  # for no SSL

这些命令将您连接到 IMAP 服务器,并允许您输入协议命令。键入以下内容(数字是命令的一部分)

1 login username password
2 list "" "%"
3 logout

当然,用户名和密码应该是典型 IMAP 帐户的真实用户凭据。第二个命令的响应应如下所示

* LIST (\HasNoChildren) "." "INBOX.Spam"
* LIST (\HasNoChildren) "." "INBOX.Trash"

这表明 . 是分隔符,并且很明显 INBOX 是一个常见的前缀(在本例中,所有条目都以 INBOX. 开头)。

前缀参数主要是一个界面优化:界面在显示大多数文件夹名称时删除前缀,以使内容更紧凑。您可以在生成的 alphamail_config 文件中手动编辑任何参数,这是一个带有注释的文本文件。用于定义一对服务于两个邮件交换的典型 IMAP 服务器的条目如下所示

imap_servers: example.com=imap.example.com:993[INBOX.], 
↪example.net=imap.example.net:143[/]

上面的设置表明用户应该能够在登录时选择他们的邮件域(example.com 或 example.net),并将这些域与相应的 IMAP 服务器、端口、前缀和 IMAP 路径分隔符关联起来。

括号中的分隔符始终是必需的,但前缀不是。符号 [//] 表示没有前缀,斜杠作为分隔符。如果您使用除 SSL 备用端口 993 之外的任何端口,则 IMAP 连接将是不安全的。

附件查看器和其他外部程序在沙箱中运行,该沙箱使用 chroot jail、用户 ID 保护和其他文件系统限制,以确保查看器中的错误不会危害超出用户尝试查看的文件的任何内容,根据定义,这将是包含漏洞利用的文件。这就是您将使用之前创建的额外用户的地方。

沙箱实用程序默认安装在 /usr/local/libexec/sandbox 中,并且是一个 setuid 程序。重要的是,此可执行文件的权限允许 Web 服务器执行,但允许任何其他用户访问该实用程序是一种安全隐患。我建议 AlphaMail 在仅服务于 Web 邮件且不提供其他任何内容的独立系统上运行,且用户没有 shell 访问权限。

配置还会要求您配置大型文件共享系统。此选项允许用户将文件上传到 AlphaMail 系统,以便其他人稍后下载。当有人需要发送大于电子邮件消息允许或推荐的文件时,大型文件共享非常有用。文件共享具有多项安全措施来防止滥用,包括使用条款协议、大小限制、密码保护、加密、下载限制和基于时间的过期。在文件共享中为大小限制选择零大小将禁用该功能。

最后一步是编辑 Apache 配置。确保 mod_perl2 和 libapreq2 与指令一起加载,例如

LoadModule apreq_module modules/mod_apreq2.so
LoadModule perl_module modules/mod_perl.so

并包含生成的 alphamail.conf Apache 配置文件。例如

Include /usr/local/etc/alphamail/apache/alphamail.conf
运行 AlphaMail

Apache 和 imap_webcache 必须运行 AlphaMail 才能工作。启动顺序无关紧要。包含 Web 缓存的示例 Red Hat init 脚本,将安装在 /usr/local/share/alphamail/util/init.d 中。

必须定期从 cron 运行垃圾回收脚本。AlphaMail 在邮件系统运行时写入大量文件,其中大部分是解码的 MIME 消息和附件。这些文件无法通过 Web 软件可靠地清理,因为无法保证用户行为。该脚本称为 garbage_sweeper,并在《管理指南》中得到了充分的记录。

AlphaMail 正在俄勒冈大学投入生产使用。性能和可用性结果非常令人鼓舞,前者可在 AlphaMail 主页上找到。

但是,该系统仍然很新,并且存在一些尚未解决的潜在错误。imap_webcache 本身是一个相当复杂的软件,可能偶尔会出现问题。因此,我建议运行一个名为 hang_detector 的包含实用程序(默认情况下位于 /usr/local/share/alphamail/util 中)。您必须在使用此脚本之前对其进行编辑,并且它需要有效的 IMAP 用户才能工作。

它每 15 秒对 Web 缓存运行一次完整查询,并且能够重新启动 imap_webcache(通过包含的 init 脚本)。如果需要,它还可以向管理员发送邮件。

常见问题

在新安装中,您可能会在几个地方遇到困难。《AlphaMail 管理员指南》中包含许多关于如何解决这些问题的提示。

最令人困惑的问题之一是由于通过不正确的域名访问服务而产生的。维护会话的 cookie 与您在配置期间指定的服务器域相关联,并存储在 AlphaMail apache 配置中的参数中

PerlSetVar alphamailDomain server.example.com

如果用户能够使用不合格的主机名(例如 server)访问登录页面,则 cookie 将无法正确交换,并且登录将失败,且没有任何错误。登录实际上是成功的,但由于 URL 不匹配,浏览器没有将 cookie 发送回去。

幸运的是,大多数用户通过链接连接或键入不安全的 HTTP URL。前者永远不是问题,重定向可以很好地纠正后者

<VirtualHost _default_:80>
   RedirectMatch ^/alphamail/?$ https://server.example.com/
   ↪alphamail/index.html
   RedirectMatch ^/alphamail/mail/?$ https://server.example.com/
   ↪alphamail/mail/index.html
</VirtualHost>

其他问题通常涉及依赖项、配置错误、不正确的权限或缺少辅助目录。这些问题的最佳指示是 alphamail_ui.log 中的错误,默认情况下,该日志在 /var/log 中创建。

SELinux 也可能是问题的根源。我没有在 SELinux 下运行过 AlphaMail,除非您愿意创建自己的安全配置文件,否则您可能需要关闭或禁用强制执行。

AlphaMail 的未来

到目前为止,AlphaMail 的开发主要关注性能和核心功能,我预计这两个问题在未来不会变得不那么重要,因为该产品面向拥有庞大而多样化的用户社区的环境。

它的功能相当丰富,但肯定不是包罗万象的。限制功能蔓延是一个持续的要求,因为关键的关注点是轻松可靠地访问基本功能,而不是邮件客户端功能的全面覆盖。

尽管如此,仍有重大改进和添加的计划,例如国际化的界面、可以改善客户端交互的可选 Ajax 组件和会话视图。

Tony Kay 是 AlphaMail 的主要开发者,并在俄勒冈州尤金市的俄勒冈大学工作。可以通过 tkay@uoregon.edutony.kay@gmail.com 联系他。

加载 Disqus 评论