前言

  • 本文的重点在于讨论方案,仅包含少量配置细节,主要讨论选择域名邮箱服务商以及配置时需要注意的事项和坑。

什么是域名邮箱

  • 简而言之就是用自己的域名作为后缀的邮箱,比如 an@example.com。

为什么要使用域名邮箱

  • 邮箱与域名同在,可以在更换邮件服务商的同时保留邮件地址,使用不同的服务商用于收信和发送,甚至同时使用多个服务商,或者使用自己架设的邮件服务 (不推荐)。
  • 比较个性。
  • 可以拥有大量邮件地址,以便于在不同的时候使用不同的邮箱。
  • 可以自由的配置 SPFDKIM 以及 DMARC

对域名邮箱的担忧以及解答

  • 后缀知名度低,可能会导致一些不便,比如部分网站只认可知名后缀的邮箱?
    个人已经用了好几年的域名邮箱,很少碰到这种情况,另外可以注册一个常见后缀的邮箱然后设置转发。
  • 很难做到完全免费?
    也有免费的服务,不过免费的东西付出的代价一般最高。
  • 因为邮箱地址后缀不常见,容易被当成垃圾邮件?
    并不一定,这取决于很多因素,而域名邮箱恰恰提供了更多的配置来提高邮件送达率何况对大多数人来说邮箱只收不发。

需要了解的技术和术语

MX 记录

MX DNS 记录用来表示发往该域名的邮件应该被哪个服务器接收,例如:

NamePriorityMail Server
@10smtp-1.example.com
@20smtp-2.example.com

第一列中,"@" 表示根域名,如果子域名也需要接收邮件,需要分别添加,例如 "subdomain" 或者直接 "*"。
第二列表示的是优先级,数字越小优先级越高,发信服务器应当先尝试往高优先级的地址投递。当然事实上很多发信服务器会选择向所有域名发送,或者挑出根域名不同的服务器再分别按优先级发送。
最后一列表示的是负责接收邮件的服务器。

MAIL FROM 和 FROM 的区别

MAIL FROM 即退信地址,又称 Return Path, envelope sender, envelope from 或者 bounce address,隐藏在邮件的 Header 里,一般不会被显示出来,可以简单理解为发送邮件的服务器的邮箱地址,按照现实世界来类比就是快递公司的地址。
FROM 即是单纯的指发件人的邮箱地址。

SPF

简单而言就是通过 DNS TXT 记录表示哪些发信服务器的 IP 是经过该域名认证的。
比如当收件方收到 MAIL FROM 为 postmaster@example.com 的邮件时,可以查找 example.com 的 TXT DNS 记录,获得与下方类似的记录:

"v=spf1 ip4:123.45.67.89 include:spf.example.com ?all"

由此可知:

  1. 来自 IP 地址 123.45.67.89 的邮件是获得认证的。
  2. 来自 spf.example.com 所对应的 IP 地址所发的邮件是获得认证的。
  3. 其余来源的邮件不予评价 (?all), 收件服务器自行处理。这种情况下,当垃圾邮件发送者冒用 @example.com 作为 MAIL FROM 发送邮件时有可能:
    1. 被当作正常邮件接收,而 @example.com 则会背上发送垃圾邮件的黑锅,甚至给欺诈邮件提供了可行性。
    2. 被当成垃圾邮件退回 @example.com 从而导致收到大量 backscatter 类型的垃圾邮件。

所以我们在配置 SPF 的时候应该尽量使用 -all 或者至少 ~all 结尾。
SPF 有三个缺点,首先是无法防止 IP 欺骗,其次是无法对转发的邮件进行验证,这两点可以通过使用 DKIM 来解决。而第三点最为致命,SPF 只对 MAIL FROM 负责,而不是邮件中的发件人地址,也就是说只要垃圾邮件使用了自己的服务器 spam.com 并且配置好了 SPF 记录,那么下面这个形式的邮件也可以成功通过 SPF 验证:

MAIL FROM: spam@spam.com
FROM: alice@example.com
TO: bob@email.com

为了应对这种类型的垃圾邮件,需要有方式验证 spam@spam.com(MAIL FROM) 是否获得了 alice@example.com(FROM) 的授权,于是 DMARC 便诞生了。

DKIM

发信服务器可以对邮件进行签名,下方是一个典型的 DKIM 签名:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=
example.com; h=content-type:date:from:message-id
:mime-version:subject:to:x-me-proxy:x-me-proxy:x-me-sender
:x-me-sender:x-sasl-enc; s=fm3; bh=12OX7bhEDqMP/Q2dMwita3Iv5MqDB
ydR+hALwpCOExU=; b=lhjDO4fWaN5IK2vbtjkj90YQAsBNeSpBCNkAThRf6ZuHv
7PkvywFs3EDQumQAQceC/oXisprhyg5P+BTwudBpgZmLsrq0tyx5ZQqBvGfd/cWV
zZI6rICZou7V2FI0fqnbsP92wn9mMBROfMbCIh/aWzi71ilk49xRgxfJB5Oailzt
OKMl5NYQlerC2+gixc82nLNWQbND/pxpsYL8YzS7qLYCL4JKnYoQHDPqaFuGScS6
d1Fwj6pnfekrJSYEeypb/b0ThXlqqW04c2VGIR5wGHGOymy7ULXZdEKsSbuB6Cxo
nPYpyrQ2BHqP/ZooBatecsGw0k/9FSG4SDzSZxwCw==

当收件方收到该邮件时,会查询 d=xxx 中的域名 (example.com) 所包含的 TXT DNS 记录来获得签名的公钥,由此验证签名是否真实。一封邮件中可以包含多个 DKIM 签名,每个签名独立判断是否通过检验。
比起 SPF, DKIM 可以有效地防止 IP 欺骗,在转发邮件时也可以验证原始签名。但是依旧有着与 SPF 相似的缺点:签名中 d=xxx 中的域名并无需与 MAIL FROM 或者 FROM 有任何关系,也就是说 DKIM 仅仅负责检验签名是否合法,而下面这个形式的邮件也可也成功通过 DKIM 验证:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=spam.com; ......
MAIL FROM: whatever@whatever.com
FROM: alice@example.com
TO: bob@email.com

为了应对这种类型的垃圾邮件,需要有方式验证 d=spam.com 是否获得了 alice@example.com(FROM) 的授权,这同样需要依靠 DMARC

DMARC

DMARC 的存在弥补了 SPFDKIM 在授权方面的缺陷。
比如当收到以下邮件时:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=spam.com; ......
MAIL FROM: spam@spam.com
FROM: alice@example.com
TO: bob@email.com

DKIM 签名中的域名为 spam.com,MAIL FROM 的域名为 spam.com,而发件人为 alice@example.com。很不幸,如果 spam.com(垃圾邮件发送者所拥有的域名)正确的配置了 SPF 和 DKIM,那么 SPF 和 DKIM 均会通过验证。
但是假如 example.com 配置了 DMARC(同样通过添加 DNS 记录),收信服务商即可参考 DMARC 中的政策来对邮件进行进一步验证以及可疑邮件的处理。
通过 DMARC 验证的方式为通过 SPF 或者 DMARC 验证以及相对应的『对齐模式』,也就是通过下面两条中的任意一条

  1. 通过 SPF 验证,并且退信地址 (MAIL FROM) 与发件人地址 (FROM) 部分匹配(其中的一方可为另一方的子域名),可以设置成严格匹配(完全一致)。
  2. 其中一条 DKIM Header 通过检验,并且通过检验的 DKIM Header 中 d=xxx 与发件人地址 (FROM) 中的域名部分匹配(其中的一方可为另一方的子域名),可以设置成严格匹配(完全一致)。

未通过验证的邮件会按照 DMARC 中的建议进行隔离或者退回,同时可以选择报告给身份被冒充的一方。
总而言之,通过 DMARC 与否直接决定了邮件会不会被当作垃圾邮件、诈骗邮件或者直接拒收。

SenderID

姑且还是提一下这个东西吧,最初由 OUTLOOK 推广,同样通过 TXT DNS 记录设置,作为 SPF 的改进版本,然而并没有成功推广,现在连 OUTLOOK 也不使用了。

送达率

发送邮件很容易,但是这并不意味着邮件一定能会被对方顺利收到,影响送达率的主要因素:
邮件标题
邮件内容
发件人地址的声誉
退信地址 (MAIL FROM)的声誉
域名是否有 MX 记录,一个没有配置 MX 记录的域名是无法接收邮件的,而只有垃圾邮件才会采取只发不收的策略。
是否通过 DKIM 验证
是否通过 SPF 验证
是否通过 DMARC 验证
发信服务器的 IP 地址的声誉
是否通过 ARC 验证(与我们关系不大,主要涉及转发服务)

如何选择邮件服务商

DIY

强烈建议不要自己架设服务器,原因是配置极其繁琐但是效果却不好 (当然存在配置简单地方案,但是需牺牲质量),这导致了配置不当容易产生安全隐患以及与其它服务商之间的兼容问题,并且稳定性很难得到保障,同时由于 IP 在其他邮件服务器没有信誉记录,提高了被当成垃圾邮件的概率。

常见因素

比如服务商的名声,处理邮件的速度,过滤垃圾邮件的能力等等。

价格

建议以满足自己需要的功能优先,价格上不是太离谱即可。
同时注意可能会导致费用成倍增加的地方,比如可以添加的域名数量是否足够,子域名是否单独占用额度。

尊重用户隐私

收件时,根据个人接受程度选择:

  1. 所有邮件在服务器上加密,仅用户能看到内容。
  2. 虽然邮件没有加密,不过邮件服务商也不会读取内容。
  3. 邮件服务商会扫描内容,用来反垃圾邮件和检测病毒。
  4. 邮件被服务商随意监视。

发件时:

  • 不会把客户端的 IP 等信息擅自加进邮件的 Header 里。
  • 此处点名批评 Mailgun,当使用 SMTP 协议发邮件时,会把客户端的 IP 附加到 Header 里。
  • 可以用 emailipleak 来测试一个邮件服务是否存在该问题。

处理 MAIL FROM 的方式

当发送一封邮件时,MAIL FROM 填写的是发件人的所拥有的邮箱地址,还是邮件服务商所拥有的邮箱地址,这直接影响了我们可以在 SPF 和 DMARC 中的设置以及送达率,详情在『配置 SPF』部分会提到。
最理想的情况下 MAIL FROM 填写的是发件服务器的邮箱地址。
退而求其次的话 MAIL FROM 与 FROM 域名相同,并且发件服务器禁止其它用户冒充你的地址发信。
最糟糕的状况是 MAIL FROM 与 FROM 域名相同,并且发件服务器允许其他用户冒充你的地址发信(不进行验证)。

对第三方客户端的支持程度

收信服务商必须支持 IMAP,发信服务商必须支持 SMTP,同时保证连接加密,并且可以针对不同的客户端设置独立密码,如果可以设置独立的权限就更好了。部分服务商虽然支持第三方客户端,但是却作出了许多限制,比如限制读取邮件的数量,延迟收件速度等。

支持子域名

绑定域名后可以使用无限量的子域名,用子域名发送邮件不需要分别配置,或者可以设置 "catch-all" 邮箱以及 Sieve
许多邮件服务商提供利用 "+" 来增加『马甲』的功能,比如发往 alice+example@gmail.com 的邮件会直接被 alice@gmail.com 接收,但是这个方法有很严重的局限性:

  1. 许多网站并不认可带 "+" 的邮箱。
  2. 垃圾邮件发送者同样懂得这种技巧,可以直接写个正则表达式把 "+" 和 "@" 之间的字符删除。

而支持无限量的子域名或者支持 catch-all + Sieve 则可以应对这种情况,详情在 『配置收件服务』部分会提到。

使用不同的服务商进行收发

尽量避免收件和发件使用不同服务商的情况,因为会导致很多麻烦,比如对『草稿』的支持。

支持 Sieve

Sieve 是一种邮件过滤脚本,可以方便的对邮件进行自定义的分类,过滤以及转发等行为。
大部分邮件服务商都是依靠 sieve 进行分类等行为的,只是不一定允许用户完整的自定义配置。
当然有些服务商提供类似的功能但是直接称作邮件过滤器 (filter)。

尽可能使用加密链接

邮件服务器与其他邮件服务商之间尽可能使用加密链接 (opportunistic TLS),即尽量保证用户的邮件在运输过程中也是被加密的,各个邮箱服务提供商的加密程度可以参考谷歌透明度报告 (Transparency Report)

信誉

发信服务商信誉较好,并且会努力维护自身信誉,不会成为垃圾邮件的温床

个人选择

Fastmail 已改用 Protonmail
注:Fastmail 处理 MAIL FROM 的方式极其糟糕,目前的解决办法仅有牺牲掉 SPF 验证(设置成禁止所有域名),或者使用别的发件服务商。除非你可以忍受其它用户能以你的名义发送邮件并且成功通过 DMARC 验证。
另外特别表扬一下 Amazon SES 的发信服务,可靠,稳定,可以自定义 MAIL FROM 的格式,对子域名以及权限的设置可以特别细致,然后还免费(其实是费用极低,然后如果发送的邮件数量不多,会因为费用太低而被免单),所以建议同时申请一个 Amazon AWS 帐号,然后也授权 Amazon SES 作为你的发件服务器,可以解决很多问题,比如主要使用的邮件服务商不支持从子域名发信,或者不能单独授权 SMTP 服务给第三方客户端。

配置收件服务

  • 注册账户并添加域名,有的邮件服务提供商需要进行 DNS 验证,根据提示处理即可。

  • 添加 MX DNS 记录,如果使用多个收件服务商则可以按照优先级配置一下,当然好多时候发送方并不会按照优先级依次发送,而是一股脑各发一份。

  • 如果收件服务商同时支持接收发送到子域名的邮件,建议这样进行设置:
    只添加一个邮件地址,例如 alice@example.com,同时使该地址拒绝接收所有从外部直接发往该地址的邮件。
    让所有发往 alice@*.example.com 的邮件全部由 alice@example.com 接收,其它地址(例如 bob@example.com )的邮件直接拒收。
    这样可以防止 alice@example.com 被垃圾邮件骚扰,同时防止针对用户名进行的探测(例如 bob@example.com),而针对子域名探测的概率极低。
    使用时根据情况留下不同子域名的邮箱即可,例如 alice@github.example.com 用于接收 github 的邮件,如果愿意甚至可以使用 alice@alt1.github.example.com 这种形式。

  • 如果邮箱支持 "catch-all" 以及 Sieve,建议这样进设置:
    只添加一个邮件地址,例如 alice@example.com,同时使该地址拒绝接收所有从外部直接发往该地址的邮件。
    把 alice@example.com 设置为 catch-all 地址,也就是说所有发往 *@example.com 的邮件都会由 alice@example.com 接收。
    (通过设置 Sieve 或者 Filter)收信时如果检测收信地址如果不是特定形式(例如 alice*@example.com)则直接丢弃,这样可以一定程度上防止针对用户名的探测。
    使用时根据情况留下不同用户名的邮箱即可,例如 alicegithub@example.com 用于接收 github 的邮件。

  • 其它 Sieve 或者自定义 Filter 的用法举例
    如果检测到发件人和收件人都是自己,可以直接归类到 "Memo" 文件夹之类的玩法。

配置发件服务

添加 SPF DNS 记录

SPF 的设置方式是添加一条 DNS TXT 记录,大部分邮件服务商会推荐设置成以下形式

"v=spf1 include:spf.example.com ~all"

不过个人推荐这样设置成下面这样(当 SPF 没有匹配时会建议直接将邮件丢弃)

"v=spf1 include:spf.example.com -all"

然后根据你的发件服务商处理 MAIL FROM 的方式不同,进行不同的优化:

  1. 如果 MAIL FROM 填写的是发件服务器的邮箱地址,推荐将发件服务器添加进你的 SPF DNS 记录里,这样可以让你的邮件成功的通过 SPF 验证,不过却无法通过相应的对齐模式检查,所以只能依赖基于 DKIM 的 DMARC 验证,事实上这并不会造成任何问题,因为反正 DMARC 只要求二选一,而且 DKIM 确实比 SPF 更加优秀一些。
  2. 如果 MAIL FROM 与 FROM 域名相同,并且发件服务器禁止其它用户冒充你的地址发信,这时推荐将发件服务器添加进你的 SPF DNS 记录里,这样可以让你的邮件成功通过 SPF 验证以及相应的对齐模式检查。
  3. 如果 MAIL FROM 与 FROM 域名相同,并且发件服务器允许其他用户冒充你的地址发信(不进行验证),这时千万不要按照服务商的推荐将域名添加进 SPF DNS 记录里,因为这样会导致使用相同邮件服务的用户可以以你的名义发邮件并且通过 DMARC 验证(因为 SPF 验证和对齐模式检查总会通过)。所以推荐直接将 SPF DNS 记录设置成 "v=spf1 -all"(拒绝所有),此时所有 SPF 验证将会失败,虽然可能导致邮件的垃圾邮件评分少量上升以及只能依赖 DKIM 来通过 DMARC 验证,但是至少保证了最基本的安全。
  • 另外记得添加指向子域名(一般直接用 "*")的 DNS TXT 记录,如果用得到子域名,内容与前面的记录相同即可,如果用不到建议填 "v=spf1 -all" 来防止第三方冒用子域名发送邮件。

添加 DKIM DNS 记录

无论你的 SPF DNS 记录如何配置,都推荐按照发件服务商的要求配置好 DKIM DNS 记录。正常而言,如果有未授权用户试图使用你的域名为收件人发送邮件时,发件服务商会直接拒绝请求或者不对该邮件添加包含你所拥有的域名的 DKIM 签名,所以按照要求添加 DKIM 记录通常是安全的。假如你发现你的发件服务商并没有这么做,直接换一家吧,能犯这种错误的服务商坚决不能继续使用。

添加 DMARC DNS 记录

只需要添加一条指向 _dmarc 的 DNS TXT 记录即可,并且子域名不需要额外添加。
如果你需要从子域名发邮件那么推荐这样设置

"v=DMARC1;p=quarantine;sp=quarantine;adkim=r;aspf=s;"

如果不需要则推荐这样设置

"v=DMARC1;p=quarantine;sp=reject;adkim=s;aspf=s;"

用一段时间后如果感觉足够稳定,那么把里面的 quanrantine 都改成 reject,这样没有通过 DMARC 验证的邮件会被建议直接丢弃而不是放进垃圾邮件。
如果希望收到关于 DMARC 记录的报告,添加上 "rua=mailto:alice@example.com;" 即可。

测试

当一切都配置好了之后,建议使用 mail-tester.com 测试一下评分。

总结

电子邮件包含的细节很多,很难一一讲出并且难免有疏漏,但愿这篇文章可以帮助一些选择困难症患者更快的进行筛选。