为 Ubuntu、Postfix 和 Mailman 设置 DKIM(域密钥)

Mou*_*inX 23 postfix dkim

我正在使用 Postfix 和 Mailman 运行 Ubuntu 12.04。我想设置DKIM。DomainKeys Identified Mail,或 DKIM,是雅虎“DomainKeys”的继承者。它包含 Cisco 的 Identified Mail。

设置这个的步骤是什么?

推荐使用opendkim吗?

我唯一的参考是HowToForge,但我更喜欢在这里获得帮助(即使它只是对该链接中步骤的确认)。实际上,我认为 HowToForge 上的信息已经过时,因为它提到了 dkim-filter 而不是 opendkim。

Mou*_*inX 40

Ubuntu Server 12.04LTS 上的 openDKIM 和 Postfix

我会尝试回来并更好地格式化。但是由于有人要求发布我的答案,我想现在发布它而不是等到我有时间正确格式化它。由于时间不够,我把我的整个答案放在了一个块引用中。我希望这个解决方案有帮助。

这些是我的参考:

维基百科对这个问题的很好的入门

您至少需要:

  • 根访问您的邮件服务器
  • 有权更新您的域的 dns 记录

从存储库安装 opendkim:

# sudo apt-get install opendkim opendkim-tools
Run Code Online (Sandbox Code Playgroud)

您必须决定要使用的“选择器”。选择器本质上是一个描述您希望使用的键的词。在这里,我将使用选择器 201205,因为密钥在 2012 年 5 月生效(狡猾,嗯?)。我举了两个例子来说明多样性,希望能增加清晰度。您只需要生成一个密钥。但是,我提供了两个示例,以便您可以比较它们。

  • 201205(第一个键)
  • my_selector(第二个键)

我的域将是example.com,但我将在第二个示例中使用子域:

  • example.com(第一个键)
  • mail.example.com(第二个键)

我决定在以下目录中工作:

# mkdir /etc/opendkim/
# cd /etc/opendkim
Run Code Online (Sandbox Code Playgroud)

使用您选择的选择器和域在当前目录中生成密钥。

# opendkim-genkey -s 201205 -d example.com
Run Code Online (Sandbox Code Playgroud)

您可能需要也可能不需要更改所有权。有关所有权和权限应该是什么,请参阅我的示例中的详细信息,了解下面的第二个键。

首先您应该检查是否有opendkim用户(您的用户/组 ID 可能不同):

# grep opendkim /etc/passwd
opendkim:x:108:117::/var/run/opendkim:/bin/false
Run Code Online (Sandbox Code Playgroud)

你可能需要这样做:

# chmod 700 /var/run/opendkim
Run Code Online (Sandbox Code Playgroud)

注意:在 Ubuntu 12.04 上不需要接下来的两个命令。但是,如果上面的命令没有显示用户 opendkim 设置正确,请执行类似于以下操作:

# useradd -r -g opendkim -G mail -s /sbin/nologin -d /var/run/opendkim -c "OpenDKIM" opendkim
# chown opendkim:opendkim 201205.private   
# cat 201205.private 
-----BEGIN RSA PRIVATE KEY-----
ABCCXQ...[long string]...SdQaZw9
-----END RSA PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)

现在检查公钥并注意有一个错误(在 Ubuntu 12.04 上的 openDKIM 2.5.2 中)!哪里包含,,;=rsa;它应该包含;k=rsa;。的k缺失。请插入。

# cat 201205.txt
201205._domainkey IN TXT "v=DKIM1;=rsa; p=WIGfM..[snip]..QIDIAB" ; ----- DKIM 201205 for example.com
Run Code Online (Sandbox Code Playgroud)

修好后会是这个样子:

201205._domainkey IN TXT "v=DKIM1;k=rsa; p=WIGfM..[snip]..QIDIAB" ; ----- DKIM 201205 for example.com
Run Code Online (Sandbox Code Playgroud)

此外,您可能需要像这样转义分号。如果您不想要结尾评论,只需将其删除即可。另请注意,您应该添加 t=y 标志以向接收服务器表明您正在测试 DKIM 但尚未积极使用它。你留下了一个可行的资源记录:

201205._domainkey IN TXT "v=DKIM1\;k=rsa\;t=y\;p=WIGfM..[snip]..QIDIAB"
Run Code Online (Sandbox Code Playgroud)

您必须将上述公钥的内容发布到您的权威 DNS 服务器。我建议使用 TXT 记录。关于是使用 SPF 记录还是同时使用这两种类型似乎存在一些争议。在阅读了一些之后,我选择只使用 TXT 记录类型,尽管我不相信这是关于这个主题的最后一句话。

您应该使用较短的 TTL(生存时间),以便您可以更改密钥而无需等待它通过 DNS 传播的时间。我用了180秒。

生成密钥对的第二个例子对我来说有点棘手。我将描述我所做的。第一个元素是我使用了域值“example.com”,即使该键将用于“mail.example.com”。我通过反复试验得出了这个结论。它有效,而使用“mail.example.com”无效。不幸的是,我不知道这背后的原因。这确实是我遇到的唯一区别,但它足够令人不安,我觉得我应该记录我使用子域的经验。我发现的其他入门级教程都没有做到这一点。生成第二个密钥:

opendkim-genkey -s my_selector -d example.com
Run Code Online (Sandbox Code Playgroud)

检查私钥的所有权和权限,如上所述。它们应该如下所示:

# ls -la /etc/opendkim
-rw-------  1 opendkim opendkim  891 May 10 07:44 my_selector.private
Run Code Online (Sandbox Code Playgroud)

发布 DNS 记录后,使用dig. 它应该准确返回您在资源记录 (RR) 中输入的内容。

$ dig 201205._domainkey.example.com txt +short
"v=DKIM1\;k=rsa\;t=y\;p=WIGfM..[snip]..QIDIAB"
Run Code Online (Sandbox Code Playgroud)

现在,测试密钥。下面的命令假设您位于密钥所在的目录中(对我来说是 /etc/opendkim)。

# opendkim-testkey -d example.com -s 201205 -k 201205.private -vvv
opendkim-testkey: key loaded from /etc/opendkim/201205.private
opendkim-testkey: checking key '201205._domainkey.example.com'
opendkim-testkey: key not secure
opendkim-testkey: key OK
Run Code Online (Sandbox Code Playgroud)

这些结果在意料之中。“密钥不安全”并不表示错误。这是不使用 DNSSSEC 的预期结果。根据我的阅读,DNSSEC 即将到来,但它还没有准备好迎接黄金时段。

使用第二个键的示例:

# opendkim-testkey -d example.com -s my_selector -k /etc/opendkim/my_selector.private -vvvv
opendkim-testkey: key loaded from /etc/opendkim/my_selector.private
opendkim-testkey: checking key 'my_selector._domainkey.example.com'
opendkim-testkey: key not secure
opendkim-testkey: key OK
Run Code Online (Sandbox Code Playgroud)

请注意,opendkim 报告密钥不安全。这与 DNSSEC 未在我的 DNS 服务器上实现的事实有关,理论上有人可以拦截 DNS 查找并将其替换为他们自己的密钥。

编辑 OpenDKIM 配置文件:

# nano /etc/opendkim.conf
# cat /etc/opendkim.conf
# This is a basic configuration that can easily be adapted to suit a standard
# installation. For more advanced options, see opendkim.conf(5) and/or
# /usr/share/doc/opendkim/examples/opendkim.conf.sample.
#
Domain                  example.com
KeyFile                 /etc/opendkim/201205.private
Selector                201205
#
# Commonly-used options
Canonicalization        relaxed/simple
Mode                    sv
SubDomains              yes
# Log to syslog
Syslog                  yes
LogWhy                  yes
# Required to use local socket with MTAs that access the socket as a non-
# privileged user (e.g. Postfix)
UMask                   022
UserID                  opendkim:opendkim
#
KeyTable                /etc/opendkim/KeyTable
SigningTable            /etc/opendkim/SigningTable
ExternalIgnoreList      /etc/opendkim/TrustedHosts
InternalHosts           /etc/opendkim/TrustedHosts
#
Socket                  inet:8891@localhost
#EOF
Run Code Online (Sandbox Code Playgroud)

如果您使用我的第二个关键示例,目标域为“mail.example.com”,该条目仍将仅引用主域:

Domain                  example.com
KeyFile                 /etc/dkim/my_selector.private
Selector                my_selector 
-----
Run Code Online (Sandbox Code Playgroud)

来自我的一个来源的注释:如果您运行多个 Postfix 实例,则需要将其添加到每个实例(或您想使用 opendkim 的实例)的 opendkim.conf 中

使用文本编辑器创建一个文件/etc/opendkim/TrustedHosts

添加应该由 OpenDKIM 处理的域、主机名和/或 IP。不要忘记本地主机。

127.0.0.1
localhost
example.com
mail.example.com
192.168.1.100 #(IP address of your server, if applicable)
Run Code Online (Sandbox Code Playgroud)

(上面的最后一行可能不需要。如果您确实有要添加的 IP 地址,请确保使用您自己的 IP 地址,而不是上面的示例。)

编辑/etc/default/opendkim

取消注释这一行并使用端口 8891:

SOCKET="inet:8891@localhost" # listen on loopback on port
Run Code Online (Sandbox Code Playgroud)

确保您的防火墙(iptables)允许本地主机上的环回:

sudo iptables -A INPUT -i lo -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

接下来,使用文本编辑器创建一个文件/etc/opendkim/KeyTable并将域添加到 KeyTable

添加行:

#EXAMPLE showing my 2nd key:
my_selector._domainkey.example.com example.com:my_selector:/etc/opendkim/my_selector.private
Run Code Online (Sandbox Code Playgroud)

Next 使用文本编辑器创建一个文件 /etc/opendkim/SigningTable并将域添加到 SigningTable

我展示了这两个例子。请注意,对于我的第二个密钥,我现在必须使用完整的域名“mail.example.com”:

example.com 201205._domainkey.example.com
mail.example.com my_selector._domainkey.example.com
Run Code Online (Sandbox Code Playgroud)

请注意,在 OpenDKIM 2.0.1 中,域名区分大小写。在本例中,我们使用的是较新版本的 OpenDKIM,这似乎不是问题。

配置后缀。编辑 /etc/postfix/main.cf 并将这些行添加到末尾

milter_default_action = accept
milter_protocol = 2
smtpd_milters=inet:localhost:8891
non_smtpd_milters=inet:localhost:8891
Run Code Online (Sandbox Code Playgroud)

还要更改主机名:

#myhostname = localhost         #original
myhostname = mail.example.com
Run Code Online (Sandbox Code Playgroud)

您还应该更改 /etc/hosts 中的相应条目。这些更改在重新启动后生效(尽管您可以使用以下命令立即设置:hostname NEW_NAME)。

如果您没有重新启动,请重新启动 postfix 和 opendkim:

# service opendkim restart
Restarting OpenDKIM: opendkim.
# service postfix restart
 * Stopping Postfix Mail Transport Agent postfix   [ OK ]
 * Starting Postfix Mail Transport Agent postfix   [ OK ] 
Run Code Online (Sandbox Code Playgroud)

测试

检查您的签名邮件是否经过身份验证以及您的 DNS 记录是否正确设置的最佳方法是使用其中一项免费测试服务。我用过这些:

  • Brandon Checketts 电子邮件验证器 - http://www.brandonchecketts.com/emailtest.php(我的最爱)
  • 将签名的电子邮件发送至:check-auth@verifier.port25.com(也是我最喜欢的)
  • 将签名的电子邮件发送至:sa-test@sendmail.net(您可以将所有测试电子邮件地址放在要测试的单个外发邮件的收件人:字段中)

  • 发送签名电子邮件至:autorespond+dkim@dk.elandsys.com <--- BROKEN!!! 不要用这个。

这些中的每一个都会告诉您事情是否正常工作,并在需要时为您提供一些有关故障排除的指示。

如果您有 Gmail 帐户,还可以在那里发送签名邮件,以便快速轻松地进行测试。

一旦您对一切顺利感到满意,您就可以删除 DNS TXT 记录中的测试标志并增加 TTL。

完毕!