歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Postfix工作原理介紹

Postfix工作原理介紹

日期:2017/2/27 16:05:09   编辑:Linux教程
  傳統的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時,不一定含有構成有效郵件的所有必要字段,而且標頭裡的地址也可能需要被改寫成標准格式 ([email protected]),並依據規范的或虛擬的查詢表(如果有的話)將原本的地址改成其他地址。所謂的“清理程序”就是補足遺漏的標頭字段, 這部分工作由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接手處理。

  轉寄郵件
  有時候,郵件在委托給MDA之後,MDA會發現該郵件其實應該寄送到另一個系統的另一個賬戶。比如說,當MDA在用戶個人的forward文件 發現了另一個地址時,就會發現這種情況。照理說,MDA可以直接使用Smtp Client(即Smtp Daemon)送出郵件。不過,由於同一封信可能有多位收件人,為了照顧到每一位收件人,同時也為了在郵件日志上留下完整記錄,MDA應該依提交新郵件的 方式,讓郵件重新回到Postfix系統,由Postfix按照“來自本機的郵件”的程序來處理。

  Postfix的隊列管理器
  郵件本身的處理工作主要是由隊列管理器(Queue Manager)負責,每一個能收到郵件的Postfix組件,都有一個共同的目的地--隊列管理器。郵件進入隊列之前的關卡是Cleanup Daemon,因為只有經過清理的郵件,才有資格進入隊列。Cleanup將郵件排入隊列後,會通知Queue Manager去處理新郵件。每當Queue Manager察覺收信隊列有新信到達時,就會使用Trivial-Rewrite來決定郵件路由信息,這些信息包括傳輸方法、下一站以及收件人地址。

  Queue Manager總共維護四種隊列:收件(Incoming)、活動(Active)、延遲(Deferred)、故障(Corrupt)。新郵件通過Cleanup之後的第一站是“收件隊列”。假設系統資源空閒。Queue Manager會將郵件移入“活動隊列”,然後調用適當的MDA來投遞郵件,而投遞失敗的郵件則會被移入“耽擱隊列”。

  如果郵件被耽擱太久,或是被判定無法送達,則Queue Manager還要負責協調Bounce與Defer Daemons來產生一份遞送狀態報告,並傳回給系統管理員或送信者(或兩者)。在Postfix的隊列目錄下(默認位置是/var/spool/postfix/),除了上述四種郵件隊列目錄之外,還有bounce/與defer/目錄。這些目錄含有狀態信息,解釋特定郵件為何被耽擱或無法遞送,Bounce與Defer Daemon就是利用這些目錄下的狀態信息來產生通知函。

  投遞操作
  Postfix依據收件地址的類型,來判斷是否要收下郵件以及如何進行投遞操作。主要的地址類型有本地(Local)、虛擬別名(Virtual Alias)、虛擬郵件(Virtual Mailbox)以及轉發(Relay)。如果收件地址不在這四種主要類型之中,則郵件會被交給Smtp Client,通過網絡寄送出去(假設原信是來自有資格使用轉發服務的客戶端);否則,Queue Manager便依據地址的類型,選擇適當的MDA來投遞郵件。

  本地郵件
  如果收件人為Postfix本地系統的用戶(在運行Postfix的那台服務器上有Shell賬戶的用戶),則他們的郵件會被交給Local MDA處理,凡是收件地址的網域名稱與mydestination參數列出的任一網域名稱相符,這類郵件都算是本地郵件,對於送到任何mydestination網域的任何有效賬戶的郵件,Local MDA會先檢查收件人是否有個人的.forward文件,如果沒有,則郵件會被存入用戶的個人郵箱;否則,則依據.forward文件的內容來進行投遞操作(或轉寄到其他地方,或是交給外部程序處理)。

  對於需要轉寄到他處的郵件,將會被重新提交會Postfix,以便傳送到新地址。如果傳送過程發生了暫時性問題,MDA會通知Queue Manager,而郵件會被保存在延遲隊列等待下次的遞送機會;如果發生永久性問題,則要求Queue Manager將信息退給發信者。

  虛擬別名郵件
  寄給虛擬別名地址的郵件,全部都需要轉寄(Forward)到其真實地址,虛擬別名的網域名稱列在virtual_alias_domains參數中,每一個虛擬網域都可以有自己的一組用戶,不同的虛擬網域可以容許有同名的用戶。用戶與其真實地址之間對應關系,列在virtual_alias_maps參數所指定的查詢表中。當Queue Manager發現郵件的收件地址的網域部分virtual_alias_domains所列出的網域之一,則會重新提交郵件,以便傳到真實地址。

  虛擬郵箱郵件
  虛擬郵箱的網域名稱列在virtual_mailbox_domains參數中。每一個網域都可以有自己的用戶群,而且有各自獨立的命名空間,換言之,即不同的虛擬郵箱網域可以有同名的用戶。用戶與郵箱之間的對應關系,定義在virtual_mailbox_maps參數所指定的查詢表中,虛擬郵箱與系統上的Shell賬戶之間沒有關聯性,虛擬郵箱郵件的投遞操作由Virtual MDA負責運行。

  轉發郵件
  實際郵箱位於其他MTA控制管理的網域,但是Postfix願意代收並轉寄的郵件,稱為轉發郵件。這類網域的名稱列在relay_domains參數中,其郵件由smtp MDA通過網絡送到目標網域的MTA。當你假設郵件網關系統時,便可利用轉發功能收下Internet寄到內部網域的郵件,並轉寄到內部網絡的郵件系統上。

  其他郵件
  如果郵件的收件地址不屬於前述四類,則一律交給Smtp以遞送到正確地點,因為這類郵件必定是要送到系統本身之外的其他網域。先前在“來自網絡的郵件”曾說過,並非所有客戶端都有資格使用轉發服務。一般而言,我們會將轉發服務開放給與Postfix Server位於相同局域網絡的其他主機,好讓這些主機可通過Postfix Server寄信到Internet上的外界網域。

  當Smtp MDA收到外地郵件時,它會依據收件地址來判斷郵件應該送到哪個(或哪些)主機,然後依序連接到這些主機,直到有一部主機願意收下郵件為止。如果投遞過程發生暫時性問題,Smtp會通知Queue Manager將郵件放在延遲隊列,等待下次傳送的機會;如果發生永久性錯誤,則要求Queue Manager退信給發信者。

  當因暫時故障而不能連接的遠程主機恢復連接時,Postfix會先采取試探性動作,以免過多的延遲郵件使對方癱瘓。一開始,Smtp只會搭建有限度的幾條連接通道(數量可通過配置文件調整)到收件方,在發現對方能夠成功收下郵件之後,才會慢慢提升連接通道的數量(到一個可設定的上限);相反的,如果Smtp發現接送方有任何麻煩,它會立刻撤銷連接。

  其他傳送代理程序
  Postfix還提供了其他MDA,可用來處理特殊的地址或目的地。這些MDA需要在master.cf配置文件中設定妥當之後才有作用。此外,你還必須在class_transport或transport_maps參數指定的傳送表(transport table)中設定如何啟動它們。最常用的兩個特殊MDA是LMTP與PIPE。

  LMTP投遞
  LMTP是一種很類似SMTP的協議,但只能用於同一網絡上的郵件系統之間,或是同一主機上的不同郵件程序之間。舉例來說,如果需要將郵件送到不同的軟件包–該軟件可能與Postfix在同一台機器上,也可能位於局域網絡上的另一台主機,則Queue Manager可以調用LMTP MDA將郵件傳送給該軟件包。

  實際上,LMTP最常被用來將郵件交給特殊的POP/IMAP Server,以便使用特殊郵箱格式來存儲郵件。在這種情況下,由於只要POP/IMAP SERVER知道特殊郵件格式,所以只好使用標准的LMTP來交付郵件。如果LMTP投遞過程中出了任何問題,LMTP MDA會通知Queue Manager將郵件放在延遲隊列,等待下次傳送的機會。

  PIPE投遞
  Postfix提供了Pipe Daemon將郵件傳送給外部程序。實際上,Pipe經常被用來將郵件傳給外部的內容過濾程序(例如:病毒掃描系統、垃圾郵件分析程序)或其他通信媒介(例如:傳真機)。同樣,如Pipe無法順利傳出郵件,它會通知Queue Manager將郵件放在延遲隊列,等待下次傳送的機會。

  實際追蹤POSTFIX的郵件處理流程
  讓我們追蹤一封典型郵件如何通過POSTFIX系統。處理流程是一封郵件從發信方到達目的地(信封地址所指的MTA),然後又被轉寄到最終的MTA(收件人實際取信處)。

  例如:HELENE的賬戶位於一台運行POSTFIX的服務器,她使用自己習慣的MUA編寫郵件,然後調用POSTFIX的sendmail命令送出郵件。POSTFIX的sendmail程序從HELENE的MUA軟件中取下郵件,然後放在隊列的MAILDROP/子目錄下。

  接著,Pickup Daemon從該目錄取出郵件,交給CLEANUP DAEMON運行必要的清理程序,如果HELENE的MUA軟件沒提供地址from:,或是該地址沒使用完整的主機名稱,則Cleanup會自動補齊不足的信息以確保郵件格式符合標准。完成清理程序之後,Cleanup將郵件存入收件隊列,並通知Queue Manager,使其知道有一封新信正在等待投遞。

  如果Queue Manager已經准備好處理新郵件,它會將郵件搬移到活動隊列。由於HELENE的信是要送到其他網域系統的用戶,所以Queue Manager使用SMTP MDA來投遞該郵件。SMTP使用DNS查出哪些郵件服務器願意收下目的地網域的郵件,然後從中挑出最優先的郵件交換主機(MX HOST)並與該主機接洽,以SMTP協議送出HELENE寫的郵件。

  當目的網域的服務器上的MTA SMTPD收下HELENE的SMTP MDA送來的郵件。當smtpd確認它應該收下該郵件之後,它會將郵件交給Cleanup Daemon進行檢查,然後存入收件隊列。

  Queue Manager將郵件搬移到活動隊列,檢查收件人地址,然後使用LOCAL MDA來進行投遞操作。接著,LOCAL發現收件地址其實是一個別名,其真實地址位於另一個網域,所以將郵件與新地址信息傳給CLEANUP DAEMON,回到POSTFIX的隊列系統。

  當CLEANUP與Queue Manager處理郵件時,依靠TRIVIAL-REWRITE將地址轉換成標准格式,並判斷傳送方式以及遞送流程到下一站。

  當Queue Manager發現新郵件應該送到另一個網絡,則會調用SMTP來進行投遞操作,而SMTP會先向DNS查出哪些郵件服務器可能接收該網域的郵件。該網域的MTA收下這封郵件後,最後會將郵件交給LOCAL MDA,由它將郵件存入該系統的郵箱。

  到這個時候,Postfix就完成了它的工作。這時收件人現可以用他自己的MUA來閱讀郵件,至於這個MUA是直接從郵箱取信,還是使用POP或IMAP之類的協議通過網絡下載郵件,都已經不是Postfix所能控制的了。

  我們的例子只假設了最理想的簡單狀態,實際的傳送程序可能會遇到一些意外狀況,諸如網絡臨時斷線、遠程主機死機、郵箱空間不足。發生意外時,MDA必須通知Queue Manager,將郵件暫時放回延遲隊列,等待一段時間之後再重新投遞。

  除了臨時意外回影響投遞過程,還有一些情況也會影響,比方說,收件人並非實際的系統賬戶,而是IMAP郵件系統的一個賬戶,在這種情況下,Queue Mananger可能要通過LMTP MDA來投遞郵件,或是通過PIPE MDA將郵件送到一個事先確定的外部程序。

  Postfix還要面對各式各樣的變化與潛在的復雜性,幸運的,它本身的結構設計足夠穩定,幾乎能夠應付所有可想像到的情況,也有足夠的可塑性來適應未來的可能變化。

  隊列種類
  收件:Incoming 活動:Active 延遲:Deferred 故障:Corrupt 保留:Hold

  組件結構
  Master組件:主導郵件處理流程、其他組件的總管。配置文件:main.cf和master.cf。
  Qmgr組件:隊列管理器。各個postfix組件之間的合作依靠隊列交換郵件。
  Sendmail組件:服務器本機發送郵件。
  Postdrop組件:將郵件存入postfix隊列目錄下的maildrop/子目錄。
  Pickup組件:監視maildrop/子目錄,讀出新郵件,交給cleanup組件。
  Cleanup組件:補足遺漏的標頭字段。
  Trivial-Rewrite組件:地址處理,改成標准格式。決定路由信息,包括傳輸方法、下一站以及收件人地址。
  Smtpd組件:接收來自網絡的郵件,交給cleanup組件處理。
  Defer組件:郵件被延時時產生通知函。
  Bounce組件:郵件無法送達目的地時產生通知函。
  Dns組件:查找符合條件的郵件服務器。

  Postfix命令行工具
  postalias:創建或查詢別名數據庫
  postcat:顯示出隊列文件的內容,讓管理員可觀察滯留在隊列裡的郵件內容。
  postconf:顯示或改變postfix參數,可一次顯示一個參數,或是顯示所有參數。
  postdrop:將郵件放回到maildrop目錄,由postfix重新進行投遞操作。
  postfix:啟動或停止postfix系統,或重新讀取配置文件。也可以用於其他維護工作,包括檢查系統配置,以及清空隊列。
  postkick:對特定postfix服務發出請求。此工具的作用,主要是給shell scripts提供一個能夠與postfix溝通服務的管道。
  postlock:鎖定特定文件,確保能夠獨占訪問。此工具的作用,主要是讓shell scripts能使用兼容於postfix的鎖定方式。
  postlog:將特定的信息記錄到系統日志文件中。這是支持shell scripts工具,使其能以類似於postfix的樣式來記錄信息到日志文件。
  postmap:創建查詢表的DB數據庫或查詢查詢表內容。postfix有許多配置信息都是記錄在postmap所建的查詢表數據庫中。
  postqueue:讓一般的用戶能夠有限度地訪問postfix隊列。可能改變隊列的訪問方式需要有管理員特權才能進行,而這方面的訪問能力由postsuper命令提供。
  postsuper:供管理員訪問postfix隊列。管理員可刪除郵件、扣留郵件(搬到hold隊列)、取回郵件(將郵件從hold隊列搬回active隊列),必要時,還可以修復隊列目錄結構。
Copyright © Linux教程網 All Rights Reserved