茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1729362 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
IMG_60D_00204.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

小企鵝開談 : [轉貼]建置 POSTFIX 伺服器

發表者 討論內容
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]建置 POSTFIX 伺服器(壹~叁章)

壹、從 sendmail 到 postfix

Fedora 系統預設的郵件伺服器是 sendmail ,而 postfix 是不會自動安裝的,如果一開始安裝系統時忘記把 postfix 裝起來,可以使用下列指令將套件補上:

yum install postfix

為了便利於 sendmail 和 postfix 之間進行切換,系統提供一個工具可以自動幫我們作設定遷移,依底下指令安裝:

yum install system-switch-mail*

要進行郵件伺服器切換,請輸入 system-switch-mail 然後選擇您想要用的伺服器(sendmail 或是 postfix),雖然選好後系統會自動將伺服器關閉和啟動好,但我們依然可以使用底下指定來確定這件事(假設您選中的是 postfix):

service sendmail stop

service postfix start

這樣 postfix 應該就會開始提供服務了!什麼都不用設定就會跑了嗎?是的!

postfix 本身也可以當成指令來執行,例如:

postfix check    檢查設定檔是否正確,相關資料夾是否建立,檔案擁有人和存取權限是否正確

postfix start        啟動服務

postfix stop        停止服務

postfix abort        立刻中斷服務

postfix reload       重新載入設定檔

postfix flush        將佇列中的郵件全部寄出去

 

貳、postfix 工作流程


sendmail 與 postfix 最大的不同在於程式結構上,sendmail 以一支大程式來執行所有的工作,而 postfix則改採模組化設計,這種設計的好處在於:程式碼容易維護、模組功能有彈性容易擴充。底下將針對組成 postfix 的每個模組,它們各是負責哪些工作,又如何與其它模組配合,作一個解說。

底下先說明收信流程:

  trivial-
rewrite(8)
Network -> smtpd(8)  
^
|
|
v
  \
Network -> qmqpd(8) ->
cleanup(8)
-> incoming
  /
  pickup(8) <- maildrop
  ^
|
Local -> sendmail(1) ->
postdrop(1)
  • 當郵件由本機寄出時,系統執行 sendmail 程式,由於之前執行過 redhat-switch-mail 的關係,此時 sendmail 已經連結到 postfix 套件中的 postdrop 模組,postdrop 模組負責將郵件存放在 maildrop 資料夾中,等候 pickup 處理, pickup 模組會對郵件內容進行檢查以保護 postfix 系統不會受到異常郵件的攻擊(譬如利用欄位溢位來破解主機)。
     
  • 如果郵件是來自網路,postfix 套件中的 smtpd 將會接收郵件並進行郵件過濾,為了應付千變萬化的偽裝郵件, 我們可以透過修改 UCE 設定檔(例如:來自 sendmail 的 access 設定檔),設定黑名單(或透過 RBL 黑名單資料庫取得黑名單)、 DNS 反查驗證,甚至是使用正規表達式來作字串匹配檢查等方法,進行嚴格的過濾。
     
  • 一般 SOHO 族為了節省連線費用會去修改 MTA 設定採用離線寄信方式,平時對外網路關閉,信件堆積在 Mail Server 上,然後在特定時間接通網路並將佇列中的信件同時寄出,這類信件將由 qmqpd 處理。
     
  • 郵件有時候是來自 postfix 本身的 bounce 模組(合併到 trivial-rewrite 中),例如:當郵件無法遞送時,bounce 模組會自動產生訊息以便通知寄信人。
     
  • 郵件有時候也會由 LDA 產生,這種情形包括:根據 alias 別名資料庫改寫過收信人的郵件,或是根據每個使用者的 .forward 檔案指定的轉信信箱修改過收信人欄位的郵件。

     
  • 除了上述因無法遞送郵件引發的問題會由 bounce or defer 模組產生通知郵件外,其它的錯誤產生時 postfix 也會自行產生通知郵件,例如:SMTP 通訊協定逾時,UCE 過濾規則衝突......等等,當然這種情形下只會通知 postmaster。
     
  • 以上五種情況產生的新郵件,最後都會由 cleanup 模組進行最後的處理。首先它會補足郵件中所缺少的欄位(例如來自 console 的信件將會缺省 From: 欄位),並根據完整郵件地址格式改寫寄信人欄位(例如:shane@localhost 改成 shane@mail.syups.tp.edu.tw),接著讀取 canonical(全名對應) 和 virtual(虛擬對應) 設定檔,根據該設定改寫收信人欄位,所有動作處理完畢後,郵件被放置在 incoming 資料夾中,接著就會通知 qmgr 模組有新郵件到了,由 qmgr 模組開始進行送信作業 。
     
  • 當 cleanup 模組進行郵件欄位改寫時,實際上是呼叫 trivial-rewrite 模組來處理,和 sendmail 不同的是,postfix 並未發展出一套複雜的巨集語言來進行 rewrite 作業,相反的是採用單純的查表法來解決, 這也是 postfix 被批評功能不如 sendmail 強大的原因。postfix 開發者似乎認為 sendmail 之所以漏洞百出,與 rewrite 巨集語言大而無當有直接相關(純屬猜測)。

底下說明寄信流程:


  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 模組是整個郵件伺服器的核心,它將視情形呼叫 local、smtp、pipe 等 agent 模組來進行寄信作業。local 模組就是 LDA ,它負責將信件分到使用者信箱。smtp agent 顧名思義是指 smtp client 程式,而非 smtpd ,它負責將信件透過 SMTP protocol 遞送到網路上的遠端郵件伺服器。pipe 則用來處理傳真或其它封閉式網路系統的特殊電子郵件通訊協定。

    當郵件出現遞送失敗的情形,qmgr 就會將郵件放在 deferred 佇列中,以避免延遲其他郵件的遞送作業 。

    正在處理中的郵件會被放在 active 佇列中,該佇列僅存放少量郵件,因為若郵件過多的話將會耗用大量記憶體,來自 incoming 資料夾的郵件,會根據郵件到達的順序依序進入 active 佇列, 而 deferred 佇列的郵件,將會暫停四個小時後,重新排入 active 佇列。

    此外,qmgr 也會根據 relocated 設定檔來產生通知郵件,relocated 設定檔用來設定帳號或網域遷移的通知訊息,當 qmgr 發現某封郵件的收信人已經遷移,則會呼叫 trivial-rewrite 模組處理 。
     

  • 在遞送郵件的過程中,qmgr 會呼叫 trivial-rewrite 模組解析收信人地址,通常 trivial-rewrite 模組只會區分該信件是要到達本機,還是需要 relay,當然我們也可以透過 transport 設定檔,來要求 trivial-rewrite 模組針對特定收信人地址遞送給特定主機(通常用來設定將 mail gateway 收到的郵件轉給下屬郵件伺服器)。
     
  • 當信件無法遞送時(收信人或收信主機不存在或無回應), qmgr 將障礙情形以郵件型式遞交給 cleanup 模組(在收信流程中)進行收信作業,同時將原始郵件排入 deferred 佇列,等待延遲遞送。如果無法遞送的原因是通訊協定或設定檔錯誤造成的(這種情形應通知管理員,而非寄信人),則信件將直接由 qmgr 處理。

     
  • local 模組主要工作是將信件寫入使用者的信箱中,或是根據 alias 設定或 .forward 設定改寫收信人欄位,並遞交給 cleanup 模組進行收信作業,除了 postfix 預設的 local 模組外,其它在 sendmail 中經常使用的外掛 LDA,例如:procmail,也可以繼續使用,這是因為 postfix 的 local 模組是與 sendmail 完全相容的。

其它幕後常駐模組:

  • master:這個模組用來監督 postfix 所有模組,是否有依照 master.cf 中的設定執行,並會將超過上限的行程砍掉,以符合效能調校相關設定值。
     
  • flush :這個模組用來維護 incoming 郵件佇列的雜湊表,它將郵件依收信目的地分類,建立多個雜湊表,當用戶端送出 ETRN syups.tp.edu.tw 要求時,則可以將要給 syups.tp.edu.tw 的郵件(有些可能還在排隊)優先全部寄出。
     
  • showq:當執行 mailq 指令查詢郵件佇列時,就是由此模組提供資訊。
     
  • proxymap:用來讀取設定檔,並提供設定檔內容給其他模組,之所以這樣做是為了減少硬碟 I/O 存取。
     
  • spawn:用來呼叫執行外掛程式,透過這個機制我們可以執行非 postfix 提供的過濾程式,例如:病毒過濾。
     
  • pipe:這個模組用來將郵件佇列中的郵件資料結構,傳輸給外部程式處理。當 master 模組啟動外掛程式時,透過 pipe 當白手套就可以和外掛程式憑藉參數傳遞來溝通。
     

常用工具:

  • postalias:
    當我們執行 newalias 時,由於 redhat-switch-mail 的作用,其實是在執行 postalias ,所以你也可以不用因此改變使用習慣喔!如果要透過這個指令建立 alias 雜湊表,指令格式比 newalias 稍微複雜一點: postalias hash:/etc/postfix/aliases,這道命令也可以用 postmap 代替,例如: postmap hash:/etc/postfix/aliases,其餘功能請參閱 postmap 的介紹
  • postcat:這是一個郵件 RFC 格式的剖析器,可以將原始郵件顯示成容易閱讀的格式,有點像用 outlook express 看到的郵件內容(假如在郵件上按右鍵查看原始內容,你可能就看不懂了),請指定要查看的檔名: postcat /var/spool/postfix/deferred/filename,由於檔名都是使用郵件編號,如果不知道要看的郵件是什麼檔名時,可以用下面的指令查詢!
  • postqueue:用來取代 mailq 指令,使用 -p 參數就可以將郵件依編號順序列出郵件標頭(寄信人、收信人和信件主旨),方便檢索查詢! -s 參數則是列出前面介紹過的 flush 雜湊表!
  • postsuper:這個命令用來操作佇列中的郵件,只有 root 身分才能執行。參數 -d 用來刪除郵件, -r 用來將郵件排到不同佇列裡( maildrop 、 incoming 、 active 或 deferred ), -p 當伺服器(或 postfix 程式)當掉重開機後,用來救回工作到一半的郵件。
  • p ostconf:這是個功能強大的工具,除了可以用來顯示 main.cf 的詳細設定內容外(自動分類),也可以用來除錯,甚至還提供修改設定的介面,例如:postconf -e
    mynetworks=168.100.189.0/25 ,這個功能如果結合 script 程式來運作,就能做到透過網頁遠端管理設定擋。我們經常使用 -n參數,來查看 postfix 設定檔擺放的位置!
  • postmap:用來取代 makemap 指令,並且與 makemap 完全相容,支援的檔案類型包括: btree 、 dbm 、 hash當用來建立資料庫檔案時,語法如後: postmap hash:/etc/postfix/access,這個工具也可以用來查詢資料庫檔案裡的內容,例如: postmap -q 172.16.2 hash:/etc/postfix/access,這會列出該行的規則,如要刪除可以使用: postmap -d 172.16.2 hash:/etc/postfix/access,透過這個方式能及時有效的管理,不用重新修改 access 文字檔,然後雜湊成資料庫,然後重新啟動 postfix 載入設定檔等等,作一連串動作!

 

叁、main.cf 基本設定

postfix 最被人稱道的地方在於設定檔的可讀性很高(當然是跟 sendmail 比),而在主要設定檔 main.cf 中,需要自行定義的東西並不多,而且這些參數就算不去定義,依照預設值也可以運作:

由本機寄出的郵件要使用哪個網域名稱

在 sendmail 中,這個功能稱為網域偽裝,也就是說可以和主機名稱不同,例如:本機名稱為 mail.syups.tp.edu.tw,而寄出的郵件其寄信人欄位則可以使用 syups.tp.edu.tw。(須配合 DNS MX 紀錄使用)

myorigin=syups.tp.edu.tw

不使用簡略名稱時,設定如下:

myorigin=mail.syups.tp.edu.tw


由於主機名稱與網域名稱會被反覆引用在不同設定值,為了簡化設定,通常是定義成變數:

myhostname = mail.syups.tp.edu.tw
mydomain = syups.tp.edu.tw

#myorigin=$mydomain
myorigin=$myhostname (省略時,視同此設定)

當然以上變數也可以省略不定義,這種情況下 postfix 將使用 gethostname( ) 函數取得系統設定。如果是將 myorigin 省略,則視同為設定 $myhostname。

另外,如果本機是某個網域的 mail gateway,也就是說網域內的所有郵件伺服器,都必須把它們的郵件送到本機來處理,這種情形可以使用 masquerade_domains 讓 postfix 自動缺省寄信人欄位中的郵件主機名稱,例如:

masquerade_domains = $mydomain

假設 $mydomain 是 syups.tp.edu.tw,則無論信件是來自 stu.syups.tp.edu.tw 或 mail.syups.tp.edu.tw 都將會被改寫成 syups.tp.edu.tw。

如果你有某些帳號不想要讓 mail gateway 改寫寄信人欄位,可以設定底下的參數(預設不啟用):

masquerade_exceptions = root

啟用 masquerade_domains 功能只會改寫郵件標頭與信封裡的寄信人欄位,如果想要將收信人欄位一併改寫,可以設置底下的參數:

masquerade_classes = envelope_sender, envelope_recipient, header_sender, header_recipient

注意:這樣做將使得 mail gateway 無法寄信給下屬郵件伺服器,因為收信人欄位 @ 後面的郵件網域名稱會被改寫成 mail gateway 自己。

要接收來自哪些網路介面的郵件


底下參數是用來定義要處理來自哪些網路介面的郵件,當未定義時,預設會處理本機所有網卡(可以使用 ifconfig 觀察),如果定義成 localhost ,則只有 loopback 介面會接受郵件,也就是說只接受主控台或 WEB 介面寄出的郵件,不接受 MUA(outlook express)遞交的郵件:

inet_interfaces = localhost

設定成 all ,表示接受所有網路介面的郵件,這是預設值:

#inet_interfaces = all

設定成 $myhostname ,表示要透過 DNS 反查 IP,當本機 IP 是由 DHCP 指派,而 DNS 又未被設定成 DDNS ,將會出現不可預期的錯誤!

#inet_interfaces = $myhostname

底下範例將會在有 DNS A 紀錄的 IP 以及 loopback 介面上提供服務,在這裡我們可以發現 main.cf 中有許多設定可以設定超過一個值,將它們用逗號區隔開來就行了!(底下的設定範例不適用於 postfix 本身兼 Proxy/NAT 的場合)

#inet_interfaces = $myhostname, localhost

哪些網域的郵件是給本機的

定義在這裡的網域將被視為是 local 網域,換句話說寄到這些網域的郵件,會被接收並分信給本機使用者,相當於 sendmail 中的 local-host-name,當不使用 DNS MX 紀錄時,設定如下:

mydestination = $myhostname localhost.$mydomain

如果有使用 DNS MX 紀錄,需修改為:

mydestination = $myhostname localhost.$mydomain $mydomian

假設該伺服器在 DNS 上有多筆 A 或 CNAME 紀錄,則須將這些紀錄也寫上去,例如:

mydestination = $myhostname localhost.$mydomain $mydomian www.$mydomain ftp.$mydomain


哪些郵件要進行 relay

在 postfix 中針對轉信網域作處理的參數有兩個,一是用來定義區域網路網段的 mynetworks,另一個是 relay_domains,未被定義在這些 參數裡的網域,系統將拒絕轉信!

首先說明區域網路網段設定,相關參數共有兩個:mynetworks_style 和 mynetworks,前者用來宣告區域網路類型,subnet代表是子網路,這也是預設值,當未作設定時,postfix 將會自行根據 ifconfig 上登記的 IP 和 網路遮罩作運算,自動求出子網路的範圍;如果設定成 class,則是不理會遮罩,自動信任同一個 class 等級的電腦,如果該伺服器使用撥接上網,這樣設定將使得同一家 ISP 的撥接用戶,都可以利用本伺服器轉信,這是非常危險的(除非你是 ISP 公司);設定成 host 則僅該單機可以寄信。

#mynetworks_style = class
#mynetworks_style = subnet
#mynetworks_style = host

mynetworks 用來設定區域網路的 IP 範圍,剛才設定的 mynetworks_style 將會被此參數取代,如果省略不設定,則由 mynetworks_style 來決定要 binding 的網卡:

mynetworks = 168.100.189.0/25

mynetworks = 168.100.189.10

除了上面範例,設定成網段或單機外,也可以指定多個網段(多重 NAT 網域時),或是使用設定檔(條列式),或使用雜湊表(makemap hash 或 postmap hash: )。

#mynetworks = 168.100.189.0/28, 127.0.0.0/8
#mynetworks = $config_directory/mynetworks
#mynetworks = hash:/etc/postfix/network_table


有關轉信網域設定,以上兩個參數就已經足以應付各種需求,但為了與 sendmail 相容,仍然保留 relay_domains 設定,與 sendmail不同的是,如果該 relay_domain 在 DNS 上有定義 MX 紀錄,將會被 postfix 故意忽略,而當成 mynetworks來處理,這是為了避免被利用作為廣告信回信站台;relay domain 對 sendmail 而言是雙向的,但對 postfix而言則是單向的,只能寄信,而且不代收回信,因此如果要將本機設定成 mail gateway,請使用 mydestination,而不要使用 relay_domains(注意:很多介紹 postfix 的文章都犯此錯誤!)建議不要設置此參數,使用預設值「不啟用」。

#relay_domains = $mydestination

當本機為某台 mail gateway 的下屬伺服器時,必須要將所有寄出的信件交給 mail gateway 代轉,這時可以設定 relayhost 為該 mail gateway 的 IP。預設不啟用。

#relayhost = $mydomain
#relayhost = mg.syups.tp.edu.tw
#relayhost = [172.16.1.3]

哪些情況須通知管理員

所謂管理員是指 postmaster 信箱,請修改 alias 設定將 postmaster 對應成管理人員真正使用的信箱,以免警告郵件沒人理會堆積在伺服器上。

notify_classes 參數用來決定哪些情形下須通知管理員,預設值如下:

notify_classes = resource, software

可以使用的參數包含:


bounce 當一般郵件無法交遞時,產生警告信給管理員(會附上原始郵件的內文)。注意:郵件無法交遞時,本來就會寄警告信給發信人,管理員收到的不過是複製版本。
2bounce 當寄給發信人的警告信無法交遞時, 產生警告信給管理員。
delay 當對方站台忙碌要求延遲遞送時,產生警告信給管理員(不會附上原始郵件)。
policy 對方寄信的要求因為不符合安全規範已經被回絕(被規則過濾掉),此時會產生警告信給管理員。
protocol 通訊協定錯誤時產生警告信通知管理員,我們比較感興趣的是對方使用了哪些不合法的 SMTP 命令。
resource 系統資源短缺導致信件無法寄出,例如:硬碟 I/O 錯誤,此時會產生警告信給管理員。
software 軟體安裝不全或程式錯誤造成的問題,產生警告信給管理員。

 Proxy/NAT 地址

當郵件伺服器位於 proxy 或 NAT 防火牆的後方時,此參數用來設定真實 IP,以避免因為 MX 紀錄與本機 IP 不同,將該信誤判成需 relay到其它 MX 的郵件;當本機所查詢的 DNS 其回覆 MX 紀錄為虛擬 IP 時,此種現象將不會發生,因此在 NAT 虛擬網域中,架設內部專用 DNS 是非常重要的,請參考 網路名稱系統一文的解說。預設值為:

proxy_interfaces =

當本機被設定成其它網域的備份 MX 時,如果未設置此參數,郵件會成為伺服器間互踢的皮球(去詢問其它網域的 DNS 查詢 MX 紀錄時,查到的必然是真實 IP,即使有架設內部專用 DNS 也沒用)。設定如下:

proxy_interfaces = 163.21.166.7

前一個主題 | 下一個主題 | | | |

討論串




Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|