Postfix邮件转发详解(1)
Postfix邮件转发详解(1)
到目前为止,我们主要的讨论焦点,都是postfix于邮递路径末端所扮演的角色。也就
是说,抵达postfix服务器的邮件,主要是被投递到本机系统。但是,postfix也常扮演
另一种角色--位于邮递路径中的中继器。
备用交换器
在DNS的术语中,MX代表mail exchanger。一个MX记录代表一个网域承接外来邮件的主
机,以及该主机的优先度。同一个网域可以同时有好几个MX记录,优先度最高的主机称
为主交换器,其余主机称为备用交换器。备用交换器的任务,是在主交换器离线时,承
接该网域的外来邮件;当优先度高于自己的其他备用交换器或主交换器恢复上线时,已
收下的邮件必须传给主交换器来处理,备用交换器不能自己擅作主张,将收到的邮件直
接投递到最终目的地。假设备用交换器时,不必特别设定如何传信给主交换器,因为
postfix自己能从DNS查出如何转信给主交换器。不过,前提是你必须让postfix知道自
己是哪一个网域的备用交换器。你的 postfix系统是哪些网域的备用交换器,那些网域
的名称就必须被列在relay_domains参数中。当寄信方的MTA发觉收信网域的主交换器离
线了,它会试着联系优先度次高的交换器,直到有一个备用交换器能够收下邮件地址为
止。如果你的postfix系统是某个网域的备用交换器,而且该网域被列在
relay_domains参数中,则postfix会收下该网域的邮件,并将其排入队列。每隔一段时
间,postfix会扫描它的队列,并检查是否有优先度更高的邮件交换器恢复连接,如果有
,则交出先前代收的邮件。
如果不能交出邮件,postfix会持续尝试,直到邮件在队列里等待的时间超过
maximal_queue_lifetime所指定的时限为止。此参数的默认值为五天,如果邮件在等待
队列里待的时间超过此上限,postfix会发出退信通知函给寄件人。如果你事先知道主交
换器停机的时间会超过五天,可以适度提高时限。
转发列表
postfix可从relay_domains参数与DNS系统知道自己的备用交换器角色,但是它如何知
道转发的网域中有哪些有效收件人?如果备用交换器无法事先知道主交换器有哪些合法
邮箱,它势必被迫盲目收下所有邮件,等到主交换器恢复连接时,才会发现有哪些邮件
无法投递并退信给原寄件人。因此,我们郑重建议你在备用交换器设置一份列表,记录
受理网域有哪些合法用户,并定期与主交换器同步更新。
当备用交换器上的postfix server收到寄给relay_domains所列网域的邮件时,它会检
查relay_recipient_maps参数所指定的查询表,借此判断是否应该收下邮件,如不应收
下则直接拒收。relay_recipient_maps参数的设定方式如下:
relay_recipient_maps = hash:/etc/postfix/relay_recipients
relay_recipients查询表应该记录所有合法收件人的邮件地址。postfix只需要此表的
索引键,所以对应值可以任意填写(但不可不填)
对于人事变动频繁的网域,我们建议你应该研制一个同步程序,利用rsync、ssh、
crond等工具,自动从主交换器下载最新列表。
如果备用交换器的postfix不过滤转发网域的收件地址,会有什么后果?答案是备用交换
器会收到一大堆无法投递的垃圾邮件,并产生一大堆寄不出去的退信通知函。因为捏造
收件人是垃圾邮件发送者常用的手段之一,他们事先不知道你的邮件交换器有哪些用户
,于是以常用的人名来捏造收件地址,试图蒙混过关。此外,垃圾邮件也不可能会提供
有效的回信地址。
假如备用交换器与主交换器位于同一个局域网,除了使用rsync、scp、ssh、crond等传
统工具之外,还有更好的方法来进行列表的同步更新工作。比方说,将用户账号储存在
某种数据库中,像mysql、ldap等,让postfix能够进行实时查询。
在你设定了relay_recipient_maps之后,还必须面对一个潜在的问题;你必须将所有转
发网域的所有合法邮件地址都列入查询表,因为 postfix将拒收任何收件地址没出现在
查询表的邮件。如果你不知道某些网域的合法邮件地址,你可以为该网域设置一个无限
别名地址;
快速清空
为许多网域承接邮件的网络,时常会面临无法立刻送出邮件的困境,因为他们的顾客的
服务器不见得永远保持连接。在客户离线的情况下,ISP只能将收到的邮件暂时存放在队
列里,等到客户的服务器恢复连接时,再使用SMTP的ETRN命令,一次清空队列里的所有
邮件;
当一个网域的主交换器恢复连接并完成收信准备时,我们的队列里已囤积了大量要传给
该网域的邮件,让postfix逐一检查每一个队列文件的收信网域为何,将会损耗许多时间
。为此,postfix提供了一种称为“快速清空”(fast flush)的功能,可用来在队列
中找出寄给特定网域的所有邮件。快速清空功能是由flush daemon控制管理的,对于
postfix所代理的每一个收信网域,flush各准备了一份列表,记录该网域邮件在队列里
的编号。如此,在发出ETRN 命令之后,postfix可以迅速找出所有要投递到该网域的邮
件。
默认情况下,flush只管理relay_domains所列的网域。如果还有其他网域也需要快速清
空服务,你可以将它们的网域名称在fast_flush_domains参数中,像这样:
fast_flush_domains = $relay_domains, example.com
此例中,example.com是一个没列在relay_domains的网域。
你可以使用postqueue -s命令来通知postfix,某各快速清空网域已经准备好接收先前
累积的邮件了:
postqueue -s example.com
传输表
当你想改变默认的邮递流程时,可利用传输表(transport map)来达成愿望。也就是
说,如果你希望postfix以你指定的方式来处理特定网域的邮件,而不管DNS MX记录是
怎么设定的,你可将相关网域与传送方式写在一二传输表中,然后将transport_maps参
数指向此传输表。
本节讨论transport_maps参数的基本用法,后面几章会陆续谈到此参数在其他方面的应
用。transport_maps参数可指向一个或多个传输表,例如:
transport_maps = hash:/etc/postfix/transport
传输表的索引键可以是完整的邮件地址、网域名称或子网域名称。当收件地址或网域名
称符合传输表某个记录的索引键时,则以该记录的对应值所指定的传输法来投递该邮件
。
传输表内容
example.com smtp:[192.168.23.56]:20025
oreilly.com relay:[gateway.oreilly.com]
oreillynet.com smtp
ora.com maildrop
kdent@ora.com error:no mail accepted for kdent
传输表对应值的格式,随传输方法而异,但大体上符合transport:nexthop这样的格式
。某些传输方法的nexthop可表示成host:port形式,表示递送路径下一站的主机名与
通信端口。以下分别说明可组成对应值的三种元素:
transport
传输方法的名称。此名称必须是master.cf所定义的传输类型之一。如果你增加
了新的传输方法,则必须先在master.cf定义其名称与传输类型。
host
收信主机或网域。host只能搭配inet传输类型(smtp或lmtp)。postfix按照一
般收信网域的处理流程host:先查询mx记录来决定邮件的去处,如果没有mx记录,则传
到a记录所指的ip地址。如果将主机名称放在一对方括号内,则postfix会直接传信到
host的a记录所指的ip地址。但如果你直接使用ip地址,则一定要加方括号,例如
〔192.168.23.56〕
port
收信主机的通信端口。通常只有inet类型的传输服务才会指定通信端口。port
的格式可以是十进制数,也可以是/etc/services文件定义的服务名称。
上例列出的传输表内容,暂时了transport:host:port的多种可能组合,分别解释如
下:
example.com smtp:〔192.168.23.56〕:20025
收下所有写给example.com的邮件,然后使用smtp MDA传送到位于
192.168.23.56的主机,而且smtp MDA必须连接到该主机的port 20025,而非默认的
smtp port25。请注意,由于我们直接使用了ip地址,所以必须加上方括号。
oreilly.com relay:〔gateway.oreilly.com〕
收下所有要寄到oreilly.com的邮件,然后使用relay MDA转寄给
gateway.oreilly.com主机。由于没指定通信端口,所以relay使用默认的port25。由于
主机名称被放在方括号内,所以邮件是直接传到gateway.oreilly.com的A记录所指的ip
地址,而非mx记录所指的ip地址。
relay MDA是postfix2.0版以后才引进的,它修正了队列调度算法可能引起的潜在效能
瓶颈。当你要将入站邮件送到内部系统时,应该直接通过relay MDA,以避免这类邮件与
出站邮件竞争资源。
oreillynet.com smtp
收下所有目的地为oreillynet.com网域的邮件,然后交给smtp MDA执行投递操
作。由于没指定host:port,所以smtp依照oreillynet.com网域的DNS MX或A记录来决
定目的地,并使用port 25来联系收信服务器。实际上这个例子实属多余,因为只要将
oreillynet.com列在relay_hosts或relay_domains参数,就可以达到相同效果。
ora.com maildrop
收下所有写给ora.com网域的邮件,然后交给maildrop处理。maildrop的运作方
式必须被明确定义在master.cf中。由于maildrop不需要inet socket,所以不必指定
host:port。
kdent@ora.com error:No mail accepted for kdent
error是一种特殊的传输服务,它唯一的作用是当场拒收邮件。冒号之后的字符
串是回复给传送方的错误信息。
传输表不一定用来将邮件传递到外界,也可以用于将特定邮件交给本地系统,以便进行
特殊处理。比方说,过滤邮件内容、暂时扣留某个网域的所有邮件等。
评论暂时关闭