我有关于 sendmail 的问题,我已经搜索过类似的问题,但找不到任何对我有帮助的内容。
我目前正在使用带有 sendmail 的服务器(带有 LAMP Stack 的 Debian),用于发送网站上用户注册的验证邮件。这通常很有效,例如 gmail 会收到邮件,一切正常。但我最近发现,使用 yahoo 时,它根本不起作用,yahoo 似乎根本没有收到邮件。因此,我自己设置了一个 yahoo 帐户进行测试,并观察到以下行为,我尝试尽可能详细地描述它:
我使用以下 PHP 代码片段发送邮件:
$toEmail = '...';
$subject = '...';
$message = '...';
$headers = array();
$headers[] = "MIME-Version: 1.0";
$headers[] = "Content-type: text/plain; charset=utf-8";
$headers[] = "From: [email protected]";
$headers[] = "Subject: {$subject}";
$headers[] = "X-Mailer: PHP/".phpversion();
if(mail($toEmail, $subject, $message, implode("\r\n",$headers))) {
return TRUE;
}
我在服务器上安装了 sendmail,用于处理来自 PHP 的邮件命令。
如上所述,除了 Yahoo(可能还有其他我还不知道的地址)之外,这几乎适用于所有收件人地址。使用网站上触发邮件发送的表单,我在几秒钟内收到了邮件。以下是显示的日志/var/log/mail.log
May 3 14:19:12 btfmx5 sendmail[544]: u43CJCtW000544: from=www-data, size=1174, class=0, nrcpts=1, msgid=<[email protected]>, relay=www-data@localhost
May 3 14:19:13 btfmx5 sm-mta[545]: u43CJDBO000545: from=<[email protected]>, size=1419, class=0, nrcpts=1, msgid=<[email protected]>, proto=ESMTP, daemon=MTA-v4, relay=localhost [127.0.0.1]
May 3 14:19:13 btfmx5 sendmail[544]: u43CJCtW000544: [email protected], ctladdr=www-data (33/33), delay=00:00:01, xdelay=00:00:01, mailer=relay, pri=31174, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (u43CJDBO000545 Message accepted for delivery)
May 3 14:19:13 btfmx5 sm-mta[547]: STARTTLS=client, relay=gmail-smtp-in.l.google.com., version=TLSv1/SSLv3, verify=FAIL, cipher=ECDHE-RSA-AES128-GCM-SHA256, bits=128/128
May 3 14:19:13 btfmx5 sm-mta[547]: u43CJDBO000545: to=<[email protected]>, ctladdr=<[email protected]> (33/33), delay=00:00:00, xdelay=00:00:00, mailer=esmtp, pri=121419, relay=gmail-smtp-in.l.google.com. [64.233.184.26], dsn=2.0.0, stat=Sent (OK 1462278313 o16si26784998wme.6 - gsmtp)
但是,当我尝试发送到 yahoo 地址时,上面的 PHP 代码返回 TRUE,但 yahoo 帐户根本没有收到任何邮件。以下是此情况下显示的日志:
May 3 14:26:50 btfmx5 sendmail[571]: u43CQoiH000571: from=www-data, size=1174, class=0, nrcpts=1, msgid=<[email protected]>, relay=www-data@localhost
May 3 14:26:50 btfmx5 sm-mta[572]: u43CQogB000572: from=<[email protected]>, size=1419, class=0, nrcpts=1, msgid=<[email protected]>, proto=ESMTP, daemon=MTA-v4, relay=localhost [127.0.0.1]
May 3 14:26:50 btfmx5 sendmail[571]: u43CQoiH000571: [email protected], ctladdr=www-data (33/33), delay=00:00:00, xdelay=00:00:00, mailer=relay, pri=31174, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (u43CQogB000572 Message accepted for delivery)
May 3 14:26:51 btfmx5 sm-mta[574]: STARTTLS=client, relay=mta5.am0.yahoodns.net., version=TLSv1/SSLv3, verify=FAIL, cipher=ECDHE-RSA-AES128-GCM-SHA256, bits=128/128
May 3 14:26:53 btfmx5 sm-mta[574]: u43CQogB000572: to=<[email protected]>, ctladdr=<[email protected]> (33/33), delay=00:00:03, xdelay=00:00:03, mailer=esmtp, pri=121419, relay=mta5.am0.yahoodns.net. [66.196.118.37], dsn=5.0.0, stat=Service unavailable
May 3 14:26:53 btfmx5 sm-mta[574]: u43CQogB000572: u43CQrgB000574: DSN: Service unavailable
May 3 14:26:53 btfmx5 sm-mta[574]: u43CQrgB000574: to=<[email protected]>, delay=00:00:00, xdelay=00:00:00, mailer=local, pri=30000, dsn=2.0.0, stat=Sent
我现在尝试从命令行使用 sendmail 向 yahoo 地址发送电子邮件,以从详细模式获取更多信息。
但令我惊讶的是,雅虎收到了这封电子邮件(在垃圾邮件文件夹中,但谁在乎呢)!现在我完全糊涂了,为什么它在命令行中可以工作,而使用 PHP 时却不行?
我用于发送邮件的命令:
echo "Subject: testmail" | sendmail -v [email protected]
以及相应的日志条目mail.log
:
May 3 14:34:35 btfmx5 sendmail[581]: u43CYZp5000581: from=alumpi, size=18, class=0, nrcpts=1, msgid=<[email protected]>, relay=root@localhost
May 3 14:34:35 btfmx5 sm-mta[582]: u43CYZx0000582: from=<[email protected]>, size=340, class=0, nrcpts=1, msgid=<[email protected]>, proto=ESMTP, daemon=MTA-v4, relay=localhost [127.0.0.1]
May 3 14:34:37 btfmx5 sm-mta[582]: STARTTLS=client, relay=mta7.am0.yahoodns.net., version=TLSv1/SSLv3, verify=FAIL, cipher=ECDHE-RSA-AES128-GCM-SHA256, bits=128/128
May 3 14:34:39 btfmx5 sm-mta[582]: u43CYZx0000582: to=<[email protected]>, ctladdr=<[email protected]> (1000/1000), delay=00:00:04, xdelay=00:00:04, mailer=esmtp, pri=30340, relay=mta7.am0.yahoodns.net. [63.250.192.45], dsn=2.0.0, stat=Sent (ok dirdel)
May 3 14:34:39 btfmx5 sendmail[581]: u43CYZp5000581: [email protected], ctladdr=alumpi (1000/1000), delay=00:00:04, xdelay=00:00:04, mailer=relay, pri=30018, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (u43CYZx0000582 Message accepted for delivery)
sendmail 命令的详细输出:
[email protected]... Connecting to [127.0.0.1] via relay...
220 MYSERVER.de ESMTP Sendmail 8.14.4/8.14.4/Debian-8; Tue, 3 May 2016 14:34:35 +0200; (No UCE/UBE) logging access from: localhost(OK)-localhost [127.0.0.1]
>>> EHLO MYSERVER.de
250-MYSERVER.de Hello localhost [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-EXPN
250-VERB
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH DIGEST-MD5 CRAM-MD5
250-DELIVERBY
250 HELP
>>> VERB
250 2.0.0 Verbose mode
>>> MAIL From:<[email protected]> SIZE=18 [email protected]
250 2.1.0 <[email protected]>... Sender ok
>>> RCPT To:<[email protected]>
>>> DATA
250 2.1.5 <[email protected]>... Recipient ok
354 Enter mail, end with "." on a line by itself
>>> .
050 <[email protected]>... Connecting to mta7.am0.yahoodns.net. via esmtp...
050 220 mta1523.mail.gq1.yahoo.com ESMTP ready
050 >>> EHLO MYSERVER.de
050 250-mta1523.mail.gq1.yahoo.com
050 250-PIPELINING
050 250-SIZE 41943040
050 250-8BITMIME
050 250 STARTTLS
050 >>> STARTTLS
050 220 Start TLS
050 >>> EHLO MYSERVER.de
050 250-mta1523.mail.gq1.yahoo.com
050 250-PIPELINING
050 250-SIZE 41943040
050 250 8BITMIME
050 >>> MAIL From:<[email protected]> SIZE=340
050 250 sender <[email protected]> ok
050 >>> RCPT To:<[email protected]>
050 >>> DATA
050 250 recipient <[email protected]> ok
050 354 go ahead
050 >>> .
050 250 ok dirdel
050 <[email protected]>... Sent (ok dirdel)
250 2.0.0 u43CYZx0000582 Message accepted for delivery
[email protected]... Sent (u43CYZx0000582 Message accepted for delivery)
Closing connection to [127.0.0.1]
>>> QUIT
221 2.0.0 MYSERVER.de closing connection
所以主要问题是:为什么发送到例如 gmail 可以工作,但发送到 yahoo 却失败?
第二个问题:为什么通过命令行发送给 yahoo 可以工作,但通过 PHP 发送却失败?
我希望我提供了所有必要的信息,提前感谢您的帮助!
答案1
感谢各位的评论,我才能够弄清楚(我对这种管理工作还不太熟悉,对信封发件人等不太了解......):
从日志中可以看出,使用 PHP 时 sendmail 使用的信封发件人是[电子邮件保护],当使用命令行时[电子邮件保护],所以我尝试改变它们。但这不是问题,也不是两种情况行为不同的原因。
事实上,愚蠢的我到那时才意识到,如果我使用正确的邮件地址作为信封发件人/返回路径,我就会收到一封可能包含有用信息的退回邮件。这样做之后,我收到了一封发往该邮件地址的退回邮件,其中包含:
554 Message not allowed - Headers are not RFC compliant[291]
是的,最初的错误并不引人注目:
正如问题中发布的 PHP 代码所示,我发送了两次主题标头。一次是在标头数组中,一次是直接使用 PHP mail() 函数的主题参数。似乎大多数邮件提供商都不在乎这个,但雅虎却在乎。
因此,我清理了我的 PHP 代码以发送单个主题并使用有用的返回路径,现在它可以完美运行(甚至不会进入垃圾邮件文件夹):
$toEmail = '...';
$subject = '...';
$message = '...';
$headers = array();
$headers[] = "MIME-Version: 1.0";
$headers[] = "Content-type: text/plain; charset=utf-8";
$headers[] = "From: [email protected]";
$headers[] = "X-Mailer: PHP/".phpversion();
if(mail($toEmail, $subject, $message, implode("\r\n",$headers), '-f [email protected]')) {
return TRUE;
}