采用 Ed25519 的 DKIM 签名
Ed25519 是一种高性能的公钥签名系统。和 RSA 相比, 同等强度的 Ed25519 的密钥长度要比 RSA 短很多,此外,软件实现的 Ed25519 的验证速度也比同等强度的 RSA 快很多。
尽管早在2018年 RFC 8463 Section 5 就已经将 RFC 6376 Section 3.3 修正为要求验证者必须支持 Ed25519 验证,然而时至今日主要的邮件服务提供商中, 包括 Google 的 Gmail 和 Microsoft 的 Outlook.com 以及 Apple 的 iCloud 都还不支持验证 Ed25519 DKIM 签名。ProtonMail 支持 Ed25519 的 DKIM 签名,但它并不使用 Ed25519 签名向外发出的邮件。
经测试,同时采用 RSA 和 Ed25519 签名发出的邮件可以让那些只支持 RSA 签名的邮件运营者正确验证邮件, 显然,这样做会增加邮件尺寸,也会增加 DNS 流量,这些都和采用 Ed25519 签名的希望背道而驰, 但我觉得总得做点什么来让互联网巨头开始面对这一现实,因此我打算从今天开始将我自己域名发出的邮件同时采用 RSA 和 Ed25519 签名,直到三大主要的邮件服务提供商(Google、 Microsoft 和 Apple)都支持它为止。
我目前采用的是 dkimpy-milter。 和之前使用的 OpenDKIM 相比,它的开发更为活跃(后者在2018年发布了一版beta之后就没有再发布新的版本了)。 其配置大致如下:
首先是生成签名用的密钥对:
dknewkey --ktype ed25519 ed25519-2023
dknewkey rsa-2023
这其中 ed25519-2023
和 rsa-2023
是计划使用的 selector
名字。程序会生成 .key
(私钥)和
.dns
(公钥,用来添加到域名 zone 中)两个文件。
注意 dkimpy 并未考虑 TXT 记录只能有255个字符的限制,对于 2048-bit 的 RSA 公钥,必须将其切开。 对于 Ed25519 公钥,由于其长度很短,因此没有这个问题。
接下来要更新域名的 DNS zone 来添加新的记录。为了方便回退,暂时不要删除旧的公钥。
dkimpy-milter.conf
的配置主要是以下几方面:
Domain
。这是希望签名(自己的)域名。KeyFile
和Selector
。这是 RSA key 的私钥(PEM格式)和 selector。除此之外也可以用 OpenDKIM 风格的KeyTable
。KeyFileEd25519
和SelectorEd25519
。这是 Ed25519 的私钥和 selector。除此之外也可以用 OpenDKIM 风格的KeyTable25519
。Socket
。我使用的是本地的 Unix socket (local:/var/spool/postfix/private/dkimpy-milter
)UserID
。抛弃特权后的身份。注意 socket 必须可以被 Postfix 读写,可以设置为postfix:dkimpy-milter
启动之后将 Postfix 的 master.cf
中 submission
服务(或者其他希望接收往外发邮件的 smtpd
的服务马甲)上的
smtpd_milters
改为 -o smtpd_milters=unix:private/dkimpy-milter
就可以了。
同时使用两种签名算法时,邮件中会出现两个 DKIM-Signature:
信头。
对方邮件服务器收到之后通常会增加对应的信头说明验证情况。