轉發電子郵件但更改 FROM 地址
我有一個在 EC2 實例上執行的 postfix 伺服器。我想通過 SES 將所有電子郵件轉發到我的個人收件箱。
問題:AWS 只允許在 AWS 控制台中驗證的 FROM 地址,在這種情況下 FROM 地址可以是任何東西,例如:twitter.com。我不能將我的伺服器的 IP 列入白名單並說:“無論發件人如何,都接受來自該位置的所有電子郵件”(無論如何這都是個壞主意)
所以,我需要想辦法用經過驗證的地址轉發我的電子郵件,但我不想失去原始發件人的地址。
有沒有辦法做到這一點?
根據我們在聊天中的討論,我將為您提供我的駭人聽聞的定制解決方案,它將按照我們的預期更改“FROM”地址,然後將其發送到原始目的地,但添加“Reply-To”標題。
這是一種非常駭人聽聞的方法,但在通過 PostFix 將它們實際發送到它們需要去的地方之前,應該按照你的預期操作這些消息。
首先,需要更改 PostFix 埠。我們需要將 Postfix SMTP 埠更改為其他內容,
25
以便我們將要設置的 python SMTP 處理程序改為在該埠上工作。編輯
/etc/postfix/master.cf
. 您將要尋找這樣的一行:smtp inet n - y - - smtpd
註釋掉這一行,並在該行下面,改用這個:
10025 inet n - y - - smtpd
這告訴 Postfix 我們不希望它監聽標準 SMTP 埠。完成此步驟後重新啟動 postfix 服務。
**接下來,**我上面提到的 Python SMTP 處理程序。這將處理傳入的消息,操縱它們,並將它們重新發送到您系統上的 PostFix。當然,假設所有郵件都在埠 25 上送出,甚至在本地也是如此。
此程式碼存在於GitHub GIST 上,並且基於我在某個地方獲得的通用 Python SMTP 伺服器程式碼範例(但不記得從哪裡抱歉!),並且已經被操縱。
程式碼也在此處,如果您好奇,它在 Python 3 中,並且使用 Python 3 作為目標 Python 版本編寫:
#!/usr/bin/env python3 # Libraries import smtplib import smtpd import asyncore import email import sys from datetime import datetime print('Starting custom mail handling server...') # We need to know where the SMTP server is heh. SMTP_OUTBOUND = 'localhost' # We also need to know what we want the "FROM" address to be FROM_ADDR = "foo@bar.baz" DESTINATION_ADDRESS = "foo@bar.baz" ############# ############# # SMTP SERVER ############# ############# # noinspection PyMissingTypeHints,PyBroadException class AutoForwardHandlerSMTP(smtpd.SMTPServer): def process_message(self, peer, mailfrom, rcpttos, data, **kwargs): print('MESSAGE RECEIVED - [%s]' % datetime.now().strftime('%Y-%m-%d %H:%M:%S')) print('Receiving message from:', peer) print('Message addressed from:', mailfrom) print('Message addressed to :', rcpttos) print('Message length :', len(data)) print(data) # Flush the output buffered (handy with the nohup launch) sys.stdout.flush() # Analyze and extract data headers msg = email.message_from_string(data) orig_from = '' try: orig_from = msg['From'] msg['Reply-To'] = orig_from # We have to use 'replace header' methods to overwrite existing headers. msg.replace_header("From", FROM_ADDR) except: print("Error manipulating headers:", sys.exc_info()[0]) conn = smtplib.SMTP(SMTP_OUTBOUND, 10025) conn.sendmail(FROM_ADDR, msg["To"], msg.as_string()) # Flush the output buffered (handy with the nohup launch) print("\n\n") sys.stdout.flush() return # Listen to port 25 ( 0.0.0.0 can be replaced by the ip of your server but that will work with 0.0.0.0 ) server = AutoForwardHandlerSMTP(('0.0.0.0', 25), None) # Wait for incoming emails asyncore.loop()
將此儲存為
/opt/PythonAutoForwarderSMTP.py
,或任何您想呼叫的名稱。首先,以 root 身份使用以下命令執行它(通過sudo
或進入root
使用者提示符),以確保它按預期工作:python3 /opt/PythonAutoForwarderSMTP.py
確認執行後,通過伺服器發送電子郵件。它應該被拾取並為您提供來自該腳本的日誌數據,表明已收到並處理了一條消息。然後,您還應該在 Postfix 的日誌上看到一個連接,並且該連接是在 Postfix 之後的某個地方傳遞的。如果所有這些看起來都正常,並且您正確處理了郵件,並且在郵件最終結束的地方看到了不同的“發件人”地址,那麼我們現在可以努力讓它自動啟動!(在繼續之前,您可以簡單地點擊
Ctrl
+C
來關閉 python 程序)。假設我們希望它在啟動時啟動,那麼我們需要對其進行設置。
作為
root
,執行crontab -e
,並將以下內容添加到root
crontab:@reboot /usr/bin/python3 /opt/PythonAutoForwarderSMTP.py 2>&1 >> /var/log/PythonSMTP.log &
保存 crontab 文件。如果您不想重新啟動伺服器,請執行您剛剛添加的命令行(減去該
@reboot
部分)來執行 Python SMTP 處理程序。無論是否執行
cron
,載入 Python 的程序最終都會分叉到後台,並將所有數據輸出(錯誤或 Python 控制台中的其他情況)以/var/log/PythonSMTP.log
附加模式放入日誌文件。這樣,您始終可以根據需要獲取日誌。如果一切按預期工作,這將正確添加回复標頭,並將消息中的“發件人”標頭調整為我們期望的樣子。 如果消息已簽名,我不能保證這對於 SPF 和 DKIM 檢查會正常工作,但我可以說這將在使用 Postfix 將它們中繼到其他地方之前正確地“預處理”消息。
強制性安全問題和功能更改通知:
- **發件人 DKIM 驗證可能會失敗。**每當簽名的郵件被操縱時,DKIM 簽名驗證都會失敗,這意味著您可能破壞了來自發件人的 DKIM 簽名。這意味著由於簽名驗證失敗,事情*可能會被視為垃圾郵件。*這個腳本可能可以定制為“正常工作”,但我寫這個不是為了做 DKIM/SPF 檢查。
- 我們必須將此 Python SMTP 伺服器作為
root
. 這是必要的,因為在 Linux 預設情況下,除非我們是超級使用者,否則我們無法綁定到 1024 以下的埠;這就是為什麼 Postfix 擁有一個主“root”擁有的程序,並且不會以 root 使用者身份執行很長時間的子程序僅用於埠綁定。- 埠 25 上的所有郵件最終都會通過這個 Python SMTP 伺服器。如果 Postfix 還處理來自外部 -> 內部的郵件,那麼 Python SMTP 伺服器將取代它。這可能會引入一些弊端,但最終會滿足您的要求。
- **這是一個脆弱的解決方案。**雖然它不像其他一些解決方案那樣脆弱,但如果 Python 程序死亡,它不會自動恢復,因此您必鬚根據具體情況處理錯誤,有時如果 Python 程序恢復正常完全死去。
- 此 .xml文件中沒有 StartTLS 或 SSL/TLS 處理程序。所以一切都是純文字(這是不安全的!)
**與往常一樣,除非您知道自己在做什麼,否則不應以 root 身份執行任何東西。**在這種情況下,我以直覺的方式提供了此程式碼,因此您可以自己辨別此腳本的作用,以及是否要以 root 身份執行它,如果您像我一樣以安全為中心且偏執(我是IT 安全專家和系統管理員,請原諒這些強制性通知)