18.16 Postfix邮件系统
Postfix是另一种sendmail的替代软件。Wietse Venema到IBM的T. J. Watson研究中心(T. J. Watson Research Center)做学术休假的一年里,启动了Postfix这个项目。Postfix的设计目标包括:开放源代码的软件发布政策、快速性能、健壮、灵活和安全。它直接同Dan Bernstein编写的qmail展开了竞争。所有主要的Linux发行版本都包含Postfix,Mac OS X从10.3版开始用它取代sendmail作为其默认的邮件系统。
对于Postfix来说,最重要的事情有:首先,它马上就能使用(最简单的配置文件只有一两行);其次,它利用正则表达式映射高效地过滤电子邮件,特别是配合PCRE(Perl Compatible Regular Expression,兼容Perl的正则表达式)库使用效果颇佳。Postfix和sendmail兼容,因为Postfix的aliases和.forward文件与sendmail的对应文件在格式和语义上都相同。
Postfix使用ESMTP协议,它也支持虚拟域和垃圾邮件过滤功能。Postfix没有像sendmail那样使用一种重写地址的语言,相反,它依靠从纯文件、Berkeley DB、dbm、LDAP、NIS、NetInfo或者MySQL这类的数据库进行的表查询。
18.16.1 Postfix体系结构
Postfix由几个小的协作程序所组成,这些程序负责发送网络消息、接收消息、在本地投递邮件等。它们之间通过UNIX域套接口或者FIFO进行通信。这种体系结构与sendmail的体系结构非常不同,sendmail就在一个大程序里完成大部分工作。
master程序启动和监视所有的Postfix进程。它的配置文件master.cf列出了这些辅助程序,还有应该怎样启动它们的信息。在那个文件中设定的默认值适合于除了非常慢或者非常快的机器(或者网络)之外的所有情况使用。一般而言,不需要对它进行调整。常做的一项修改是注释掉一个程序,例如smtpd,在客户机不应该监听SMTP端口的时候这么做。
在投递电子邮件的过程中,那些最重要的服务器程序如图18.5所示。
图18.5 Postfix的服务器程序 |
18.16.2 接收邮件
smtpd在SMTP端口上收邮件,它还要检查连上来的客户机是否得到授权,能够发送它们正在尝试投递的邮件。当通过/usr/lib/sendmail这个Postfix兼容sendmail的程序往本地发邮件的时候,会在/var/spool/postfix/maildrop目录下写一个文件。pickup程序定期扫描这个目录,处理它发现的任何新文件。
传入的所有电子邮件都要经过cleanup,它根据canonical和virtual映射,加上缺少的信头,重写邮件地址。在把电子邮件插入到incoming队列之前,cleanup要用trivial-rewrite把它略做重写,这个程序对地址做一些小的修正,例如,给不完整的地址追加一个邮件域名。
18.16.3 邮件队列管理器
等候投递的邮件由qmgr控制,这个队列管理器管理着5个队列:
— incoming(传入)—刚到的邮件;
— active(活动)—正在投递的邮件;
— deferred(推迟)—以前投递失败的邮件;
— hold(约束)—队列中的邮件被系统管理员阻止发送;
— corrupt(错误)—不可读或者不可分析的邮件。
队列管理器一般采用一种简单的FIFO(先进先出)策略来选择要处理的下一个消息,但它也支持一种复杂的抢先式算法,该算法优先发送收件人少的消息,把有大量收件人的批量发送邮件放到后面。
为了不让接收邮件的主机忙不过来,特别是当它刚刚宕过机之后,Postfix使用了一种慢启动算法来控制它尝试投递邮件的速度有多快。推迟发送的消息获得一个二次重发时间戳,这个时间按指数退避,从而不让无法投递的消息浪费资源。不可达的目的地会被缓存下来,以此避免做不必要的投递努力。
18.16.4 发邮件
trivial-rewrite帮助qmgr确定应该把一则消息发到哪里。trivial-rewrite做出的路由决策可以被transport映射所覆盖。
smtpd程序负责通过SMTP协议把邮件投递到远程主机。lmtp使用RFC 2022里制定的LMTP协议(Local Mail Transfer Protocol,本地邮件传送协议)投递邮件。LMTP基于SMTP,但这个协议已经做了修改,不要求邮件服务器管理邮件队列。这个邮寄程序(mailer)对于把电子邮件投递到Cyrus IMAP软件这样的邮箱服务器特别有用。
local的工作是向本地投递电子邮件。它在别名表里解析地址,按照从收件人的.forward文件里找到的指示处理邮件。消息不是被转发给另一个地址,传给一个外部程序处理,就是保存在该用户的邮件目录里。
virtual这个程序把电子邮件投递到“虚拟邮箱”,也就是说,和本地的Linux账号没有关系的邮箱,但仍然代表有效的邮件目的地。最后,pipe实现了通过外部程序投递邮件。
18.16.5 安全
Postfix在几个层面上落实安全措施。大多数的Postfix服务器程序都能运行在一个chroot过的环境下。它们是没有父子关系的独立程序,而且它们中也没有一个是setuid程序。放邮箱的目录的组可写权限给了postdrop这个组,postdrop程序的setgid就是这个组。
有一点令人印象深刻,除了DoS(拒绝服务攻击)之外,任何版本的Postfix里尚未出现其他被利用的安全漏洞。
18.16.6 Postfix命令和文档
用户可以通过几个命令行工具与这个邮件系统交互:
— sendmail、mailq、newaliases—都是和sendmail兼容的替代程序;
— postfix—启动和停止该邮件系统(必须以root身份运行);
— postalias—构造、修改和查询别名表;
— postcat—打印队列文件的内容;
— postconf—显示和编辑main.cf这个主配置文件;
— postmap—构造、修改或者查询查找表;
— postuper—管理邮件队列。
Postfix的软件发布带有一套手册页,该手册描述了所有这些程序及其选项。此外,在www.postfix.org的在线文档说明了配置和管理Postfix的各个方面。在Postfix的软件发布中也包含了同样的文档,所以您应该能发现它们已经装到了您的系统上,通常是在一个叫做README_FILES的目录下。
18.16.7 配置Postfix
main.cf文件是Postfix的首要配置文件。master.cf文件配置服务器程序。它还定义了各种的查找表,供main.cf访问,并且提供不同类型的服务映射。
postconf(5)的手册页描述了能在main.cf文件中设定的每一个参数。如果您只是键入man postconf,那么看到的是postconf程序的手册页。使用man -s 5 postconf才能看到描述main.cf配置选项的手册版本。
Postfix配置语言看上去有点儿像是Bourne shell注释和赋值一类的语句。在变量前面加一个$,就可以在定义其他变量的时候引用它。变量定义就像它们出现在配置文件一样被保存下来,它们在使用的时候才扩展,此时要做全部的替换。
您可以通过给变量赋值的方式创建新变量。要小心选择不会和现有的配置变量冲突的名字。
包括查找表在内的所有的Postfix配置文件,都把以空白开头的行当作续行。这个约定能产生可读性很好的配置文件,但是您必须在第一列开始新行。
18.16.8 main.cf的内容
在main.cf文件里可以设置超过300个参数。不过,在一个普通的站点上,只需要设其中的几个即可,因为默认的设定几乎都做好了。Postfix的作者强烈建议您支配没有默认值的那些参数。那样一来,如果一个参数的默认值在将来发生了变化,那么您的配置就会自动采用新的默认值。
随Postfix软件发布带的main.cf文件样板包括了许多注释掉的参数例子,还有一些简要介绍。最好把原来的版本留着以供参考。从空文件开始设定您自己的配置,这样一来,您所做的设定就不会淹没在注释的汪洋大海里。
18.16.9 基本设置
让我们从一个尽可能简单的例子开始:一个空文件。吃惊吧,这个空文件也是一个完全合理的Postfix配置文件。它配置的邮件服务器往本地投递邮件(本地的意思是指与本地主机名在同一个域),以及把目的地不是本地地址的任何消息直接发给合适的远程服务器。
另一个简单的配置是一个“空客户机(null client)”,也就是说,一个系统不向本地投递任何电子邮件,只把对外的邮件转发给一台指定的中央服务器。对于这种配置,我们定义了几个参数,首先是mydomain,它定义了主机名的域名部分,其次是myorigin,它是给不全的电子邮件地址追加的邮件域。如果mydomain和myorigin两个参数相同,那么我们就可以写成下面这个样子:
mydomain = cs.colorado.edu |
我们应该设定的另一个参数是mydestination,它指定了本地的邮件域(也称为“规范”域)。如果一则消息的收件人地址把mydestination作为其邮件域,那么这则消息就要通过local程序投递给相应的用户(假定没有找到对应的别名或者.forward文件)。如果在mydestination里包含了一个以上的邮件域,那么这些域都被当作是同一个域的别名。
我们想要我们的空客户机(null client)不向本地投递邮件,所以这个参数应该为空:
mydestination = |
relayhost = [mail.cs.colorado.edu] |
中括号告诉Postfix把指定的字符串当作一个主机名(DNS的A记录),而不是当作一个邮件域名(DNS的MX记录)。
既然空客户机不应该接收从其他系统发来的邮件,所以在空客户机的配置里最后要做的一件事情是,注释掉master.cf文件里的smptd一行。这个改动根本不让Postfix运行smtpd。只用这么简单的几行配置,我们就定义了一个功能完善的空客户机。
对于一台“真实的”邮件服务器来说,您不但多需要几个配置选项,而且还要映射表。我们在接下来的几小节里介绍这些表。
18.16.10 使用postconf
postconf是一个能帮助您配置Postfix的方便工具。不带参数运行该工具,它会打印出所有当前配置好的参数。如果您把一个特定参数作为postconf的命令参数,那么它就会打印出那个参数的值。-d选项能让postconf打印参数的默认值而不是当前配置的值。
例如:
另一个有用的选项是-n,它让postconf只打印当前配置值和默认值不同的参数。如果您要在Postfix的邮递列表上寻求帮助,那么您应该在自己的邮件里带上这个命令输出的配置信息。
18.16.11 查找表
Postfix操作的许多方面都是通过查找(lookup)表来决定的,这张表能把关键字映射到值,或者实现简单的列表。例如,alias_maps表的默认设定为:
alias_maps = dbm:/etc/mail/aliases, nis:mail.aliases |
数据源用type:aliases这样的表示方法指定。注意,这个特殊的表实际上同时使用了两个不同的信息源:一个是dbm数据库,另一个是NIS映射。多个值用逗号、空格或者两者合起来进行分隔。表18.22列出了能用的数据源,postconf -m命令也能给出这一信息。
表18.22 可用作Postfix查找表的信息源
类 型 | 说 明 |
dbm / sdbm | 传统的dbm或者gdbm数据库文件 |
cidr | CIDR形式的网络地址 |
hash / btree | Berkeley DB散列表(代替dbm)或者B-树表 |
ldap | LDAP目录服务 |
mysql | MySQL数据库 |
nis | NIS目录服务 |
pcre | 兼容Perl的正则表达式 |
pgsql | PostgreSQL数据库 |
proxy | 通过proxymap访问,例如逃出chroot |
regexp | POSIX正则表达式 |
static | 不管关键字如何,都返回path指定的值 |
unix | Linux的/etc/passwd和/etc/group文件,使用NIS句法a |
a.unix:passwd.byname是passwd文件,unix:group.byname是group文件。
使用dbm和gdbm类型只是为了和传统的sendmail别名表保持兼容。Berkeley DB(hash)是一种更为现代的实现;它更安全,速度也更快。如果兼容性不是一个问题的话,那么使用:
alias_database = hash:/etc/mail/aliases |
alias_database指定由newaliases重建的表,它应该与您在alias_maps中指定的表相对应。有两个参数的原因是alias_maps可能包括非DB的信息源,例如mysql或者nis,它们不需要重建。
所有DB类的表(dbm、sdbm、hash和btree)都基于一个文本文件,这个文本文件可以编译成一个搜索效率高的二进制格式。在注释和续行方面,这些文本文件的句法都和配置文件的句法相似。文件中的配置项用简单的一对“关键字/值”来指定,两者间用空格分隔,对此例外的是别名表,为了保持与sendmail的兼容性,这个表必须在关键字之后有一个分号。例如,下面这几行适合于别名表:
postmaster: david, tobias |
.cs.colorado.edu OK |
$ postmap hash:/etc/postfix/access |
$ postmap -q blabla hash:/etc/postfix/access |
18.16.12 本地投递
local程序负责把邮件投递到合乎规定的域。它还处理本地别名。例如,如果mydestination设为cs.colorado.edu,而收到一封发给evi@cs.colorado.edu的电子邮件,那么local首先查一次alias_maps表,然后递归地替换任何匹配项。
如果没有匹配的别名,那么local就找evi主目录里的.forward文件,如果有这个文件(句法和一个别名映射的右边一样),它就按照这个文件的指示处理邮件。最后,如果没有找到.forward文件,那么电子邮件就投递到evi的本地邮箱。
在默认情况下,local把电子邮件写到/var/mial下标准mbox格式的文件里。您可以用表18.23里的参数改变local的操作。
表18.23 local投递到本地邮箱采用的参数(在main.cf里设置)
参 数 | 说 明 |
mail_spool_directory | 把邮件投递到一个服务所有用户的中央目录 |
home_mailbox | 把邮件投递到指定的相对路径下的~usr |
mailbox_command | 用一个外部程序投递邮件,一般是procmail |
mailbox_transport | 通过master.cf里定义的一个服务投递邮件a |
recipient_delimiter | 允许使用扩展的用户名(参见下面的介绍) |
a.这个选项和邮箱服务器程序(例如Cyrus的impad)交互。
mail_spool_directory和home_mailbox这两个参数正常情况下会生成mbox格式的邮箱,但是它们也能生成qmail风格的Maildir邮箱。在路径名末尾加一个斜线,就能按这个方式生成邮箱。
如果recipient_delimiter被设为+,那么可以接受发到evi+whatever@cs.colorado.edu这个地址的邮件,它被投递给evi的账号。有了这个功能,用户就能创建特殊用途的地址,并且按目的地址来对它们进行分类。Postfix首先按完整地址来查找,只有在找不到的情况下,它才去掉扩展的部分,退而使用基本地址。Postfix还能查找相应的转发文件.forward+whatever做更进一步的别名替换。
18.16.13 虚拟域
如果您想要在Postfix邮件服务器上托管一个邮件域,那么您可以有3种选择。
— 在mydestination里列出这个域。邮件按照前面介绍的那样来投递:做别名扩展,把邮件投递给相应的用户。
— 在参数virtual_alias_domains里列出这个域。这个选项让这个域有自己的独立寻址空间,和系统的用户账号没有关系。在这个域中的所有地址都必须能解析成(通过映射)它之外的真实地址。
— 在参数virtual_mailbox_domains里列出这个域。和virtual_alias_domains选项一样,这个域有自己的名字空间。不过,邮件可以投递到一个指定的目录下的所有邮箱里,和用户账号没有关系。
在上述3个地方之一列出这个域。请仔细选择,因为许多配置元素都要依靠这个选择。我们已经看过mydestination方法的处理。其他几个选项在下面讨论。
18.16.14 虚拟别名域
如果一个域列为virtual_alias_domains参数的值,那么Postfix就接受发到那个域的邮件,而且必须把这些邮件转发到本地机器或者别处的一个实际的收件人那里。
对虚拟域里地址的转发功能必须在参数virtual_alias_maps里包括的一张查找表里定义。这张表里的表项,左边是虚拟域,右边是实际的目的地址。
右边域名不全的名字被解释为本地主机上的一个用户名。
考虑下面这个从main.cf里截取的例子:
发给evi@admin.com的邮件都被重新定向到evi@cs.colorado.edu(追加了myorigin),最终投递到evi用户的邮箱,因为mydestination里包括cs.colorado.edu。
定义可以递归:右边可以包括在左边再次被定义的地址。注意,右边只可以是一个地址的列表。如果您需要执行一个外部程序,或者要使用:include:文件,那么要把这个电子邮件重定向为一个别名,接着就可以按照您的需要对别名进行扩展。
为了把所有内容都放在一个文件里,您可以把virtual_alias_domains设为和virtual_alias_
maps一样的查找表,并且在这张表里加一个特殊项,把它标为一个虚拟的别名域。在main.cf文件里:
virtual_alias_domains = $virtual_alias_maps |
admin.com notused |
18.16.15 虚拟邮箱域
在virtual_mailbox_domains下列出的域和本地(规范)域类似,但是用户的列表及其对应的邮箱必须独立于系统的用户账号进行管理。
参数virtual_mailbox_maps指向了一张表,其中列出了该域内所有的有效用户名。这个映射表的格式为:
user@domain /path/to/mailbox |
如果这一路径以斜线结尾,那么邮箱就保存为Maildir格式。virtual_mailbox_base的值一定以这个指定的路径开头。
您经常可能想要给virtual_mailbox_base中的地址起个别名。使用virtual_alias_map就能达到上述目的。下面是一个完整的例子。
在main.cf中的配置为:
evi@admin.com nemeth/evi/ |
postmaster@admin.com evi@admin.com |
18.16.16 访问控制
邮件服务器只应该为可信的客户机中继转发邮件。如果邮件服务器把不认识的客户机发来的邮件转发给其他服务器,那么就称为开放中继(open relay),这种情况很不好。参考18.10.1节了解有关这个问题的详情。
还好,Postfix默认不会做开放中继。实际上,它的默认配置相当严格,您更有可能的是要放开权限而不是紧缩权限。Postfix中对SMTP处理的访问控制通过“访问限制列表”来配置。表18.24中的参数控制着在一次SMTP会话的不同阶段应该检查什么smtpd_client_restrictions。
表18.24 local投递到本地邮箱采用的参数(在main.cf里设置)
参 数 | 何 时 应 用 |
smpd_client_restrictions | 建立连接请求的阶段 |
smtpd_helo_restrictions | 在HELO/EHLO命令阶段(启动会话) |
smtpd_sender_restrictions | 在MAIL FROM命令阶段(发件人说明) |
smtpd_recipient_restrictions | 在RCPT TO命令阶段(收件人说明) |
smtpd_data_restrictions | 在DATA名阶段(邮件主体) |
smtpd_etrn_restrictions | 在ETRN命令阶段a |
a.这是用于重新发送队列中邮件的一个特殊命令。
最重要的参数是smtpd_recipient_restrictions,因为当获悉收件人的地址,并且识别出它是否为本地地址之后最容易实施访问控制。表18.24中的其他所有参数在默认配置中都为空。这个默认值为:
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination |
依次测试每一项指定的限制,直到找到对该邮件的明确处理决定。表18.25给出了最常用的限制。
表18.25 常见的Postfix访问限制
参 数 | 何 时 应 用 |
check_client_access | 使用一张查找表来检查客户主机的地址 |
check_recipient_access | 使用一张查找表来检查收件人邮件地址 |
permit_mynetworks | 授权给mynetworks列出的地址 |
reject_unauth_destination | 拒绝发给非本地收件人的邮件,不做中继 |
每样信息都能用这些限制来测试,不只是像smtpd_sender_restrictions中的发件人地址那样的特定信息。因此,为了简单起见,您可能想把所有的限制都放在一个参数之下,这个参数应该是smtpd_sender_restrictions,因为只有这一个参数能够测试所有的信息(除了DATA部分)。
smtpd_recipient_restriction是检测邮件中继的位置。您应该保留reject_unauth_
destination这个限制,仔细选择在它之前的“允许(permit)”限制。
18.16.17 访问表
每项限制返回表18.26中的动作之一。在这些限制中使用访问表(例如,check_client_access和check_recipient_access)来分别选择一个基于客户主机地址或者收件人地址的动作。
表18.26 访问表的动作
动 作 | 含 义 |
4nn text | 返回临时错误码4nn和消息text |
5nn text | 返回临时错误码5nn和消息text |
DEFER_IF_PERMIT | 如果限制的结果是PERMIT,那么把它改为一个临时错 |
DEFER_IF_REJECT | 如果限制的结果是REJECT,那么把它改为一个临时错 |
DISCARD | 接受消息,但是悄悄地丢弃它 |
DUNNO | 假装没有找到该关键字,测试更多的限制 |
FILTER transport:dest | 把邮件通过过滤器transport:dest a传给邮件 |
HOLD | 把邮件阻止在队列中 |
OK | 接受这个邮件 |
PREPEND header | 给消息加一个信头 |
REDIRECT addr | 把这个邮件转发到一个指定的地址 |
REJECT | 拒绝该邮件 |
WARN message | 在日志里加入给定的警告消息message |
a.参考18.16.19节的内容。
举个例子,假定您想要给cs.colorado.edu域内的所有机器做中继,而且还想只让可信的客户机向内部的邮递列表newsletter@cs.colorado.edu发邮件。那么您应该在main.conf里用下面的几行配置实现上面两项策略:
.cs.colorado.edu OK |
newsletter@cs.colorado.eduREJECT Internal list |
8.16.18 客户机身份验证
对于从家里发邮件的用户来说,通过家里的ISP邮件服务器送出邮件,而不管发件人的地址是否出现在那封邮件中的做法通常最容易。大多数ISP信任自己的直接用户,所以允许中继。如果不可能有这样的配置,或者如果您正在使用诸如Sender ID或者SPF这样的系统,那么就要确保能授权网络之外的用户向您的smtpd提交消息。
解决这个问题的一种途径是捎带在POP或者IMAP所用的验证协议之上。需要发邮件的用户也需要读他们的邮件,所以仅一步身份验证就能实现发邮件和读邮件两方面的验证。
这种捎带系统叫做POP-before-SMTP(先POP再SMTP)或者IMAP-before-SMTP(先IMAP后SMTP),它的工作方式如下:只要用户已经由POP或者SMTP守护进程验证了身份,那么用户的IP地址就明确列入可以用SMTP发邮件的名单(whitelist,白名单)大约30分钟。列入这个名单的客户机的数据库由一个专门负责该任务的守护进程维护。在Postfix中,这样的配置类似下面:
smtpd_recipient_restrictions = permit_mynetworks |
18.16.19 反垃圾邮件和病毒
Postfix有许多功能有助于阻止可疑的电子邮件。
有一类保护功能要求严格实现SMTP协议。合法的邮件服务器应该会遵守这一协议,但是垃圾邮件和病毒的发送者则往往对协议轻率行事,因而把自己暴露了出来。遗憾的是,世界上仍然有不健全的邮寄程序在处理合法的邮件,所以这项技术操作起来不一定可靠。选择限制条件时要很仔细,并且要监视日志文件。表18.27给出了这类功能中的一些。
表18.27 严格检查SMTP协议的参数和限制
动 作 | 含 义 |
reject_non_fqdn_sender | 拒绝发件人域名不完整、收件人域名不完整或者HELO/EHLO主机名不完整的消息 |
reject_unauth_pipelining | 如果客户机没有等着看一条命令的结果状态就接着往下,则放弃当前的会话(限制) |
reject_unknown_sender_domain | 拒绝发件人域名不能解析的消息(限制)a |
smtpd_helo_required | 对话一开始就要求HELO/EHLO(参数,不是yes就是no) |
strict_rfc821_envelopes | 要求MAIL FROM和RCPT TO命令中的电子邮件地址语法正确(参数,不是yes就是no) |
a.返回一个临时的出错消息,因为这个问题可能源于一次暂时的DNS小毛病。
在将一项限制投入正式使用之前要测试一下(始终是个不错的主意),把warn_if_reject这个限制加到它前面,把作用效果从直接拒绝转为发警告性的日志消息。
18.16.21 SpamAssassin和promail
Postfix支持SpamAssassin和那一类的其他过滤器。参考18.10.8节和18.9.16节了解这些工具的一般知识。
从用户的.forward文件可以启动procmail,但是这样做很复杂而且容易出错。更好的办法是在main.cf文件里加入下面一行:
mailbox_command = /usr/bin/procmail -a "$EXTENSION" |
Postfix接着使用procmail投递邮件,而不是直接把消息写到邮件池里去。给procmail的参数传递了地址的扩展(在+之后的部分),随后可以在procmail里用$1访问到它。
18.16.22 策略守护进程
Postfix的2.1版引入了一种将访问控制授权给外部程序的机制。这些程序称为策略守护进程(policy daemon),它们收到Postfix对一则邮件消息掌握的所有信息,必须返回表18.26列出的一种处理动作。
或许用这样的一个策略守护进程能实现的最有意思的功能就是“greylisting(灰名单技术)”。灰名单技术根据客户主机名、发件人地址和收件人地址这个三元组来对每个传入的消息进行分类。Postfix第一次看到一个给定的三元组的时候,它返回给发件人一个临时错误消息。合法的邮件服务器会在大约10分钟后尝试重新投递邮件,什么时候才允许这则消息进来。因为第一次投递通常在几分钟里就做了,所以邮件不会被过分地拖延。
灰名单技术在思想上类似于Postfix要求严格遵守SMTP的功能。在使用灰名单技术的情况下,重新投递的尝试本身就体现出它是合法的邮件服务器。灰名单经证实对于清除垃圾邮件非常有效,因为许多垃圾邮件源都使用不那么高级的软件,它们不会尝试重新投递邮件。
18.16.23 内容过滤
Postfix能够使用正则表达式检查电子邮件消息的信头和主体是否有违禁内容。它还能把消息传给其他程序,例如专门的反垃圾邮件工具或者反病毒应用。
对信头和主体的检查是随着消息通过SMTP接受实时执行的。做检查的每个正则表达式如果匹配,就会调用表18.26中指定的一个动作。例如,下面这行在main.cf文件中的配置:
header_checks = regexp:/etc/postfix/header_checks |
/^Subject: reject-me/ REJECT You asked for it |
就能拒绝标题以“reject-me”开头的任何消息。虽然支持正则表达式总是不错的,但是在处理电子邮件的情况下要澄清许多地方。具体而言,这不是一种过滤垃圾邮件或者病毒的有效方法。
功能很强的病毒过滤技术通常是通过Amavis实现的,Amavis是一个Perl程序,它把邮件服务器软件同一个或者几个反病毒应用衔接起来。这样的过滤器用Postfix的content_filter参数来配置,这个参数要求Postfix把发来的每一则消息都穿过指定的服务。除了设定content_filter参数之外,您必须修改master.cf文件中的一些现有的配置项,并且增加一些新的配置项。Amavis带有对此的详细指导。有许多Amavis的变体可用,我们推荐Mark Martinec编写的amavisd-new。
18.16.24 调试
当您遇到Postfix出问题的时候,首先要检查日志文件。您问题的答案最有可能就在那儿,这只是个把答案找出来的问题。每个Postfix程序正常情况下都会给它所处理的每则消息生成一条日志记录。例如,一则对外发出的消息的日志记录可能看上去像下面这样:
由此可见,这则引起我们关注的信息出现了好多行。注意,标识符0E4A93688每行都有:只要一则消息进入邮件系统,Postfix就给它分配一个队列ID,并且从不改变它。因此,在日志中搜索一则消息的历史时,首先要集中精力确定该消息的队列ID。一旦您知道了ID,那么grep一下日志,找到所有相关的日志记录就很容易了。
Postfix非常擅长于给它所注意到的问题记录有用的日志消息。不过,在成千上万行正常的状态消息中定位重要的消息行有时候却比较困难。这里正是使用10.5节介绍的日志分析工具来凝练出有用信息的好地方。
18.16.25 查看邮件队列
找问题的另一个地方是邮件队列。和sendmail系统中的情形一样,有一个mailq命令可以打印出队列中的内容。您可以用它看看一则消息是否处理不下去了,为什么会这样。
另一个有用的工具是Postfix最近的版本带的qshape这个脚本。它给出了有关一个队列的汇总统计数据。输出结果如下:
qshape按照收件人的域给出了指定队列的分类总结。各列报告相关消息已经在队列中等候的时间。例如,您可以看到有49个发往expn.com的消息已经在队列中等候了超过1280分钟的时间。这个例子中的所有目的地址都暗示出这些是用户的休假应答脚本响应垃圾邮件的消息。
qshape也能用-s标志按发件人的域来做总结。
18.16.26 soft_bounce
如果soft_bounce被设为yes,那么Postfix对于在它正常情况下应该发送永久性错误消息(例如“user unknown”或者“relaying denied”)的时候,则发送临时的出错消息。这是一种很棒的测试功能,它能让您监视修改过配置之后的消息处理情况,而不必冒永久丢失合法邮件的风险。您拒绝的任何东西最终都会再回头试一次。但是不要忘记在您做完测试之后关闭这项功能。否则,您就不得不要一遍遍处理每一个被拒绝的消息了。
18.16.27 测试访问控制
测试访问控制限制的最简单的方法是从一台外界的主机发一个消息,看看情况如何。这是一项很好的基本测试,但是它不能涵盖特殊的条件,例如从一个您无法登录进去的特定域发来的邮件。
Postfix 2.1引入了一种对SMTP协议的扩展,称为XCLIENT,它模拟从另一个地方提交邮件。这项功能默认是禁用的,但是在main.cf文件里采用下面的配置行,就能让从localhost发起的连接具有这一模拟功能:
smtpd_authorized_xclient_hosts = localhost |
测试会话看上去就像下面这样:
自由广告区 |
分类导航 |
邮件新闻资讯: IT业界 | 邮件服务器 | 邮件趣闻 | 移动电邮 电子邮箱 | 反垃圾邮件|邮件客户端|网络安全 行业数据 | 邮件人物 | 网站公告 | 行业法规 网络技术: 邮件原理 | 网络协议 | 网络管理 | 传输介质 线路接入 | 路由接口 | 邮件存储 | 华为3Com CISCO技术 | 网络与服务器硬件 操作系统: Windows 9X | Linux&Uinx | Windows NT Windows Vista | FreeBSD | 其它操作系统 邮件服务器: 程序与开发 | Exchange | Qmail | Postfix Sendmail | MDaemon | Domino | Foxmail KerioMail | JavaMail | Winwebmail |James Merak&VisNetic | CMailServer | WinMail 金笛邮件系统 | 其它 | 反垃圾邮件: 综述| 客户端反垃圾邮件|服务器端反垃圾邮件 邮件客户端软件: Outlook | Foxmail | DreamMail| KooMail The bat | 雷鸟 | Eudora |Becky! |Pegasus IncrediMail |其它 电子邮箱: 个人邮箱 | 企业邮箱 |Gmail 移动电子邮件:服务器 | 客户端 | 技术前沿 邮件网络安全: 软件漏洞 | 安全知识 | 病毒公告 |防火墙 攻防技术 | 病毒查杀| ISA | 数字签名 邮件营销: Email营销 | 网络营销 | 营销技巧 |营销案例 邮件人才:招聘 | 职场 | 培训 | 指南 | 职场 解决方案: 邮件系统|反垃圾邮件 |安全 |移动电邮 |招标 产品评测: 邮件系统 |反垃圾邮件 |邮箱 |安全 |客户端 |