由于一个无效地址,Postfix拒绝具有多个目的地的传出电子邮件

我正在使用Postfix发送我的电子邮件,而且我有一大堆电子邮件发送通讯。 所以我更喜欢把我的SMTP请求包装成一个,把其中一个电子邮件设置为To ,一个更多地设置为Bcc (在PHP中)。

我的问题是,如果其中一个电子邮件是无效的,Postfix拒绝整个请求提示以下错误:

 5.1.1 : Recipient address rejected: User unknown in local recipient table 

如果我能够以某种方式configurationPostfix,这将是非常好的,所以它会转储无效的文件,然后发送剩余的文件。 我知道我可以在电子邮件中使用它们之前自己validation地址,但是如果Postfix完成,我更喜欢它。

[UPDATE]

这是maillog的内容:

 Nov 18 16:20:28 mail postfix/smtpd[12922]: 14A5FB812E1: client=localhost[127.0.0.1] Nov 18 16:20:28 mail postfix/smtpd[12922]: 14A5FB812E1: reject: RCPT from localhost[127.0.0.1]: 550 5.1.1 <mehran_hotmail.com>: Recipient address rejected: User unknown in local recipient table; from=<mehran@localhost> to=<mehran_hotmail.com> proto=ESMTP helo=<localhost> 

当我尝试发送邮件[email protected]作为主要收件人和mehran_hotmail.com作为Bcc生成此错误。

[UPDATE]

以下是与请求关联的完整日志:

 Nov 19 09:47:01 mail postfix/smtpd[20947]: connect from localhost[127.0.0.1] Nov 19 09:47:01 mail postfix/smtpd[20947]: EC281B81BCE: client=localhost[127.0.0.1] Nov 19 09:47:01 mail postfix/smtpd[20947]: warning: Illegal address syntax from localhost[127.0.0.1] in RCPT command: <mehran@?????.com> Nov 19 09:47:01 mail postfix/smtpd[20947]: disconnect from localhost[127.0.0.1] 

这是一个新的场景(导致同样的问题),我使用了一个正确的电子邮件地址( ToBcc保持正确的电子邮件地址,但不是相同的地址),但这次邮件地址被拒绝,因为Postfix不能识别它。 我使用非ASCII字符作为域名(mehran @مهران。com)。 我不在乎Postfix是否支持非ASCII地址,只是当它拒绝一个地址,整个请求被拒绝! 没有电子邮件发送到[email protected](这是命名To )!

现在返回给我的代码(PHP发MUA)的错误信息是:

 5.1.3 Bad recipient address syntax 

至于我的PHP代码与SMTP服务器交互:

 $mail = new \Zend_Mail('utf-8'); $mail->setMessageId($mail->createMessageId()); foreach ($array_to as $to) { $mail->addTo($to['email'], $to['name']); } foreach ($array_cc as $to) { $mail->addCc($to['email'], $to['name']); } foreach ($array_bcc as $to) { $mail->addBcc($to['email'], $to['name']); } $mail->setSubject($subject); $mail->setBodyHtml($body); $mail->setFrom($current_user_email, $current_user_name); $mail->setDate(new \Zend_Date()); $smtp = createSmtpConnection(); $smtp->send($mail); 

正如你所看到的,我使用了Zend Framework(v1),而且我的代码非常简单。 $array_*variables是包含电子邮件地址的简单数组。 在我的testing场景中,只有两个电子邮件地址,一个用于To ,另一个用于Bcc

TLDR:您的情况是在正确的SMTP事务中exception行为的邮件客户端。 也许在你的PHP代码中有错误。 在postfix邮件列表上看到这个线程。 来自该线程中Postfix作者的引用

你误会了。 你没有证据表明Postfix拒绝整个消息。

众所周知,当一个收件人不被接受时,即使其他收件人是好的,某些SMTP CLIENT程序也会放弃发送邮件。


SMTP拒绝如何工作

首先,我们将参加SMTP交易。 下面是SMTP如何在低层工作。 您可以随时通过telnet / netcat来尝试。

案例1这是有单个收件人时的交易。

 S: 220 smtp.example.net Simple Mail Transfer Service Ready C: HELO client.example.com S: 250 Hello client.example.com C: MAIL FROM:<[email protected]> S: 250 OK C: RCPT TO:<[email protected]> S: 250 OK C: DATA S: 354 Send message content; end with <CRLF>.<CRLF> C: The message data (body text, subject, e-mail header, attachments etc) is sent C: . S: 250 2.0.0 Ok: queued as D7D3E84403 C: QUIT S: 221 Bye 

因此,SMTP是一个琐碎的协议,每当客户端发出命令(HELO / MAIL / RCPT / DATA / QUIT)时,服务器应该在事务继续之前应答它。 在这种情况下,所有的答案都有代码250,或者我接受了这个代码

情况2多个收件人的SMTP事务

 S: 220 smtp.example.net Simple Mail Transfer Service Ready C: HELO client.example.com S: 250 Hello client.example.com C: MAIL FROM:<[email protected]> S: 250 OK C: RCPT TO:<[email protected]> S: 250 OK C: RCPT TO:<[email protected]> S: 250 OK C: RCPT TO:<[email protected]> S: 250 OK C: DATA S: 354 Send message content; end with <CRLF>.<CRLF> C: The message data (body text, subject, e-mail header, attachments etc) is sent C: . S: 250 2.0.0 Ok: queued as D7D3E84403 C: QUIT S: 221 Bye 

在这个例子中有三个收件人。 我们在单个事务中使用多个RCPT命令。 RCPT命令是特殊命令。 对于给定的电子邮件消息,此命令可以重复多次,以便将单个电子邮件发送给多个收件人。

案例3如果一些收件人拒绝(但不是全部),交易继续进行。 这里是示例交易。

 S: 220 smtp.example.net Simple Mail Transfer Service Ready C: HELO client.example.com S: 250 Hello client.example.com C: MAIL FROM:<[email protected]> S: 250 OK C: RCPT TO:<[email protected]> S: 250 OK C: RCPT TO:<[email protected]> S: 550 5.1.1 <[email protected]>: Recipient address rejected: User unknown in local recipient table C: RCPT TO:<[email protected]> S: 250 OK C: DATA S: 354 Send message content; end with <CRLF>.<CRLF> C: The message data (body text, subject, e-mail header, attachments etc) is sent C: . S: 250 2.0.0 Ok: queued as D7D3E84403 C: QUIT S: 221 Bye 

为什么服务器仍然接受电子邮件? 因为在一个无效的收件人旁边有两个有效的收件人。

免责声明:以上资源来自这里 。


(失败)尝试重现问题

好的,我试图在我的盒子里重现你的问题。 这是我的PHP代码库PHPMailer 。 (我不熟悉zend框架)

 <?php require '../PHPMailerAutoload.php'; $internaldomain = 'in.example.com'; $externaldomain = 'ex.example.com'; $mail = new PHPMailer; $mail->isSMTP(); $mail->SMTPDebug = 2; $mail->Host = "smtp6.example.com"; $mail->Port = 25; $mail->SMTPAuth = false; $mail->setFrom('from@' . $internaldomain, 'First Last'); $mail->addAddress('valid@' . $externaldomain, 'valid 1'); $mail->AddBCC('bounce@' . $internaldomain, 'valid 3'); $mail->AddBCC('invaliduser@' . $internaldomain, 'invalid user'); $mail->AddBCC('root@' . $internaldomain, 'valid 4'); $mail->Subject = 'PHPMailer SMTP test'; $mail->IsHTML(false); $mail->Body = "This is test"; if (!$mail->send()) { echo "Mailer Error: " . $mail->ErrorInfo; } else { echo "Message sent!"; } 

由于SMTPDebug已启用,输出包含完整的SMTP事务。 这个输出与上面的例子类似。

 SERVER -> CLIENT: 220 smtp6.example.net ESMTP at your service CLIENT -> SERVER: EHLO web.example.net SERVER -> CLIENT: 250-smtp6.example.net 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN CLIENT -> SERVER: MAIL FROM:<[email protected]> SERVER -> CLIENT: 250 2.1.0 Ok CLIENT -> SERVER: RCPT TO:<[email protected]> SERVER -> CLIENT: 250 2.1.5 Ok CLIENT -> SERVER: RCPT TO:<[email protected]> SERVER -> CLIENT: 250 2.1.5 Ok CLIENT -> SERVER: RCPT TO:<[email protected]> SERVER -> CLIENT: 550 5.1.1 <[email protected]>: Recipient address rejected: User unknown in local recipient table SMTP ERROR: RCPT TO command failed: 550 5.1.1 <[email protected]>: Recipient address rejected: User unknown in local recipient table CLIENT -> SERVER: RCPT TO:<[email protected]> SERVER -> CLIENT: 250 2.1.5 Ok CLIENT -> SERVER: DATA SERVER -> CLIENT: 354 End data with <CR><LF>.<CR><LF> CLIENT -> SERVER: Date: Wed, 19 Nov 2014 09:28:16 +0700 CLIENT -> SERVER: To: valid 1 <[email protected]> CLIENT -> SERVER: From: First Last <[email protected]> CLIENT -> SERVER: Subject: PHPMailer SMTP test CLIENT -> SERVER: Message-ID: <[email protected]> CLIENT -> SERVER: X-Priority: 3 CLIENT -> SERVER: X-Mailer: PHPMailer 5.2.9 (https://github.com/PHPMailer/PHPMailer/) CLIENT -> SERVER: MIME-Version: 1.0 CLIENT -> SERVER: Content-Type: text/plain; charset=iso-8859-1 CLIENT -> SERVER: Content-Transfer-Encoding: 8bit CLIENT -> SERVER: CLIENT -> SERVER: This is test CLIENT -> SERVER: CLIENT -> SERVER: . SERVER -> CLIENT: 250 2.0.0 Ok: queued as D7D3E84403 CLIENT -> SERVER: QUIT SERVER -> CLIENT: 221 2.0.0 Bye 

和maillog入口

 Nov 19 09:28:16 cache postfix/smtpd[14865]: D7D3E84403: client=unknown[192.168.192.100] Nov 19 09:28:16 cache postfix/smtpd[14865]: D7D3E84403: reject: RCPT from unknown[192.168.192.100]: 550 5.1.1 <[email protected]>: Recipient address rejected: User unknown in local recipient table; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<web.example.net> Nov 19 09:28:16 cache postfix/cleanup[14867]: D7D3E84403: message-id=<[email protected]> Nov 19 09:28:17 cache postfix/qmgr[1200]: D7D3E84403: from=<[email protected]>, size=617, nrcpt=3 (queue active) Nov 19 09:28:17 cache postfix/local[14870]: D7D3E84403: to=<[email protected]>, relay=local, delay=0.21, delays=0.21/0/0/0, dsn=2.0.0, status=sent (delivered to mailbox) Nov 19 09:28:17 cache postfix/smtp[14869]: D7D3E84403: to=<[email protected]>, relay=example.org[192.168.3.3]:25, delay=0.22, delays=0.21/0/0/0.01, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 3jj7Hj0pM3z5Twh) Nov 19 09:28:17 cache postfix/local[14868]: D7D3E84403: to=<[email protected]>, relay=local, delay=0.23, delays=0.21/0/0/0.02, dsn=2.0.0, status=sent (forwarded as 165E084404) Nov 19 09:28:17 cache postfix/qmgr[1200]: D7D3E84403: removed 

好吧,看起来像在我的箱子,后缀和PHPMailer正常情况下的行为。 你可以用它来比较你的盒子里的maillog 🙂

这不是邮件服务器的工作方式。 它们被devise成通过发送邮件,或者如果有什么不起作用,则将错误/失败的原因返回给最终用户。 改变这种行为改变了SMTP的function。

正如NDR上的Wiki页面所述 :

NDRs are a basic SMTP function. As soon as an MTA has accepted a mail for forwarding or delivery it cannot silently delete ("drop") it; it has to create and send a bounce message to the originator if forwarding or delivery failed.

通过取消注释文件中的以下条目来修改您的Postfix / main.cf文件。 重新启动postfix并尝试再次发送。

local_recipient_maps

在尝试发送电子邮件的电子邮件应用程序客户端中发生的事情与通过命令行执行testing的过程不同,因为命令行中允许电子邮件stream继续,但是立即检测到错误的本地地址。