搭建企业邮箱
一、什么是企业邮箱?
不同于qq.com、163.com、gmail.com等,企业邮箱往往会使用自己的域名作为邮箱后缀,如szpost.com,但是为什么能够使用该域名作为邮箱呢?谁来保证它能够进行邮件发送呢?这就是ESP
(邮件服务提供商)所做的内容了,搭建企业邮箱,也就是为这些尚不具备邮件发送能力的域名,提供发送邮件的渠道,使得其能够像使用qq邮箱一样发送邮件。为了实现这一步,那我们就不得不去了解一下qq邮箱是怎么实现邮件发送的。下面的内容涉及概念,相对比较枯燥,不过了解它对于理解邮件发送有着重要的意义。
如果希望一个域名能够作为邮箱进行发送。至少需要配置SPF和DKIM,推荐也要配置MX和DMARC记录,这样更有利于发送到对方的收件箱。
SPF:SPF 是一种防止邮件地址伪造的技术,允许域名所有者指定哪些邮件服务器可以代表该域名发送邮件。通过检查邮件的发送服务器是否在 SPF 记录中列出,接收服务器可以验证邮件的真实性。举个简单的例子,qq的邮件服务器怎么知道发过来的邮件就是“qq邮箱”呢,你可能会说qq邮箱不都是qq.com作为后缀的吗,以这个标准处理不就好了。但是这存在两个问题:第一,如果这个qq.com是假冒的呢?第二,qq邮箱也提供了绑定其他域名的方式,如可以绑定foxmail,那又该如何识别foxmail作为后缀的邮箱呢?SPF提供了一个解决方案,就是查看你的域名的DNS记录里是否包含qq所提供的SPF信息,如果有,则表明你的域名是qq授权的,可以发送,否则,他会拒绝你的邮件。
DKIM:DKIM 是一种电子邮件认证技术,通过对邮件内容进行数字签名,接收服务器可以验证邮件的真实性和完整性。签名由发送服务器生成,并附加在邮件头中。接收服务器通过 DNS 记录中的公钥验证签名的有效性。简而言之就是验证邮件是否经过篡改,其中涉及非对称加密的知识,感兴趣的小伙伴可以自己去查询相关知识。
MX:MX(Mail Exchanger)记录是一种 DNS 记录类型,指定域名的邮件服务器,用于接收该域名的电子邮件。MX 记录指向邮件服务器的主机名,并包含优先级,用于决定多个邮件服务器的处理顺序。它用来指定哪个邮件服务器来处理,优先级高的优先处理,相对比较好理解。
DMARC 是一种基于 SPF 和 DKIM 的电子邮件认证协议,允许域名所有者发布策略,告诉接收邮件服务器如何处理未通过 SPF 或 DKIM 认证的邮件。DMARC 还提供报告机制,让域名所有者能够监控邮件认证的结果。
二、企业邮箱实现路径
好了,那我们现在明白,如果要给用户提供企业邮箱的实现方案,那我们就需要给他们提供SPF记录和DKIM记录。幸运的是,Mailu(如不熟悉可在我的其他博客看到相关介绍)通过自动化工具为我们提供了生成这些记录的API,通过调用其API就能够获得这些记录并提供给用户了。一旦用户配置了这些DNS记录,我们就可以为其实现代发!
当然,用户在配置完成后,我们还需要知道他已经配置完成了,并且提供给他是否配置成功的信息,这是整个业务流程不可缺少的一环。下面是我最终达成的效果:
这里我是怎么判断配置是否正确呢?其实并不复杂,命令行输入指令
nslookup -type=TXT example.com
可以获取到该域名的所有TXT记录,可以看到,SPF、DKIM、DMARC都属于TXT记录,那么是可以通过以上方式获取的,通过校对其内容是否是对应的,来判断DNS记录已经正确配置。以DKIM记录为例,下面是实现的demo:
public static List<String> checkDkim(String domain,String selector){ try { // 构造DKIM记录的查询名称,通常是"<selector>._domainkey.<domain>" String dkimRecordName = selector + "." + "_domainkey."+ domain; Lookup lookup = new Lookup(dkimRecordName, Type.TXT); lookup.setResolver(new SimpleResolver("1.1.1.1")); // 使用Cloudflare的公共DNS服务器 Record[] records = lookup.run(); if (records==null || records.length==0){ return null; } List<String> dkimTxtRecords = new ArrayList<>(); StringBuilder dkimRecord = new StringBuilder(); for (Record record : records) { if (record instanceof TXTRecord) { TXTRecord txt = (TXTRecord) record; List<String> strings = txt.getStrings(); for (String str : strings) { dkimRecord.append(str); } dkimTxtRecords.add(dkimRecord.toString()); } } return dkimTxtRecords; } catch (TextParseException | UnknownHostException e) { e.printStackTrace(); return null; } }
private Boolean dkimVerify(String domain,String dkim) { List<String> dkimList = DnsUtil.checkDkim(domain,selector); if (dkimList!=null && dkimList.contains(dkim)){ return true; } return false; }
上面的代码中,先是构造了DKIM记录的查询名称,并使用Cloudflare的公共DNS服务器去获取TXT的DNS记录,并将获取到的结果存储到一个集合中,最后判断其中是否有记录与我们给定的DKIM记录匹配,若有则返回true,前端显示验证成功。至此,就已经实现了企业邮箱的功能。
需要说明的是,这种模式进行的邮件发送方是无法在收件箱看到自己所发送的营销邮件的,因为在邮件服务器我们是相当于创建了一个同名的账户去进行代发,而当收件方进行回信时,需要在邮件服务器设置对应的转发,从而转发到发件方真正的收件箱中,这样才能够正确收到。据我目前调研的结果来看,很多邮件服务提供商都是基于这种方式的,如mailgun,sendcloud等。