遠端 IP 和 SMTP 代理
是否可以透明地代理電子郵件 - 例如使用後綴 - 以便後端郵件伺服器將獲得最後一個 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 地址和埠號。然後它插入一個iptables
NAT 規則,該規則指定具有特定源 IP 和埠以及目標 IP 和埠組合的傳出數據包必須被 NAT 到客戶端的源 IP。在代理實際執行connect
系統呼叫之前,它確實知道所有這些地址和埠號,因此它可以創建一個完全有針對性的iptables
規則,該規則將匹配這個 TCP 連接,而不是其他任何東西。