對這文章發表回應
發表限制: 非會員 可以發表
肆、main.cf UCE(unsolicited commercial email)過濾
過去這類的郵件被稱為垃圾郵件,比較正式的稱呼是 SPAM 郵件,postfix 則稱此種郵件為 UCE,有那麼一點縮小打擊範圍的含意,因此使用 UCE 過濾並無法解決其它問題郵件(例如:匿跡郵件、病毒郵件、郵件炸彈)所帶來的困擾,請不要期望過高。
儘管如此,與 sendmail 使用 access 來進行存取控管相比較,postfix 的 UCE 過濾顯然要精細得多,彈性也比較好,以外掛方式讀取過濾規則使得管理員能隨時修改設定,並將它模組化,可以說是 postfix 最大的優點。
如前所述,postfix並不使用複雜的巨集語言來進行規則運算,而是採用較為單純的查表法來控制,但各位可不要小看它,它所支援的查表方式可謂琳瑯滿目,諸如:欄位比對(純文字檔,欄位以逗號或空格或定位點區隔)、DBM 檢索、HASH 雜湊、NIS 查詢、RBL 查詢.....等,比對規則也可以選擇採用正規表示法(regexp)或是 perl 改良過的正規表示法(pcre)。
UCE郵件測試
[root@linux postfix]# telnet 172.16.11.1 25
Trying 172.16.11.1...
Connected to 172.16.11.1.
Escape character is '^]'.
220 linux.syups.tp.edu.tw ESMTP Postfix
helo test.com // 嘗試假冒自己身份為 test.com
250 linux .syups.tp.edu.tw
mail from: spam@test.com // 假裝寄信人是 spam@test.com
250 2.1.0 ok
rcpt to: spam@test.com
// 假裝收信人也是 spam@test.com
250 2.1.5 o k // 居然被接受了,其實因為是從 127.0.0.1 連線,所以會這樣
quit
221 2.0.0 Bye
Connection closed by foreign host.
這次改從遠端連線進行測試
220 linux.syups.tp.edu.tw ESMTP Postfix
helo test.com // 假冒自己的身分
250 linux .syups.tp.edu.tw
mail from: spam@test.com // 假裝寄信人是 spam@test.com
250 2.1.0 ok
rcpt to: spam@test.com // 假裝收信人是 spam@test.com
550 5.7.1 Error: Proper authentication required. // 果然被要求要先登入
rcpt to: shane@mail.syups.tp.edu.tw // 改寄給本機帳號 shane@mail.syups.tp.edu.tw
250 2.1.5 ok // 被接受了,事實上單純收信是不會擋 RELAY
data // 開始輸入信件內容
354 End data with <CR><LF>.<CR><LF>
From: 你抓不到我 @test.com // 透過這個標頭, 可以取代 MAIL 指令所設定的郵件信箱地址,以避免被追蹤
To: 你抓不到我 @test.com // 透過這個標頭, 可以取代 RCPT 指令所設定的郵件信箱地址,以避免被追蹤
S ubject: hello
hi, how are you?
. // 結束輸入,必須另起一行然後輸入英文句號
250 2.0.0 Ok: queued as 88AF713C0152 // 信件被接受並進行分信處理
quit
221 2.0.0 Bye
Connection closed by foreign host.
認證模式測試
220 ESMTP
auth plain // 嘗試以純文字密碼登入
503 5.5.1 Error: authentication not enabled // 這種驗證機制已經被移除
auth login // 嘗試以 POP3 方式登入
334 VXNlcm5hbWU6
// 提示輸入 username ,之所以看不懂是因為被編成 base64
shane // 直接輸入帳號是錯的 ,請先使用底下指令找出 base64 字串:
perl -MMIME::Base64 -e 'print encode_base64("要編密的字串");'
334 UGFzc3dvcmQ6 // 提示輸入 password
123456 //與帳號相同,要先編成 base64
535 5.7.0 Error: authentication failed // 由於 base64 編碼事實上並未加密,最好還是不要用
auth digest-md5 // 嘗試其他驗證機制存不存在
504 5.3.3 Error: AUTH mechanism digest-md5 not available
starttls // 嘗試 TLS/SSL 安全傳輸層有沒有啟用
454 4.3.3 Error: TLS not available after start
...........................................................
郵件標頭過濾
標頭過濾所過濾的對象,除了郵件標頭外,更擴大範圍到附加檔案的 MIME 標頭,使得過濾可以更精確的進行,而不會因規則過於模糊,殃及無辜的郵件。用過 procmail 的使用者要特別注意:
附加檔案檔名或檔案類型是在此過濾,而非在郵件內文過濾。設定方式如下:
header_checks = regexp:/etc/postfix/header_checks
header_checks = pcre:/etc/postfix/header_checks
在外掛設定檔 header_checks(可以改用其它檔名)中,當字串比對命中時,可以採取各種處理動作,包括:
REJECT | 拒收信件。 |
OK | 跳過符合條件的標頭不作後續檢查,在 sendmail 中一旦 OK 該信件就會被接受,但在 postfix 中,OK 僅用來跳過該標頭的後續比對,萬一有其它標頭被拒絕,該封郵件一樣會被拒絕。 |
IGNORE | 從郵件刪除該標頭。 |
WARN | 附加警告訊息。 |
HOLD | 放回佇列,等候處理。 |
DISCARD | 直接將郵件丟棄,不回應拒收訊息。 |
FILTER transport.nexthop | 呼叫外掛過濾程式,進行郵件內文剖析過濾。外掛過濾程式可以是任何一種可執行的檔案,例如:shell script。該程式必須先定義在 master.cf 中,模擬成一個 socket 來執行(由 master 模組負責伺服監聽),當需要呼叫它執行時,postfix 中的 clearup 模組會將整封郵件丟到指定的 port 號,master 模組監聽到訊息後會執行相對應的過濾程式。 |
header_checks 的範例如下:
/^Subject: Make Money Fast/ REJECT
/^To: friend@public.com/ REJECT
如果未設置此參數,則郵件標頭過濾功能將會關閉不啟用,這是系統預設值。
郵件內文過濾
這是用來過濾所有標頭過濾沒檢查到的郵件內容,設定方式與前面相同:
body_checks = regexp:/etc/postfix/body_checks
body_checks = pcre:/etc/postfix/body_checks
如果未設置此參數,則郵件標頭過濾功能將會關閉不啟用,這是系統預設值。
用戶端過濾
當用戶使用 SMTP 通訊協定連上伺服器提出寄信請求時,針對用戶端輸入的指令進行過濾。在前面的UCE郵件測試中已經詳細論及在 SMTP連線階段中出現的各種欺騙伺服器的手法, postfix 提供非常詳盡的設定可以針對這些問題加以預防。使用用戶端過濾時,必須將 smtpd_delay_reject= yes 設定上去,這是系統預設值。當設定成 no 時,雖然效率較高,但是這樣做將會使得 HELO 網域偽裝、送信人信箱偽裝、寄信人信箱偽裝 以外的其它過濾功能失效。
用戶端過濾能夠使用的過濾功能,包括:
reject_unknown_client | 用戶端之 IP 或 Domain name 無法從 DNS 查詢驗證時,拒絕連線。 |
permit_mynetworks | 符合 $mynetworks 定義的用戶端允許連線。 |
reject_rbl_client | 從 SPAM 資料庫站台驗證用戶端網域名稱,符合時拒絕連線,當這種情況發生時,postfix 將會依照 default_rbl_reply 的設定回覆相關訊息,也可以依照 rbl_reply_maps 的設定根據不同用戶端給予不同訊息,事實上我們根本不需要設置此兩個參數(除非想將訊息改成中文)。這個參數必須放在最後面,當成過濾政策。 |
reject_rhsbl_client | 同上,使用另一種 SPAM 資料庫站台。這個參數必須放在最後面,當成過濾政策。 |
check_client_access | 根據 access 設定過濾存取權限,與 sendmail 中的 access 資料庫相容。 可以省略參數名稱,直接寫檔名,例如:hash:/etc/postfix/access。 |
permit | 允許連線,設定在過濾規則的最後面,表示未被之前的規則拒絕的用戶端一律允許連線,也就是採用黑名單政策。 |
defer | 延遲連線,設定在過濾規則的最後面,表示未被之前的規則拒絕或接受的用戶端,必須在稍後重新接受檢驗,也就是採用拖延政策。 |
reject | 拒絕連線,設定在過濾規則的最後面,表示未被之前的規則接受的用戶端一律拒絕連線,也就是採用白名單政策。 |
warn_if_reject | 被拒絕時產生警告訊息,這是用來測試過濾規則用的。 |
reject_unauth_pipelining | 當用戶端持續一直傳送 SMTP 命令時,拒絕其連線,這可以防止某些軟體一次寄送大量郵件。 |
使用用戶端過濾跟稍後會介紹的各種 SMTP 過濾,可以把規則依照前後順序編排成一組規則鍊(寫成一行,中間用逗號隔開或從逗號後面分行),由於組合出來的過濾功能並非單獨運作的,因此順序非常重要!
smtpd_client_restrictions = reject_rbl_client dialup.ecenter.idv.tw(台灣免費的 SPAM 資料庫:擋撥接發廣告信)
smtpd_client_restrictions = reject_rbl_client relays.ordb.org(國外免費的 SPAM 資料庫 :擋開放轉信的伺服器)
smtpd_client_restrictions = reject_rbl_client spam.ecenter.idv.tw(台灣免費的 SPAM 資料庫:擋寄廣告信的信箱)
smtpd_client_restrictions = hash:/etc/postfix/access , reject(採用白名單政策)
smtpd_client_restrictions = permit_mynetworks,reject_unknown_client
smtpd_client_restrictions = permit_mynetworks, hash:/etc/postfix/client_checks,reject_unknown_client,reject_unauth_pipelining
是否要求使用 HELO 命令
當啟用此功能時,將要求用戶端進行連線時須先傳送 HELO 字串,稍後我們可以根據 HELO 字串傳回來的網域名稱進行過濾,由於某些寄信程式不會傳送 HELO 命令,這樣做有可能會使得這些用戶端程式無法正常寄信。預設值是:
smtpd_helo_required = no
HELO 命令過濾
用來過濾 HELO 命令後面的網域名稱是否允許其連線,能夠使用的過濾功能,包括:
reject_invalid_hostname | 網域名稱字串不符合文法時,拒絕其連線。 |
reject_unknown_hostname | 網域名稱無法從 DNS 查到 A 或 MX 紀錄時,拒絕其連線。 |
reject_non_fqdn_hostname | 網域名稱不是完整 FQDN 格式時,拒絕其連線。 |
check_helo_access | 根據 access 設定過濾存取權限。 |
其它 permit、defer、reject、warn_if_reject、reject_unauth_pipelining 請參考前面的說明。 |
設定範例:
smtpd_helo_restrictions = permit_mynetworks, reject_invalid_hostname
信封標頭欄位過濾
此功能用來過濾郵件的信封標頭是否符合 RFC 821 之規定,預設是不啟用此過濾。因為目前最多人使用的 MUA 是 outlook express,它會使用許多額外的標頭來進行郵件控制,例如:大家熟知的要求回覆功能,如果啟用此參數將使得這些信件被拒絕無法寄出。
strict_rfc821_envelopes = yes
寄信人過濾
此功能並非過濾郵件標頭裡的寄信人欄位,而是過濾 mail from: 命令後面的字串,預設值是不過濾,但由於廣告信寄信程式為了能順利寄信,經常會偽造此字串,建議應該啟用。
可以使用的選項包括:
reject_unknown_sender_domain | 寄信人的網域名稱無法從 DNS 查詢驗證時,拒絕連線。 |
reject_rhsbl_sender | 寄信人信箱如果被紀錄在 SPAM 資料庫站台,就拒絕他連線。 |
check_sender_access | 根據 access 設定過濾存取權限。 |
reject_non_fqdn_sender | 寄信人的網域名稱不是完整 FQDN 格式時,拒絕其連線。 |
reject_sender_login_mismatch | 寄信人信箱與登入的帳號不吻合時,拒絕其連線。須配合 SASL 使用者認證機制使用(SMTP AUTH)。 配合 smtpd_sender_login_maps 指定的對應表,可以讓登入帳號與使用的信箱作對應,例如:shane 帳號可以用 webmaster 信箱寄信。 |
其它 permit、defer、reject、warn_if_reject、reject_unauth_pipelining 請參考前面的說明。 |
設定範例如下:
smtpd_sender_restrictions = reject_rhsbl_sender dsn.rfc-ignorant.org(國外免費的 SPAM 資料庫:擋寄廣告信的信箱)
smtpd_sender_restrictions = hash:/etc/postfix/access, reject_unknown_sender_domain
smtpd_sender_restrictions = permit_sasl_authenticated,reject_unknown_sender_domain,reject_non_fqdn_sender
收信人過濾
此功能並非過濾郵件標頭裡的收信人欄位,而是過濾 rcpt to: 命令後面的字串,預設值是不過濾,但由於廣告信寄信程式為了能順利寄信,經常會偽造此字串,建議應該啟用。
可以使用的選項包括:
permit_auth_destination | 收信人網域符合 $relay_domains、$mydestination、$inet_interfaces、$vitual_alias_domains、$virtual_mailbox_domains 的定義時,接受連線。 |
reject_unauth_destination | 收信人網域不符合上述設定時,拒絕連線。 |
permit_mx_backup | 當從 DNS 上查到本機為收信人網域的備份 MX 時,接受連線。使用此功能有安全漏洞,可以配合 permit_mx_backup_networks = 172.16.0.0/16 來檢查主要 MX 是否在該網段內,來加強過濾功能(避免被不信任的網域設定為轉信 MX)。 |
check_relay_domains | 允許代收要給 relay_domians 的信件。 |
check_recipient_access | 根據 access 設定過濾存取權限。 |
check_recipient_maps | 當收信人網域不符合 permit_auth_destination 之要求,或是收信人信箱不符合 $local_recipient_maps、$virtual_alias_maps、$virtual_mailbox_maps、$relay_recipient_maps 的定義時,拒絕連線。此參數可以放在收信人過濾規則的最後面,當作過濾政策。 |
reject_unknown_recipient_domain | 收信人的網域名稱無法從 DNS 查詢驗證時,拒絕連線。 |
reject_rhsbl_recipient | 收信人信箱如果被紀錄在 SPAM 資料庫站台,就拒絕他連線。 |
reject_non_fqdn_recipient | 收信人的網域名稱不是完整 FQDN 格式時,拒絕其連線。 |
其它 permit、defer、reject、warn_if_reject、reject_unauth_pipelining 請參考前面的說明。 |
設定範例如下:
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination,reject_non_fqdn_recipient
ETRN 命令過濾
用來過濾哪些網域或哪些用戶端,可以使用 ETRN 命令。ETRN 命令用來一次處理大量郵件,當某個用戶端使用 ETRN時,有時候會影響到其它用戶寄信的效能,通常只有撥接用戶、幫撥接用戶轉信的 mail gateway、郵件討論群組(mailing list)或電子報發行站台,需要使用此功能。postfix 的預設值是所有用戶端都可以使用 ETRN 命令。
能使用的特殊參數只有 check_etrn_access,其餘與用戶端過濾參數相同,請自行查閱前文。設定範例如下:
smtpd_etrn_restrictions = permit_mynetworks, hash:/etc/postfix/etrn_access, reject
伍、效能調校
在這一章中,所有未特別說明的參數,都是設定在 main.cf 中!
行程限制
系統預設行程限制(default_process_limit)為 100,也就是說同時可以收發總共 100 封郵件,如果發現伺服器效能很差,可以嘗試降低此數值,請修改 master.cf:
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (100)
# ==========================================================================
. . .
smtp inet n - - - 10 smtpd
. . .
以上各欄位意義說明如下:
service | 識別名稱 |
type | 服務類型總共有三種:inet、unix、fifo。inet 是指透過網路介面 sockets 提供服務(例如:127.0.0.1:25),unix 指使用 unix sockets 提供服務(直接呼叫執行),fifo 是指使用 pipe name 提供服務(例如:網路傳真) 。 |
private | 切斷對外服務,預設值是 yes。注意:inet 類型無法設定成 yes。 |
unpriv | 不要以 root 身分執行,而是以 $mail_owner 身分執行。預設值是 yes。 |
chroot | 開啟郵件暫存資料夾時,要不要將該資料夾變成根目錄,這是為了防止與 postfix 無關的資料夾遭到入侵者以 $mail_owner 身分闖入。預設值是 yes。注意:pipe、virtual 和 local 模組無法設定成 yes。 |
wakeup | 服務每隔多久喚醒一次,預設值是 0(不喚醒)。只有 pickup、qmgr 和 flush 模組需要設定喚醒週期。 |
maxproc | 最大執行緒。 |
command + args | 該服務執行的命令及參數。 |
master.cf 除了控制 postfix 各個模組的運作方式外,也可以加入外掛過濾引擎,postfix希望透過這個方式與其它程式設計專家合作,後文將介紹兩個經常使用的過濾程式 SapmAssassin 以及病毒過濾軟體 amavisd + clamav。更詳細的內容可以自行到 www.postfix.org 查看!
同步處理限制
postfix 採用同步處理限制來進行流量調整和控制,當 postfix 寄信到某個郵件主機時,首先傳兩封信過去(initial_destination_concurrency= 2),如果一切正常則逐步增加每次傳送的量,一直到傳輸失敗或者是到達同步上限每次 20 封信(default_destination_concurrency_limit = 20)。
如果想要針對不同 agent 來設定同步上限,也可以使用底下的參數(未設定的參數將會沿用 default_destination_concurrency_limit 限制):
local_destination_concurrency_limit = 2
uucp_destination_concurrency_limit = 2
smtp_destination_concurrency_limit = 10
收信人限制
這是指一封信可以寄給多少人,postfix 預設可以處理 50 個收信人(default_destination_recipient_limit = 50),如果一封信的收信人超過 50 人,postfix 會自動將此信複製成很多份,以 50 人為單位分批寄送。
和同步處理限制一樣,可以針對不同 agent 來設定不同上限:
uucp_destination_recipient_limit = 2
smtp_destination_recipient_limit = 10
延遲傳送
當郵件伺服器使用撥接線路連線時,由於部分時段處於斷線狀態,當 postfix處理信件時會因為無法收發信件,持續產生錯誤訊息,為了避免發生這個現象,我們可以設定 defer_transports = smtp 來告知 postfix,要從 smtp agent 傳送出去的郵件暫時不要傳送。這些郵件可以等到上線後,再以 ETRN 指令全部寄出。
如果本機是前述郵件伺服器的 mail gateway,由於該伺服器只有部分時段上線,因此有可能 mail gateway 已經累積許多信件等待傳送給它,為了避免 mail gateway 持續嘗試傳送,可以設定:
defer_transport = hold
接著在 /etc/postfix/transport 設定:
customer.com hold:[gateway.customer.com]這個設定的意思是,要給 customer.com 的郵件先暫存在 gateway.customer.com,等待前者上線後再全部傳送給它(使用 ETRN 命令)。
設定好後,還需修改 master.cf,找到 smtp 行程設定(可參考前面小節),將 smtp 改為 hold 即可:
hold unix - - n - - smtp
傳送失敗處理
當郵件傳送失敗的時候,負責傳送郵件的 Agent 會將郵件退回給 qmgr 模組,qmgr 模組則會計算從郵件到達到現在的時間間隔,依此時間間隔將郵件排入延遲傳送佇列中,以等待下次傳送。
如果該封郵件傳送到一半的時候失敗了,也就是說有些收信人有收到,有些沒有。這種情況下,除了將該郵件排入延遲傳送佇列外,也會將傳送失敗的對象排入 dead 清單一段時間,在這段時間內如果有其它郵件要傳送給這些對象時,就會直接排入延遲傳送佇列,而不用徒勞無功地去嘗試傳送!
底下是有關於郵件傳送失敗處理的相關效能設定:
queue_run_delay = 1000s | qmgr 模組每 1000 秒(約 16 分鐘)檢查一次 defer 佇列,查看是否有郵件須排入 active 佇列 |
maximal_queue_lifetime = 5d | 無法傳送的信件在 defer 佇列裡最多保存 5 天,超過時間則退給寄信人 |
minimal_backoff_time = 1000s | 傳送失敗的郵件至少在 defer 佇列中暫停 1000 秒,而且被排入 dead 清單的收信人至少也要待 1000 秒,也就是說在這段時間內不再嘗試寄信給他 |
maximal_backoff_time = 4000s | 傳送失敗的郵件最多在 defer 佇列中等待 4000 秒(約 1 小時) |
qmgr_message_recipient_limit = 1000 | dead 清單的大小,也就是說第 1001 個傳送失敗的對象,不會被排入 dead 清單 |
拖延戰術
當懷有惡意的用戶端連續傳送大量郵件時,postfix 為了處理這些郵件耗掉太多資源,導致無法正常工作,這也就是經常被討論的「阻斷服務攻擊」。
postfix 的設計者認為阻斷服務攻擊是不可能被解決的,因為我們無法單從郵件區分出它是惡意或善意,但是我們可以透過一些手段來降低損害。postfix採用的方法是針對每條連線,設定一個連線錯誤計數器( session error count),當用戶端連線時,開啟計數器,如果用戶端傳送不存在的 SMTP 命令(這絕對是惡意想阻斷服務),或是超過字數限制的長字串(記憶體溢位攻擊)、超過一行的標頭(引發郵件剖析錯誤),計數器就會不斷累加。當郵件交寄成功時,計數器才會歸零重新計算。
現在我們只要根據計數器採取適當的處理動作就行了:
smtpd_soft_error_limit = 10 | 當計數器到達 10 時,就暫停該連線一段時間 |
smtpd_hard_error_limit = 100 | 當計數器到達 100 時,直接斷線 |
smtpd_error_sleep_time = 5s | 每次暫停 5 秒鐘 |
陸、資源管制
postfix 可以在記憶體有限的系統上執行,而不會影響其它服務的效能,這是因為 postfix 提供的記憶體管理功能非常有彈性,可以依據各種需求加以調整。
每封郵件用量限制
當 postfix 處理郵件時,必須將郵件暫存於郵件佇列中,其中 maildrop 和 incoming 佇列使用硬碟,而 active 和deferred 則使用記憶體,每封暫存在佇列中的郵件耗用多少記憶體是由郵件資料結構來決定,幸運的是這個資料結構的欄位大小是可以微調的,透過這些微調就能決定 postfix 的最大記憶體用量了!
line_length_limit = 2048 | 從用戶端接收待寄郵件時,每行最多 2 KB |
header_size_limit = 102400 | 每封郵件的標頭大小不得超過 100 KB |
extract_recipient_limit = 10240 | 每封郵件的收信人欄位不得超過 10 KB |
message_size_limit = 10240000 | 每封郵件(包含信封)的大小,不得超過 10 MB |
queue_minfree = | 當記憶體剩下多少 Bytes 時,才可以處理下一封郵件,預設是沒有限制。 |
bounce_size_limit = 50000 | 警告信的大小限制為 50 KB。 |
假設通通使用預設值,也就是所有參數都不設置,那麼處理一封郵件須耗用 10.05 MB,再加上 postfix 模組程式的大小,總共約 20 MB,這也就是 postfix 運行的最小需求了!
郵件數量限制
當前述用量限制設置完畢後,接著我們還可以針對郵件佇列一次要處理多少郵件作出限制,把每封郵件記憶體用量乘上郵件數量,就可以算出所需的記憶體總量,當記憶體足夠時,我們當然希望儘可能多處理幾封郵件來增進 postfix 的效能。
qmgr_message_recipient_limit = 1000 | 這個參數之前介紹過了,除了用來控制 dead 清單的大小外,也控制著處理中的郵件收信人總量,兩者的預設限制都是 1000。 |
qmgr_message_active_limit = 1000 | 最多同時處理 1000 封郵件。 |
duplicate_filter_limit = 1000 | 在進行收信人過濾時,要快取多少已通過過濾的清單,這個功能是用來提高過濾效能,預設要快取 1000 個不同收信人 |
時間限制
postfix 某些模組在運作時,會依照設定檔的要求讀取外掛程式或是執行 shell 命令,有些則是會讀取外部檔案。如果無限制的讓 postfix等待外部命令執行完畢或等待外部檔案讀取完畢,將會因為這些外部程式的設計不當或 I/O 衝突,而導致 postfix 無法運作,因此就需要設定等候時間限制,超過此時間限制 postfix 將逕行處理下一個程序。
舉例來說:當 local agent 將郵件分到使用者信箱時,會透過 proxymap 模組讀取 alias 資料庫,接著根據 alias 設定讀取:include: 檔案,最後讀取 .forward 檔案,前述動作中如果其中一個因為系統 I/O 忙碌無法於時間限制內讀取檔案,local agent 就會直接跳過進行下一個處理動作。
command_time_limit = 1000s | 等候外部命令或 I/O 的時間不可超過 16 分鐘。 |
service_time_limit = | 這個參數的目的是允許不同 service 採用不同時間限制,因此它會取代前述參數的設定,其中 service 就是 master.cf 中的第一個欄位。 |
檔案鎖定
當 local agent 要將信件分到使用者信箱時,有時候使用者正透過 POP3 讀取信箱,因此信箱被鎖定無法開啟,這種情況發生時,local agent 必須等候一段時間重新嘗試讀取檔案,但也不能一直等下去,所以必須要有一些限制。
postfix 支援兩種的檔案鎖定機制:一、使用系統函式 fcntl( ) 或 flock( ),二、使用 local file,postfix將根據作業系統的不同,選擇其中一種或兩種並用。有關檔案鎖定機制在這裡不予討論,有興趣的讀者可以從「專業 Linux 程式設計」(Wrox 出版,碁峯翻譯經銷)一書一窺究竟。
deliver_lock_attempts = 5 | 檔案被鎖定時,嘗試讀取 5 次。 |
deliver_lock_delay = 1s | 每次嘗試讀取前,先等候一秒鐘。 |
stale_lock_time = 500 | 當 lock file 存在超過 500s 時,強制刪除 lock file 解除其鎖定狀態。使用 lock file 其實是透過程式設計技巧來模擬檔案鎖定功能,它必須由程式設計師自行維護鎖定狀態,萬一有粗心的設計者鎖定檔案後忘記解除,或是程式當掉無法解除鎖定,都會造成檔案長期被鎖定的假象,所以需要此設定來排除問題。 |
行程自動回復
當行程或子執行緒因為某些原因當掉,例如:記憶體不足......等,這個時候 master 將會延遲一段時間後嘗試重新啟動該行程。當然,如果程式當掉的原因是 main.cf 檔案損毀所造成的,就算是不斷重複啟動也不能恢復正常,因此 postfix 也會將當掉的情形紀錄在系統日誌裡,以便管理員偵錯並人工修復。
fork_attempts = 5 | 行程當掉以後,會嘗試重新啟動它 5 次! |
fork_delay = 1s | 每次重新啟動前,先等候一秒鐘。 |
transport_retry_time = 60s | qmgr 每隔 60 秒嘗試驅動 agent 進行分信。 |