Postfix sasl身份验证功能(1)


基本的smtp协议没有验证用户身份的能力。虽然信封上的寄件人地址已经隐含了发信者的身份,然而,由于信封地址实在太容易假造,所以不能当成身份凭据。 为了判断客户端是否有权使用转发服务(relay),服务器端必须确认客户端(寄件人)是否当真是对方所自称的那个人。在不能以寄件人地址为身份证书的前 提下,smtp势必需要其他补充机制,才能验证客户端的身份。那我们就来看看Postfix sasl身份验证机制,是如何运行的。

从postfix的角度看,它需要扮演两种角色:当它身为smtp server时,需要能够验证用户个人的身份(让他们能使用smtp server寄出邮件);当它身为smtp client时,它需要能够提供出自己的身份证书给其他mta检验(以便通过远程mta将邮件递送到最终目的地)。因此,我们也会解释如何设定 postfix,使其能通过其他mta的身份验证。

大多数邮件系统只容许内部网络上的客户端使用转发服务,换言之,ip地址成了客户端身份的识别 凭据。然而,并非所有合法用户都具有固定ip地址。比方说,带着笔记本电脑出差远方的同事,他们可能使用领近isp或饭店旅馆提供的临时性ip地址;或 者,有些在家工作的用户,他们位于办公室之外的网络,但是需要透过办公室里的邮件系统来寄信。不管你是否能够事先知道用户的ip地址,sasl都能提供可 靠的身份验证。

RFC 2554 “smtp service extension for authentication”制定了如何在基本smtp协议上增加验证功能的机制,此机制使得smtp能使用sasl协议来验证客户端身份。我们将示范 如何使用carnegie mellon大学开发的cyrus sasl函数库来扩充postfix,使其具备sasl验证能力。

由于cyrus sasl以“函数库”的形式存在,要让你的postfix支持sasl,你必须在编译postfix时就将cyrus sasl函数库链接进去,此外,远程用户也必须设定他们的mua,使其在通过你的邮件系统转发邮件时,能送出正确的标识信息。

sasl概论

有 许多客户机/服务器协议没有验证能力,sasl就是用于加强或增加这类协议的一种通用方法。当你设定sasl时,你必须决定两件事;一是用于交换“标识信 息”(或称身份证书)的验证机制;一是决定标识信息存储方法的验证架构。sasl验证机制规范client与server之间的应答过程以及传输内容的编 码法,sasl验证架构决定服务器本身如何存储客户端的身份证书以及如何核验客户端提供的密码。如果客户端能成功通过验证,服务器端就能确定用户的身份, 并借此决定用户具有怎样的权限。对postfix而言,所谓的“权限”指的就是转发服务的访问权。你也可以决定通过验证的用户在转发邮件时,是否要使用特 定的寄件人地址。

选择适当的验证机制

cyrus sasl支持多种验证机制,至于要使用哪一种验证机制,客户端与服务器双方必须事先取得共识。以下是一些比较常见的机制;

plain

plain是最简单的机制,但同时也是最危险的机制,因为身份证书(登录名称与密码)是以base64字符串格式通过网络,没有任何加密保护措施。因此,使用plain机制时,你可能会想要结合tls。

login

login不是其正式支持的机制,但某些旧版的mua使用这种机制,所以cyrus sasl让你可选择其是否支持login机制。如果你的用户仍在使用这类老掉牙的mua,你必须在编译sasl函数库时,指定要包含login的支持。 login的证书交换过程类似plain。

otp

otp是一种使用“单次密码”的验证机制。此机制不提供任何加密保护,因为没必要--每个密码都只能使用一次,每次联机都要改用新密码。smto client必须能够产生otp证书。

digest-md5

使用这种机制时,client与server共享同一个隐性密码,而且此密码不通过网络传输。验证过程是从服务器先提出challenge(质询)开始, 客户端使用此challenge与隐性密码计算出一个response(应答)。不同的challenge,不可能计算出相同的response;任何拥 有secret password的一方,都可以用相同的challenge算出相同的response。因此,服务器只要比较客户端返回的response是否与自己算 出的response相同,就可以知道客户端所拥有的密码是否正确。由于真正的密码并没有通过网络,所以不怕网络监测。

kerberos

kerberos是一种网络型验证协议。除非你的网络已经使用kerberos,否则你应该用不到kerberos机制;相对的,如果你的网络已经架设了kerberos验证中心,sasl就能完美的将smtp验证整合进现有的体系。

anonymous

anonymous机制对smtp没有意义,因为smtp验证的用意在于限制转发服务的使用对象,而不是为了形成open relay,sasl之所以提供这种机制,主要是为了支持其他协议。

当 客户端链接到一个支持sasl的邮件服务器时,服务器会以优先级列出可用的机制供客户端选择。如果客户端也支持多钟机制,则当第一种机制验证失败时,客户 端可能会继续尝试第二种机制,直到通过验证或是所有机制都失败为止。如果双方在一开始就无法协调出共同的机制,验证过程就算失败。

一旦双方在使用哪种机制上达成共识,就开始进行验证过程。实际的交互过程随机制而定,但通常包含一次或多次应答过程。验证协议本身也规定了应答内容的编码格式。

选择适当的验证架构

sasl验证架构可以使用现有的unix系统密码,也可用smtp用户专用密码文件。如果你的网路上kerberos之类的中间控制式验证构架,也可以使用。

哪 一种验证架构最适合你,取决于你的服务器从何、如何取得证书信息。举例来说,如果smtp与pop/imap的所有用户的证书数据都是储存在系统密码文 件,并通过pam来验证,那么sasl就应该透过pam来取得证书数据。另一方面,如果所有smtp user都只有虚账户,你或许应该将证书数据存放在专用的数据库,并设定sasl与POP/IMAP server从该数据库取得证书数据。

postfix与sasl

在开始使用sasl之前,你应该决定好,要采用哪一种机制与架构的组合,因为你的决定将影响编译、安装、设定的过程。首先,你必须先将sasl函数库安装 到你的系统上,或是确定sasl函数库的安装目录与版本。接着,使用你收集到的sasl安装信息来设定postfix的编译选项,然后重新编译 postfix,使其具备sasl验证能力。某些系统平台可能已经预先安装了sasl函数库,甚至提供支持sasl的postfix包,不过,大部分预先 编译好的postfix包都不支持sasl。因此,如果你使用现成的postfix包,最好先研读相关说明文件,或是按照本章“测试验证配置”一节所说的 测试方法,确认你的postfix确实支持sasl。此外,你也要确认你的sasl函数库支持客户端可能使用的每一种验证机制。比方说,若你的用户中还有 人使用老版的outlook express,你的sasl函数库就必须支持login验证机制。

cyrus sasl函数库的研发进度,目前分为两条线路,即sasl与saslv2。其中,sasl已经逐渐被saslv2所取代。在未来,postfix可能只支 持saslv2,所以本章只讨论saslv2。此外,postfix与sasl函数库两者的版本都必须正确,才能组合在一起。

postfix从1.17-20020331实验版开始支持saslv2函数库,在这之前的版本,只能使用saslv1。理论上,最新版的postfix与最新版的cyrus saslv2应该可以顺利结合在一起。

postfix的sasl配置

假设你已经安装好sasl函数库,而且postfix也支持sasl,并下定决心要使用哪一种验证机制与架构的组合。现在,让我们逐步设定postfix,使其能够使用sasl来验证用户的身份。

设定验证架构

对于每个使用cyrus sasl函数库的应用系统,cyrus sasl各提供一个独立的配置文件。影响postfix的sasl配置文件是smtpd.conf。此文件通常位于 /usr/local/lib/sasl2/smtpd.conf。基本上,smtpd.conf至少要指出所要使用的验证架构。我们打算讨论两种最常用 的架构:unix系统密码以及独立的sasl专用密码。

unix系统密码

通常,让sasl直接使用现有的系统密码来验证用户身份是最方便的。传统的系统密码文件应该是/etc/passwd,但是讲究安全性的现代系统则比较可 能使用/etc/shadow、pam或诸如此类的证书数据库。由于这类密码文件只有特权进程才能访问,而postfix却被刻意设计成避开特权身份,所 以postfix不能直接访问系统密码文件。

cyrus函数库对于这个问题的解决办法,是提供一个特殊的验证服务器程序,称为saslauthd,它能够代替postfix来取得密码数据。 saslauthd eaemon本身需要特权身份,不过,由于它是一个独立于postfix之外的进程,而且通常不必于外界进行网络通信,所以安全性的危害已经被降到最低。 如果你打算让sasl使用unix系统密码,你必须启动cyrus sasl包随附的saslauthd daemon。请注意,使用saslauthd来访问unix系统密码,表示你只能使用明文密码,因为asalauthd需要实际密码才能进行核验。

要让sasl知道postfix将通过saslauthd daemon来访问证书数据库,你必须将下列内容加入smtpd.conf配置文件:

pwcheck_method: saslauthd

cyrus sasl包随附的saslauthd应该会被安装在$PATH环境变量所列的某个目录下。你必须先在后台启动saslauthd daemon,postfix才能使用它来验证客户端。当你启动saslauthd时,你必须使用-a选项指定密码系统的类型最常见的类型包括pam、 shadow或getpwent。举例来说,在一个使用pam的系统上,你应该使用下列命令来启动saslauthd daemon:

saslauthd -a pam

sasl专用密码

如果你不想使用系统密码来验证smtp client,你刻意另外建一个无关系统密码的独立账户数据库。当你的postfix系统纯粹用于提供寄信服务,而不用于接收外来邮件,用户也不用登录服 务器系统本身时,使用sasl密码可能是个好主意。请将下列内容加入你的smtpd.conf配置文件:

pwcheck_method: auxprop

在cyrus的术语中,auxprop的意义是auxiliary property plug-ins(辅助性的专属外挂模块),其作用是使用外部程序来进行验证。默认的辅助外挂模块是sasldb(这也是cyrus sasl包随附的程序之一),它应该能满足postfix的所有需求。关键字auxprop只是要求使用外部的sasl密码文件。

使用sasl密码时,不需要用到saslauthd daemon,但是你必须将所有的smtp client账户与密码存放在一个专用的外部密码文件中。sasl默认使用的密码文件是/etc/sasldb2。postfix smtp server至少要具备能读取此文件的权限;如果你使用cyrus sasl的auto_transition功能,则postfix将需要能够写此文件的权限;如果你用不到auto_transition功能,最好不要 将写权限开放给postfix。

如果还有其他进程也需要能够访问sasl密码文件(比方说,pop/imap server),你必须适当调整该文件的拥有权与访问权限,让相关进程都能访问它。举例来说,你可以建立一个sasl组,并确定postfix与其他需要 访问该文件的账户都隶属于此组。如果有任何去他进程需要更新该文件,则只读模式可能太严格,而你必须提供写权限给必要的进程。下列命令将 /etc/sasldb2的访问模式设定为440,这使得sasl组的所有成员都能够读取该文件,除此之外的其他进程则没有访问权:

chown postfix:sasl /etc/sasldb2

chmod 440 /etc/sasldb2

cyrus sasl包所提供的saslpasswd2工具,可用来产生、维护/etc/sasldb2密码文件。对于每一个账户,你必须提供三项信息:登录名称、 sasl网域名称、密码。就postfix而言,网域名称必须与myhostname参数的值吻合。所以,最保险的设定方法,就是利用postconf -h myhostname来决定网域名称,如下:

saslpasswd2 -c -u `postconf - h myhostname` kdent

-c选项要求saslpasswd2创建(create)一个账户。“-u”选项指出该账户所属的网域,其值直接取自postfix的配置文件。

设定postfix

所有与sasl密码验证相关的postfix参数,全部都是以smtpd_sasl*(关于smtp server的参数)或smtp_sasl*(关于smtp client的参数)为前缀。对于服务器端的配置,你至少需要设定smtpd_sasl_auth_enable参数,并且将 permit_sasl_authenticated限制条件列在某一个smtpd_*_restriction的过滤规则里。

启用sasl验证

smtpd_sasl_auth_enable参数决定postfix smtp server是否支持sasl验证:

smtpd_sasl_auth_enable = yes

有些老的mua没有完全遵守smtp验证协议。依照规范说明书的标准规定,当smtp client送出ehlo命令之后,smt server应该要列出其验证机制支持列表,而且此列表是出现在关键字auth与一个空格之后。

不过,有些mua却期待收到auth与一个等号;

postfix容许你接受这种不遵守规定的行为:

broken_sasl_auth_clients = yes

设定此参数之后,postfix会分别以标准与非标准两种格式来列出它所支持的smtp验证机制。

由于两种格式都出现在smtp server的响应中,所以既不会影响标准的mua,同时又能让那些不标准的mua使用smtp sasl验证。

避免寄件人冒名

当客户端通过postfix寄信时,要如何确定客户端使用的真实的寄件人地址?比方说,某人以A身份通过smtp验证,但是却以B为发行人地址,要如何避 免这种冒名情况?postfix容许你设定寄件地址与sasl登录身份的对应关系。举例来说,假设某人的邮件地址是kdent@example.com, 其sasl登录身份为kdent,如果你希望kdent只能以该地址的名义来发邮件,而不能使用其他寄件地址,你应该将下列对应关系定义在一个查询表中:

kdent@example.com kdent

这是一个普通的postfix查询表,你可以逐一列出每一个地址与每一位sasl用户的对应关系,也可以使用正则表达式来表示邮件地址的人名部分或网域部分。制作好查询表之后,请将main.cf的smtpd_sender_login_maps参数指向此表:

smtpd_sender_login_maps = hash:/etc/postfxi/sasl_senders

下一步是将reject_sender_login_mismatch限制条件纳入某个smtpd_*_restrictions过滤规则组合里,这样一 来,如果kdent通过sasl验证,但是他却试图以mary@example.com的名义寄出邮件,那么postfix将拒绝帮他寄信。

核准授权用户

如果你的ube过滤规则里包含了smtpd_recipient_restrictions,你得使postfix准许通过验证得用户使用转发服务,也就是将permit_sasl_authenticated安插在限制条件里得适当位置。

设定验证机制

当客户端联机到smtp server时,有哪些密码验证机制可使用,由smtpd_sasl_security_options参数决定。完整得机制选项,取决于你得系统上有哪 些机制可用以及你得sasl函数库支持哪些机制。如果不指定任何选项,默认值是接受包括明文密码在内得所有可用机制,但匿名登录除外。如果使用了 saslauthd daemon,就必须接受明文密码,所以,默认值的设想是合情合理的。如果你指定了任何选项,则默认值无效,所以你的选项里必须包含 noanonymous。例如:

smtpd_asal_security_options = noanonymous, noplaintext


相关内容