DNS 系列4 --- DKIM
一、承上启下
二、DKIM
1. 概念
域名密钥识别邮件 (DKIM) 是一种电子邮件验证方法,有助于防止垃圾邮件发送者和其他恶意方冒充合法域名。
与SPF一样,DKIM也是一种TXT DNS记录,或者说它利用TXT DNS记录来实现域名校验。
所有电子邮件地址都有一个域名,即地址中"@"符号之后的部分。垃圾邮件发送者和攻击者在发送电子邮件时可能试图冒充域名,以进行网络钓鱼攻击或其他骗局。
假设李四为example.com工作并掌握公司机密信息,张三不是example.com的员工但他希望从李四那里得到example.com的机密信息,于是张三使用假冒的zhangsan@example.com给李四发邮件,他可以给李四发送一封看似来自"zhangsan@example.com"的电子邮件,以骗取李四的信任,让李四以为张三也在为example.com工作。
DKIM与发送方策略框架(SPF)和基于域名的消息身份验证、报告和一致性(DMARC)一起,使得攻击者以这种方式冒充域名的难度大大增加。没有通过DKIM和SPF的电子邮件会被标记为“垃圾邮件”,或者不被电子邮件服务器投递。如果example.com为其域名设置了DKIM、SPF和DMARC,那么李四甚至可能永远不会看到张三的恶意电子邮件,因为它要么进入了李四的垃圾邮件文件夹,要么被电子邮件服务器完全拒绝。
2. DKIM组成
DKIM 有两个主要方面:
a. DKIM 记录,它存储在域名的Domain Name System(DNS)记录中;
b. DKIM 标头,它附加在所有来自该域名的电子邮件中。
3. DKIM记录
(1) TXT记录
上文提到DKIM记录是一种TXT记录,所以DKIM首先需要遵循TXT记录的格式:
[FQDN] IN TXT [任意字符串]
FQDN:需要设定为DKIM指定的域名;
任意字符串:需要填写DKIM的版本、公钥和加密算法等信息。
(2) FQDN --- DKIM名称
与其他TXT记录不同,DKIM的FQDN需要遵循其特殊的格式:
[selector]._domainkey.[domain]
a. selector: 是由域名使用的电子邮件服务提供商发布的专门值,但是也可以是当前的日期、域名的代称,或者其他特定的值。
需要注意的是,[selector]._domainkey就是hostname,以阿里云DNS解析为例,需要将hostname填写到“主机记录”中:
b. domain: 是需要设定DKIM的域名。
我们为域名example.com配置DKIM记录:
20230212._domainkey.example.com //Hostname是20230212._domainkey
或者如果我们使用Apache James:
james3._domainkey.example.com
(3) TXT值
DKIM的TXT记录值同样需要遵循DKIM的特定格式:
v=DKIM1; k=rsa; p=[Public Key]
v=DKIM1 表示这个TXT记录应当被解释为DKIM;
k=rsa表示这个DKIM使用的加密算法是rsa算法;
Public Key就是的公钥。这里的TXT值对应阿里云的域名解析的“记录值”:
(4) TTL
TTL代表生存时间(以秒为单位),它表示该记录在需要刷新之前被视为有效的时长。DKIM 记录的TTL一般为几分钟。
4. DKIM标头
发送电子邮件的服务器使用电子邮件标题、电子邮件正文和私钥来创建其数字签名。该数字签名作为 DKIM 标头的一部分附加在电子邮件中。
DKIM标头是附加在电子邮件中的多个标头之一。大多数电子邮件应用程序在显示电子邮件时不会显示标头,除非用户选择某些选项。以Gmail为例,用户可以通过点击电子邮件右上方的三个垂直点,然后点击"显示原文"来查看电子邮件的标头。
下面是一个DKIM标头的示例:
v=1; a=rsa-sha256; d=example.com; s=james3; h=from:to:subject; bh=uMixy0BsCqhbru4fqPZQdeZY5Pq865sNAnOAxNgUS0s=; b=LiIvJeRyqMo0gngiCygwpiKphJjYezb5kXBKCNj8DqRVcCk7obK6OUg4o+EufEbB tRYQfQhgIkx5m70IqA6dP+DBZUcsJyS9C+vm2xRK7qyHi2hUFpYS5pkeiNVoQk/Wk4w ZG4tu/g+OA49mS7VX+64FXr79MPwOMRRmJ3lNwJU=
v= 显示正在使用哪个版本的 DKIM;
d= 是发件人的域名;
s=是选择器,接收服务器应使用它来查找DNS记录;
h=列出了用于创建数字签名(b)的标头字段。在本示例中,使用的是发件人、收件人和主题标头;
bh=是电子邮件正文的哈希值。哈希值是一个专门的数学函数的结果,称为哈希函数。包含该值是为了使接收电子邮件的服务器能够在整个电子邮件正文加载之前计算签名,因为电子邮件正文可能是任何长度,在某些情况下加载可能需要很长的时间;
a=是用于计算数字签名(b)以及生成电子邮件正文哈希值(bh)的算法。在这个示例中,使用的是RSA-SHA-256(RSA使用SHA-256作为数字签名的哈希函数,并使用SHA-256用于正文哈希);
b=是数字签名,由h和bh产生,并使用私钥签名。
5. 工作原理
DKIM基于私钥加密的数字签名方案,它使用一对公钥和私钥来确保发送方身份。具体流程如下:
(1) 邮件服务提供商(比如example.com)需要生成一对公钥和私钥,然后将公钥维护到一个公开的DNS记录中,这个DNS记录就是DKIM;
(2) 发送方在发信时使用私钥加密邮件中的必要属性(包括发件人、收件人和标题等)并生成加密字符串,这个加密字符串就是数字签名,该数字签名将被附着在邮件标头中,这个过程叫签发;
(3) 收件人在收到邮件之后,首先查询发件人所属域名的DNS记录,获取其中的DKIM公钥,使用公钥来解密加密字符串,然后与相关属性进行比对,这个过程叫做验签:
a. 如果无法解密加密字符串,说明公钥私钥不匹配,邮件非法;
b. 如果解密之后有任一属性值与邮件的属性值不匹配,则说明邮件被修改过,邮件非法。
6. 生成公钥私钥
(1) 生成私钥
使用OpenSSL生成私钥,1024位是DKIM要求的最小长度:
openssl genrsa -out dkim-private.pem 1024
(2) 生成公钥
openssl rsa -in dkim-private.pem -out dkim-public.pem -pubout
三、验证配置
TXT类型的DNS记录配置完成之后,需要24小时才能在全网生效,本地网络可能不会耗时这么长。
1. dig验证
dig txt [selector]._domainkey.[domain]
该命令会返回TXT的值,也即是阿里云的“记录值”。
2. 在线工具验证
https://easydmarc.com/tools/dkim-lookup
四、参考
1. 官方
https://datatracker.ietf.org/doc/html/rfc6376/
2. 其他
https://james.apache.org/howTo/dkim.html
https://support.dnsimple.com/articles/dkim-record/
https://www.cloudflare.com/learning/dns/dns-records/dns-dkim-record/
https://robertmunn.com/blog/configuring-dkim-and-spf-for-apache-james/