给hmailserver添加DKIM签名

时间: 2010-11-19 / 分类: 邮件服务器 / 浏览次数: 20,404 / 41个评论 发表评论

上一篇说了hmailserver如何设置反垃圾邮件功能,现在来说说如何让自己的hmailserver发出去的邮件不要被别人反垃圾了。
hmailserver的反垃圾邮件功能中有提到给垃圾评分标准,其中比较主要的四个,SPF、HELO、DNS MX、DKIM签名,看hmailserver默认的分值,无疑DKIM签名是最高的,如果校验DKIM失败,直接会当作垃圾邮件的。无疑,如果对方的邮件服务器启用了这几个校验,如果你发出去的邮件未通过,就会被当作垃圾邮件了,我试了一下,都没有设置,发往gmail的邮件直接发送失败,发往腾讯企业邮箱的邮件还收到了。

那如何让这些校验通过呢?首先你最好得有一个固定IP,这样才好设置SPF,需要给你的域名添加一个txt记录,里面包含你邮件服务器的IP。可以用nslookup来查询一下qq.com的txt记录,那就是SPF了,关于SPF的介绍,可以查看http://baike.baidu.com/view/1372988.htm来了解一下。HELO这是直接在hmailserver的Settings-Protocols-SMTP-Delivery of e-mail中的local host name中填写。MX记录解析,这个在域名中添加mx记录即可,最后就到了DKIM签名。
DKIM的全称是Domain Key Identified Mail,域名密钥识别邮件,就是邮件服务器对自己发的邮件签名,表示这个邮件是自己发出去的,如果一个对方邮件服务器能够验证这个签名,就表明这个邮件可能不是垃圾邮件,因为垃圾邮件一般都会伪造地址发送的。那岂不是那些垃圾邮件发送者只要给垃圾邮件也每个签名也能表示它发送的不是垃圾邮件?接收邮件服务器如何能辨别这个签名真假?那发送邮件服务器跟接收邮件服务之间有个约定,呃,你记好了,我的签名是如何如何防伪的,这就是基于私钥与公钥的签名。
发送方基于私钥给邮件DKIM签名,接收方根据发送方的公钥来验证这个DKIM签名,很明显,私钥是给发送邮件服务器来使用的,那公钥如何传输呢?不多说了,了解一下就行了,下面是网上的介绍。

一些签名的具体细节:
1、算法,必须支持rsa-sha256,可选支持rsa-sha1。key size建议1024。
标准化(Canonicalization). 有的邮件服务器可能会少量修改文件内容,比如换行或者移除一些空格等等。因此DKIM定义了两种2、标准化方法,simple和relaxed。simple最简单,就是一个字节也不能改,改了就错。relaxed就是可以少量的修改一些空格等等。邮件头和内容这两部分的标准化可以选择不同的方法,表示起来用/隔开,比如simple/relaxed表示头部用simple方式,内容用relaxed方式来标准化。
3、过程,签名是先对内容(body)部分hash,然后把这个body hash放在header里面,再对头部做签名。头部也不是所有字段都签名的,只有一些常用的字段,或者比较有意义的,会被签名。像Received和Return-Path这样的字段一般不被签名。而From则必须被签名。

下面我们来给hmailserver加上DKIM签名,工欲善其事,必先利其器,咱们得把器准备好,hmailserver这个主角可不能少,当然,用其他的邮件服务器也可以参考一下。
Openssl,我们要用它来生成私钥与公钥,在这里下载openssl的windows版本,根据需求吧,64位系统就下64位的,我这里下的是Win32 OpenSSL v1.0.0a,安装这个得先安装Visual C++ 2008 Redistributables,呃,中文windows就下中文的,英文就下英文的,别搞得装不上重下,装好openssl咱就来生成密钥吧。
详情可以参考一下这篇文章
http://www.elandsys.com/resources/sendmail/dkim.html
默认openssl安装在C:\OpenSSL-Win32,按照下面命令生成

cd C:\OpenSSL-Win32\bin
openssl.exe genrsa -out rsa.private 1024 //生成私钥
openssl.exe rsa -in rsa.private -out rsa.public -pubout -outform PEM //生成公钥

然后会看到bin目录下多了两个文件rsa.private与rsa.public,先把私钥rsa.private移到hmailserver的安装目录去,然后用记事本打开rsa.public,里面有一串base64编码的字符串,掏出来,然后到域名解析的控制面板去添加一个txt记录,名称为hmail._domainkey(hmail这个可自定义,后面的_domainkey是必需的),记录值为k=rsa; t=y; p=base64,这个p=后面的base64换成rsa.public里面的那串字符串,t=y表示测试模式,告诉接收服务器忽略DKIM签名,可以去掉,也可以加个v=DKIM1来说明版本,添加完txt记录,可以用以下命令来查看一下是否生效了

nslookup
set type=txt
hmail._domainkey.domain.com //domain.com替换为你的域名

如果看到像下面的结果就表示生效了

非权威应答:
s0907._domainkey.qq.com text =

“k=rsa; t=y; p=MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhAJJepXlnnJe5bFumOeyG8v2W8
LFpudv3kOkV3eMapHGkl1TU6hgVCyNSOJgYgQkvozdZRJ5b9d7FJsrEhHbeR+klTcLYCe1u1HP7HbxdU
fDU34szV/Tc0rE125WENSGXlwIDAQAB”

这里公钥就设置完成,然后在hmailserver邮件服务器中设置私钥。
打开到Domains-你的域名-DKIM signing,选上Enabled激活DKIM签名先,
Private key file就选择之前移到hmailserver目录的rsa.private文件,
Selector里填入hmail,这个要跟添加txt记录时_domainkey前面的值一致。
Header method与Body method都选择Relaxed,前面说了Simple比较严格一些,如果你添加的记录里面多或少了一个空格,那就通不过了。
Signing algorithm,签名算法,SHA1肯定是赶不上SHA256安全,不过SHA256加密时占用CPU资源会高一些,根据你自己的需求选吧。
设置完成,当然得Save一下,然后发个邮件给gmail试试,呃,为啥选gmail呢,因为gmail比较好看,比较好看原始邮件,可以在里面查找到dkim=pass字样,还有dkim-signature后面的签名,OK,成功了,DKIM签名就说到这里,费了一中午时间。
并不是说你做到了这样你的邮件就不会被判为垃圾邮件了,只是少了许多可能罢了,还有方方面面的原因,比如你的ip在rbl里之类的,不在赘述。

最后还是补充一点关于SPF记录的设置吧,让你的邮件通过SPF验证,哪怕你是动态IP,也一样过
参考:http://www.linuxfocus.org/ChineseGB/December2004/article354.shtml
SPF 记录包含在一个 TXT 记录之中,格式如下:v=spf1 [[pre] type [ext] ] … [mod]
最常见的就是v=spf1 ip4:xxx.xxx.xxx.xxx ~all,还有v=spf1 include:sub.domain.com ~all,实际上一样的。
参数描述
v=spf1,SPF 的版本,如果使用 Sender ID 的话,这个字段就应该是 v=spf2
ip4:xxx.xxx.xxx.xxx或include:sub.domain.com,include:包含一个给定的域名的测试,include:domain 的形式书写。
ip4:使用 IPv4 进行验证,这个可以以 ip4:ipv4 或 ip4:ipv4/cidr 的形式使用。建议使用这个参数,以减少域名服务器的负荷。
还有几个可选参数:
ip6:使用 IPv6 进行验证
a:使用一个域名进行验证,这将引起对域名服务器进行一次A记录查询,可以按照a:domain, a:domain/cidr a/cidr 的形式来使用。
mx:使用DNS MX记录进行验证,MX记录定义了收信的MTA,这可能和发信的MTA是不同的,这种情况基于mx的测试将会失败,可以用mx:domain, mx:domain/cidr或mx/cidr这些形式进行mx验证。
ptr:使用域名服务器的PTR记录进行验证,这时,SPF使用PTR记录和反向图进行查询。如果返回的主机名位于同一个域名之内,就验证通过了,这个参数的写法是ptr:domain
exist:验证域名的存在性,可以写成exist:domain的形式。
另外可用ext对上面的几个参数进行的扩展,如果没有这个字段,那么仅使用单个记录进行问询。
看了上面的几个应该明白了吧,既然我动态IP没法用IP地址来验证,我可以验证mx、验证域名是否存在,这样就可以了,于是老夫发到gmail的邮件,里面就会显示已经通过了。
信息如下:

Return-Path:
Received: from mail.osmail.cn ([121.35.164.244])
by mx.google.com with SMTP id o2si8011332ybn.89.2010.11.18.23.51.54;
Thu, 18 Nov 2010 23:51:55 -0800 (PST)
Received-SPF: pass (google.com: domain of admin@osmail.cn designates 121.35.164.244 as permitted sender) client-ip=121.35.164.244;
Authentication-Results: mx.google.com; spf=pass (google.com: domain of admin@osmail.cn designates 121.35.164.244 as permitted sender) smtp.mail=admin@osmail.cn; dkim=pass (test mode) header.i=@osmail.cn
dkim-signature: v=1; a=rsa-sha256; d=osmail.cn; s=hmail;
c=relaxed/relaxed; q=dns/txt; h=From:Subject:Date:Message-ID:To:MIME-Version:Content-Type;
bh=KJqaSfBaD5OTEAwPyYjfJB0AduS/gOcD2VRqIXQZ69k=;
b=dMePUGCBJVvJNuATpLIEH8XaL5IeWHufhDYf4nCpWd0MvLt3DtfRCNsuyA413wsGoaSZJ/OXxXU0GdJ/eEhgyvLE7/G+i4bkllbjjQIn0KE4Z4owTUlz6ZgeczpHXP0IkMC+NljU7oH1sHUQ0T78z2aAwX7yFhjt/SSTmPuwtVk=

41个评论

  1. 大概是个博客
    2013/10/21 09:45:34

    @Milllion.Zhang,IP被列入黑名单了,网易能成功gmail不能成功说明两者网易没用这个黑名单而gmail用了

  2. 大概是个博客
    2013/10/21 09:43:32

    @张誉曦,我可没对你有啥厚恩,都是你自己想办法解决的

  3. Million.Zhang
    2013/10/17 15:26:09

    楼主你好,我按照你写的步骤一个个做下去,最后给网易邮箱发送邮件是成功的,邮件头里面也有m; dkim=pass header.i=的信息,但给gmail发信还是不成功,返回诸如此类的信息:
    RECEIVED: 550-5.7.1 users from spam, mail sent from your IP address has been blocked.
    RECEIVED: 550 5.7.1 our Bulk Email Senders Guidelines. gu5si13225098pac.14 – gsmtp
    楼主能否指点一二?
    我除了设置 private key and public key on hmailserver,还加上了txt记录和
    SPF记录:
    v=spf1 include:mail.mbrcctv.com -all
    hmail._domainkey k=rsa; t=y; p=code..

  4. 张誉曦
    2013/09/17 20:32:43

    你写的文章就是有含金量!!!

  5. 大概是个博客
    2013/01/04 17:09:23

    找不到可能是因为域名还没生效吧,动态域名发送外部邮件这个问题基本无解,设置DKIM会稍微好点,国内一般问题不是很大,国外的就不好说了,中继服务我也不太清楚,一般就用的普通企业邮箱,不过也是很麻烦,每个用户得对应建立个邮箱,因为很多邮箱收邮件时会验证邮件来路,如果发件人与中继发件账号不一致也会被挡掉的。

  6. dkim
    2013/01/04 16:09:49

    还有大概老师,我当前是要解决花生壳+hmail搭建的邮件服务器,可以收到外部邮件但是不能发送外部邮件的问题,设置这个dkim签名有用吗

    如果需要购买中继服务,有什么服务商推荐参考呢

  7. dkim
    2013/01/04 15:54:03

    太感谢您了,用这个方法生成成功了,我添加了txt记录,但是测试后得到的结果是can‘t find….Non-existent domain

    txt记录的格式应该是这样的吗

    hmail._domainkey k=rsa; t=y; p=base64

    hmail是我自定义的

    base64是我得到的公钥字符串

  8. 大概是个博客
    2013/01/04 13:57:10

    那就奇怪了,换个方式试试看,看这里的http://dagai.net/archives/1002

  9. dkim
    2013/01/04 11:40:35

    生成私钥和公钥的命令都做了 openssl.exe rsa -in rsa.private -out rsa.public -pubout -outform PEM //生成公钥

    就是这一步 做完去查看公钥文件没有

  10. 大概是个博客
    2013/01/03 13:29:08

    其中有一步是以私钥生成公钥的,你没做吧

  11. DKIM
    2013/01/02 22:18:00

    求教 ,DKIM生成只生成了私钥,没有公钥文件是什么原因呢

  12. 大概是个博客
    2013/01/01 19:47:46

    没有设置DKIM吧

  13. jSf
    2012/12/31 17:50:15

    ; dkim=pass (test mode) header.i=@163.com
    163发到gmail的有上面这个,自己建的就没有,其它都正常。。为什么。。。

  14. […] 之前讲过如何给hmailserver添加DKIM签名,需要一堆软件,写了一大堆步骤,能不能简单一点?很好,有老外给咱们准备好了一体包。先下载这个软件包ftp://ftp.handymail.ch/pub/hmailserver/hMailServer_SSL_0_9_8j.zip,里面已经给我们准备好了必需的VC2008库和官方的OpenSSL,还有两个批处理和一个小软件。 […]

  15. 大概是个博客
    2012/08/14 09:53:10

    跟t=y没关系,这个只是测试开关,测试好了去掉就行了

  16. 147zhangzhe
    2012/08/13 09:52:20

    不过问题解决了最终 谢谢你的文章哈 帮助和启发很大

  17. 147zhangzhe
    2012/08/13 09:51:32

    哎 现在我也不能确定是延迟的问题 还是因为我多写了个 t=y;

  18. 大概是个博客
    2012/08/10 09:53:32

    yahoo的接收服务器没有检测到DKIM的信息存在,也许是yahoo邮件服务DNS的延迟吧

  19. 147zhangzhe
    2012/08/09 11:04:29

    请您帮我看下我的DKIM哪里写的不对 总是通不过gmail,sina,yahoo的dkim验证
    但是在DKIM DNS CHECKER http://dkimcore.org/c/keycheck 里显示是正确的

    这是我的DKIM
    ———————分割线——————————–

    C:\Users\Administrator>nslookup
    DNS request timed out.
    timeout was 2 seconds.
    默认服务器: UnKnown
    Address: 192.168.1.1

    > set q=txt
    > dk._domainkey.domain.com
    服务器: UnKnown
    Address: 192.168.1.1

    非权威应答:
    dk._domainkey.domain.com text =

    “v=DKIM1;k=rsa;t=y;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKBW5/JHI+TgHxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxRYVHewzsgPqohp0tRkovpSFLUXnZqTsWF0PAnD9SYYU8H41MCAlDYNmLHaWVUvtikM9yMTjtW6ETg7AhcKWrH/Wl89OX1eprwIDAQAB”

    >

    ———————分割线——————————–
    这是yahoo看到的邮件头
    ———————分割线——————————–

    From admin@domain.com Thu Aug 9 10:38:31 2012
    X-Apparently-To: totola147@yahoo.cn via 203.209.250.177; Wed, 08 Aug 2012 19:38:46 -0700
    Return-Path:
    Received-SPF: pass (domain of domain.com designates xx.xx.xx.xx as permitted sender)
    X-YMailISG: DIIlh9sWLDs.ZW7RKHjmwPqg8WTg1w5qEpBoVKjVyaOWlilM
    io3iPtxlmdzHRn8k.Ywzx0nzuq2VxAxr3AX2ycnErGRcuOjOOTcLK1Q7Q9a8
    BwKdv.3SXu.bxkJk4FE1naFUPU1pzxcZYurgB115zoXR3tZskLMvYh8ecrld
    vY8n.NO3Xl7YtbNufLGKv8WGldAGnpXdkPzbTeh6lQp.48C70X9H8zWwL47f
    IdpzreQY0hY5DiaORzS48JojntFlFCVzGFFjdNfY.ghdntA2RC.MFI_Gn08l
    3TwzPn5_RJHVeWl.f6lj2wGvcEY6ur0yHQ7BoGcaGqLCosGVGKS4Mcu6Dey8
    cpxJ5gu3JUxZBvEDMjclu02OG3gW4a36N11FGMYpMktg6vz0IO6fbehIO_XD
    uA_MrqBLNHm8Sj.eHWUt1wYYX9raa1E-
    X-Originating-IP: [xx.xx.xx.xx]
    Authentication-Results: mta1006.mail.cnh.yahoo.com from=domain.com; domainkeys=neutral (no sig); from=domain.com; dkim=neutral (no sig)
    Received: from 127.0.0.1 (HELO localhost) (xx.xx.xx.xx)
    by mta1006.mail.cnh.yahoo.com with SMTP; Wed, 08 Aug 2012 19:38:46 -0700
    Received: from domain.com ([127.0.0.1])
    by localhost
    ; Thu, 9 Aug 2012 10:38:31 +0800
    MIME-Version: 1.0
    X-Mailer: AfterLogic WebMail PHP
    X-Originating-IP: xx.xx.xx.xx
    X-Priority: 3 (Normal)
    Message-ID:
    From: admin@domain.com
    To: totola147@yahoo.cn
    Subject: 147
    Date: Thu, 9 Aug 2012 02:38:31 +0000 (UTC)
    Content-Length: 3

    谢谢您了

  20. wow
    2011/08/27 09:39:25

    能加我QQ吗 331911080
    签名和反垃圾那块不是很明白!

  21. Dagai
    2011/08/27 08:51:59

    就是你做域名解析的地方

  22. wow
    2011/08/26 23:22:44

    然后到域名解析的控制面板去添加一个txt记录,名称为hmail._domainkey(hmail这个可自定义,后面的_domainkey是必需的)

    这里的“域名解析的控制面板”什么意思?

  23. 大概是个博客
    2011/06/15 10:25:12

    @小白
    你了解一下dns.he.net或www.dnspod.cn,你可以把万网域名的NS服务器改到这些免费dns的ns服务器上,然后再在这些服务商提供的面板上解析就行了,我一般用dnspod比较多

  24. 小白
    2011/06/14 23:34:34

    如果没看到这边文章,是百度里面找到唯一一篇关于邮件方面有价值的文章,不过我用的万网的域名增加不了hmail._domainkey,万网如果用的别的dns将不能解析,用自己dns增加不上,如果在花生壳上操作有需要增加70元支出,请教这个问题该怎么解决?

  25. Dagai
    2011/02/12 17:59:31

    这个按照官方的文档是说Delivery attempts – 1 the first time the message is delivered, 2 ond the second attempt and so on.我看不太明白这个意思。
    那个路由虽然添加了,默认似乎邮件不会自动去走,还要符合规则才会处理,所以要添加规则才行。

  26. Sevi
    2011/01/31 00:41:03

    另外关于hMailServer路由原理,我还是很模糊,还请多多指教!!
    假如我添加新路由:Domain处填xxx.net,然后依次填好主机、端口以及授权信息,最后确定。
    之后发出的任何信件都会透过新路由进行传递?还是当发件人/收件人域部分匹配xxx.net时才会用路由传递信件?

  27. Sevi
    2011/01/31 00:19:02

    测试失败!!
    感觉Delivery attempts不起任何作用,或者说程序根本不会去判断Delivery attempts…
    因为Delivery attempts无论设置大于/等于任意整数,条件好像都不会成立的。

  28. Dagai
    2011/01/27 08:48:58

    这个倒没有试过,你可以尝试一下,先添加一条路由,把外部的smtp中继添加进去,然后加一条规则,规则随便命个名,然后激活,在Criteria里点add,选Predefined field里的Delivery attempts,search type选equals或greater than,value给个值1或者2,actions添加一个send using route,to当然就选你添加的那条路由了。
    规则的意思就是当投递尝试次数等于或者大于1到2次时,就使用中继去投递。
    我就懒的测试了,你测试结果告诉我一下,谢谢

  29. Sevi
    2011/01/26 11:08:09

    不是!
    比如说客户端使用hMailServer的SMTP往xxxxx@sina.com发邮件时,如果本地SMTP发送失败,hMailServer就用外部SMTP(中继)再向xxxxx@sina.com发送邮件…

  30. Dagai
    2011/01/26 09:52:45

    你的意思是在中继服务器有这个帐号,但本地服务器没有这个帐号,当发往的这个帐号本地没有就自动通过中继服务器发?

  31. Sevi
    2011/01/26 01:28:45

    您好!
    请教一个问题,使用hMailServer发邮件时,如何设成当本地发送失败时,自动使用中继重试…

  32. Dagai
    2011/01/22 12:48:29

    动态IP还是不要绑的好,不然会折腾死人的

  33. Sevi
    2011/01/20 12:13:25

    没错!

    设置 TXT 记录:v=spf1 a:domain ~all
    流程:
    首先查询domain的A,如果domain不是直接绑定动态IP(没有A记录),就会查询domain所对应的CNAME。

    不过个人认为,如果条件允许,建议domain直接绑定动态IP。

  34. Dagai
    2011/01/13 11:21:22

    在顶上那个关于里面有我的联系抠抠和GTALK

  35. teddy
    2011/01/12 23:57:54

    大概 能给个QQ号码或者手机吗?我研究hmailserver遇到难题了,怎么实现hmailserver收发外网邮件啊。。。急急急!!!313881051是我的QQ号码,希望得到你的指点!

  36. 大概是个博客
    2011/01/03 08:49:43

    噢,那是我错了,原来查询a记录如果没有a记录会自动查询cname,谢谢指出

  37. Sevi
    2010/12/31 20:00:12

    测试通过!动态IP验证a:可行!!

    TXT 记录:
    v=spf1 a:XXXX.net.cn ~all

    Gmail 原文片段:
    Delivered-To: sys@gmail.com
    Received: by 10.229.80.198 with SMTP id u6cs384644qck;
    Fri, 31 Dec 2010 03:42:46 -0800 (PST)
    Return-Path:
    Received: from XXXX.net.cn ([113.74.6.210])
    by mx.google.com with SMTP id n40si35091876wfa.108.2010.12.31.03.42.42;
    Fri, 31 Dec 2010 03:42:44 -0800 (PST)
    Received-SPF: pass (google.com: domain of sys@XXXX.net.cn designates 113.74.6.210 as permitted sender) client-ip=113.74.6.210;
    Authentication-Results: mx.google.com; spf=pass (google.com: domain of sys@XXXX.net.cn designates 113.74.6.210 as permitted sender) smtp.mail=sys@XXXX.net.cn; dkim=neutral (bad format) header.i=@XXXX.net.cn
    … …

    113.74.6.210 -> 动态IP

  38. Dagai
    2010/12/31 13:26:09

    我觉得应该不行吧,既然验证A记录,你域名绑动态IP怎么绑?一般都用cname绑的,所以A记录没有的,除非,你用花生壳的付费版估计可以。

  39. Sevi
    2010/12/31 12:52:44

    动态IP应该可以验证a,例如:a:domain, a:domain/cidr,而这里的domain绑定动态IP。

  40. Dagai
    2010/12/17 14:35:29

    不太明白你的意思

  41. lala
    2010/12/17 14:01:54

    这个首先要做反向解析和DNS服务器上的TXT记录吗?

发表评论

您的昵称 *

您的邮箱 *

您的网站