远程 IP 和 SMTP 代理

远程 IP 和 SMTP 代理

是否可以透明地代理电子邮件 - 例如使用 postfix - 以便后端邮件服务器将获取最后一个 SMTP 服务器 IP 地址(rbl 目的)而不是代理 IP 地址?

如果可能的话,并且出于同样的原因,SMTP 代理是否可以通过收件人域将电子邮件路由到不同的后端?

答案1

您所问的问题基本可行,但有一些注意事项。几年前,我曾尝试自己编写这样的代理,但遇到了一些挑战,我从未完全解决过。

在我看来,定义代理和完整中继之间的差异的属性是:代理永远不会独自对邮件负责。

中继将接收来自发送主机的邮件,并在最后DATA向发送主机确认它负责递送邮件。这意味着它必须当时已在中继的磁盘上持久化,并且发送主机可以忘记它。

另一方面,代理将连接到后端,同时仍从发送主机接收邮件。代理本身不承担邮件的责任。相反,代理从负责邮件的后端接收承诺,并简单地将该消息代理回发给发送主机。

但现在这种代理的最大挑战来了:可能有多个后端。假设发送主机向您发送的收件人地址不只是一个,而是多个,并且这些地址解析到不同的后端。您是否要打开与每个后端的 SMTP 会话,同时仍从客户端接收?

如果您在收到来自每个后端的确认后才向客户端发送确认DATA,那么您可能经常会发现自己处于这样一种情况:您收到了来自某些后端的确认,但不是所有后端的确认。如果您向客户端报告成功,则您有责任将其传递给所有后端。如果您报告失败,或者客户端超时,则客户端会在不知道邮件已发送给某些收件人的情况下重新发送。

SMTP 的设计确实会引入此类情况下邮件重复的可能性。当收到两份具有相同收件人、消息 ID 和内容的副本时,接收端的优秀软件可以删除重复邮件。但具有多个后端的代理方案将使此类重复更有可能发生,并且同一封邮件很容易发生多次。

那么,在与后端通信时,如何保留客户端 IP?我采取的方法是将其嵌入域中,我将命令发送HELO到后端。当然,我可以发送一个看起来像插入我自己的域的域。我甚至可以在 IP 地址之前或之后<IP>.example.com包含原始命令中的域。HELO

Received在转发邮件之前,我还会插入完整且格式正确的标头。Received标头可能是将 IP 地址传送到后端的最佳方式,因为它相当标准化,因此后端应该能够解析它。

实际上,在某些情况下,在与后端通信时欺骗原始客户端的 IP 在技术上也是可行的,但这很复杂。您不仅要进行转发或 NAT,还必须终止代理上的 TCP 连接,因此这是一个全新的 TCP 连接。

如果从后端到客户端 IP 地址的网络路由通过代理接收数据包,那么代理当然可以伪造客户端的 IP 地址。但是,同时在某些 TCP 连接上使用相同的 IP 地址作为本地地址,而在其他 TCP 连接上使用远程地址,可能会混淆 TCP 层。您可以选择不在 TCP 层本身进行任何伪造,而是使用一个单独的组件,该组件以某种方式指示如何对流量进行 NAT。

这可能可以通过标准 NAT 实现,如下iptables所示。代理首先绑定到本地 IP 地址和端口号。然后插入iptablesNAT 规则,该规则指定具有特定源 IP 和端口组合以及目标 IP 和端口组合的传出数据包必须通过 NAT 转换为客户端的源 IP。在代理实际执行系统connect调用之前,它确实知道所有这些地址和端口号,因此它可以创建一个完全有针对性的iptables规则,该规则将匹配此 TCP 连接,而不会匹配其他任何内容。

答案2

您可能需要postfix重写标题才能获得理想的结果,但它会绝不保持透明,因为这会破坏某些 RFC。

相关内容