academe/laraveldkim

语言: PHP

git: https://github.com/academe/laraveldkim

使用DKIM签名在Laravel中签署所有外发电子邮件
Sign all outgoing emails in Laravel with a DKIM signature
README.md (中文)

Larveldkim

使用DKIM签名在Laravel 4中签署所有外发电子邮件。

这个包在Laravel 5上不起作用,确实如此 不太可能我会找到timne或者需要把它带到Laravel 5.如果你有任何修复, 我很乐意接受拉动请求。 Laravel 5仍然使用SwiftMailer进行邮件传输,所以它应该 有可能解决它。

但是,如果您能够通过另一台为您添加DKIM的服务器发送邮件,那么就是这样 到目前为止是最简单的解决方案。

ALL

  • 测试

你为什么要用这个?

大多数应用程序需要发送邮件。尽可能地看起来像SPAM一样,有很多 应该应用于发送邮件的技术。一个被称为 DomainKeys Identified Mail(DKIM)。

DKIM使用公钥/私钥对。公钥存储在域发送的TEXT记录中 电子邮件,所以所有收件人(邮件服务器)都可以看到。私钥是保密的,习惯了 签署传出消息。签名是消息内容和一些标头的散列,并将散列添加到 标题的顶部。只有拥有私钥的人才能以可以通过其验证的方式对其进行签名 公钥。谷歌,雅虎,Hotmail都做了这个检查。任何对途中消息的篡改也会中断 签名等可以在目的地被拒绝。

现在,许多应用程序将通过操作系统或邮件发送服务为他们处理DKIM (例如Sendgrid,或其ISP的SMTP服务器,或使用控制面板设置)。在某些情况下,这不是 一个选项,因此创建了此包以在应用程序级别进行签名。

Laravel使用Swift Mailer处理其传出的电子邮件,Swift Mailer内置了它 支持DKIM签名。每次实例化Swift消息时,此包都会注入签名组件。

关于Coding Horror的DKIM有很好的描述

限制

编写此包是为了满足特定需求,因此可能没有您想要的灵活性。请随意 如果您有任何改进,请提交拉取请求。

该软件包假设您使用的是内置的Laravel电子邮件提供程序。如果你正在使用 其他电子邮件包,如laravel-mailgun然后我 不知道这会起作用(我不知道其他邮件包是否位于Laravel的邮件提供商之上 或替换它)。尝试一下,让我知道它是怎么回事。

它还假设所有电子邮件都来自单个域。我确实尝试过多次使用Swift Mailer 针对多个域的证书,看它是否会选择与发送地址匹配的域, 但它只是毫无疑问地添加了所有证书。也许有更新SwiftMailer的余地 它不会选择和使用签名组件,直到它的处理更晚,当它有更多时 它发送的内容和对象的详细信息,因此可以更好地决定使用时的设置 签约。例如,在知道发送域之前,它确实不知道哪个是潜在的 用于签名的证书列表。 所以,现在只需要一个域名和证书,我们将看到它是如何在野外发生的。

所有电子邮件都将使用相同的证书进行签名。

版本1.0.4为SwiftMailer DKIM签名者中的问题引入了一种解决方法。一些邮箱标题 永远不应该包含在签名中。 SwiftMailer不会自动排除这些标题, 所以他们现在在这个包中明确地“忽略”了。你可以检查一下是否存在 这里修复了SwiftMailer:https://github.com/swiftmailer/swiftmailer/issues/442

如何使用

步骤是:

  • 在您的应用程序中包含该包。
  • 添加您的私钥设置。
  • 使用新的邮件程序。

在您的应用程序中包含该包

向项目的composer.json添加一个需求

"require": {
    "academe/laraveldkim": "1.*"
},

添加您的私钥设置

您的签名密钥详细信息需要添加到laravel应用程序配置中。将以下内容添加到您的 mail.php配置文件:

'dkim' => array(
    'private_key' => <<<ENDDKIMKEY
-----BEGIN RSA PRIVATE KEY-----
...your key goes in here...
-----END RSA PRIVATE KEY-----
ENDDKIMKEY
    ,
    'domain_name' => 'example.com',
    'selector' => 'dkim',
),

请注意,ENDDKIMKEY的两个实例之间的所有内容都必须一直到行的开头。 您可以将RSA密钥更轻松地放入点文件(例如.mail.prod.php)中以获得更高的安全性。 请参阅Laravel:保护敏感配置 有关点文件支持的更多详细信息。 另一种方法可能是从配置文件中的文本文件中读取密钥并返回该密钥。 “mail.dkim.private_key”必须是包含完整私钥的字符串,每行一行 以换行符终止。如果存储为PHP字符串,则可以更安全地连接每个字符串 具有显式嵌入换行符的双引号键的行,如下所示: “-----开始RSA私钥----- \ n”。 “第1行\ n”。 “第2行\ n”等。假设行尾 源文件中的终结符是\ n永远不是一个好主意,尽管PSR-2确实明确了(第2.2节),行必须以\ n结尾。

domain_name是将发送电子邮件的域。选择器是您选择的选择器 将您的公钥存储在DNS中。上例中的公钥将存储在 dkim._domainkey.example.com的TEXT条目

使用新的邮件程序

现在我们需要告诉Laravel使用自定义邮件程序而不是标准的内置邮件程序。这个做完了 在app.php配置文件中。请注意,“新邮件程序”只是默认Laravel的包装器 邮件程序,并不是一个完整的功能替代品,因此您不必修改邮件程序的使用 在你的申请中。

providers数组将具有以下条目:

'Illuminate\Mail\MailServiceProvider',

注释掉并用此条目替换它:

'Academe\LaravelDkim\MailServiceProvider',

而已。您的电子邮件现在应该使用DKIM签名。您可以检查电子邮件来源中的标题 您的应用程序发出,您应该在那里看到DKIM签名。它看起来像这样:

DKIM-Signature: v=1; a=rsa-sha1; bh=Gwuoen3CG+KClMvlMKjUh1ZJmzg=;
d=example.com; h=Message-ID: Date: From: MIME-Version: Content-Type;
i=@example.com; s=dkim; t=1391259163;
b=cIkL/FZ6/v/XUdcYvhvmSo9abedf0DLlM/LYkOX4GoW4EUzPxN10hOHQpWlqjeDa2YdsI7GH
dGCc16Xgb2kpZbPEom0RMv62G4SYf8763abb7380ebMRP2tv0/Mq+CaOmQejk34vlBnzcj0JE
6PGOPxEEe9dgdoOMx4uEhhlkd=

本文使用googletrans自动翻译,仅供参考, 原文来自github.com

en_README.md

laraveldkim

Sign all outgoing emails in Laravel 4 with a DKIM signature.

This package does not work on Laravel 5, and it is
unlikely I will find the timne or have the need to take it forward to Laravel 5. If you have any fixes though,
I will be happy to accept pull-requests. Laravel 5 still uses SwiftMailer for its mail transport, so it should
be possible to fix it.

However, if you are able to sent mail through another server that adds DKIM for you, then that is going to
be the simplest solution by far.

TODO

  • tests

Why would you use this?

Most applications need to send out mail. To look as little like SPAM as possible, there are a number of
techniques that should be applied to sent mail. One is called
DomainKeys Identified Mail (DKIM).

DKIM works using a public/private key pair. The public key is stored in a TEXT record of the domain sending
the email, so all recipients (mail servers) can see that. The private key is kept secret and used to
sign the outgoing message. The signature is a hash of the message content and some headers, and adds the hash to the
top of the headers. Only someone with the private key can sign it in a way that can be validated by the
public key. Google, Yahoo, Hotmail all do this check. Any tampering of the message en-route will also break
the signature and so can be rejected at the destination.

Now, many applications will have DKIM handled for them by the operating system or the mail sending service
(e.g. Sendgrid, or their ISP's SMTP server, or set up using Control Panel). In some instances this is not
an option, and so this package was created to do the signing at the application level.

Laravel uses Swift Mailer to handle its outgoing email, and Swift Mailer has built-in
support for DKIM signing. This package injects the signing component each time a Swift message is instantiated.

There is a great description of DKIM on Coding Horror

Limitations

This package was written to fill a specific need, so may not be as flexible as you want. Do feel free to
submit pull requests if you have any improvements.

The package makes the assumption that you are using the built-in Laravel email provider. If you are using
other email packages such as laravel-mailgun then I
don't know it this will work (I don't know if other mail packages sit on top of Laravel's mail provider
or replace it). Try it and let me know how it goes.

It also assumes that all emails will be coming from a single domain. I did try giving Swift Mailer multiple
certificates against multiple domains to see if it would choose the one that matched the sending address,
but it just added all the certificates without question. Maybe there is scope to update SwiftMailer so that
it does not choose and use the signing components until much later in its processing, when it has more
details of what it is sending and to whom, so it can make better decisions on the settings to use when
signing. For example, until it knows the sending domain, it really does not know which of a potential
list of certificates to use for the signing.
So, just the one domain and certificate for now, and we will see how that goes out in the wild.

All emails will be signed with the same certificate.

Version 1.0.4 introduces a workaround for an issue in the SwiftMailer DKIM signer. Some email headers
should never be included in the signature. SwiftMailer does not exclude those headers automatically,
so they are now set to "ignore" explicitely in this package. You can check whether this has been
fixed in SwiftMailer here: https://github.com/swiftmailer/swiftmailer/issues/442

How to Use

Steps are:

  • Include the package in your application.
  • Add your private key settings.
  • Use the new mailer.

Include the package in your application

Add a requirement to your project's composer.json

"require": {
    "academe/laraveldkim": "1.*"
},

Add your private key settings

Your signing key details need to be added to the laravel application config. Add the following to your
mail.php config file:

'dkim' => array(
    'private_key' => <<<ENDDKIMKEY
-----BEGIN RSA PRIVATE KEY-----
...your key goes in here...
-----END RSA PRIVATE KEY-----
ENDDKIMKEY
    ,
    'domain_name' => 'example.com',
    'selector' => 'dkim',
),

Note that everything between the two instances of ENDDKIMKEY must be right up to the start of the line.
You may be able to put the RSA key more easily into a dot-file (e.g. .mail.prod.php) for more security.
See Laravel: Protecting Sensitive Configuration
for more details on dot file support.
Another approach may be to read the key from a text file in the config file and return that.
The "mail.dkim.private_key" needs to be a string containing the full private key, with each line
terminated with a newline character. It may be safer, if stored as a PHP string, to concatenate each
line of the key in double-quotes with explicit embedded newlines, like this:
"-----BEGIN RSA PRIVATE KEY-----\n" . "line 1\n" . "line 2\n" etc.. Assuming the end-of-line
terminators in a source file are \n never was a great idea, though PSR-2 does make it clear (section 2.2) that lines MUST be terminated with a \n.

The domain_name is the domain that email will be sent from. The selector is the selector you chose to
store your public key against in your DNS. The public key in the above example will be stored in the
TEXT entry of dkim._domainkey.example.com

Use the new mailer

Now we need to tell Laravel to use the custom mailer rather than the standard built-in mailer. This is done
in the app.php config file. Please note that the "new mailer" is just a wrapper for the default Laravel
mailer, and is not a complete functional replacement, so you won't have to modify the use of the mailer
in your application.

The providers array will have this entry:

'Illuminate\Mail\MailServiceProvider',

Comment that out and replace it with this entry:

'Academe\LaravelDkim\MailServiceProvider',

That's it. Your emails should now be signed with DKIM. You can check the headers in the source of emails that
your application sends out and you should see the DKIM signature in there. It will look something like this:

DKIM-Signature: v=1; a=rsa-sha1; bh=Gwuoen3CG+KClMvlMKjUh1ZJmzg=;
d=example.com; h=Message-ID: Date: From: MIME-Version: Content-Type;
i=@example.com; s=dkim; t=1391259163;
b=cIkL/FZ6/v/XUdcYvhvmSo9abedf0DLlM/LYkOX4GoW4EUzPxN10hOHQpWlqjeDa2YdsI7GH
dGCc16Xgb2kpZbPEom0RMv62G4SYf8763abb7380ebMRP2tv0/Mq+CaOmQejk34vlBnzcj0JE
6PGOPxEEe9dgdoOMx4uEhhlkd=