为小型办公室提供电子邮件服务
我为之工作的公司可以用委婉的说法来形容为节俭。我们有 1930 年代的旧设备,我在那里工作了三个月才发现我们甚至有一个互联网帐户。(对于系统管理员来说,这太糟糕了,是吗?)这是我的第一份真正的 IS 工作,为了获得经验,我愿意处理这种情况。后来我发现,这个帐户被老板的儿子和他的朋友们囤积在工程部门。
随着时间的推移,我们的客户开始要求我们更与时俱进,访问 Web 上的信息,发送和接收电子邮件等等。我看到了许多其他方法,将 Linux 盒子添加到网络可以帮助公司,并在短时间内收回成本。所以我写了一份提案,并获得许可购买一台盒子,用作文件服务器、传真服务器、内部 Web 服务器、电子邮件服务器和 Internet 网关。除了工程部门的人员外,工厂的其余人员甚至没有使用过电子邮件,而工程部门只使用过一两次。他们认为 Web 是互联网上唯一可以做的事情。我们暂且不谈他们访问了哪些网站。
本文的重点是电子邮件部分。我打算介绍如何使用 sendmail、fetchmail 和 procmail,以便小型公司可以有效地“隐藏”在单个电子邮件地址后面。现在,在您冲出去这样做之前,您可能需要考虑您的 ISP 对此有何看法。在我们的例子中,电子邮件的量很小,每天可能只有 20 条消息。与我个人的帐户(每天收到 100-400 条)以及我的商务帐户(每天收到 20-30 条)相比,这简直是小菜一碟,我认为我们的 ISP 没有什么可抱怨的。您的里程可能会有所不同。
您是否曾经注意过阅读电子邮件时返回地址的外观?大多数时候,如果此人在其电子邮件客户端配置中设置了全名,或者如果管理员在 /etc/passwd 中设置了全名,您将看到类似这样的内容
Firstname Lastname <somehandle@someisp.com>
我确信我可以使用它,以某种方式重写外发返回地址,这样,当邮件被回复时,我可以将其通过过滤器传递给合适的人员,同时仅消耗我们 ISP 的一个电子邮件地址。我最终购买了 O'Reilly 的 sendmail 书籍,并进行了几周的实验,但我现在有了一个已经使用了大约两年半并且运行良好的解决方案。从我们的 ISP 那里额外支付每个电子邮件地址每月 5 美元,并且有大约 15 个用户,我认为这是值得的。
以下是计划。当然,名称是虚构的。
thriftycompany@someisp.com——我公司从 ISP 获取的电子邮件地址。
smtp.someisp.com——我们 ISP 的 SMTP 服务器(我们发出的邮件)。
pop3.someisp.com——我们 ISP 的 POP3 服务器(发给我们的邮件)。
linuxserver.thriftycompany.com——我们的文件服务器 (thriftycompany.com 仅为内部使用,并非注册域名)。
mrpserver.thriftycompany.com——一台 Sun 机器,托管我们的 MRP 系统。这不是计划的必要部分,但我的许多用户将所有时间都花在连接到这台机器的 xterm 上,因此我在 Sun 机器上为他们安装了 Pine。(Pine,按照 GNU 的传统,代表 Pine Is Not Elm——另一个基于文本的电子邮件程序。Pine 实际上是一个非常高效的邮件客户端,也是我的首选程序。用 GUI 处理我的电子邮件需要几天时间。)
thriftycompany@linuxserver.thriftycomany.com——Linux 机器上的虚假默认电子邮件地址。所有收到的邮件都通过此地址,procmail 将其传递给用户。
通过一些 /etc/sendmail.cf 的魔法,以及传入端的 procmail 过滤器,我可以让多个用户使用同一个电子邮件帐户,但在很大程度上,保持他们的邮件私密性。
外发场景:1) 用户编写电子邮件,无论是在 Sun 上的 Pine 中,还是在 Outlook 或 Netscape 的邮件客户端中。我只为需要处理附件的人员设置了 GUI 帐户。2) 如果邮件是在 PC 上编写的,则配置为将邮件传递到 Sun 机器,并从同一位置检索邮件。3) 如果是内部地址,Sun 机器会传递它。4) 如果是外部地址,则将其传递到 Linux 机器。5) Linux 机器上的外发邮件会排队,并在每小时两次分批发送,在拉入传入邮件之后。6) 在适当的时间,运行 /usr/sbin/sendmail -q -v,并且通过使用 /etc/genericstable.db 和 /etc/sendmail.cf 中的一些伪装规则,用户的返回地址被重写为名字 姓氏 <thriftycompany@someisp.com>
传入场景:1) 服务器在 cron 中定义的时间连接到 ISP。或者如果已经连接,则保持连接不变。这由 pppd 和 diald 处理,但那是另一篇文章。2) 使用 fetchmail 检索传入邮件,并将其传递到默认帐户 thriftycompany@linuxserver.thriftycompany.com。3) thriftycompany 帐户中的 Procmail 过滤器在传入地址中查找正确的名称,并将邮件传递给用户。不符合过滤器规则的邮件会落入默认邮箱,并且作为预防措施,在此帐户的 mail/ 目录中为每个用户设置一个文件夹。4) 除 root 和 thriftycompany 之外的所有本地邮件都转发到 Sun 机器。5) 用户要么在 Sun 机器上的 Pine 中实时接收邮件,要么使用 GUI 客户端从 Sun 机器交互式检索邮件。6) 所有这些听起来很复杂,但实际上并非如此。请记住,Sun 机器只是为了方便我的情况,对于该过程来说不是必需的。您可以只让您的用户从 Linux 机器获取他们的邮件。
现在是文件部分。您需要的大部分(如果不是全部)内容应该已经在大多数 Linux 发行版中或在您的 CD 上。以防您需要帮助,您将在我们的“资源”部分找到 URL。
让我们首先处理 Sun/Linux 邮件传递,这样如果您不需要第二台服务器,您可以忽略它并继续。
Sun 机器的 /etc/mail/sendmail.cf 是标准的。当我设置它时,我对 Solaris 仍然是新手,并且犹豫是否要过多地摆弄运行我们整个工厂的系统,所以我这样做是为了通过 /etc/mail/sendmail.cf 条目传递邮件
DRmailhost CRmailhost
/etc/hosts/条目
192.9.200.2 linuxserver mailhost在我进行更改之前,/etc/hosts 在 Sun 的 IP 地址之后有 mailhost 条目
192.9.200.1 mrpserver mailhost这似乎可以解决将外发邮件发送到 Linux 机器的问题。
在 Linux 机器上,我们希望所有本地邮件都发送到 Sun 机器,用户的邮件文件夹位于该机器上。除了我之外,我的用户都没有直接登录到 Linux 机器。他们使用通过 Samba 共享的文件。Telnet 和 FTP 访问已关闭
DHrelay:mrpserver.thriftycompany.com
此处的例外是 root 和 thriftycompany 用户,我希望他们留在这台机器上
CL root thriftycompany这几乎涵盖了两台本地 UNIX 机器之间的交互。本地邮件保留在 Sun 上,Internet 邮件传递到 Linux,然后排队等待下一次连接。传入的 Internet 邮件将被重新寻址到本地用户,然后中继到 Sun 机器。Linux 机器上的 root 和 thriftycompany 帐户保持不变,我将检查这些帐户作为我的日常工作的一部分。
此设置的一部分取自多年来的各种 HOWTO;其他部分是我从搜索 Usenet 和 O'Reilly sendmail 书籍中收集的。
sendmail 启动:对于按需拨号场景,我们不希望 sendmail 在每次队列中有邮件时都启动连接,因此您需要编辑 sendmail 启动行以延迟“昂贵”邮件
old entry: /usr/sbin/sendmail -bd -q15m new entry: /usr/sbin/sendmail -bd -os
在基于 Red Hat 的系统上,这将在 /etc/sysconfig/sendmail 和/或 /etc/rc.d/init.d/sendmail 中设置。
您将在列表 1 的 /etc/sendmail.cf 文件中定义哪些邮件是昂贵的,并告诉 sendmail 保留此类邮件。
请注意 smtp、esmtp 和 smtp8 的“F=”部分中的“e”。这是“昂贵”标志,我们将其从本地中继中删除。此外,Mlocal 和 Mprog 不应具有此标志,以便本地系统邮件立即传递。
cron 作业每小时连接到互联网两次,作为该作业的一部分,一旦互联网连接就绪,我们将发送所有排队的邮件
/usr/sbin/sendmail -q -v
现在要让外发邮件被传递并且不被互联网上的域拒绝。由于我们没有有效的域名,我们需要对返回地址进行一些处理。我们需要伪装返回地址以及信封,并且为了让任何回复返回给原始发件人,我们需要重写“From:”地址。
如果您正在从 m4 源构建 sendmail.cf,那么您的本地 .mc 文件需要包含以下内容
MASQUERADE_AS(someisp.com) FEATURE(masquerade_envelope) FEATURE(limited_masquerade) FEATURE(genericstable)
我们正在使用有限的伪装,因此只有 CM 中定义的主机才会被伪装。如果您只是编辑 /etc/sendmail.cf,那么需要按如下所示修改以下行
# who I masquerade as (null for no masquerading) (see also $=M) DMsomeisp.com您可能还希望通过您的 ISP 中继邮件,以便任何下游邮件服务器都将邮件视为来自有效域
# "Smart" relay host (may be null) DSsmtp:smtp.someisp.com定义应转换为伪装地址的域名
CG mrpserver.thriftycompany.com CM mrpserver.thriftycompany.com(如果您只有一台机器,这将是 linuxserver.thriftycompany.com。)
现在,用于伪装内容和信封的 sendmail.cf 行变得有点混乱。您最好从 m4 源构建 sendmail.cf,如列表 2 所示。
外发难题的最后一部分是重写用户的返回地址。如果我要在 Sun 机器上编写消息,Pine 会组合一个看起来像这样的返回地址
Stew Benedict <stew@mrpserver.thriftycompany.com>
看起来足够好,但它不是互联网上的真实地址,我永远不会收到对我消息的回复。此外,大多数邮件系统会拒绝将其作为不存在的域名地址接收。
我希望它看起来像这样
Stew Benedict <thriftycompany@someisp.com>
这就是 sendmail 的“genericstable”功能将完成工作的地方。同样,如果您正在从 m4 源构建 sendmail.cf,则以下行将完成这项工作
FEATURE(genericstable)在 sendmail.cf 文件中,如果您是手动编辑它
# Generics table (mapping outgoing addresses) Kgenerics hash -o /etc/genericstable(-o 表示“可选”,因此 sendmail 不会因为缺少文件而在启动时停止。)添加到您的本地 .mc 文件的这一项会生成列表 3 中 sendmail.cf 中显示的块。
genericstable.db 文件是从以下格式的文本文件构建的
stew thriftycompany@someisp.com joe thriftycompany@someisp.com
然后将此文件馈送到 makemap 程序以创建 db 文件
makemap hash genericstable.db < genericstable这就完成了外发邮件的设置。完成创建/修改 sendmail.cf 和创建 genericstable.db 文件后,您需要重新启动 sendmail。在基于 Red Hat 的系统上,这可以通过以下命令完成
/etc/rc.d/init.d/sendmail restart
对于传入邮件,我们使用 fetchmail 从 ISP 获取邮件。我的 cron 作业建立互联网连接,然后运行如下行
su -c "/usr/bin/fetchmail -a -f /home/thiftycompany" thriftycompany's .fetchmailrc: poll pop3.someisp.com proto pop3 user thriftycompany
Procmail 在 sendmail.cf 文件中被定义为本地 MDA(邮件传递代理)。
Mlocal, P=/usr/bin/procmail, F=lsDFMAw5:/|@qShP, T=DNS/RFC822/X-Unix, A=procmail -a $h -d $u所有传入邮件都转到 thriftycompany 帐户,其中有一个 .procmailrc 文件设置为解析传入的“To:”行并转发给相应的用户,如列表 4 所示。
您还可以使用此 procmail 过滤器来过滤掉 ILOVEYOU 类型病毒、限制或隔离附件以及其他有用的东西。查看 procmail 文档以获取有关此的更多信息。每个用户的邮件都保存在 thriftycompany 下的文件夹中,以防意外擦除等情况。我定期手动清除这些文件夹。
我的老板还没有完全认同互联网的有用性,并要求完全跟踪其使用情况。我的跟踪的一部分包括记录每个用户的全部传入和传出邮件消息——数量和大小。这是通过 cron 每天早上运行的 shell 脚本完成的,如列表 5 所示。此作业的输出如列表 6 所示。
这就差不多完成了。棘手的部分是让外部人员正确寻址传入邮件。对于大多数邮件客户端,这只需要在地址簿中创建一个名字、姓氏和电子邮件地址条目,其中包含人员的正确姓名和我们的 ISP 电子邮件地址。对于那些有经常联系人但似乎无法正确处理的人,我添加了一个带有“From:”地址的 procmail 规则,以确保邮件到达其正确的目的地。我给用户的另一个建议是向对方发送电子邮件,让他们将该电子邮件中的返回地址添加到他们的地址簿中。
我需要对该系统进行一定量的维护,但这很少。在撰写本文时,我也考虑了自动化这些部分的方法;但就目前而言,这真的不是什么负担。
我每天检查 thriftycompany 的邮件,以检查是否有没有通过 procmail 过滤器的邮件。没什么大不了的,我可以将此邮件转发给自己,然后我会更快地看到它,或者我可以设置 KBiff (KDE 邮件通知实用程序) 来监视此邮箱。
此外,我喜欢清除 thriftycompany 电子邮件帐户下的各个邮件文件夹。再说一次,没什么大不了的。我在这台服务器上不缺空间,而且我们的邮件量很小。可能有一个 Perl 脚本可以使用,我可以用来修剪“n”天前的消息。
目前,当我添加新用户时,我必须在 genericstable 文件中添加一个新条目,运行 makemap,重新启动 sendmail,并在 thriftycompany 的 procmail 过滤器中添加一个条目。我也考虑过编写一个 shell 脚本来完成这些步骤,但目前我每年可能只添加四次用户。
我希望本文能让您深入了解如何为小型公司设置电子邮件解决方案,这种公司尚未准备好通过域名完全跃升到 DSL 或 T1 连接。如果您需要使用互联网和电子邮件与您的客户和供应商进行通信,这应该能为您提供完成工作所需的一切。
Stew Benedict 是俄亥俄州克利夫兰市一家汽车制造商的系统管理员。他也是一名自由顾问,经营 AYS Enterprises,专门从事印刷电路设计、数据库解决方案以及利用 Linux 作为商业操作系统和软件的低成本替代方案。自 1994 年以来,他一直在使用和推广 Linux。当不沉浸在 CRT 的光芒中时,Stew 喜欢与他的妻子、女儿和两只狗在他在田纳西州 Smokies 山麓 Norris 湖畔的未来(不会太久!)退休之家共度时光。