postfix架构简介是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
postfix怎样接收邮件
当一封邮件进入postfix系统时,它的第一站是一个叫incoming的队列。下图展示了新邮件处理的主要流程,带数字的表示命令或程序,不带数字的表示队列.
trivial- rewrite(8) |
||||||
Network | -> | smtpd(8) | ^ || v | |||
\ | ||||||
Network | -> | qmqpd(8) | -> | cleanup(8) | -> | incoming |
/ | ||||||
pickup(8) | <- | maildrop | ||||
^ | |
||||||
Local | -> | sendmail(1) | -> | postdrop(1) |
-
网络上的邮件通过smtpd或qmqpd服务进入postfix,这两个服务会移除掉邮件的smtp或qmqp协议的封装信息,对邮件进行健全检查来保护postfix,然后将发件人,收件人和邮件内容提交给cleanup服务。可以通过配置smtpd来阻止那些不想要的邮件。
-
通过sendmail命令可以从本地提交邮件给postfix,邮件通过postdrop命令进入maildrop队列,这个过程在postfix没有运行时也可以进行。本地服务pickup会对本地提交的邮件进行健全检查,然后将发件人,收件人和邮件内容提交给cleanup服务。
-
从内部来源的邮件会直接传给cleanup(8)服务,这些来源在上表中并没有展示出来,比如由local(8)转发的邮件,delivery agent,由bounce(8)退回给sender的邮件,server,postmaster的通知邮件。
-
cleanup(8)实现了邮件进入队列前的最最后处理阶段。它会补上缺失的From:和其他头部信息,并将地址转换为规范格式。此外,它还可以配置成对邮件内容进行轻量检查和正则检查。cleanup(8)将处理好的邮件变成一个文件交给incoming队列,并能知队列管理器有新邮件到达。
-
trivial-rewrite(8)将邮件地址重写成标准格式。当前,postfix并没有实现一种重写语言,但是通过lookup表可以实现很多重写,此外还可以通过正则表达式来实现。
postfix怎么投递邮件
一旦一封邮件进入了incoming队列就开始了投递流程,下表展示了postfix投递邮个的整个过程:
trivial- rewrite(8) |
smtp(8) | -> | Network | |||||
/ | ||||||||
^ || v | – | lmtp(8) | -> | Network | ||||
/ | ||||||||
incoming | -> | active | -> | qmgr(8) | — | local(8) | -> | File, command |
^ || v | \ | |||||||
– | virtual(8) | -> | File | |||||
deferred | \ | |||||||
pipe(8) | -> | Command |
-
队列管理器qmgr(8)是postfix进行邮件投递的心脏,它连接smtp(8),lmtp(8),local(8),virtual(8),pipe(8),discard(8),error(8)投递代理,然后发送投递请求投递给多个收件人。discard和error代理比较特殊,它们会丢弃和回弹所有邮件,在上表中并没有展示这两个服务。队列管理维护着一个小的active队列,队列里的邮件是将要进行投递的邮件。active队列对于有可能会很大的incoming和deferred队列来说就像一个有限大小的窗口,这个窗口限制可以使得postfix不会因为队列过大而将内存用完。队列管理器维护着一个 deferred队列保存那些不能投递的邮件,这样即使有大量的邮件积压也不会影响正常队列的访问。
-
trival-rewrite(8)将每一个收件人地址按本地和远程进行分类。附加的路由信息可以通过transport(5)表指定。trival-rewrite不定期地查询relocated(5)表来判断哪些收件人地址已经改变,发给这些收件人的邮件将返回给发件人并加上说明。
-
smtp(8)邮件发送客户端会查询一系列mx服务器作为目标地址交将按优先级排序,逐个尝试这些服务器直到其中一个有响应为止,然后按照协议组装好收件人,发件人和邮件内容,包括了将8-bit MIME转换为7-bit编码。
-
lmtp(8)客户端使用类smtp协议,是一种为了投递邮件而优化过的协议。这种做法的好处是一个postfix可以对接多个邮件服务器,当然一台邮件服务器也可以对接同一个postfix。
-
local(8)代理能识别unix风格,兼容qmail邮箱目录文件,sendmail风格的邮件等等。
-
virtual(8)代理是一个最简单的代理,只能投递unix风格和qmail格式的邮件。不过,它可以为多个域名进行投递,所以特别适合在一台机器上作为多个小域名的host。
-
pipe(8)邮寄者是一个与外部邮件处理系统对接的外发接口,兼容unix。
Postfix behind the scenes
-
master(8)是postfix邮件系统的监控者,在postfix start命令时启动,并伴随着系统的整个运行过程。它负责启动postfix的进程来接收和投递邮件,并在服务意外终止时重启服务,根据master.cf中的配置项来限制服务进程的数量。
-
anvil(8)服务为smtpd服务实现了客户端连接和请求频率限制:
-
Network->smtpd(8)<->anvil(8)
-
bounce(8),defer(8),trace(8)每个服务都维护了一个自己的队列目录树,每封邮件对应一个文件,postfix利用这些信息来发送“失败“,”延迟“或”成功“这些投递状态通知给发件人。
-
cleanup(8) -> qmgr(8)
Postfix
queue-> Delivery
agents^
||
v|
v(Non-)
delivery
notice<- bounce(8)
defer(8)
trace(8)<- Queue id,
recipient,
status^ || v Per-
message
logfiles -
flush(8)服务为每个目标维护日志。将延迟队列中的邮件转移到incoming队列进行投递。
-
incoming
^
deferred^
|smtpd(8)
sendmail(1)
postqueue(1)– Destination
to flush-> flush(8) <- Deferred
destination,
queue id– Delivery
agents,
qmgr(8)^ || v Per-dest-
ination
logs -
proxymap(8)为postfix进程提供了只读和只写的表查询服务,这种方式避免了chroot的限制,查询表可以在多个进程共享,因此减少了表的打开数量,并实现了单个进程来更新表。
-
scache(8)服务为smtp进程维护连接缓存,可以针对指定目标开启连接缓存,为了安全起见,postfix会对连接重用的次数进行限制。
-
showq(8)服务可以列出posfix队列状态,供mailq和postqueue命令使用。
-
spawn(8)服务运行非postfix指令。
-
tlsmgr(8)服务在postfix为smtp和smtpd开启了TLS时运行,它有两个职责:
-
维护一个伪随机数生成器生成种子供TLS引擎使用,生成器的状态定期保存到一上文件,并在tlsmgr启动时读取。
-
维护TLS会话中的key的缓存,缓存key可以提高TLS会话的性能。
-
verify(8)服务在smtpd在接收邮件前验证发件人或收件人是否可投递,验证服务先去地址验证缓存进行查询,如果没有找到则向postfix队列注入一个探测消息,由投递代理或队列管理器处理状态更新。
-
postscreen(8)服务可以放在smtpd进程前面,它的目标是从网络接收连接并判断哪些smtp客户端允许访问postfix。postscreen的目的是阻止垃圾邮件的发送者,它会维护一个临时的白名单,白名单中的客户端可以跳过检测。
Postfix support commands
-
postfix,这个命令是用来启动,关闭和重启系统用的,是预留给超级用户使用的。
-
postalias,用来维护aliases(5)类型数据库。
-
postcat,用来展示队列中的文件内容,这是一个初级的工具,可能会被有更强大功能是命令取代。
-
postconf,展示或更新main.cf中的参数。
-
postdrop,一个邮个发送工具,将邮件放到maildrop队列。
-
postkick,使得一些内部通信管道可用,比如供shell脚本用。
-
postlock,提供了postfix兼容的邮筒锁,比如供shell脚本用。
-
postlog,提供了postfix兼容的日志供shell脚本用。
-
postmap,维护了postfix查询表,比如canonical(5),virtual(5)。
-
postmulti,为每一个postfix实例重复”postfix start“命令,并支持创建,删除postfix实例。
-
postqueue,是享有特权的命令,供sendmail和mailq用来刷新或列出队列用。
-
postsuper,用来维护postfix队列,它移除旧的临时文件,并移动队列文件到正确的目录,这个命令在postfix启动和重启时运行。