Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2503798
  • 博文数量: 540
  • 博客积分: 11289
  • 博客等级: 上将
  • 技术积分: 6160
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-11 20:27
个人简介

潜龙勿用,见龙在田

文章分类

全部博文(540)

文章存档

2018年(2)

2013年(5)

2012年(24)

2011年(104)

2010年(60)

2009年(217)

2008年(128)

分类:

2009-01-07 14:37:16

 postfix传输层安全协议(TLS)

从SSL演变而来的“传输层安全协议”,能以加密技术来保障TCP通信的私密性(信息不外泄)与完整性(能侦测数据在传输过程中是否遭到篡改)。RFC 3207为smtp指定了一种称为starttls的扩充机制,其主要用途在于保障点对点通信的私密性,也能确保你的邮件不互被送错地方,比方说,避免邮 件被投递到伪装成收信地地非法系统。另一种有用地应用是与sasl结合,避免plain密码以明文形式流经网络。
TLS令人赞赏地优点之一,在于 两系统之间不必经过事先安排,就可以获得可靠地身份标识与私密性地保证,甚至连“强效验证”也是可以办到地--如果用户地 mua支持地话。借由客户端证书,邮件服务器可确信联机进来地客户端确实是对方自己所宣称地身份。“客户端证书”是一种以密码技术签名地标识符,可用来取 代或搭配sasl验证,但是需要额外地控制管理工作,因为你得要为每一个客户端产生专用得证书,并且将这些证书“逐一”安装在每个客户端。不过,如果你只 要利用TLS来加密验证数据,那倒是相当容易设定。
有个很重要得概念一定要谨记在心:TLS不是用来保护邮件内容。当client与server 双方以TLS进行通信时,所有东西(包括邮件本身)确实是被编码成密文形式,然而,TLS能保护得也仅仅于两系统间得通信。服务器收下了邮件之后,仍可能 以明文形式存储,当服务器要将邮件送递到下一站,或是收件人从服务器下载邮件时,邮件内容仍可能以明文形式流经网络。换言之,除非你能确定从出发点到终点 站之间得全程都受到加密保护,否则,就不能保护完全没有泄密得可能。要达成点对点得私密性,你需要客户端得解决方案,像是PGP或S/MIME。

postfix与tls

postfix对于tls得支持,由lutz janicke所写得一组修补文件提供。从postfix主页得add-on software链接处可以取得这组修补文件。如果你使用平台随附得预编译版postfix包,请确定该版本确实包含tls patch。
除 了postfix本身要支持tls之外,你还必须制作、设定tls证书。你需要一个公钥(public key)与一个私钥(private key)。公钥是代表服务器身份得证书,你必须向具有一定信誉得认证中心(certificate authority,ca)提出申请,他们依据你得申请书向你求证之后,会以他们自己得数字签名签署一个公钥给你,只要客户端愿意相信ca得签名,就等于 间接相信ca核发得公钥所证明得系统--你得服务器。除了你自己的证书外,你还必须取得ca的公钥(核发证书给你的那一家ca)。
对电子交易而 言,让买方能够证明卖方身份是很重要的。因此,网络交易商确实有必要花钱取得ca的签名。然而,就保密通信而言,服务器公钥是否来自有公信力的ca,并不 是绝对必要的事,这表示你可以自己扮演ca的角色,自己核发证书给自己。当客户端mua连接到你的tls server时,如果不认识你使用的ca证书,mua通常会提供一个机会给用户,让用户自己决定要不要相信这个ca以及是否将ca的证书纳入认同名单中。

tls证书
postfix tls patch需要用到openssl函数库。openssl包随附了一组管理证书的命令行工具,你可用这些工具来制作证书。就postfix而言,所有证书 都必须是pem格式。openssl工具的默认输出格式刚好就是pem,所以不用任何转换就可产生postfix可用的证书。openssl工具的默认安 装目录位于/usr/local/ssl,管理证书所需的命令行工具是openssl。

自己开设认证中心
服务器端证书必须要经过ca的签署才有效。你可以付费请有公信力的ca为你签署,不过,就保密用途而言,你并不需要花这笔钱。openssl包提供了一个脚本,让你可以自己开设ca,自己签署自己的证书。在openssl的安装目录下,键入下列命令:
       misc/ca.pl -newca
然后回答所有问题,完成之后,它会在./democa/目录下产生开设ca所需的全部文件,其中包括可用来签署证书的“ca数字签名”(又称为“根证书”)

tls证书概述
tls 使用公钥加密技术,让client/server之间能够进行私密通信。此外,tls能保证没有人能够在传输中途篡改信息,或是冒名伪装成某一方,因为协 议本身容许通信双方相互验证彼此的身份。然而,再次提醒tls的好处仅限于tls联机两端,至于数据在传输之前发生过什么事,以及在传输到目的地之后会被 怎样处理,tls都无法保证。
公钥加密技术的原理,是运用一对互补的key,其中一个可以公开给众人知道,称为“公钥”;而另ygie key则只能由个人拥有,决不可泄漏,所以称为“私钥”或“密钥”。公钥加密的数据,只可由私钥予以解密,反之亦然。利用这种特性,公钥可用来让别人传输 私密数据给你,而你可用私钥来证明自己的身份。当别人要传递机密数据给你时,对方可使用你事先提供的公钥来加密数据,由于只能用你自己的私钥予以解密,所 以不怕机密数据泄漏(除非你泄露自己的私钥)。私钥又如何用来证明自己的身份?你可用自己的私钥加密一份数据(这动作称为“签名”),如果对方能用你的公 钥解开,表示数据一定来自于你,不可能是别人(除非你把自己的密钥泄露给别人)。因此,你的密钥可视为你个人的数字签名。一般而言,你应该尽可能将公钥散 布出去,而密钥则必须不及一切代价予以保护。
当你收到别人的公钥时,你如何能够相信,公钥的拥有者确实是对方所宣称的那个人?实际上,公钥散布 时,往往会同时散布一个代表公钥拥有者的标识符--通常是服务器的主机名称。收到公钥的一方,可通过比对此标识符是否与dns查出的主机名称吻合,借此确 认公钥的拥有者确实是当前的联机对象。
有ca数字签名,称为证书。ca通常是交易双方都信任的第三方组织。理论上,有ca的证明,表示公钥拥有者 的身份已经被ca调查并予以证实,取得公钥的人,可以相信该公钥确实属于其宣称的拥有者。换言之,证书的授信基础来自于你对ca的信任。值得注意的是, ca只担保证书拥有者的身份,而不是担保其信用。
在加密通信的过程中,公私钥仅用于联机初期,让双方互相确定对方的身份,并协商出一个随机产生的 session key,实质的通信内容,其实是由这个session key来加密与解密。一个session key只用於一次通信,在通信完毕之后,session key就可以丢掉了。
让我们看看client与server之间是如何进行秘密通信的。首先,client联机到server,并提出秘密通信要求。对于web server,client使用https命令;对于smtp server,client发出starttls命令。
如 果server同意请求,便会返回一个由ca签署的证书,其中含有ca的数字签名以及一个代表server的标识符。client检验server的标识 符是否符合预期,并检查该ca的数字签名是否在认同名单中。如果两项检查都过关,client与server双方便开始展开session key协商,决定后续通信内容要使用哪一种加密算法,并产生一个只用於该次通信的session key。接着,双方便使用协议出来的session key与算法进行秘密通信。

产生服务器端证书
产生服务器端证书的第一步,是使用openssl工具为服务器产生一对公钥与私钥, 然后产生一个“证书签署请求”(certificate signing request, csr),并将csr与公钥交给ca签署。经过ca签署的公钥证书可以广泛散布出去,但是私钥则必须被谨慎保管。事实上,有许多应用系统将私钥加密封存在 一个特殊文件,在访问私钥之前,必须先提供密码(passphrase)才能解密,这种储存私钥的方法称为“密封”。然而,postfix需要能够直接访 问私钥,不能使用密封方法,因为访问私钥的动作发生在运行时,而此时你不可能实时提供密码。
openssl包提供一组脚本可帮助你产生公私钥与csr,不过,它们所产生的key是“密封”的,所以,你得直接使用openssl命令来产生公私钥:
       openssl req -new -nodes -keyout mailken.pem -out mailreq.pem -days 365
openssl得-new选项表示你想产生公私钥与csr,-nodes选项表示不加密,-keyout和-out分别指出私钥文件与csr文件得名称。最后,-days 365指出证书得有效期限是一年。
如果你使用第三方ca,请按照ca得指示,提出你得csr来要求他们签署。如果你自己扮演ca得角色,你可用下列命令来核发证书:
          openssl ca -out mail_signed_cert.pem -lnfiles mailreq.pem
此步骤所产生得mail_signed_cert.pem文件,就是ca所核发得证书。
你可能会想要将postfix/tls用到得所有证书文件复制到一个方便得位置。假设你完全依照上述得步骤,则请用下列命令将证书文件复制到postfix的配置目录下:
   cp /usr/local/ssl/mailkey.pem  /etc/postfix
   cp /usr/local/ssl/mail_signet_cert.pem /etc/postfix
mailkey.pem文件存有服务器的密钥,mail_signed_cert.pem是ca签署的公开证书。由于postfix不能使用密封的私钥文件,所以你应该以最严格的权限模式来保护私钥文件:
       chown root /etc/postfix/mailkey.pem
       chmod 400 /etc/postfix/mailkey.pem
上述命令将私钥文件的拥有权判给root账户,而且只有root能够读取。

安装ca证书
postfix/tls server必须要能够访问ca的公开证书(也就是所谓的“根证书”),包括为你的服务器签名的那一个ca以及核发证书给你的用户的每一个ca。当然,如果双方使用同一个ca,则只需要安装一个根证书就够了。
如果你的服务器端证书是自己签发给自己的,请将先前的ca.pl脚本所产生的cacert.pem文件复制到postfix的配置目录:
       cp /usr/local/ssl/democa/cacert.pem /etc/postfix
如果你的服务器或任何客户端的证书是第三方ca所签发的,你必须设法取得这些ca的根证书(pem格式);对于你不信任的ca,自然没必要取得他们的根证书。请将搜集到的所有根证书集中在/etc/postfix/cacert.pem文件里。
有 两种方法可将新的ca根证书安装到postfix/tls系统。第一种办法是将所有根证书集中在一个文件,并将smtpd_tls_cafile参数指向 此文件。你只需将新的根证书附加在现有文件末端即可。比方说,若原有的ca根证书是存储在/etc/postfix/cacert.pem文件中,而新 ca的根证书是存放在newca.pem文件中,那么,下列命令可将新的根证书纳入认同名单:
       cp /etc/postfix/cacert.pem /etc/postfix/cacert.pem.old
       cat newca.pem >> /etc/postfix/cacert.pem
另一种方法是将每个ca的根证书全部集中一个专用目录下的个别文件里,并将smtpd_tls_capath参数指向此目录。以后,每当需要安装新的ca根证书时,只要将新的证书文件存放在此目录下,然后执行一次openssl的c_rehash命令即可。
当你有许多ca根证书要处理时,这种方法可让维护工作稍微轻松些;不过,如果你的postfix是在chroot环境下运行,则还需要将新的根证书文件复制到chroot环境下的对应目录,然后运行postfix reload,新证书才会有效。

设定postfix/tls
postfix tls patch引进了一组关于tls运作环境的参数。本小节只列出基本配置所需的关键参数,至于完整的tls参数说明,请参阅tls patch随附的配置文件样本。
smtpd_use_tls
    启动tls支持。如果没有设定此参数或是设定成no,postfix的运行方式就像没有tls patch一样。例如:
       smtpd_use_tls = yes
smtpd_tls_key_file
       指向服务器私钥文件。例如:
          smtpd_tls-key_file = /etc/postfix/mailkey.pem
smtpd_tls_cert_file
       指向服务器的pem证书文件(必须经过ca签署)。例如:
       smtpd_tls_cert_file = /etc/postfix/mail_signed_cert.pem
smtpd_tls_cafile
       指向ca根证书文件。该文件含有所有你愿意信任的ca的公开证书。例如:
          smtpd_tls_cafile = /etc/postfix/cacert.pem
smtpd_tls_capath
       指向ca根证书文件目录。该目录下的每个pem文件,都含有一个你信任的ca公开证书。例如:
          smtpd_tls_capath = /etc/postfix/certs
将上述参数设定到main.cf配置文件,并运行postfix reload之后,你的postfix/tls server将具备秘密通信的能力,并准备迎接客户端的starttls命令。

postfix/tls的设定过程整理
总结前述的基本知识,在postfix系统上设定tls的大致过程如下:
1、安装openssl包,因为我们需要使用该软件包来产生tls证书。
2、使用tls patch,并重新编译、安装postfix。
3、产生一份服务器端证书以及一个证书签署请求(csr)。然后将两者一并提交给有一定信誉的ca请求签署;或是自己扮演ca的角色,自己核发证书给自己。
4、将所有证书文件(服务器的密钥、csr、ca的根证书)安装在postfix目录下。
5、编辑main.cf,设定下列tls参数:
    smtpd_use_tls = yes
    smtpd_tls_key-file = /etc/postfix/mailkey.pem
    smtpd_tls_cert_file = /etc/postfix/mail_sigend_cert.pem
    smtpd_tls_cafile = /etc/postfix/cacert.pem
如果还需要设定其他tls参数,现在正是时候。
6、重新加载postfix,使我们在main.cf所做的改变生效。
现在,每当有客户端要求秘密通信,postfix/tls server都能适当应对。

取得客户端证书
你可能会想要使用客户端证书来代替或加强其他smtp验证技术。客户端证书是非常可靠的验证方法,因为其非常难以假造。
客户端证书必须由ca核发。如果你打算选择一个ca来核发证书给你的用户,你应该遵照该ca的申请过程来取得客户端证书。当然,你也可以使用openssl包提供的工具,自己扮演ca的角色,自己签发证书给用户。

制作客户端证书
客户端证书的制作程序,其实与服务器端证书的制作过程很相似,唯一差别是多了一个步骤:将签署好的证书换成mua可用的格式。大部分流行的mua都偏好 pkcs12格式的证书文件,这种格式将签署好的证书与私钥封装在一起,并以一个密码保护。如果你使用第三方ca,该ca应该能提供正确格式的证书文件来 满足用户的mua。如果你自己签署证书,你应该制作pkcs12格式的证书文件来分发给用户。证书文件应该包含核发给用户个人的证书(公钥)、搭配于该证 书的私钥以及你自己的ca根证书。
对于每一位你打算以证书来验证其身份的用户,你都必须分别产生一对专属的公私钥。你应该指定“辨别名称”的命名原则。一般而言,在产生证书时,你应该使用 个人的邮件地址或是客户端机器的主机名称。举例来说,假设你决定以邮件地址为分辨名称,而现在要签发证书给kdent@ora.com这位用户,步骤如 下:
1、使用openssl命令产生一对公私钥。请注意,你自己的公钥也必须有ca的签名
       openssl req -new -nodes -keyout kdentkey.pem -out kdentreq.pem -days 365
       由于使用了-new选项,所以上述命令会产生一个私钥与一份csr。-nodes选项要求openssl不要将私钥密封。-keyout和-out分别指出私钥文件和csr的文件名。最后,-days 365表示证书的有效期是一年。
2、签署证书。如果你与ca合作,请按照他们的申请流程,提出前一步骤所产生的csr,要求他们签署。如果你自己作为ca,请用下列命令签署证书:
       openssl ca -out kdent_signed-cert.pem -infiles kdentreq.pem
3、将签署好的证书文件转换成适当格式。问清楚用户所用的mua是哪一种,将ca签章的证书文件转换成该mua能接受的格式:
          openssl pkcs12 -in kdent_sigend_cert.pem -inkey kdentkey.pem -certfile /etc/postfix/cacert.pem -out kdent.p12 -export -name "kdent@ora.com"
       这命令会要求你提供一个密码来保护所产生的文件(kdent.p12),而你必须将这个密码告知用户。-certfile选项指出你自己的ca根证书文件。完成之后,就可将kdent.p12文件与脚本交付给用户。
最后一步,请用户自己将证书文件安装道mua。大多数mua都提供相当简便的步骤来导入证书文件,所以应该不成问题。如果你有不擅长操作计算机的用户,请给予适当的指导。

设定客户端证书验证
postfix/tls依据证书的“指纹”来判别证书是否可接受。“指纹”是从证书中计算出来的值,不同的证书,不可能计算出相同的指纹。你必须将每个客 户端证书的指纹都存放于一个标准的postfix查询表。每当有客户端出示其证书,postfix/tls就计算该证书的指纹,然后检查该指纹是否已登记 在查询表,借此决定是否要容许客户端使用转发服务。
你必须收集每一位获得授权的客户端的证书指纹。许多mua都有显示证书指纹的功能,你可以要求用户将他们在mua看到的证书指纹提供给你。如果他们的证书是你自己核发的,你可以用openssl x509命令直接算出指纹:
       openssl x509 -fingerprint -noout -in kdent_signed_cert.pem | cut -d -f2
整个设定流程如下:
1、分别取得每一位用户的证书指纹。你可以按照上述步骤自己计算,或是要求用户提供给你。
2、将收集道的指纹集中在/etc/postfix/clientcerts文件,并注明其对应的辨别名称。
3、将制作好的clientcerts查询表转换成数据库:
       postmap /etc/postfix/clientcerts
4、编辑main.cf配置文件,加入下列参数:
       relay_clientcerts = hash:/etc/postfix/clientcerts
       smtpd_tls_ask_cert = yes
       smtpd_recipient_restrictions =
                   permit_mynetworks
                   permit_tls_clientcerts
                   reject_unauth_destination
5、重新加载postfix,使我们在main.cf所做的改变生效:
          postfix relaod

tls/smtp client的设定过程

既然smtp/tls server能要求客户端出示证书,那么,当postfix扮演客户端角色时--寄信到其他smtp server,或要求其他smtp server转发邮件--smtp mda也可能被要求提供客户端证书。注意,一个postfix系统只能有一个代表自己的客户端证书,除非你在master.cf中设定了其他mda,才有 可能安装多个的客户端证书。
证明服务器端身份的证书,也可以用来证明客户端身份。不过,正式ca核发的证书,不见得能让你同时用在两种身份上。这种情况下,你可能需要向ca另外申请 一个客户端证书。我们先前制作的自签名服务器证书没有这样的限制。不管你的客户端证书是怎么来的,其辨别名称都必须符合myhostname参数所指定的 主机名称。
制作客户端证书的过程,其实与服务器端证书的制作过程完全一样,所以不再赘述。如果你打算使用同样的证书,那么,只要将几个tls client参数指向tls server参数所用的相同文件即可。
以下是最基本的tls client参数。
smtp_use_tls
       启动postfix smtp client的tls支持。
       smtp_use_tls = yes
smtp_tls_key_file
       指向客户端证书所对应的私钥文件。
smtp_tls_key_file = /etc/postfix/mailkey.pem
smtp_tls_cert_file
       指向客户端证书文件。
       smtp_tls_cert_file = /etc/postfix/mail_signed_cert.pem
smtp_tls_cafile
       签署客户端证书的ca的根证书文件,例如:
       smtp_tls_cafile = /etc/postfix/cacert.pem
假设你打算让smtp使用与smtpd相同的证书,设定步骤相当简单:
1、编辑main.cf,设定下列参数:
       smtp_use_tls = yes
       smtp_tls_key_file = /etc/postfix/mailkey.pem
       smtp_tls_cert_file = /etc/postfix/mail_signed_cert.pem
       smtp_tls_cafile = /etc/postfix/cacert.pem
2、重新加载postfix,使main.cf的改变生效;
       postfix reload
现在,每当postfix联机到一个妖气出示客户端证书的smtp server,smtp便会提供必要的信息。

阅读(2186) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~