介绍
对于大多数邮件服务器管理员来说,被错误地标记为垃圾邮件发送者的沮丧并不陌生。除了排除服务器被入侵的可能性外,虚假标记通常是由以下原因之一引起的:
- 服务器是一个开放的邮件中继
- 发件人或服务器的 IP 地址被列入黑名单
- 服务器没有完全合格的域名(FQDN)和 PTR 记录
- 缺少 Sender Policy Framework(SPF)DNS 记录或配置错误
- 缺少 DomainKeys Identified Mail(DKIM)实现或未正确设置
这些是大多数专有和开源垃圾邮件过滤器(包括 SpamAssassin)检查的一些基本属性。通过这些测试对于配置良好的邮件服务器来说非常重要。
本教程将重点介绍安装和配置 OpenDKIM:DKIM 发件人身份验证系统的开源实现。
假定读者知道如何通过 SSH 访问服务器,已经安装和配置了 Postfix 和 Dovecot(教程),主机名和 FQDN 已设置(教程,教程),并且 SPF 记录已经就位(教程)。
关于 DKIM
DKIM 是一种互联网标准,它使个人或组织能够将域名与电子邮件消息关联起来。实际上,这相当于一种声明对消息负责的方法。在其核心,DKIM 由非对称加密驱动。发件人的邮件传输代理(MTA)使用私钥对每个发出的消息进行签名。收件人从发件人的 DNS 记录中检索公钥,并验证自消息签名以来消息正文和一些标头字段是否未被更改。
安装 OpenDKIM
在开始安装之前,建议进行系统更新:
sudo apt-get update sudo apt-get dist-upgrade
安装 OpenDKIM 及其依赖项:
sudo apt-get install opendkim opendkim-tools
附加软件包将列在依赖项中,输入 yes
并按 Enter
继续。
配置 OpenDKIM
为了配置 OpenDKIM,必须创建并编辑一些文件。
Nano 将被用作编辑器,因为它默认安装在 DigitalOcean droplets 上,并且操作简单:
- 使用箭头键进行导航
- 不保存更改退出:按
CTRL + X
,然后按N
- 保存更改并退出:按
CTRL + X
,然后按Y
,最后按Enter
重要提示:在所有命令和配置文件中,将每个示例中的 example.com 替换为您自己的域名。编辑后不要忘记保存文件。
让我们从主配置文件开始:
sudo nano /etc/opendkim.conf
将以下行追加到 conf 文件的末尾(下面解释了每个参数)。可选择自定义端口号作为 Socket
。确保它没有被其他应用程序使用。
AutoRestart Yes AutoRestartRate 10/1h UMask 002 Syslog yes SyslogSuccess Yes LogWhy Yes Canonicalization relaxed/simple ExternalIgnoreList refile:/etc/opendkim/TrustedHosts InternalHosts refile:/etc/opendkim/TrustedHosts KeyTable refile:/etc/opendkim/KeyTable SigningTable refile:/etc/opendkim/SigningTable Mode sv PidFile /var/run/opendkim/opendkim.pid SignatureAlgorithm rsa-sha256 UserID opendkim:opendkim Socket inet:12301@localhost
- AutoRestart:在失败时自动重新启动过滤器
- AutoRestartRate:指定过滤器的最大重新启动速率,如果重新启动速度超过此速率,过滤器将终止;
10/1h
- 最多允许每小时重新启动 10 次 - UMask:为
UserID
定义的用户组赋予所有访问权限,并允许其他用户读取和执行文件,这将允许创建和修改 Pid 文件 - Syslog、SyslogSuccess、LogWhy:这些参数通过调用 syslog 启用详细日志记录
- Canonicalization:定义消息签名时使用的规范化方法,
simple
方法几乎不允许修改,而relaxed
方法容忍轻微更改,如空格替换;relaxed/simple
- 消息标头将使用relaxed
算法处理,正文将使用simple
算法处理 - ExternalIgnoreList:指定可以作为签名域之一发送邮件的外部主机,无需凭据
- InternalHosts:定义不应验证但应签名的内部主机列表
- KeyTable:将密钥名称映射到签名密钥
- SigningTable:根据
From:
标头字段中找到的地址列出要应用于消息的签名 - Mode:声明操作模式;在本例中,milter 作为签名者(
s
)和验证者(v
) - PidFile:包含进程标识号的 Pid 文件路径
- SignatureAlgorithm:创建签名时选择要使用的签名算法
- UserID:opendkim 进程以此用户和组运行
- Socket:milter 将在此处指定的套接字上监听,Postfix 将通过此套接字向 opendkim 发送消息进行签名和验证;
12301@localhost
定义了在localhost
上监听的 TCP 套接字,端口为12301
此简单配置旨在允许一个或多个域的消息签名。要了解其他选项,请参阅此处。
连接 milter 到 Postfix:
sudo nano /etc/default/opendkim
添加以下行,仅在使用自定义端口时编辑端口号:
SOCKET="inet:12301@localhost"
配置 postfix 使用此 milter:
sudo nano /etc/postfix/main.cf
确保以下两行存在于 Postfix 配置文件中,并且没有被注释掉:
milter_protocol = 2 milter_default_action = accept
很可能 Postfix 已经使用了过滤器(如 SpamAssasin、Clamav 等);如果以下参数已存在,只需将 opendkim milter 追加到它们(多个 milter 用逗号分隔),端口号应与 opendkim.conf
中的相同:
smtpd_milters = unix:/spamass/spamass.sock, inet:localhost:12301 non_smtpd_milters = unix:/spamass/spamass.sock, inet:localhost:12301
如果参数缺失,按以下方式定义它们:
smtpd_milters = inet:localhost:12301 non_smtpd_milters = inet:localhost:12301
创建一个将保存受信任主机、密钥表、签名表和加密密钥的目录结构:
sudo mkdir /etc/opendkim sudo mkdir /etc/opendkim/keys
指定受信任主机:
sudo nano /etc/opendkim/TrustedHosts
我们将使用此文件来定义 ExternalIgnoreList
和 InternalHosts
,来自这些主机、域和 IP 地址的消息将受信任并签名。
由于我们的主配置文件将 TrustedHosts
声明为正则表达式文件(refile
),我们可以使用通配符模式,*.example.com
表示来自 example.com 的子域的消息也将受信任,而不仅仅是从根域发送的消息。
自定义并添加以下行到新创建的文件。可以指定多个域,不要编辑前三行:
127.0.0.1 localhost 192.168.0.1/24 *.example.com #*.example.net #*.example.org
创建一个密钥表:
sudo nano /etc/opendkim/KeyTable
密钥表包含每个选择器/域对及其私钥路径。任何字母数字字符串都可以用作选择器,在此示例中使用了 mail
,并且不需要更改它。
mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com/mail.private #mail._domainkey.example.net example.net:mail:/etc/opendkim/keys/example.net/mail.private #mail._domainkey.example.org example.org:mail:/etc/opendkim/keys/example.org/mail.private
创建一个签名表:
sudo nano /etc/opendkim/SigningTable
此文件用于声明域/电子邮件地址及其选择器。
*@example.com mail._domainkey.example.com #*@example.net mail._domainkey.example.net #*@example.org mail._domainkey.example.org
生成公钥和私钥
切换到密钥目录:
cd /etc/opendkim/keys
为该域创建一个单独的文件夹来保存密钥:
sudo mkdir example.com cd example.com
生成密钥:
sudo opendkim-genkey -s mail -d example.com
-s
指定选择器,-d
指定域,该命令将创建两个文件,mail.private
是私钥,mail.txt
包含公钥。
将私钥的所有者更改为 opendkim
:
sudo chown opendkim:opendkim mail.private
将公钥添加到域的 DNS 记录
打开 mail.txt
:
sudo nano -$ mail.txt
公钥在 p
参数下定义。请不要使用下面的示例密钥,这只是一个示例,不会在您的服务器上起作用。
mail._domainkey IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5N3lnvvrYgPCRSoqn+awTpE+iGYcKBPpo8HHbcFfCIIV10Hwo4PhCoGZSaKVHOjDm4yefKXhQjM7iKzEPuBatE7O47hAx1CJpNuIdLxhILSbEmbMxJrJAG0HZVn8z6EAoOHZNaPHmK2h4UUrjOG8zA5BHfzJf7tGwI+K619fFUwIDAQAB" ; ----- DKIM key mail for example.com
复制该密钥并向您的域的 DNS 条目添加一个 TXT 记录:
- 名称: mail._domainkey.example.com.
- 文本: “v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5N3lnvvrYgPCRSoqn+awTpE+iGYcKBPpo8HHbcFfCIIV10Hwo4PhCoGZSaKVHOjDm4yefKXhQjM7iKzEPuBatE7O47hAx1CJpNuIdLxhILSbEmbMxJrJAG0HZVn8z6EAoOHZNaPHmK2h4UUrjOG8zA5BHfzJf7tGwI+K619fFUwIDAQAB”
请注意,DNS 更改可能需要几个小时才能传播。
重新启动 Postfix 和 OpenDKIM:
sudo service postfix restart sudo service opendkim restart
恭喜!您已成功为邮件服务器配置了 DKIM!
可以通过向 check-auth@verifier.port25.com
发送一封空邮件来测试配置,并将收到一封回复。如果一切正常,您应该在“结果摘要”下看到 DKIM check: pass
。
========================================================== Summary of Results ========================================================== SPF check: pass DomainKeys check: neutral DKIM check: pass Sender-ID check: pass SpamAssassin check: ham
或者,您可以向您控制的 Gmail 地址发送一封消息,在 Gmail 收件箱中查看收到的电子邮件的标头,Authentication-Results
标头字段中应该存在 dkim=pass
。
Authentication-Results: mx.google.com; spf=pass (google.com: domain of contact@example.com designates --- as permitted sender) smtp.mail=contact@example.com; dkim=pass header.i=@example.com;