- 論壇徽章:
- 0
|
![]()
Postfix 體系架構(gòu)概述
本文最后修改時(shí)間: 2005年10月22日 13:27
介紹
本文通過(guò)個(gè)人對(duì)Postfix的使用和官方文檔的介紹,對(duì)Postfix的體系結(jié)構(gòu)的一些見(jiàn)解,有理解不當(dāng)?shù)牡胤竭請(qǐng)發(fā)郵件指正,郵件地址:
![]()
。官方文檔:
http://www.clusting.com/postfix/docs/OVERVIEW.html
。
本文主要討論以下內(nèi)容:
Postfix如何接收郵件
當(dāng)一封郵件進(jìn)入Postfix郵件系統(tǒng)后,首先被放入
incoming queue(入口隊(duì)列)
. 下圖體現(xiàn)了處理一封新郵件涉及的主要進(jìn)程和順序。 帶數(shù)字的名稱(chēng)代表Postfix的命令或服務(wù)程序,不帶數(shù)字的名稱(chēng)代表Postfix的郵件隊(duì)列。
trivial-
rewrite(8)
網(wǎng)絡(luò)
->
smtpd(8)
^
|
|
v
\
網(wǎng)絡(luò)
->
qmqpd(8)
->
cleanup(8)
->
incoming
/
pickup(8)
maildrop
^
|
本機(jī)
->
sendmail(1)
->
postdrop(1)
- 網(wǎng)絡(luò)郵件通過(guò)
smtpd(8)
或
qmqpd(8)
服務(wù)器進(jìn)入Postfix,這兩個(gè)服務(wù)刪除郵件的SMTP或QMQP協(xié)議封裝(去掉協(xié)議頭,又叫解封),并且強(qiáng)制進(jìn)行一些郵件健康檢查(sanity checks)來(lái)保護(hù)Postfix,然后將郵件的發(fā)送者、接收者地址和郵件內(nèi)容交給
cleanup(8)
服務(wù)處理?梢酝ㄟ^(guò)配置
smtpd(8)
服務(wù)來(lái)阻塞服務(wù)器不想接收的郵件,具體的配置方法可以參看:
SMTPD_ACCESS_README
。
- 本機(jī)發(fā)送的郵件是由Postfix自帶的
sendmail(1)
兼容性命令來(lái)處理,并且被特權(quán)命令
postdrop(1)
放入
maildrop queue
隊(duì)列中進(jìn)行排隊(duì),這種方式使得即使Postfix郵件系統(tǒng)沒(méi)有運(yùn)行也能正常工作(本機(jī)能夠發(fā)送郵件,只不過(guò)發(fā)送完的郵件必須在maildrop queue中,直到Postfix郵件系統(tǒng)啟動(dòng)才能被發(fā)送出去。但對(duì)用戶(hù)來(lái)講,不必關(guān)心郵件什么時(shí)候被發(fā)送出去。)。 本地的
pickup(8)
服務(wù)從maildrop queue中讀取本機(jī)發(fā)送的郵件,并且強(qiáng)制進(jìn)行一些郵件健康檢查(sanity checks)來(lái)保護(hù)Postfix,然后將郵件的發(fā)送者、接收者地址和郵件內(nèi)容交給
cleanup(8)
服務(wù)處理。
- 內(nèi)部(Postfix郵件系統(tǒng)本身)發(fā)送來(lái)的郵件直接被提交給
cleanup(8)
服務(wù)來(lái)處理,這部分沒(méi)有包括在上面的圖示中。所謂內(nèi)部發(fā)送的郵件主要包括:被
local(8)
投遞代理轉(zhuǎn)發(fā)的郵件(參看下一小節(jié))、被
bounce(8)
服務(wù)(參看下一小節(jié))返回給發(fā)送者的郵件以及postmaster關(guān)于Postfix系統(tǒng)問(wèn)題的通知。
trivial-rewrite(8)
服務(wù)將郵件地址(發(fā)送者)重寫(xiě)為標(biāo)準(zhǔn)的郵件地址格式:"user@fully.qualified.domain",參看:
ADDRESS_REWRITING_README
。Postfix當(dāng)前版本本身不執(zhí)行地址重寫(xiě)語(yǔ)言(rewriting language),但是大多數(shù)情況下我們可以通過(guò)表查找或正則表達(dá)式來(lái)實(shí)現(xiàn)。
Postfix如何投遞郵件
一封郵件一旦到達(dá)
incoming queue
隊(duì)列,下一步就是進(jìn)行投遞。下圖簡(jiǎn)要表示了Postfix投遞器的主要組件。 帶數(shù)字的名稱(chēng)代表Postfix的命令或服務(wù)程序,不帶數(shù)字的名稱(chēng)代表Postfix的郵件隊(duì)列。
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
隊(duì)列管理器(圖中的
qmgr(8)
服務(wù))是Postfix郵件投遞的核心,它直接與
smtp(8)
,
lmtp(8)
,
local(8)
,
virtual(8)
,
pipe(8)
,
discard(8)
或
error(8)
投遞代理打交道,并且為一個(gè)或多個(gè)發(fā)送郵件地址發(fā)送投遞請(qǐng)求。其中,
discard(8)
和
error(8)
投遞代理比價(jià)特殊:它們丟棄或彈回所有的郵件(在上圖中沒(méi)有別列出)。
隊(duì)列管理器維護(hù)一個(gè)郵件已經(jīng)被打開(kāi)準(zhǔn)備投遞的
active queue
(活動(dòng)隊(duì)列)。
active queue
在有可能非常大的
incoming queue
(入口隊(duì)列) 或
deferred queues
(延遲隊(duì)列:上未發(fā)出的郵件隊(duì)列)中充當(dāng)了一個(gè)限制窗口的腳色,被限制的
active queue
防止了在重負(fù)荷情況下隊(duì)列管理器產(chǎn)生內(nèi)存溢出。
隊(duì)列管理器同時(shí)維護(hù)著一個(gè)單獨(dú)的不能被立即投遞出去的郵件隊(duì)列:
deferred queue
(延遲隊(duì)列),因此大量郵件在服務(wù)器上的積壓(backlog)不會(huì)減慢服務(wù)器對(duì)普通隊(duì)列的訪問(wèn)。要設(shè)置隊(duì)列管理器對(duì)被延遲投遞的郵件再次投遞的策略,請(qǐng)參看文檔:
QSHAPE_README
和
TUNING_README
。
trivial-rewrite(8)
服務(wù)根據(jù)它的本地和遠(yuǎn)程地址類(lèi)的定義決定每個(gè)郵件地址的格式,地址類(lèi)的定義請(qǐng)參看文檔:
ADDRESS_CLASS_README
。附加的郵件路由信息可以可以使用可選的
transport(5)
表來(lái)指定。對(duì)于誰(shuí)的郵件地址已經(jīng)被改變,
trivial-rewrite(8)
服務(wù)隨時(shí)查詢(xún)
relocated(5)
,這樣的(地址被改變的)郵件地址將被返回給發(fā)送者(服務(wù)器會(huì)給發(fā)送者發(fā)送一封說(shuō)明郵件)。
smtp(8)
客戶(hù)程序查詢(xún)一個(gè)目標(biāo)主機(jī)的郵件交換器列表,并根據(jù)郵件交換器列表的優(yōu)先級(jí)進(jìn)行排序,然后從高優(yōu)先級(jí)的服務(wù)器開(kāi)始依次嘗試以郵件交換器(目標(biāo)服務(wù)器)連接,直到其中一個(gè)服務(wù)器回應(yīng)為止。然后按照SMTP協(xié)議的要求封裝郵件的發(fā)送者、接收者和郵件內(nèi)容,這個(gè)過(guò)程包括將8-bit的MIME郵件內(nèi)容轉(zhuǎn)換為7-bit的編碼。
lmtp(8)
客戶(hù)程序使用一種類(lèi)似SMTP的已經(jīng)被優(yōu)化來(lái)遞送郵件給郵箱服務(wù)器(例如cyrus)的協(xié)議。使用
lmtp(8)
的優(yōu)勢(shì)是:一臺(tái)Postfix主機(jī)可以通過(guò)LMTP為多個(gè)郵箱服務(wù)器(pop3或imap服務(wù)器)服務(wù),同樣的,一臺(tái)郵箱服務(wù)器可以被多臺(tái)Postfix主機(jī)服務(wù)(接收多臺(tái)Postfix主機(jī)發(fā)送來(lái)的郵件)。
LMTP_README
文檔中給出了一些如何使用
lmtp(8)
客戶(hù)程序的例子。
local(8)
投遞代理(本地投遞代理程序)能夠識(shí)別標(biāo)準(zhǔn)的Unix郵箱格式mailboxes,Qmail的兼容郵箱格式maildir files,Sendmail風(fēng)格的
aliases(5)
數(shù)據(jù)庫(kù),sendmail風(fēng)格的為每個(gè)用戶(hù)設(shè)置的.forward文件。多個(gè)本地投遞代理可以并行運(yùn)行,但是并行投遞到同一個(gè)用戶(hù)通常是被限制的。
local(8)
投遞代理有兩種本地投遞方式:你可以配置它將本地郵件直接投遞到用戶(hù)主目錄下的用戶(hù)郵箱文件中;你也可以配置它將本地郵件遞交給一個(gè)外部的程序(例如procmail)來(lái)處理,或者你可以指派它將本地郵件遞交給其它的postfix投遞代理來(lái)處理。
virtual(8)
投遞代理(虛擬域投遞代理程序)是一個(gè)僅能投遞到Unix風(fēng)格的mailbox郵箱和Qmail風(fēng)格的maildir郵箱的透明代理程序。這個(gè)投遞代理可以為多個(gè)域投遞郵件,特別適合在單一的主機(jī)上為很多域提供郵件服務(wù)的場(chǎng)合。關(guān)于虛擬域投遞代理的配置,請(qǐng)參考文檔:
VIRTUAL_README
pipe(8)
信封是郵件處理系統(tǒng)的外部接口(Postfix的
sendmail(1)
是內(nèi)部接口)。該接口是Unix的兼容性接口:它在命令行和輸入流中提供信息,并且等待在中定義的進(jìn)程狀態(tài)代碼;
pipe(8)
mailer的例子,請(qǐng)參看文檔:
MAILDROP_README
和
UUCP_README
Postfix的后臺(tái)工作
前面兩節(jié)已經(jīng)對(duì)Postfix服務(wù)程序如何處理發(fā)送和接收郵件,這些服務(wù)器進(jìn)程都需要依賴(lài)那些在后臺(tái)工作的服務(wù)器進(jìn)程。下面我們將討論每個(gè)服務(wù)在它自己的環(huán)境中如何工作。帶數(shù)字的名稱(chēng)代表Postfix的命令或服務(wù)程序,不帶數(shù)字的名稱(chēng)代表Postfix的郵件隊(duì)列。
常駐內(nèi)存的服務(wù)
master(8)
就像一個(gè)督察員,它隨時(shí)監(jiān)視Postfix郵件系統(tǒng)的狀況。一般情況下當(dāng)執(zhí)行“postfix start”命令時(shí)該進(jìn)程就啟動(dòng),直到系統(tǒng)關(guān)閉時(shí)才結(jié)束。要啟動(dòng)用于接收和投遞郵件的Postfix服務(wù)器進(jìn)程,它們必須依賴(lài)
master(8)
(必須先啟動(dòng)master進(jìn)程),或者接收和投遞的服務(wù)器進(jìn)程由于某些原因需要重新啟動(dòng),它們也必須依賴(lài)于master進(jìn)程。在master.cf配置文件中指定的用于強(qiáng)制限定服務(wù)進(jìn)程個(gè)數(shù)的選項(xiàng)(參數(shù))也必須依賴(lài)
master(8)
進(jìn)程。下圖簡(jiǎn)單表示了Postfix啟動(dòng)時(shí)后臺(tái)程序啟動(dòng)的層次關(guān)系,圖中只列出了郵件處理的后臺(tái)守護(hù)進(jìn)程。
postfix(1)
|
|
postfix-script(1)
/
/
|
|
\
\
postsuper(1)
master(8)
postlog(1)
/
/
|
|
\
\
smtpd(8)
qmgr(8)
local(8)
anvil(8)
服務(wù)實(shí)現(xiàn)了客戶(hù)端連接和請(qǐng)求所有的
smtpd(8)
服務(wù)的速率限制,
TUNING_README
文檔可以指導(dǎo)我們處理SMTP客戶(hù)端的一些不規(guī)范行為(例如并發(fā)發(fā)送郵件等惡意行為)。
anvil(8)
服務(wù)是在Postfix 2.2 之后的版本中才加入的功能。
Network
->
smtpd(8)
anvil(8)
bounce(8)
、
defer(8)
和
trace(8)
服務(wù)安照每封郵件一個(gè)日志文件的方式分別維護(hù)著它們各自的隊(duì)列目錄樹(shù),這些信息將用于通知發(fā)送者(sender)郵件是否已經(jīng)被投遞出去。
trace(8)
服務(wù)用于支持(跟蹤)Postfix 的 “sendmail -bv”和 “sendmail -v”命令所產(chǎn)生的關(guān)于Postfix如何投遞郵件的報(bào)告信息。該功能是在Postfix 2.1之后的版本中加入的。關(guān)于
trace(8)
服務(wù)的更多信息,請(qǐng)參考:
DEBUG_README
。
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)
服務(wù)維護(hù)每個(gè)目的地址日志,并且實(shí)現(xiàn)了ETRN(Extended TuRN的縮寫(xiě),是SMTP協(xié)議的一個(gè)擴(kuò)展,允許兩臺(tái)計(jì)算機(jī)在一個(gè)TCP連接中進(jìn)行雙向郵件傳輸。) 和 "sendmail -qRdestination" 兩種功能,關(guān)于ENTR請(qǐng)參考:
ETRN_README
文檔。
flush(8)
服務(wù)使得被選中的隊(duì)列文件可以從
deferred queue
(延遲隊(duì)列)返回到
incoming queue
(入口隊(duì)列)以便請(qǐng)求繼續(xù)投遞。
flush(8)
服務(wù)在Postfix 1.0之后的版本中被加入。
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)
服務(wù)為Postfix進(jìn)程提供只讀表格的查詢(xún)服務(wù)(以只讀方式打開(kāi)表格), 這一功能可以越過(guò)chroot的限制,并且在多進(jìn)程中通過(guò)共享已經(jīng)打開(kāi)的一個(gè)表格的數(shù)據(jù),從而減少了同一表格被打開(kāi)的數(shù)量。
scache(8)
服務(wù)為Postfix的
smtp(8)
客戶(hù)維護(hù)連接緩存。當(dāng)一個(gè)被選中的目標(biāo)的連接緩存被開(kāi)啟時(shí),
smtp(8)
客戶(hù)不必在一封郵件傳輸完后立即斷開(kāi)連接,而是將該連接送入連接緩存服務(wù)器以便保持客戶(hù)端與服務(wù)器的連接,
smtp(8)
客戶(hù)繼續(xù)發(fā)出其它的郵件投遞請(qǐng)求,直到限定的時(shí)間到達(dá)才被斷開(kāi)連接(同時(shí)該連接從連接緩存服務(wù)器中清出)。在連接緩存被保存期間內(nèi),
smtp(8)
進(jìn)程可以隨時(shí)請(qǐng)求
scache(8)
服務(wù)使用被緩存的連接進(jìn)行其它的郵件投遞工作,而不必從新與服務(wù)器建立連接。為安全起見(jiàn),Postfix限定了連接可以被緩存(重用)的時(shí)間。
當(dāng)我們投遞郵件到一個(gè)多郵件服務(wù)器的目的地址時(shí),連接緩存可以幫助我們避開(kāi)那些沒(méi)有響應(yīng)的服務(wù)器,同時(shí)也提高了郵件的投遞速度。
smtp(8)
?
scache(8)
?
smtp(8)
?
showq(8)
服務(wù)列出Postfix的隊(duì)列狀態(tài)。該服務(wù)為
mailq(1)
和
postqueue(1)
命令工作。
Output
mailq(1)
post-
queue(1)
showq(8)
Postfix
queue
spawn(8)
服務(wù)在客戶(hù)執(zhí)行基于socket或FIFO請(qǐng)求時(shí)運(yùn)行其它非Postfix命令,命令的標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和錯(cuò)誤輸出都直接發(fā)送到通訊終端。關(guān)于
spawn(8)
服務(wù)的使用可以在
SMTPD_POLICY_README
文檔中看到一些實(shí)例。
tlsmgr(8)
服務(wù)在 Postfix
smtp(8)
客戶(hù)或
smtpd(8)
服務(wù)開(kāi)啟TLS功能時(shí)運(yùn)行,該進(jìn)程有兩重責(zé)任:
- 維護(hù) 隨機(jī)數(shù)(PRNG)作為 Postfix
smtp(8)
客戶(hù)或
smtpd(8)
服務(wù)進(jìn)程的TLS引擎的種子值,PRNG的狀態(tài)被定期地存入到一個(gè)文件,當(dāng)
tlsmgr(8)
啟動(dòng)時(shí)會(huì)讀取該文件。
- 維護(hù) Postfix
smtp(8)
客戶(hù)或
smtpd(8)
服務(wù)器的TLS會(huì)話的密鑰緩存。,被保存的會(huì)話密鑰通過(guò)減少TSL會(huì)話過(guò)程中的運(yùn)算量提高了系統(tǒng)的性能。
TSL的支持在Postfix 2.2 以后的版本中已經(jīng)加入,關(guān)于Postfix TSL的實(shí)現(xiàn)請(qǐng)參考:
TLS_README
文檔。
Network->
smtpd(8)
?
tlsmgr(8)
?
---seed--->
smtp(8)
?
->Network
/
/
|
|
\
\
smtpd
session
cache
PRNG
state
file
smtp
session
cache
verify(8)
服務(wù)在
smtpd(8)
服務(wù)接受一封郵件前交驗(yàn)它的發(fā)送者(sender)和接受收者地址是否存在(可用的)。
verify(8)
服務(wù)通過(guò)從投遞代理或者隊(duì)列管理器往Postfix 隊(duì)列發(fā)送消息來(lái)校驗(yàn)用戶(hù)是否可用。關(guān)于該程序的描述,請(qǐng)參:
ADDRESS_VERIFICATION_README
文檔。該服務(wù)在Postfix 2.1 之后的版本中加入。
Network
->
smtpd(8)
verify(8)
->
cleanup(8)
->
qmgr(8)
Postfix
queue
->
Delivery
agents
\
\
|
v
/
/
Postfix 的常用命令
我們將以Postfix郵件系統(tǒng)的常用命令擇要來(lái)結(jié)束該文檔。除了Sendmail的兼容命令
sendmail(1)
,
mailq(1)
, 和
newaliases(1)
外,Postfix系統(tǒng)有自己的工具命令集,下面將列出所有以post開(kāi)頭的命令:
Copyright© 2005 Clusting.com All Rights Reserved
聯(lián)系:
![]()
本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u/11372/showart_76974.html |
|