【问题标题】:Setting up DomainKeys/DKIM in a PHP-based SMTP client [closed]在基于 PHP 的 SMTP 客户端中设置 DomainKeys/DKIM [关闭]
【发布时间】:2011-02-17 11:33:44
【问题描述】:

看起来有一些很棒的库可以在 C#/.NET 上对电子邮件进行 DomainKeys 签名,但我很难找到对 PHP 的相同类型的支持。也许我没有找对地方?

我找到的唯一一个是http://php-dkim.sourceforge.net/;它看起来非常h​​acky,只支持PHP4。考虑到 PHP 的流行程度,以及域名密钥对于将电子邮件分类为非垃圾邮件的重要性,我希望有更好的工具;你知道吗?你还有什么推荐的技巧吗?

额外信息:我正在使用外部 SMTP 提供商,因为我每天需要发送数千封电子邮件。

【问题讨论】:

    标签: php smtp email-spam dkim domainkeys


    【解决方案1】:

    我建议在 MTA 级别支持 DKIM,以便默认情况下对给定域的所有服务器生成的电子邮件进行签名。 (除非您有充分的理由不签署所有服务器生成的域电子邮件)。

    使用 dkim-milter 和 sendmail(在我的例子中是 CentOS 5.2)在 LAMP 上设置 DKIM 谷歌搜索的最佳起点是 Jeff Atwood's post about sending emails through code

    我同意他的观点,你应该解决的前两件事是反向 PTR 记录和 DKIM 签名。

    也很重要:

    1. 用于发送电子邮件的盒子的 IP 地址尚未被列入黑名单。
    2. 确保 postmaster@emailsendingdomain.com 是有效的邮箱
    3. 如果您的服务器生成的电子邮件需要看起来来自其他地方(例如需要来自表单中提供的姓名/电子邮件的联系表格)follow these guidelines for email headers

    这是我使用的email ip address blacklist checker

    这 5 件事可能会解决您 95% 的电子邮件送达率问题。

    这个Guide for Fedora/dkim-milter/postfix也很好。

    我用于我的应用程序的 PHP 邮件库是 PHPMailer 5.1,它支持 DKIM(并且仅支持 PHP 5),但经过研究,我决定在 sendmail 级别实现是一个更好的解决方案。如您所见,即使是PHPMailer 5.1的作者也不建议在PHP邮件库级别使用DKIM是最好的解决方案http://dkim.worxware.com/

    祝你好运。

    【讨论】:

    • 有用的信息,但不适合我,抱歉。我正在使用外部 SMTP 电子邮件提供商,无法控制他们的代码。我必须使用它们,因为我要发送数千封电子邮件。其余建议并不直接适用于我的问题。
    • @Alex:我正要为 PHP 编写我自己的 DKIM 实现,但我支持 jigglee:MTA 应该处理它。想象一下,MTA 更改/重新格式化电子邮件内容,PHP 无法先验地知道这一点,这会使私钥/公钥分崩离析,这将产生不利影响。
    • @AlexWeinstein 如果此解决方案不适合您,为什么将其标记为答案?我也在与第三方电子邮件提供商合作,这似乎不是正确的答案......
    【解决方案2】:

    这是我关注了一段时间的问题,在网络上的任何地方都无法在此线程中找到原始问题的明确答案。我现在已经能够使用 PHP/Pear 实现发送 DKIM 签名的 SMTP 电子邮件。以下是所需的步骤。

    1. 我从 http://www.ra726.net/blog/2010/07/20/sending-email-to-gmail-from-php-without-being-marked-as-spam/ 找到了 DKIM 的修改版本(您可以通过 http://www.ra726.net/php-dkim.zip 下载它)。如果您已经实现了 DKIM 并且只需要使其与 SMP 邮件一起使用,那么您所需要的就是 dkim.php 文件,正如博客所说,该文件经过轻微修改以处理作为数组传递的标头。在我的代码中,我将其命名为 dkimNEW.php。

    2. 确保包含大多数标头,以便 MTA 在您签名后不会修改邮件。在我有限的研究中,添加最多的标头是 Date 和 Message-ID 标头,因此我的标头数组如下所示: 注意:我使用它来发送 html 电子邮件,更改以适应!另外,将您的域添加为 Message-ID 的最后一部分

      $headers = array(
          'Subject' => $subject,
          'From' => $from,
          'To' => $to,
          'MIME-Version' => '1.0',
          'Date' => date('r'),
          'Message-ID' => '<'.sha1(microtime(true)).'@yourdomain.com>',
          'Content-Type' => 'text/html',
          'Content-Transfer-Encoding' => 'quoted-printable',
      ); // end $headers
      
    3. 然后您将使用上面提到的修改后的 dkim.php 来签署您的电子邮件并将签名添加到 headers 数组中,也就是

      require 'dkimNEW.php';
      $dkim = AddDKIM($headers, $subject, $body);
      $headers['DKIM-Signature'] = $dkim;
      

    其余代码是使用 PHP/Pear 通过 SMTP 发送电子邮件的普通代码。完整的工作代码是:

    <?php
        require_once 'Mail.php';
        require_once 'Mail/mime.php';
      // set all of the parameters
        $subject = 'Test of DKIM';
        $from = 'My Name <myname@mydomain.com>';
        $to = 'First Recipient <recipient1@domain.com>';
        $pbody ='<html><head></head><body><h1>Done! DKIM test</h1>Result, next?</body></html>';
        $text = strip_tags($pbody);
    
        // create the headers
        $headers = array(
            'Subject' => $subject,
            'From' => $from,
            'To' => $to,
            'MIME-Version' => '1.0',
            'Date' => date('r'),
            'Message-ID' => '<'.sha1(microtime(true)).'@mydomain.com>',
            'Content-Type' => 'text/html',
            'Content-Transfer-Encoding' => 'quoted-printable',
        ); // end $headers
    
    
        // create the message
        $mime = new Mail_mime("\n");
        $mime->setTXTBody($text);
        $mime->setHTMLBody($pbody);
    
        // always call these methods in this order
        $body = $mime->get();
        $headers = $mime->headers($headers);
    
        require 'dkimNEW.php' ;
        $dkim = AddDKIM($headers, $subject, $body);
        $headers['DKIM-Signature'] = $dkim;
    
        // create the smtp mail object
        $smtp_params = array(
            'host' => 'mail.mydomain.com',
            'auth' => true,
            'username' => 'myUserName',
            'password' => 'myPassWord',
        ); // end $smtp_params
        $smtp = Mail::factory('smtp', $smtp_params);
    
        // send the message
    
        $recipients = array('recipient1@domain.com', 'recipient2@domain.com');
        $mail = $smtp->send($recipients, $headers, $body);
    
    ?>
    

    附言。以防万一您没有注意到,请将值替换为您自己的值!

    因此,使 DKIM 与 SMTP 电子邮件(或实际上是 PHP 邮件)一起工作所需要做的就是确保您指定由 MTA 添加到您的电子邮件中的所有标头,然后签署标头、主题和邮件正文,最后在标题中包含签名部分。

    【讨论】:

      【解决方案3】:

      你试过了吗:phpMailDomainSigner 它支持面向对象风格的 DKIM-Signature 和 DomainKey-Signature。

      这里有一些例子:

      // Create mailDomainSigner Object
      include_once './lib/class.mailDomainSigner.php';
      
      $mds = &new mailDomainSigner($domain_priv,$domain_d,$domain_s);
      $new_data = $mds->sign(
                      $mail_data,
                      "Message-ID:Subject:From:Content-Type:MIME-Version:Content-Transfer-Encoding:Received:To:Date",
                      true,true,false);
      

      【讨论】:

      【解决方案4】:

      一个仅用于 DKIM 的类,它是 PHPMailer 的衍生产品,但在尊重 RFC 和整洁的代码方面有所改进:

      https://sourceforge.net/projects/dkim-class-php/

      例子:

      include_once('dkim.class.php');
      $dkim = new DKIM();
      $dkim_header = $dkim -> get_DKIM_header($to, $subject, $message, $headers);
      mail($to, $subject, $message, $dkim_header.$headers);
      

      【讨论】:

      猜你喜欢
      • 2011-01-22
      • 2011-03-15
      • 2011-04-16
      • 2015-06-16
      • 2013-03-20
      • 2010-11-16
      • 2011-07-31
      • 2011-11-01
      相关资源
      最近更新 更多