为服务器发出的邮件再加分——添加 MX、DNS 反向解析、SPF 和 DMARC 记录,并为邮件加上 DKIM 签名(日期:20180326)

2018年3月26日 6 条评论 1.59k 次阅读 0 人点赞

在前面的两篇文章中,我分别写了怎么安装和配置好 Sendmail 和 Postfix 来发邮件,感兴趣的可以点击下面的两个链接看看。

1.《[Debian]开启 WordPress 的邮件通知功能,让服务器支持发邮件——Sendmail 的安装与简单配置(日期:20180326)》

2.《[Debian]开启 WordPress 的邮件通知功能,让服务器支持发邮件——Postfix 的安装与简单配置(日期:20180326)》

在上面的两篇博文中,我们算是简单配置好了我们的邮件服务器,但是这是不够的,现在大家都知道,互联网上垃圾邮件泛滥,尽管我们自己可以说我们服务器发出的邮件绝不是什么垃圾邮件,但是很明显,这样的说明很难有说服力,因为如果你细心一点就会发现,一个假设好的邮件服务器是可以任意伪造邮件的发件人的,在没有一些防范和验证措施的情况下,收件人的服务器很难判定这封邮件是否是垃圾邮件,是否是伪造的,所以如果你实际的测试过向类似 Gmail 这样的大型邮箱服务发邮件的话,你可能会发现你的邮件最终不是出现在收件人的收件箱里,而是默默的躺在了垃圾邮件列表里——你无法有效的证明这确实是域名的持有者所发出的真实邮件。这篇博文就将针对这种情况,来对我们的邮件服务器进行更进一步的配置,好让从我们服务器中发出的邮件更加的可靠,可信。

在开始看下文的内容之前,先试试现在自己自建的邮件服务器发出的邮件得分吧:https://www.mail-tester.com

 

一、说明

本博文将会尽可能的说一下和邮件服务器相关的一些设置,因此可能会包含有在前两篇博文中出现或说明的东西,还请大家谅解。另外,本文后面有关于 DKIM 相关的内容,安装和配置环境为 Debian 系统,当然,其它的系统也基本是通用的,这里给大家提一下,好让大家能多多注意。

 

二、添加 MX 记录

MX 记录的添加是需要在我们的域名注册商处进行的,这个记录的作用说起来也很好理解,当你有一个邮箱地址 A@example.com 时,别人想向你的邮箱发邮件,对方的服务器首先得知道这封邮件应该发到哪里(也就是哪个服务器)才能被收到,然后才能给你发出这封邮件。而 MX 记录的作用,就是供对方的服务器查询该记录,知道发给 A@example.com 这个邮箱的邮件应该具体的送到互联网上的哪一台服务器里,也就是你的服务器里。

知道了这点之后,相信大家也能猜到,这个 MX 记录里具体应该填写的内容了——当然是写你的服务器 IP 地址了。当然,写一个域名也是没问题的,前提是这个域名有 A 记录/AAAA 记录,也就是通过域名能查到域名指定的服务器 IP。

要添加 MX 记录,你需要在你的域名注册商那里打开该域名的 DNS 记录管理,然后选择添加 MX 记录。那么,我们先来看看 MX 记录要填写哪些内容吧。

  1. 主机名:如果你的邮箱域名格式是@example.com 这种,主机名这里留空就行,如果是@mail.example.com 这种,主机名填写子域名的名称,也就是 mail
  2. 地址:这里填写具体的服务器 IP 或者是域名,注意如果填的是域名,一定要确保该域名绑定有 A/AAAA 记录(也就是域名绑定了 IP),如果你想让 MX 记录支持用 IPv6 地址,选择填写域名的方式,再添加 AAAA 记录是个很好的选择
  3. 优先级/距离:MX 记录是可以有多条的,也就是说,可以有多个服务器支持收到发往一个域名的邮件,那么具体这封邮件被哪个服务器收下呢?就是根据这个优先级来判定的。优先级高的,别人的服务器在发件时会优先连接这台服务器,如果连接没问题,则将邮件送出,有问题再按照优先级填写的数字,从小到大挨个尝试。比如有一个数字为 0 和一个数字为 10 的 MX 记录,别人的服务器发件时,会优先连接这个记录为 0 的服务器,不成功才会尝试 10 的。
  4. TTL:这里填写的是数字,是告诉服务器你的这条 MX 记录缓存的时间(以秒算),缓存时间过了就要重新查询下 MX 记录了,防止你更新了你的 MX 记录而别人的服务器还不知道。这里的值具体填写多少,看你自己的选择,一般默认就行了

PS:MX 记录是用作收信的,如果你只想发不想收,可跳过不添加。

 

三、添加 DNS 反向解析记录

DNS 反向解析的记录,在发邮件时也是有作用的,它能告诉别的服务器,你的服务器 IP 绑定了什么域名,再配合后面将要说的 SPF 记录(你的域名绑定了什么 IP),两个互相匹配时,能让你的服务器发出的邮件更加可信——我的服务器 IP 是 XXX,我用我的服务器发出的邮件申明发件人是 XXX@example.com,DNS 反向解析告诉别人,这个 IP 确实绑定了 example.com 这个域名,而在 example.com 的 SPF 记录里,确实能查到域名也绑定了这个服务器的 IP 信息,某种程度上就能说明这封邮件确实是由域名持有人底下的服务器发出的邮件。

以上纯属个人理解,如有错误之处,还请指正。

至于 DNS 反向解析记录该怎么添加,这个需要在你的服务器商家那里进行设置,不同的商家设置方法不一定相同,这里就不细说了,具体要添加什么也挺简单的,就是将这个服务器的 IP 绑定上你的邮件服务器域名,所以只需要加上域名就行了。

 

四、添加 SPF 记录

关于 SPF 记录,在前面的 DNS 反向解析记录里已经和大家说明了它的作用了,就是让你的域名和一个或者多个 IP 绑定,让别的服务器能知道,当别人用你这个域名的名义发出邮件时,根据 IP 地址是否包含在 SPF 记录中来判断这封邮件到底能不能确信是域名持有人发出的,防止伪造邮件。

SPF 记录和前面的 MX 记录一样,实在域名注册商那里进行添加的。至于 SPF 记录该怎么添加,在开始说明之前,希望大家先了解一下 SPF 记录该怎么写。

首先,我们要知道 SPF 记录里能填写哪些参数(有哪些机制),他们是:

  1. all:会匹配到所有的 IP ,一般放在整个 SPF 记录的最后再来写,告诉别人除了前面说的那些情况,剩下的不匹配的 IP 该怎么处理。
  2. ip4:匹配 IPv4 地址,告诉别的服务器,遇到这些 IPv4 地址时,该怎么处理。这个参数的后面,既可以写单个的 IPv4 地址,也能写成 XXX.XXX.XXX.XXX/16 这种形式来成片匹配。
  3. ip6:匹配 IPv6 地址,告诉别的服务器,遇到这些 IPv6 地址时,该怎么处理。这个参数的书写方法和 IPv4 类似,既能填写单个 IPv6 地址,也能成片匹配
  4. a 和 mx:匹配域名的 A 记录和 MX 记录绑定的域名,如果单写,后面不加域名,则是匹配的当前域名的记录,如果后面加上域名,则匹配相应域名的记录。
  5. include:后面填写一个域名,表示本域名的 SPF 记录匹配你填写的这个域名的 SPF 记录,注意,填写的域名本身一定要添加好了 SPF 记录,否则容易出错
  6. 还有几个,因对本文影响不大暂不介绍

上面写的是限定匹配的 IP 范围,那么对于那些被匹配到的 IP 该怎么做呢?有下面几种做法(加在上面那些参数的前面):

  1. +:表示这些 IP 通过,也就是匹配到的 IP 可以被验证和域名持有人有关(IP 发出的信件被别人的服务器允许接收)
  2. -:拒绝,含义和上面的“+”相反(IP 发出的信件不被别人的服务器允许接收)
  3. ~:不是域名持有人的 IP,但是不采取措施(IP 发出的信件被别人的服务器接收,但是会做出报告)
  4. ?:无法确定的 IP(发出的信件还是会被别人的服务器接收)
  5. 如果前面的参数不加任何以上的符号,默认的是“+”模式,也就是匹配到的 IP 表示通过

 

知道了上面的这些东西,我来说一个具体的例子,好让大家能更好的操作。

例子:我有一个域名 example.com,我想让我的服务器(IPv4:127.0.0.1,IPv6:::1)发出的邮件能被正常的接收,同时也让拿这个域名 example.com 建站的服务器(和前面的那台服务器不同)发出的信件也被允许接收。此外,我还有一个域名 example1.com,我想让和这个域名有关的服务器以@example.com 这样的名义发出的邮件也能被允许接收。除了上述的那些所涉及到的 IP,其它的 IP 以@example.com 发出的邮件一律不可信,应该拒绝。那么我的 SPF 记录可以这么写:

  • 首先,打开你域名注册商相关域名的 DNS 管理,选择添加 SPF 记录,有些域名注册商没有这个选项的,选择添加 TXT 记录。
  • 然后,因为上面我们的例子说的是以@example.com 发出的邮件,所以主机名称(域名名称)那里,留空不写,如果你是@mail.example.com 这种的子域名格式,主机名称填写 mail。
  • 在 TXT 记录要填写的地方,写上下面的参数:
v=spf1 a mx ip4:127.0.0.1 ip6:::1 include:example1.com -all

要注意的是,v=spf1 这开始的一段是固定的,它表示你填写的 SPF 记录的版本,目前只有版本一,所以就这么写就行了,开头这一句也是必不可少的。

  • TTL 该怎么填写,参照上面的 MX 记录中关于 TTL 的说明。

 

不知道这样举例之后,大家能否理解呢?没有理解的,可以直接复制下面这个参数,把 ip4 里面的 IPv4 地址和 ip6 里面的 IPv6 地址替换成你自己的,如果没有 IPv4 或者 IPv6 地址的,删掉对应的参数 ip4 或者 ip6 就行了。

v=spf1 a mx ip4:127.0.0.1 ip6:::1 -all

PS:还没明白或者对这个感兴趣的,可以看看 Renfei Song 的博客中关于 SPF 记录的有关说明,本文中关于 SPF 记录的解释也是参考他的博文来写的:《SPF 记录:原理、语法及配置方法简介

 

五、添加 DMARC 记录

DMARC 记录,作用就是告诉别人的服务器,你的域名发出的邮件应该是受到了 SPF 记录或者 DKIM 签名(后面会说)保护的,在号称是你的域名发过来的邮件无法通过这两种认证时,建议别人的服务器该怎么处理。这个记录和前面说的 MX 和 SPF 记录一样,是要在域名注册商那里添加的。

  • 首先,我们打开域名注册商有关域名的 DNS 管理页面,选择添加 TXT 记录
  • 选择之后,如果你的邮箱域名是 example.com,那么在主机名那里写上:_dmarc.example.com。如果是 mail.example.com,那么主机名就是_dmarc.mail.example.com。
  • 记录具体填写的内容,请参照下面的格式说明填写。

DMARC 可填写的常用标记:

  1. v:放在开头最先填写,后面接 DMARC 的协议版本号,当前是 DMARC1,所以最开头都应该是 v=DMARC1
  2. p:必须填写的,告诉别人的服务器,当 SPF 和 DKIM 认证无法通过时,建议别人的服务器该怎么做(三个参数:none(不采取措施),quarantine(隔离邮件),reject(拒绝邮件))
  3. pct:过滤邮件,后面接百分比的数字,比如 pct=20,表示过滤百分之二十的邮件
  4. rua:后面写“mailto:自己的邮箱”,表示定期接受 DMARC 有关的每日报告汇总邮件
  5. 其它的,个人感觉普通用户用得比较少,就不细说了

 

  • 下面以谷歌给出的例子来让大家加深理解(部分内容修改):在以下 TXT 记录中,如果有任何声称从你的域名 example.com 发送的邮件未通过 DMARC 检查,系统会按 5% 的比例隔离这类邮件,然后将每日汇总报告通过电子邮件发送到 A@example.com:
v=DMARC1; p=quarantine; pct=5; rua=mailto:A@example.com

相信看了这个例子大家应该知道该怎么填写了吧?如果还不清楚,可以看看谷歌的说明:https://support.google.com/a/answer/2466563?hl=zh-Hans

 

  • 填写完之后保存即可,至于 TTL 该怎么写,看上面 MX 记录中关于 TTL 的有关说明。

 

六、安装和配置 DKIM,让发出的邮件带有签名

DKIM 的作用,就是它会生成一个公钥和私钥,公钥写在你的 DNS 有关记录里,而私钥会随着你的邮件一起送出到达别人的邮箱服务器,当别人的服务器收到这样的信件时,它会查找发件人的域名上所记录的 DKIM 公钥,然后看是否和邮件中的私钥相匹配,如果匹配,则能说明这是由域名持有人签名认证的邮件,无法轻易造假。

1.安装和配置 OpenDKIM

下面演示的是在 Debian 上安装 OpenDKIM 生成私钥公钥并和邮件程序绑定使用的方法:

 

  • 连接服务器的 SSH,输入以下的命令安装 OpenDKIM
apt-get install opendkim opendkim-tools
  • 安装完成以后,输入以下命令生成公钥和私钥,注意将其中的 example.com 替换成你的邮箱将使用的域名
opendkim-genkey -t -s default -d example.com

特别说明:其中的 default 可以更改,同时后文中某些地方要对应修改,不改不会有什么问题,选择默认的即可。

  • 创建一个新文件夹,用来存放生成好的公钥和私钥
mkdir /etc/opendkim
  • 复制公钥和私钥到新文件夹中
cp default.private /etc/opendkim
cp default.txt /etc/opendkim
  • 配置/etc/opendkim.conf
vi /etc/opendkim.conf

按 i 键之后可以进入编辑模式,编辑好了之后,输入:wq 保存并退出。需要修改的内容如下(本处以邮箱域名为 example.com 为例):

Domain  example.com
KeyFile  /etc/opendkim/default.private
#记得前面说可以改的那个 default 吗?如果你改了,记得这里也要改成一样的
Selector  default
#注释掉下面这一行或者类似的内容(就是在开头加一个#号)
#Socket  inet:8892@localhost
#注释之后,在底下加上这一行
Socket  inet:8891@localhost
  • 修改/etc/default/opendkim
vi /etc/default/opendkim

修改和保存的方法同上,下面说要修改和添加的内容:

#找到下面这两条或者与之相似的内容,注释掉 SOCKET 这一行,也就是在前面加个#
# default:
#SOCKET=local:$RUNDIR/opendkim.sock
#另起一行,输入如下内容
SOCKET=inet:8891@localhost
  • 修改保存完成,重启 OpenDKIM
service opendkim restart

 

2.为 Sendmail 使用上 DKIM 签名(Postfix 用户请跳过此步)

  • 编辑/etc/mail/sendmail.mc,修改 Sendmail 配置
vi /etc/mail/sendmail.mc

编辑和保存方法请看上文。或者自行网上搜索和 vi 有关的命令。

  • 加入 OpenDKIM 的监听端口配置(如前面配置 OpenDKIM 端口时和本文的一样,直接插入无需任何更改)
#另起一行或者写在该文件的末尾都可以
INPUT_MAIL_FILTER(`opendkim', `S=inet:8891@localhost')
  • 退出编辑状态并保存,输入命令使配置更新
m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
  • 强迫症:重启 Sendmail
service sendmail restart

OK!Sendmail 加上 DKIM 签名到这里就大功告成了!

注:此处参考 Phil Bayfield 的博客文章《Setting up DKIM with Sendmail on Ubuntu 14.04

 

3.为 Postfix 用上 DKIM 签名(Sendmail 用户不需要)

  • 编辑/etc/postfix/main.cf
vi /etc/postfix/main.cf

编辑和保存方法请看上文。

  • 在/etc/postfix/main.cf 中另起一行插入如下内容(如前面配置 OpenDKIM 端口时和本文的一样,直接插入无需任何更改)
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
  • 保存退出,重启 Postfix
service postfix restart

注:该步参考教程来自 Debian WiKi:https://wiki.debian.org/opendkim

上面插入的内容具体含义,本人还没有去理解,但已测试可正常工作。

 

4.添加 DKIM 记录

这一步,也是要在域名注册商那里操作的。

  • 在有关域名 DNS 设置中,添加一条 TXT 记录,其中主机名称为 default._domainkey(这是 example.com为邮箱域名的情况,如果是 mail.example.com,则添加的主机名称为 default._domainkey.mail),这里注意一下,default 这个单词如果你在前面生成公钥私钥时改动过,要写改动之后的单词
  • 记得我们在第一步生成公钥和私钥时,为了存放他们而新建的文件夹/etc/opendkim 吗?进入到该目录,找到其中的 default.txt(/etc/opendkim/default.txt)并打开它,你将看到类似下面这样的内容:
default._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; t=y; " "p=XXXXXXXXXXXXXXXXXXXXX" ) ; ----- DKIM key default for example.com
  • 复制括号里的内容,并去除多余格式,最后你获得的内容应该是类似下面这样的:
v=DKIM1; h=sha256; k=rsa; t=y; p=XXXXXXXXXXXXXXXXXXXXX

注意!复制的时候一定要复制完整,并把多余的引号,换行符删除,不然可能造成 DKIM 记录无法正常读取!

  • 将处理好的内容,复制到前面创建的 TXT 记录的内容栏中,保存
  • TTL 请根据自己的选择填写,具体的解释可参考 MX 记录中关于 TTL 的说明
  • 如果因为复制之后的内容过多,TXT 的内容栏不允许填写的,可以生成 1024 位的公钥和私钥(本文不会涉及这个),但并不推荐这么做,最好还是和你的域名注册商反馈

 

5.检测 DKIM 信息是否存在问题

给大家推荐几个检查的网站,大家在配置好以上的内容后,可以检查下自己的 DKIM 记录。

注:下面几个网站,要你输入两项内容之后检测,一项是 Selector,一项是 Domain,Selector 如果你是按照教程走的,写 default,如果你前面改动过,写你改动之后的,Domain 写你的邮箱域名。

  1. 检查 DKIM 是否正确和 DKIM 类型:https://protodave.com/tools/dkim-key-checker
  2. DKIM,SPF 和 Spam 检测,配置好自己的邮箱之后,向它给出的邮箱地址发邮件,稍后可查看你发出的邮件的检测结果:http://dkimvalidator.com

 

七、全部完成,开始综合检测

按上面说的把全部步骤都做完之后,基本就配置得差不多了,现在我们开始进行两个测试:

  • 使用 https://www.mail-tester.com 测试现在自己的服务器发出的邮件得分
  • 尝试给 Gmail 等大型邮件服务商的地址发送邮件,看看是否被拦截下来或者被判定为垃圾邮件

如果第一个测试评分是 10/10,恭喜你,你算是成功了。再看看第二个测试中发出的邮件是否有正常的进入收件人的收件箱,能进入基本就没什么问题了,此时如果你查看邮件的详细信息,可能还会看到 SPF 认证通过和 DKIM 认证通过的信息。

 

八、本文引用或参考的一些教程的链接

SPF 记录:原理、语法及配置方法简介:https://www.renfei.org/blog/introduction-to-spf.html

添加 DMARC 记录:https://support.google.com/a/answer/2466563?hl=zh-Hans

Setting up DKIM with Sendmail on Ubuntu 14.04:https://philio.me/setting-up-dkim-with-sendmail-on-ubuntu-14-04

Debian WiKi:https://wiki.debian.org/opendkim

 

八、备注

  1. 考虑到 1024 位的 DKIM 公钥私钥认证可能会有安全风险,所以本文没有说明怎么生成,TXT 记录写不下 2048 位产生的记录的,建议联系域名注册商解决
  2. 本文只考虑了单域名的情况,多域名发邮件不在本文讨论范围
  3. 只涉及到了和发件相关的一些配置,对于服务器的收件箱邮件过滤,防骚扰之类的本文暂不涉及
  4. 好累,希望能帮到大家_(:3」∠)_

12点半

Hello world!

文章评论(6)

  • Sam

    博主你好,如果服务器上两个域名发邮件,应该怎么设置呢?

    2018年4月27日
    • 12点半

      @Sam 没太理解,具体说的是什么情况呢?

      2018年4月27日
      • Sam

        @12点半 用postfixadmin+roundcube设置了两个域名(abc.com和abb.com)作为邮件服务器 同时进行发信,是不是反向解析只能做一个域名的,另外DKIM也只能做一个域名的

        2018年4月27日
        • 12点半

          @Sam 应该都没什么问题的,只是再加一条记录而已。DKIM 的话,不仅在域名那边要加好记录,可能还需要再编辑下它的几个配置文件,加上对应的域名和私钥路径之类的。

          2018年4月27日
          • Sam

            @12点半 谢谢,我去试试

            2018年4月27日
        • 12点半

          @Sam 抱歉,是我想当然了。我搜了下反向解析的有关解答,似乎是不推荐一个 IP 绑定多个域名这种情况来着,从我自己的服务器设置来看,也是单个 IP 只允许添加一条这样的情况。

          2018年4月28日