sendmail可以立即转发电子邮件,而不是排队吗?

一些通过我的服务器传递的电子邮件被转发到外部帐户。

不幸的是,我的上游SMTP服务器对于垃圾邮件非常挑剔,并且拒绝了一些合法的邮件。 当发生这种转发邮件,我得到反弹(作为邮政局长) – 而不是发起人。

我明白,这是因为sendmail在本地排队消息,从中继断开连接,然后继续进一步转发它们。 如果进一步的转发因为任何原因而中断 – 比如因为下一个中继将这个消息误认为是垃圾邮件 – 我的sendmail留下来。

可以configuration的东西,使转发立即开始而不是(一旦转发目的地确定)? 状态 – 成功或失败 – 然后可以被直接传送到仍然在线上的以前的继电器…

如果sendmail不能这样做,可以使用其他的MTA吗? 谢谢!

不,这是不可能的,因为它没有与任何广泛的SMTP软件实施; 你将不得不编程自己的SMTP服务器,支持这种行为, 这将超出Serverfault范围 。 在这个答案中,我解释了为什么所有MTA都非常类似地使用队列来实现SMTP协议,以及如何才能完成协议的所有要求。

邮件传输代理 MTA总是要么拒绝邮件,要么根据自己的设置接受和排队邮件。 然后,它被转发或从队列中交付。

那是因为

  • 可能会有永久和暂时的错误。 如果MTA无法连接下一个即时消息,则会稍后再试,只有在延迟达到设定的限制时才会反弹。 在closures连接之前,它也不能等待另一个MTA做出响应,因为它可能还有其他消息先传送。

  • 可以有几个收件人。 虽然客户端可以使用RCPT TO命令简单列出所有收件人,但邮件最终可以传送到其他服务器,其中一些服务器可以现在或稍后可用。 此外,MTA无法在初始连接期间一次打开所有这些连接,并等待他们的回应。 单个收件人的邮件工作stream程完全不同,没有实际的理由。

  • 应该始终明确哪个MTA目前负责传递信息。 (MadHatter回答中的例子已经解释了这一点)

这就是SMTP的devise。 而不是连接命令的语法要求,这导致非常相似的体系结构 ; Sendmail , Postfix甚至MS Exchange都有独立的发送和接收邮件组件。

  1. SMTP服务器组件接收邮件并将其添加到队列中。
  2. 然后,单独的SMTP客户端尝试将其进一步发送到其他MTA,或者如果收件人是本地的,则可以将邮件保存到文件或传递给邮件传递代理 MDA,例如Procmail。

要求仍然来自SMTP规范; 关于SMTP模型基本结构的RFC 5321 2.1 :

预计支持全function的SMTP实现(包括这些function较弱的继电器及其目的地)将支持本规范中讨论的所有排队,重试和替代地址function。 在许多情况和configuration中,上面讨论的性能较差的客户端应该使用消息提交协议( RFC 4409 )而不是SMTP。

还有一点:

换句话说,邮件传输可以在原始的SMTP发送者和最终的SMTP接收者之间的单个连接中发生,或者可以通过中间系统在一系列跳转中发生。 在任何一种情况下,一旦服务器在邮件数据的末尾发出成功响应,就会发生消息责任的正式切换:协议要求服务器必须承担责任,即交付消息或者正确报告失败这样做(见第6.1,6.2和7.8节)。

我认为Esa的回答非常好,但我不同意。 我认为你想要什么可能的,但是这是一个坏主意,它不会帮助你。 正如他所说,RFC5321 s2.1指出

一旦服务器在邮件数据的末尾发出成功响应,就会发生消息责任的正式切换:协议要求服务器必须承担交付消息或正确报告失败的责任

在服务器B收到来自服务器A的消息并将其发送到服务器C的情况下,我没有看到这阻止了B等待确认收到A,直到它已经从C接收到确认 – 这就是你请求。 但是问题是两台服务器之间的250 OK是primefaces的(接收方已经接受了它,所以负责交付,或者它没有,所以发送者仍然负责),而三者之间不是。

考虑到客户端A在发送邮件之后但在它已经有250 OK之前无意中断开连接的情况,而B正在将它传送给C,然后C以250 OK确认收到,所以B知道C具有它。 但是A不行,所以A必须要负责任,并且必须继续向B重新发送。如果A和B之间存在系统的通信问题(例如,那些可爱的防火墙之一认为他们的工作是混淆内容的SMTP会话),这可能会导致传递相同邮件的大量副本。

而且,sendmail已经做了你认为没有的事情:如果发送给C的失败,它会尝试把这个降级传递给A.这通常只有在A是恶意的时候才会失败,并且要么位于信封-File (应该向谁发出通知),或根本不运行邮件服务器。 在这种情况下,邮件必须交付给B的邮政局长,因为B负责交付(对于A说250 OK ,但是没有C),不能交付给C(它被试过并且得到5xx永久性故障),不能回到A(因为A使这不可能),所以没有其他人给它。 这是我今天上午得到的一个例子:

 Date: Tue, 8 Aug 2017 02:53:55 +0100 From: Mail Delivery Subsystem <[email protected]> To: [email protected] Subject: Returned mail: see transcript for details Parts/Attachments: 1 Shown 17 lines Text 2 Shown 407 bytes Message, "Delivery Status" 3 Shown 15 KB Message 3.1 10 KB Application ---------------------------------------- The original message was received at Tue, 8 Aug 2017 02:53:53 +0100 from localhost [IPv6:::1] ----- The following addresses had permanent fatal errors ----- <[email protected]> (reason: 550-5.7.1 Unauthenticated email from aol.com is not accepted due to domain's) ----- Transcript of session follows ----- ... while talking to gmail-smtp-in.l.google.com.: >>> DATA <<< 550-5.7.1 Unauthenticated email from aol.com is not accepted due to domain's <<< 550-5.7.1 DMARC policy. Please contact the administrator of aol.com domain if <<< 550-5.7.1 this was a legitimate mail. Please visit <<< 550-5.7.1 https://support.google.com/mail/answer/2451690 to learn about the <<< 550 5.7.1 DMARC initiative. 53si155585wrc.260 - gsmtp 554 5.0.0 Service unavailable [ Part 2: "Delivery Status" ] Reporting-MTA: dns; lory.teaparty.net Received-From-MTA: DNS; localhost Arrival-Date: Tue, 8 Aug 2017 02:53:53 +0100 Final-Recipient: RFC822; [email protected] Action: failed Status: 5.7.1 Remote-MTA: DNS; gmail-smtp-in.l.google.com Diagnostic-Code: SMTP; 550-5.7.1 Unauthenticated email from aol.com is not accepted due to domain's Last-Attempt-Date: Tue, 8 Aug 2017 02:53:55 +0100 [ Part 3: "Included Message" ] Date: Tue, 08 Aug 2017 01:53:46 -0000 From: [email protected] To: [email protected] [...] 

请注意,原始电子邮件如何声称来自aol.com地址。 那么,我怎么没有试图将失败报告交给他们呢? 因为他们在原来的SMTP交易中撒谎:

 Aug 8 02:53:51 lory sendmail[9457]: v781rmjA009457: from=<[email protected]>, size=14095, class=0, nrcpts=1, msgid=<[email protected]>, proto=SMTP, daemon=MTA-v6, relay=[37.114.157.178] 

这是我的错,我还没有为我的特定领域( stphilipschurch.org.uk )设置SPF,但由于我没有,所以没有任何东西阻止我接受这个谎言 – 然后我被无法投递邮件不能退回给发件人,因为发件人是恶意的和不感兴趣的(通过阿塞拜疆的ISP连接)。

TL; 博士 :sendmail已经做了你所要求的,当它可以。 当你做不到的时候,你想做的事情将无济于事,并且会产生问题。 不要这样做。