![如何为 DKIM 和 SPF 设置中间带有域的 DNS 设置?](https://linux22.com/image/775734/%E5%A6%82%E4%BD%95%E4%B8%BA%20DKIM%20%E5%92%8C%20SPF%20%E8%AE%BE%E7%BD%AE%E4%B8%AD%E9%97%B4%E5%B8%A6%E6%9C%89%E5%9F%9F%E7%9A%84%20DNS%20%E8%AE%BE%E7%BD%AE%EF%BC%9F.png)
我正在开发一种帮助用户发送电子邮件的工具。我计划在后端使用 MTA(邮件传输代理),如 AWS-SES 或 Sendgrid 等。为了让电子邮件成功到达收件人的收件箱,用户必须通过配置各自域的 DNS 设置来设置 DKIM/SPF。
现在,如果我以 SES 为例,我知道他们有一个 API 允许我添加“身份”并使用 API 为其取回所有必要的 DNS 记录。我相信 Sendgrid 和其他 MTA 都有类似的 API,允许添加身份并返回 DNS 记录供用户应用。
我向用户显示返回的 DKIM DNS 设置,然后他们将其添加到他们的 DNS 提供商,之后当他们发送电子邮件时,收件人就可以正确收到它(标题中没有任何“via amazonses.com”的内容)
现在为了举例子 - 让我们假设我正在构建的工具托管在 chillybilly.xyz 上,并且使用我的工具的用户之一有一个名为 frankthetank.xyz 的域,他们想使用该域通过我的平台发送电子邮件。
当用户尝试通过我的平台验证他的域名时,我将在 AWS SES 中点击上面提到的 API - 并向用户显示如下内容:
之后,他们可以添加这些 CNAMES 和 TXT 记录,以确保 DKIM/SPF 成功,然后开始发送电子邮件。但是,如果仔细观察,他们就会发现我使用的是 SES,这是因为这些 CNAMES 和 TXT 记录的值。而这正是我想要避免的,相反,我希望将它们命名为7nuk24xywyawocu6ctqjxmjasiaiq3vq.dkim.chillybilly.xyz
可以显示我的品牌的名称,但在后台它仍将指向正确的 SES。
现在我意识到,这样的事情是可能的,因为当我注册 ConvertKit 时,他们向我展示了如下内容:
如您所见,其中的两个值指向 converkit.com,但是当我通过 DNS 查找运行它们时:
我可以看到它在后台指向属于 Sendgrid 的 MX 和 TXT 记录。我该如何实现这一点?(我相信同样的原则也适用于 SES 或任何其他 MTA)
编辑:
我尝试了一些方法 - 我在 chillybilly.xyz(我的项目域名)中设置了 CNAME、MX 和 TXT,并从 frankthetank.xyz 指向了两个 CNAME,spf.frankthetank.xyz
并dkim.frankthetankxyz
https://dnschecker.org/all-dns-records-of-domain.php?query=spf.frankthetank.xyz&rtype=ALL&dns=google
如您所见,我能够实现与 ConvertKit 使用 Sendgrid 所实现的结果非常相似的结果。但这种方式无法得到验证。:(
当我检查这些 DNS 查询(上面的链接)时,我看到的唯一区别是 CNAME 也出现在我的查询中,但在 convertkit 的情况下却没有。所以我认为我接近解决方案了,但不确定我遗漏了什么,有什么想法吗?:)
答案1
第一个 SPF:如果您用自己的品牌替换 sendgrid 的传出 SPF 记录(包含在您的 SPF 记录中),则您同时承担了跟踪 sendgrid 可能对其传出邮件服务器的名称和地址进行的所有动态操作的工作。您不想这样做,因此如果您通过 sendgrid 发送,则需要包含 sendgrid 的 SPF。因此,既然您使用 sendgrid,您就无法摆脱 SPF 记录中的“include: sendgrid.net”,而不会给自己带来麻烦。
DKIM 类似,amazonses 示例是为 Amazon DNS 中存在的记录创建 CNAME。如果您想用自己的记录替换它(您可以,没问题),您必须将这些记录放入您自己的 DNS 中。这没有问题,但是,您必须以某种方式将签名密钥传输给签署这些电子邮件的人,这可能是一个问题。使用 Amazon 解决方案,他们会创建密钥并为您提供他们放入 DNS 中的公钥链接,该公钥与他们用来签署您的电子邮件的私钥相匹配。
但是,如果您想从 Amazon 或 sendgrid 的邮件服务器中删除“品牌”,唯一的方法就是将其收购,因为这是通过反向 DNS 完成的,并且他们永远不会将其传出服务器指向您的 DNS 命名空间中的名称。
答案2
因此,您可以只执行指向原始源记录的 CNAME 记录,或者只将正确的 SPF 放在您的域下(如 convertkit 示例所示)。
或者使用中间件在 sendgrid/AWS 中执行域验证过程,在您的域上创建 DNS 记录,然后告诉客户将其 CNAME 到您创建的新 DNS 记录,然后在客户单击按钮表示他们已完成此操作后完成验证
这不会阻止电子邮件标头或跟踪 DNS 记录来查找原始提供商,但对于普通人来说,这是可能美好的。
然而我想提醒一下——层层的混淆实际上会损害 DNS 层。
例如,SPF 在 RFC 中有一个明确的硬编码 10 次查找限制 - Sendgrid 自己对此进行了说明 -https://docs.sendgrid.com/ui/account-and-settings/spf-limitations
- 原始 RFC。如果你对 SPF 进行任何类型的混淆,则很有可能遇到此问题
额外的 DNS 查找将增加邮件传递流程和/或应用程序中任何基于 DNS 的查找的响应时间 - 这可能会导致非常痛苦在很多层面上,尤其当 MTA 实时处理时,任何延迟都有可能产生巨大的连锁影响。
进行一些数学计算,假设一封电子邮件需要 20 毫秒才能通过带有 DNS 的 MTA 进行处理和发送 - 这是假设的最佳情况这种逻辑确实如此。您每小时可以发送大约 18 万封电子邮件。如果我们需要通过添加至少 1 次额外的 DNS 查找来将其翻倍,那么每小时的电子邮件数量将减半为 9 万封。如果您依赖于数量,那么您现在需要投入两倍的硬件来保持相同的吞吐量。
答案3
SG 有一个选项,automatic_security
称为验证域名API。我认为此选项在后端的作用是让 SG 使用其 DNS 记录管理/轮换 DKIM 密钥和其他记录。因此,当您将此选项设为 True 时,它们将返回 CNAME 记录而不是 MX 和 TXT 记录。并且 MX/TXT 记录由 SG 在后台管理。
CNAME 记录的便利之处在于其他 CNAME 记录可以轻松指向它们。所以我指出了chillybilly.xyz -> SG CNAME records
我从 SG 返回的内容,然后我frankthetank.xyz records -> chillybilly.xyz CNAME records
又指向了它们,从而在两者之间创建了一种中间件。
请注意,这chillybilly.xyz
是我的应用程序的域,也是frankthetank.xyz
客户端的域。这是我们在解决这个问题时所依据的假设。
当然,答案之一指出这会增加 DNS 查找,因为中间还有另一层,我们仍然需要评估这样做是否真的对我们有意义,或者在最终扩大规模时是否会增加电子邮件传递时间。但解决方案确实有效。我认为这是一个仅限 SG 的实现。我无法让它与 AWS SES 一起工作。我很快就会打电话给他们——如果我知道更好的办法,我会编辑这个答案 :)