在基于PHP的SMTP客户端中设置DomainKeys / DKIM

时间:2021-11-01 18:11:56

It looks like there are some great libraries out there to do DomainKeys signing of emails on C#/.NET, but I'm having a really hard time finding the same kind of support for PHP. Maybe I'm not looking in the right place?

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

The only one I found is http://php-dkim.sourceforge.net/; it looks incredibly hacky and supports PHP4 only. Considering how popular PHP is, and how critical DomainKeys are for email classification as non-spam, I'd expect better tools; do you know of any? Any other tricks you'd recommend?

我找到的唯一一个是http://php-dkim.sourceforge.net/;它看起来非常h​​acky并且仅支持PHP4。考虑到PHP的流行程度,以及DomainKeys对于非垃圾邮件分类的重要性,我希望有更好的工具;你知道吗?你推荐的其他任何技巧?

Extra info: I'm using an external SMTP provider because I need to send out thousands of emails per day.

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

4 个解决方案

#1


21  

I'd recommend DKIM support at the MTA level so all your server generated email for a given domain is signed by default. (unless you have a really good reason to not sign all server generated email for a domain).

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

The best starting point in my googling to get DKIM setup on LAMP with dkim-milter and sendmail (on CentOS 5.2 in my case) was Jeff Atwood's post about sending emails through code.

我在google搜索中使用dkim-milter和sendmail(在我的案例中为CentOS 5.2)上使用LAMP设置DKIM的最佳起点是Jeff Atwood关于通过代码发送电子邮件的帖子。

I would agree with him that the first 2 things you should address are reverse PTR record and DKIM signing.

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

Also very important:

同样非常重要:

  1. IP address of the box to send email not already being blacklisted.
  2. 发送电子邮件的框的IP地址尚未列入黑名单。
  3. make sure postmaster@emailsendingdomain.com is a valid email box
  4. 确保postmaster@emailsendingdomain.com是一个有效的电子邮箱
  5. if your server generated email needs to appear to come from somewhere else (like a contact form needing to come from name/email provided in a form) follow these guidelines for email headers.
  6. 如果您的服务器生成的电子邮件需要来自其他地方(例如需要来自表单中提供的姓名/电子邮件的联系表单),请遵循以下电子邮件标题指南。

Here is the email ip address blacklist checker that I used.

这是我使用的电子邮件IP地址黑名单检查器。

Those 5 things will solve perhaps 95% of your email deliverability issues.

这5件事可能会解决95%的电子邮件可传递性问题。

This Guide for Fedora/dkim-milter/postfix is also very good.

这本Fedora / dkim-milter / postfix指南也非常好。

The PHP mail library I use for my app is PHPMailer 5.1 which has DKIM support (and is PHP 5 only), but after doing the research, I decided implementing at the sendmail level was a better solution. As you can see, even the author of PHPMailer 5.1 does not suggest DKIM at the PHP mail library level is the best solution http://dkim.worxware.com/.

我用于我的应用程序的PHP邮件库是PHPMailer 5.1,它支持DKIM(仅限PHP 5),但在进行研究后,我决定在sendmail级别实现更好的解决方案。正如您所看到的,即使PHPMailer 5.1的作者也不建议PHP邮件库级别的DKIM是最佳解决方案http://dkim.worxware.com/。

Best of luck to you.

祝你好运。

#2


13  

This is one that has been on my radar for a while and could not find a definitive answer to the original question in this thread anywhere on the web. I have now been able to implement sending DKIM signed SMTP email with PHP/Pear. Below are the steps required.

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

  1. I found a modified version of the DKIM from http://www.ra726.net/blog/2010/07/20/sending-email-to-gmail-from-php-without-being-marked-as-spam/ (you can download it via http://www.ra726.net/php-dkim.zip). If you have already implemented DKIM and just need to make it work with SMP mail then all you need from this is the dkim.php file which, as the blog says, is slightly modified to handle headers passed as an array. In my code, I have named it dkimNEW.php.

    我从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. Ensure you include most headers so that the MTA does not modify the message after you have signed it. In my limited research, the most added headers are the Date and Message-ID headers, thus my header array looks like this: Note: I used this for sending an html email, change to suit! Also, add your domain as the last part of the Message-ID

    确保包含大多数标头,以便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. You will then get to utilize the modified dkim.php mentioned above to sign your email AND add the signature to the headers array, aka

    然后,您将使用上面提到的修改后的dkim.php来签署您的电子邮件并将签名添加到头部数组,又名

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

The rest of the code is the normal code to send email via SMTP with PHP/Pear. The full working code is:

其余代码是使用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);

?>

PS. Just in case you did not notice, replace values with your own!

PS。如果您没有注意到,请用您自己的值替换值!

Therefore, all that is essentially needed to make DKIM to work with SMTP email (or indeed the PHP mail) is to ensure that you specify all the headers that are added to your email by your MTA, then sign the headers, subject and body of the message, and finally include that signed portion with your header.

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

#3


11  

Have you try : phpMailDomainSigner It support DKIM-Signature and DomainKey-Signature in Object Oriented Style.

您是否尝试过:phpMailDomainSigner它支持面向对象样式的DKIM-Signature和DomainKey-Signature。

Here some example:

这里有一些例子:

// 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


10  

A class solely for DKIM which is a spin-off from PHPMailer, but with improvements regarding the respect of the RFC and nice-and-clean code :

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

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

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

Example :

示例:

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);

#1


21  

I'd recommend DKIM support at the MTA level so all your server generated email for a given domain is signed by default. (unless you have a really good reason to not sign all server generated email for a domain).

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

The best starting point in my googling to get DKIM setup on LAMP with dkim-milter and sendmail (on CentOS 5.2 in my case) was Jeff Atwood's post about sending emails through code.

我在google搜索中使用dkim-milter和sendmail(在我的案例中为CentOS 5.2)上使用LAMP设置DKIM的最佳起点是Jeff Atwood关于通过代码发送电子邮件的帖子。

I would agree with him that the first 2 things you should address are reverse PTR record and DKIM signing.

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

Also very important:

同样非常重要:

  1. IP address of the box to send email not already being blacklisted.
  2. 发送电子邮件的框的IP地址尚未列入黑名单。
  3. make sure postmaster@emailsendingdomain.com is a valid email box
  4. 确保postmaster@emailsendingdomain.com是一个有效的电子邮箱
  5. if your server generated email needs to appear to come from somewhere else (like a contact form needing to come from name/email provided in a form) follow these guidelines for email headers.
  6. 如果您的服务器生成的电子邮件需要来自其他地方(例如需要来自表单中提供的姓名/电子邮件的联系表单),请遵循以下电子邮件标题指南。

Here is the email ip address blacklist checker that I used.

这是我使用的电子邮件IP地址黑名单检查器。

Those 5 things will solve perhaps 95% of your email deliverability issues.

这5件事可能会解决95%的电子邮件可传递性问题。

This Guide for Fedora/dkim-milter/postfix is also very good.

这本Fedora / dkim-milter / postfix指南也非常好。

The PHP mail library I use for my app is PHPMailer 5.1 which has DKIM support (and is PHP 5 only), but after doing the research, I decided implementing at the sendmail level was a better solution. As you can see, even the author of PHPMailer 5.1 does not suggest DKIM at the PHP mail library level is the best solution http://dkim.worxware.com/.

我用于我的应用程序的PHP邮件库是PHPMailer 5.1,它支持DKIM(仅限PHP 5),但在进行研究后,我决定在sendmail级别实现更好的解决方案。正如您所看到的,即使PHPMailer 5.1的作者也不建议PHP邮件库级别的DKIM是最佳解决方案http://dkim.worxware.com/。

Best of luck to you.

祝你好运。

#2


13  

This is one that has been on my radar for a while and could not find a definitive answer to the original question in this thread anywhere on the web. I have now been able to implement sending DKIM signed SMTP email with PHP/Pear. Below are the steps required.

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

  1. I found a modified version of the DKIM from http://www.ra726.net/blog/2010/07/20/sending-email-to-gmail-from-php-without-being-marked-as-spam/ (you can download it via http://www.ra726.net/php-dkim.zip). If you have already implemented DKIM and just need to make it work with SMP mail then all you need from this is the dkim.php file which, as the blog says, is slightly modified to handle headers passed as an array. In my code, I have named it dkimNEW.php.

    我从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. Ensure you include most headers so that the MTA does not modify the message after you have signed it. In my limited research, the most added headers are the Date and Message-ID headers, thus my header array looks like this: Note: I used this for sending an html email, change to suit! Also, add your domain as the last part of the Message-ID

    确保包含大多数标头,以便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. You will then get to utilize the modified dkim.php mentioned above to sign your email AND add the signature to the headers array, aka

    然后,您将使用上面提到的修改后的dkim.php来签署您的电子邮件并将签名添加到头部数组,又名

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

The rest of the code is the normal code to send email via SMTP with PHP/Pear. The full working code is:

其余代码是使用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);

?>

PS. Just in case you did not notice, replace values with your own!

PS。如果您没有注意到,请用您自己的值替换值!

Therefore, all that is essentially needed to make DKIM to work with SMTP email (or indeed the PHP mail) is to ensure that you specify all the headers that are added to your email by your MTA, then sign the headers, subject and body of the message, and finally include that signed portion with your header.

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

#3


11  

Have you try : phpMailDomainSigner It support DKIM-Signature and DomainKey-Signature in Object Oriented Style.

您是否尝试过:phpMailDomainSigner它支持面向对象样式的DKIM-Signature和DomainKey-Signature。

Here some example:

这里有一些例子:

// 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


10  

A class solely for DKIM which is a spin-off from PHPMailer, but with improvements regarding the respect of the RFC and nice-and-clean code :

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

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

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

Example :

示例:

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);