Postfix

sendmail 可以立即轉發電子郵件而不是排隊嗎?

  • August 10, 2017

通過我的伺服器的一些電子郵件被轉發到外部帳戶。

不幸的是,我的上游 SMTP 伺服器對垃圾郵件非常挑剔——並且拒絕一些合法的郵件。當轉發的郵件發生這種情況時,我會收到退回郵件(作為郵件管理員)——而不是發件人。

我理解,這是因為 sendmail 在本地對消息進行排隊,與中繼斷開連接,然後才繼續進一步轉發它們。如果進一步的轉發由於任何原因而中斷——例如因為下一個中繼錯誤地將郵件辨識為垃圾郵件——我的 sendmail 將保留這些碎片。

是否可以將事情配置為立即開始轉發(一旦確定轉發目的地)?然後可以將狀態(成功或失敗)直接傳達給仍然線上的前一個繼電器……

如果 sendmail 做不到,其他 MTA 可以嗎?謝謝!

不,這是不可能的,因為它沒有通過任何廣泛傳播的 SMTP 軟體實現;您必須編寫自己的支持這種行為的 SMTP 伺服器,這超出了 Serverfault 的範圍。在這個答案中,我解釋了為什麼所有 MTA 都使用隊列非常相似地實現了 SMTP 協議,以及這是實現協議所有要求的最佳方式。

郵件傳輸代理MTA 始終根據自己的設置拒絕郵件或接受郵件並將其排隊。然後,它從隊列中中繼或傳遞。

那是因為

  • 可能存在永久性錯誤和臨時錯誤。如果 MTA 不能立即連接下一跳,它會稍後再試,並且只有在延遲達到設置的限制時才會反彈。它也不能在關閉連接之前等待另一個 MTA 響應,因為它可能要先傳遞其他消息。
  • 可以有多個收件人。雖然客戶端可以簡單地使用命令一次列出所有收件人RCPT TO,但消息最終可以傳遞到其他幾個伺服器,其中一些現在可用,一些稍後可用。此外,MTA 無法在初始連接期間立即打開所有這些連接並等待它們的響應。對於具有單個收件人的消息,沒有任何實際理由具有完全不同的工作流程。
  • 應該始終清楚目前哪個 MTA 負責傳遞消息。(這已通過 MadHatter 回答中的範例進行了解釋。)

這就是 SMTP 的設計方式。這導致了非常相似的架構,而不是連接命令的語法要求;SendmailPostfix甚至MS Exchange都有用於發送和接收郵件的獨立組件。

  1. SMTP 伺服器組件接收郵件並將其添加到隊列中。
  2. 然後,單獨的 SMTP 客戶端嘗試將其進一步發送到其他 MTA,或者如果收件人是本地的,則可以將消息保存到文件或傳遞給郵件傳遞代理MDA,例如 Procmail。

該要求仍然來自 SMTP 規範;RFC 5321 2.1 關於 SMTP 模型的基本結構:

功能齊全的 SMTP 實現,包括這些功能較弱的中繼所使用的中繼,以及它們的目的地,都有望支持本規範中討論的所有排隊、重試和備用地址功能。在許多情況和配置中,上面討論的功能較弱的客戶端應該使用消息送出協議 ( RFC 4409 ) 而不是 SMTP。

更進一步:

換句話說,郵件傳輸可以發生在原始 SMTP 發件人和最終 SMTP 收件人之間的單個連接中,也可以發生在通過中間系統的一系列躍點中。在任何一種情況下,一旦伺服器在郵件數據的末尾發出了成功響應,就會發生對消息的正式責任移交:協議要求伺服器必須承擔傳遞消息或正確報告失敗的責任這樣做(參見第 6.1、6.2 和 7.8 節)。

引用自:https://serverfault.com/questions/867377