传统的Sendmail将所有功能都集中在同一个程序里,这种结构我们称之为“单体式设计”(monolithic).Postfix采用专职负责的策略,不同的功能分别交由不同的专门程序处理,这种结构称为“模块化设计”(modular)。这些自成一格的专门程序,我们称之为组件(component)。大多数组件都是以daemon的形式存在,也就是常驻在系统内存里的连续动作的后台进程(background process)。
当Postfix被启动后,首先启动的是master daemon,它主导邮件的处理流程,同时也是其他组件的总管。在处理邮件的过程中,master会启动对应功能的组件来处理相关事宜,被master启动的组件,在完成交付的工作之后会自行结束;或者,如果组件的处理时间超过时限,或是工作量到达预定限度,组件也会自行结束。master daemon会常驻在系统中,当管理员启动它时,它从main.cf和master.cf这两个配置文件取得启动参数。
Postfix内部收信、发信流程图
整个处理流程分为三个阶段:接收邮件、将邮件排入队列、递送邮件。每个阶段由一组独立的Postfix组件负责。当一封邮件被收下并排入队列之后,队列管理器(Queue Manager)会启动适当的MDA,将邮件送到终点。
邮件如何进入Postfix系统
邮件有四种渠道可以进入Postfix系统:
1、Postfix可接受来自本机系统的邮件(本机用户或自主进程提交的邮件)。
2、Postfix可接受网络传入的邮件(来自MUA或者其他MTA)。
3、已经被Postfix收下并交给MDA的邮件,被MDA传回到Postfix(通常是为了转寄到另一个地址)。
4、当Postfix无法将邮件寄到目的地时,自己会产生退信通知函。
邮件有可能在进入Postfix之前就被拒绝了,或者因为暂时性的故障(网络断线、远程服务器响应暂时性的错误等),同样的邮件可能会每隔一段时间就重复进入Postfix系统一次,重新递送。
来自服务器本机的邮件
各个Postfix组件之间的合作全靠队列(Queue)交换邮件、Postfix系统有多个队列,这些队列全部队列管理器(Queue Manager)负责控制管理。Postfix组件可将邮件交付给Queue Manager,由其代为放入适当的队列。当需要处理特定工作时,Queue Manager将队列里的邮件交付给正确的组件。
在Unix系统上,当用户要寄出邮件时(不管这封信是寄到哪里),通常是使用sendmail包内的sendmail命令。Postfix提供了一个与此命令兼容的同名工具,也称为sendmail。当用户以Postfix的sendmail寄出邮件后,sendmail(postfix的版本)会使用postdrop程序将邮件存入Postfix队列目录下的maildrop/子目录。专门注意maildrop子目录有无变化的是Pickup Daemon,每当有新的邮件进入maildrop时,Pickup Daemon便会读出新邮件,然后交给cleanup daemon进入“清理程序”。
当邮件刚进入Postfix时,不一定含有构成有效邮件的所有必要字段,而且标头里的地址也可能需要被改写成标准格式(user@domain.tld),并依据规范的或虚拟的查询表(如果有的话)将原本的地址改成其他地址。所谓的“清理程序”就是补足遗漏的标头字段,这部分工作由cleanup daemon负责;地址的处理由Trivial-Rewrite Daemon负责。
经过Cleanup Daemon处理好的邮件,会被传入收件队列(Incoming Queue)。Queue Manager会不断的注意收件队列的变化,每当有新邮件进入收件队列时,便会用适当的MDA将邮件送到下一站,或直接送到最终目的地。
来自网络的邮件
来自网络的邮件由Postfix Smtpd Daemon接收进来,然后交给Cleanup Daemon运行清理程序,随后排入收件队列,由Queue Manager选择适当的MDA将邮件送到下一站或最终目的地。Smtpd有可能收到两种邮件,第一种是外界寄给Postfix所控制的网域的邮件(Postfix系统本身是邮件的终点站或网关),另一种是要寄到其他网域的邮件。
Smtpd一定会收下第一种邮件(如果收件人存在的话),至于第二种邮件(目的地在其他网域),就要看传邮件过来的客户端是否有资格。网络收下要寄到其他网域的邮件,并代为寄送到目的地的动作称为转发(relay)。在两种情况下,Postfix愿意提供转发服务:一是客户端符合配置文件限定的资格,二是收信网域是relay_domain参数所列出的网域之一。
通知函
当用户的邮件被延时时,或是根本无法递送到目的地时,Postfix使用Defer或Bounce Daemon产生一封新的通知函。这封通知函会被交给Cleanup Daemon,由它进行例行的清理程序之后再排入收件队列,由Queue Manager接手处理。
转寄邮件