【问题标题】:PHP mail issue with www-datawww-data 的 PHP 邮件问题
【发布时间】:2011-04-14 16:18:00
【问题描述】:

我正在尝试通过以下代码通过 PHP 的邮件函数调用 sendmail:

$to      = 'blah@email.state.edu';
    $subject = 'test';
    $message = 'test';
    $headers = 'From: mail@smartrek.blah.me' . "\r\n" .
               'Reply-To: mail@smartrek.blah.me' . "\r\n" .
                'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);

但是在我的 mail.log 中,我收到一条消息,指出发件人不是我在标题中指定的地址:

<www-data@Name>: Sender address rejected: Domain not found

这是为什么?我在 ubuntu 上运行 PHP 的 fast-cgi 为什么 sendmail 不使用我通过 PHP 代码指定的标头?

【问题讨论】:

  • 你有这个文件吗:/etc/postfix/main.cf,同时在你的终端运行postconf -n,让我们知道输出。
  • 我使用的是 sendmail 而不是 postfix

标签: php sendmail


【解决方案1】:

看起来www-data@Name 是您的信封“发件人”地址。信封“发件人”地址与电子邮件“发件人:”标头中显示的地址不同。这是 sendmail 在与接收邮件服务器的“MAIL FROM/RCPT TO”交换中使用的。它被称为“信封”地址的主要原因是出现在邮件标题和正文的外部,在邮件服务器之间的原始 SMTP 交换中。

unix 上的默认信封“发件人”地址取决于您使用的 sendmail 实现。但通常它将设置为运行进程的用户名,后跟“@”和机器的主机名。在典型配置中,这将类似于 username@example.com

如果您的邮件被接收邮件服务器拒绝,或者如果您需要更改退回邮件的发送地址,您可以更改信封“发件人”地址来解决您的问题。

要更改 unix 上的信封“发件人”地址,您可以在 sendmail 二进制文件中指定“-r”选项。您可以通过在“sendmail_path”命令行中添加“-r”选项来在 php.ini 中全局执行此操作。您还可以通过将-r mail@smartrek.blah.me 作为 附加参数 参数传递给 mail() 函数(第 5 个参数),以编程方式在 PHP 中执行此操作。如果你在两个地方都指定了一个地址,sendmail 二进制文件将使用两个“-r”选项调用,根据你的 sendmail 实现,这可能具有未定义的行为。使用 Postfix MTA,后面的“-r”选项会静默地覆盖早期的选项,从而可以设置全局默认值,并且当您尝试在本地覆盖它时仍然可以获得合理的行为。

编辑

关于可以传递给 sendmail 的可选标志: -f 将设置发件人地址,-r 将覆盖 sendmail 生成的默认返回路径(通常使用发件人地址) .如果您希望您的退回邮件转到与发件人地址不同的地址,请尝试同时使用这两个标志:-f mail@smartrek.blah.me -r bounced-mail@smartrek.blah.me

我的 php.ini

[mail function]
; For Win32 only.
; http://php.net/smtp
SMTP = localhost
; http://php.net/smtp-port
smtp_port = 25

; For Win32 only.
; http://php.net/sendmail-from
;sendmail_from = me@example.com

; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
; http://php.net/sendmail-path
;sendmail_path =

; Force the addition of the specified parameters to be passed as extra parameters
; to the sendmail binary. These parameters will always replace the value of
; the 5th parameter to mail(), even in safe mode.
;mail.force_extra_parameters =

; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename
mail.add_x_header = On

; Log all mail() calls including the full path of the script, line #, to address and headers
;mail.log =

【讨论】:

  • 我在 sendmail_path 中添加了 -r 选项,现在我得到了:sendmail[2719]: p3EGvC1r002719: from=www-data, size=259, class=0, nrcpts=0, msgid=, 中继=www-data@localhost
  • 如果我在 sendmail_path 中指定 -f mail@smartrek.blah.me 它可以工作,但我不想这样做
  • 只是为了测试,您可以尝试从您的代码中删除From:Reply-To:
  • 在您的 php 中,您可以像这样调用邮件函数:mail('to-email@example.com', 'the subject', 'the message', $headers, '-fmail@smartrek.blah.me'); 为邮件函数提供运行时值。
  • @anubhava 为了在this question 上帮助我,您从这个问题中得到了很大的帮助。
【解决方案2】:

虽然这是一个老问题,但我会添加这个答案,以防它对某人有所帮助:

From: 标头被重新写入www-data@host... 时遇到了同样的问题,我最终将其追踪到 ssmtp 桥接服务,该服务将邮件从我们的 Web 服务器传送到我们的邮件服务器。我在文件/etc/ssmtp/ssmtp.conf 中添加了FromLineOverride=YES 行,问题就消失了。

【讨论】:

    【解决方案3】:

    就我而言,我有一个托管服务器,所以我需要编辑这个文件:

    /etc/ssmtp/ssmtp.conf

    然后取消注释这一行:

    FromLineOverride=YES

    完成后,个人标题就可以工作了。

    【讨论】:

      【解决方案4】:

      当我的所有邮件都使用此标头发送和接收时,我遇到了与 www-data 类似的问题:

      From: www-data <www-data@example.com>
      

      我使用-f info@example.com 标志作为 PHP email() 函数的第 5 个参数(如已接受的答案中所述),但我仍然收到我的电子邮件:

      From: www-data <info@example.com>
      

      所以我又添加了一个标志-f info@example.com -F info 来设置电子邮件的全名,最后我收到了我想要的电子邮件:

      From: info <info@example.com>
      

      我发布这个答案是因为这里没有人提到它,我有点卡住了。

      【讨论】:

        【解决方案5】:

        这对我有用:

        $mail->Sendmail = $mail->Sendmail.' -f '.$mail_errorsto; 
        

        【讨论】:

          【解决方案6】:

          我在使用 exim4smarthost 时遇到了这个问题。邮件是用

          发送的
          Return-path: <www-data@servername>
          

          被 ISP 拒绝。我需要将其更改为至少www-data@example.com(假设“example.com”是服务器的公共域名)。我可以通过将/etc/mailname 更改为

          来实现
          servername
          

          example.com
          

          这已经为我工作了,将www-data@example.com 设置为Return-path

          不过——如果你想彻底改变邮箱地址,可以在/etc/email-addresses中配置为

          www-data: notifications@example.com
          

          在此之后,电子邮件默认使用

          发送
          Return-path: <notifications@example.com>
          

          【讨论】: