Postfix

遠端 IP 和 SMTP 代理

  • July 10, 2014

是否可以透明地代理電子郵件 - 例如使用後綴 - 以便後端郵件伺服器將獲得最後一個 SMTP 伺服器 IP 地址(rbl 目的)而不是代理 IP 地址?

如果有可能並且同樣的想法,SMTP 代理是否可以按收件人域將電子郵件路由到不同的後端?

您要問的問題大多是可能的,但有一些警告。幾年前,我嘗試自己編寫這樣的代理,但有一些挑戰,我從未完全解決。

在我看來,定義代理和完整中繼之間區別的屬性是:代理從不單獨負責郵件。

中繼將接收來自發送主機的郵件,並在結束時DATA向發送主機確認它負責傳遞郵件。這意味著它必須在那個時候已經在中繼上的磁碟上持久存在,並且發送主機可以忘記它。

另一方面,代理將連接到後端,同時仍接收來自發送主機的郵件。代理本身不承擔郵件的責任。相反,代理從負責郵件的後端接收承諾,並簡單地將消息代理回發送主機。

但現在這種代理面臨的最大挑戰是:可能有多個後端。假設發送主機不僅向您發送一個,而是多個接收地址,並且這些地址解析到不同的後端。您是否要在仍然從客戶端接收的同時打開每個後端的 SMTP 會話?

如果您在最後延遲對客戶端的DATA確認,直到您收到來自每個後端的確認,那麼您可能經常會發現自己處於一種情況,您收到了來自某些後端但不是所有後端的確認。如果您向客戶報告成功,則您有責任將其傳遞給所有後端。如果您報告失敗,或者客戶端超時,客戶端將在不知道郵件已經發送到某些收件人的情況下重新傳輸。

設計的 SMTP 確實在這種情況下引入了郵件重複的可能性。當接收到具有相同收件人、消息 ID 和內容的兩個副本時,接收端的好的軟體可以進行重複數據刪除。但是具有多個後端方案的代理會增加這種重複的可能性,並且對於同一封郵件很容易發生多次。

那麼在與後端通信時如何保留客戶端 IP?我採取的路徑是將其嵌入域中,我將HELO命令發送到後端。當然,我可以發送一個看起來像<IP>.example.com插入我自己的域的域。HELO我什至可以在 IP 地址之前或之後包含原始命令中的域。

在轉發郵件之前,我還會插入一個完整且格式正確的Received標題。header 可能是獲取後端 IP 地址的Received最佳方式,因為它是相當標準化的,所以後端應該能夠解析它。

實際上在與後端通信時欺騙原始客戶端的IP在某些情況下在技術上也是可行的,但它是複雜的。您不僅在進行轉發或 NAT,還必須終止代理上的 TCP 連接,因此這是一個全新的 TCP 連接。

如果從後端到客戶端IP地址的網路路由通過代理取包,那麼代理當然有可能欺騙客戶端的IP地址。但是同時在某些 TCP 連接上具有與本地地址相同的 IP 地址,而在其他 TCP 連接上具有與遠端地址相同的 IP 地址可能會混淆 TCP 層。您可以選擇不在 TCP 層本身進行任何欺騙,而是使用一個單獨的組件,該組件以某種方式指示如何對流量進行 NAT。

這可以通過iptables如下方式使用標準 NAT 實現來實現。代理首先綁定到本地 IP 地址和埠號。然後它插入一個iptablesNAT 規則,該規則指定具有特定源 IP 和埠以及目標 IP 和埠組合的傳出數據包必須被 NAT 到客戶端的源 IP。在代理實際執行connect系統呼叫之前,它確實知道所有這些地址和埠號,因此它可以創建一個完全有針對性的iptables規則,該規則將匹配這個 TCP 連接,而不是其他任何東西。

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