Ubuntu

轉發電子郵件但更改 FROM 地址

  • April 5, 2020

我有一個在 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,並將以下內容添加到rootcrontab:

@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 安全專家和系統管理員,請原諒這些強制性通知)

引用自:https://unix.stackexchange.com/questions/389323