我有一个域,可以发送两种不同类型的电子邮件:一种是通过自动化流程创建的,例如发送给用户的通知,另一种是从请求跟踪器(票务系统)生成的。
我们之前设置了 DKIM,但我犯了一个错误,从未验证这两种电子邮件是否正常工作,所以我从未检查过 RT 电子邮件。最近我们意识到 RT 生成的邮件偶尔会进入垃圾邮件过滤器,感觉 DKIM 检查失败可能与此有关。
RT 给每条消息添加一些标题,例如:
X-RT-Loop-Prevention: Support
RT-Ticket: Support #3165
Managed-by: RT 3.8.2 (http://www.bestpractical.com/rt/)
RT-Originator: [email protected]
X-RT-Original-Encoding: utf-8
但是,这些标头不会出现在 DKIM 签名中。例如,这是今天早上来自 Gmail 的硬故障字符串:
Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of [email protected] designates xxx.xxx.xxx.xxx as permitted sender) [email protected]; dkim=hardfail [email protected]
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xxx.com; s=mta;
h=Date:Content-Type:Content-Transfer-Encoding:MIME-Version:To:Message-ID:References:In-Reply-To:Reply-To:From:Subject; bh=GDIpYEyFTXB3RPUtFDKxW+iBpkOYngdUELnMw316Ohk=;
b=A6iZYrFUZ68gszu/KeTyMoUUE0jbGlZ+yxcz72gq7Bdxe+jAkcgFoExN+duxLPIZqJm87Gz+XCB9IwnQbKC5lsVKK8cwUzQTHZx6E8ZPyynkv0NvC8MStDgOswFnjdcy;
如您所见,RT 标头未包含在 DKIM 签名中。当从 RT 之外的网站发送邮件时,Gmail 会正确验证签名。
我的理解是“自定义”标头(X-xxxxxxxx)被 DKIM 忽略,但其他标头不会被忽略,例如上面的 RT-Ticket、Managed-by 和 RT-Originator。
有没有人有这方面的详细经验,或者知道我可以在哪里找到 DKIM 来将这些标头包含在签名中?我搜索了一下 RT 支持,但找不到太多信息。我使用 exim 作为 MTA,系统是 Debian Lenny。
编辑:我可能在这里用标头字段搞错了方向,我不确定。我修改了 exim 配置,通过从 RFC4871 中获取标头列表来明确告诉它要查看哪些标头(https://www.rfc-editor.org/rfc/rfc4871)并添加 RT 正在添加的额外标头,如下所示:
dkim_sign_headers = From:Sender:Reply-To:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:Precedence:X-RT-Loop-Prevention:RT-Ticket:Managed-by:RT-Originator:X-RT-Original-Encoding
这样,所有 RT 标头都正确添加到签名中,但是,当签名通过 RT 发送时,Gmail 仍然报告签名出现硬故障。据我所知,RT 使用 exim 的方式与任何其他外部程序相同,因此我无法解释为什么这些消息会失败。
答案1
准备在这里发布一个半答案,以防有人遇到类似的问题并通过搜索找到它。
在 exim 中使用宽松的标头规范化进行 DKIM 签名时,我无法解决这个问题。我以我的 RT 生成的邮件为例,这些邮件的签名在 Gmail 和 Yahoo 邮箱中均失败,然后按如下方式测试它们:
我使用 PHP 实现了文档中指定的 DKIM 签名算法(http://www.dkim.org/specs/rfc4871-dkimbase.html)。当我使用 Relaxed/Relaxed 运行我的消息时,我生成了相同的正文哈希值,但消息签名与我的 Exim 生成的不同。
我使用 PHP 实现了 DKIM 验证算法,然后获取 Gmail 和 Yahoo Mail 收到的邮件源并运行该算法,得到了相同的结果。我还运行了以下邮件:不是是由我的请求跟踪器生成的,但经过了我的 exim,并且它们在我的验证测试中正确通过,就像在 Gmail 和 Yahoo Mail 上一样(这样做的目的是证明我的密钥和其他配置在 RT 上下文之外正常工作,它们似乎是这样)。
此时,我发现我的 exim 在轻松/轻松模式下处理 DKIM 签名的方式存在错误或配置错误。我下载了 exim 使用的 PDKIM 库的源代码([https://github.com/duncanthrax/pdkim]),编译它,然后修改测试示例以匹配我的密钥、设置和测试消息。运行测试后,我得到了与我的 PHP 实现相同的结果:相同的哈希值,相同的签名。
这让我只剩下最后一个选择,那就是干扰 exim 的来源,试图确定是哪种特定情况导致消息签名发生变化。但是,我已经达到了我愿意花在这上面的时间上限。
简单的解决方案是将我的 exim 配置改回简单规范化,这样 Gmail 和 Yahoo Mail 都可以通过 dkim 验证,验证由我的请求跟踪器生成的消息。这不是我想要的,但目前已经足够好了。
答案2
我遇到了类似的问题,我认为这是因为 RT 包含“回复”标头但没有添加值。这种情况只发生在通过 Web UI 打开工单时,而不是收到电子邮件时。
我插入了
dkim_sign_headers = from:sender:reply-to:subject:date:message-id:to:cc:mime-version:content-type:content-transfer:encoding:x-rt-ticket:x-rt-loop-prevention:x-rt-originator
这似乎已经解决了问题。我可能会尝试一下要签名的标头,但会忽略“回复”标头。
Exim 仍以轻松模式签署。