
我有一個 (Linux) 郵件伺服器,其中包括postfix
用於接收郵件,amavisd-new
用於內容過濾(使用clamav
和SpamAssassin
),以及dovecot
用於交貨和 IMAP。
我想進行設置,以便每次將電子郵件傳遞到特定郵箱時都會觸發腳本。該腳本不一定需要了解有關訊息內容或標題的任何資訊。我知道至少有幾個選擇:
使用
postfix
的內建過濾。設定標頭檢查以將發送到該郵箱的任何電子郵件重新路由到我的腳本,然後該腳本可以將其傳回postfix
.這裡的缺點是這一切都發生在amavis
過濾之前,所以即使對於在發送之前最終被阻止的電子郵件,我的腳本也會被觸發。如果我沒有正確執行電子郵件的傳輸,還可能會出現效能損失和遺失電子郵件的風險postfix
。將我的腳本作為內容過濾器添加到
amavis
.與之前相比,這可能是性能的改進,而且似乎是一個更好的地方。不幸的是,在對訊息做出執行/不執行決定之前,它仍然會受到執行的影響。此外,我還沒有找到amavis
詳細說明這實際上應該如何完成的文檔,並且conf文件並不是真正決定性的。
似乎最後的dovecot
傳遞步驟是僅獲取已過濾郵件的最佳位置,但我不確定是否有辦法實現這一點。
建議?有什麼我忽略的嗎?
編輯:忘了補充,我想避免輪詢類型的解決方案(查看日誌、IMAP 用戶端腳本等)
答案1
我發現了另一個可能被證明是一個足夠好的解決方案的選項:在訊息從 傳遞到 時劫持postfix
訊息dovecot
。
對於postfix
,我更改了以下幾行master.cf
:
dovecot unix - n n - - pipe
flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/dovecot-lda -d $(user)@$(domain)
到:
dovecot unix - n n - - pipe
flags=DRhu user=vmail:mail argv=/scripts/emaildeliverycheck.py $(user)@$(domain)
然後創建/scripts/emaildeliverycheck.py
如下(Python 3.4):
#!/usr/bin/python3
from sys import argv, stdin, exit
from subprocess import Popen, check_call, CalledProcessError
# Define recipients that should trigger the script here
notifyusers = ('[email protected]',
'[email protected]')
recipient = argv[1]
if recipient in notifyusers:
# Run the script. Use Popen so that we don't have to wait for the
# script to finish
Popen(['/scripts/myscript.py', recipient])
try:
# Now pass the email to dovecot-lda. Use check_call because we *do*
# want to wait for it to finish
check_call(['/usr/lib/dovecot/dovecot-lda', '-d', recipient], stdin=stdin)
except CalledProcessError as error:
# Propagate any error codes back to Postfix
exit(error.returncode)
Postfix 的pipe
進程將最終投遞的電子郵件傳遞給上述腳本,而不是直接傳遞給dovecot-lda
.該腳本根據清單檢查收件者(在命令列上傳遞,因此根本不需要查看訊息),如果存在符合則觸發另一個腳本。然後它將訊息通過管道傳遞給dovecot-lda
,而該訊息不應該知道它不是直接從 Postfix 獲取訊息,並將退出狀態傳回進程pipe
。
在初始測試中工作正常。這只會讓我收到經過後過濾的電子郵件,這就是我想要的。
答案2
我用作procmail
當地的送貨代理。這允許使用適用於使用者的規則進行廣泛的過濾。應該可以設定 postfix 使用 procmail 進行過濾,如果需要的話,也可以傳送電子郵件。
procmail
具有將過濾器應用於標題、內容或兩者的廣泛功能。您可以使用任何程式作為過濾器,因此您應該能夠為發送給指定使用者的每封電子郵件觸發腳本。