我在Ubuntu 14.04 Trusty Tahr上设置了OpenLDAP slapd 。 我希望某些不是用户的实例(复制等)能够使用DIGEST-MD5机制通过SASL进行login。
与用户不同,它们不应该在目录树中有相应的DN(以及密码)。 相反,他们的凭据应该存储在外部,因此SASL 。
我现在正在使用saslauthd (如果可以直接访问sasldb,这并不是一个很难的要求),使用机制PLAIN和LOGIN时它可以正常工作,而使用机制DIGEST-MD5和CRAM-MD5 。
我错过什么或做错了什么? 我如何才能使用DIGEST-MD5 ?
OpenLDAP在/etc/ldap/sasl2/slapd.confconfiguration为SASL ,如下所示:
mech_list: EXTERNAL DIGEST-MD5 CRAM-MD5 PLAIN LOGIN pwcheck_method: saslauthd saslauthd_path: /var/run/saslauthd/mux
/etc/default/saslauthd中有趣的(改变的)选项是:
START=yes MECHANISMS="sasldb"
他们导致saslauthd像这样开始:
/usr/sbin/saslauthd -a sasldb -c -m /var/run/saslauthd -n 5
我用DIGEST-MD5重现了这个失败的案例:
# ldapsearch -U replication -ZZ -Y DIGEST-MD5 -H ldap://ldap-master.example.com/ -b "dc=example,dc=com" "(objectClass=*)" SASL/DIGEST-MD5 authentication started Please enter your password: ldap_sasl_interactive_bind_s: Invalid credentials (49) additional info: SASL(-13): user not found: no secret in database
slapd日志中似乎失败的部分(日志logging在any )如下所示:
slapd[23330]: [rw] authid: "uid=replication,cn=digest-md5,cn=auth" -> "uid=replication,cn=digest-md5,cn=auth" slapd[23330]: slap_parseURI: parsing uid=replication,cn=digest-md5,cn=auth slapd[23330]: >>> dnNormalize: <uid=replication,cn=digest-md5,cn=auth> slapd[23330]: <<< dnNormalize: <uid=replication,cn=digest-md5,cn=auth> slapd[23330]: <==slap_sasl2dn: Converted SASL name to uid=replication,cn=digest-md5,cn=auth slapd[23330]: slap_sasl_getdn: dn:id converted to uid=replication,cn=digest-md5,cn=auth slapd[23330]: SASL Canonicalize [conn=1002]: slapAuthcDN="uid=replication,cn=digest-md5,cn=auth" slapd[23330]: SASL [conn=1002] Failure: no secret in database slapd[23330]: SASL [conn=1002] Debug: DIGEST-MD5 common mech dispose slapd[23330]: send_ldap_result: conn=1002 op=2 p=3 slapd[23330]: send_ldap_result: err=49 matched="" text="SASL(-13): user not found: no secret in database" slapd[23330]: send_ldap_response: msgid=3 tag=97 err=49
在/var/log/auth.log也没有任何东西在saslauthd的debugging输出中,当我手动运行时,这可能表明slapd甚至没有把authentication交给saslauthd (与工作案例相反, 见下文)。
我使用PLAIN或LOGIN重现了这个工作案例:
# ldapsearch -U replication -ZZ -Y PLAIN -H ldap://ldap-master.example.com/ -b "dc=example,dc=com" "(objectClass=*)" SASL/PLAIN authentication started Please enter your password: SASL username: replication SASL SSF: 0 # extended LDIF …
slapd日志中表示上述情况失败的相应部分现在看起来像这样:
slapd[23330]: [rw] authid: "uid=replication,cn=plain,cn=auth" -> "uid=replication,cn=plain,cn=auth" slapd[23330]: slap_parseURI: parsing uid=replication,cn=plain,cn=auth slapd[23330]: >>> dnNormalize: <uid=replication,cn=plain,cn=auth> slapd[23330]: <<< dnNormalize: <uid=replication,cn=plain,cn=auth> slapd[23330]: <==slap_sasl2dn: Converted SASL name to uid=replication,cn=plain,cn=auth slapd[23330]: slap_sasl_getdn: dn:id converted to uid=replication,cn=plain,cn=auth slapd[23330]: SASL Canonicalize [conn=1006]: slapAuthcDN="uid=replication,cn=plain,cn=auth" slapd[23330]: daemon: activity on 1 descriptor slapd[23330]: daemon: activity on: slapd[23330]: slapd[23330]: daemon: epoll: listen=8 active_threads=0 tvp=zero slapd[23330]: daemon: epoll: listen=9 active_threads=0 tvp=zero slapd[23330]: daemon: epoll: listen=10 active_threads=0 tvp=zero slapd[23330]: SASL proxy authorize [conn=1006]: authcid="replication" authzid="replication" slapd[23330]: conn=1006 op=1 BIND authcid="replication" authzid="replication" slapd[23330]: SASL Authorize [conn=1006]: proxy authorization allowed authzDN="" slapd[23330]: send_ldap_sasl: err=0 len=-1 slapd[23330]: conn=1006 op=1 BIND dn="uid=replication,cn=plain,cn=auth" mech=PLAIN sasl_ssf=0 ssf=128 slapd[23330]: do_bind: SASL/PLAIN bind: dn="uid=replication,cn=plain,cn=auth" sasl_ssf=0 slapd[23330]: send_ldap_response: msgid=2 tag=97 err=0
/var/log/auth.log和saslauthd的debugging输出现在包含这个:
saslauthd[23354]: rel_accept_lock : released accept lock saslauthd[23358]: get_accept_lock : acquired accept lock saslauthd[23354]: cache_get_rlock : attempting a read lock on slot: 458 saslauthd[23354]: cache_lookup : [login=replication] [service=] [realm=ldap]: not found, update pending saslauthd[23354]: cache_un_lock : attempting to release lock on slot: 458 saslauthd[23354]: cache_get_wlock : attempting a write lock on slot: 458 saslauthd[23354]: cache_commit : lookup committed saslauthd[23354]: cache_un_lock : attempting to release lock on slot: 458 saslauthd[23354]: do_auth : auth success: [user=replication] [service=ldap] [realm=] [mech=sasldb] saslauthd[23354]: do_request : response: OK
显然, PLAIN和LOGIN与DIGEST-MD5和CRAM-MD5工作方式必须有所不同。
更新和澄清:
用于授权访问树的DN分别为uid=replication,cn=digest-md5,cn=auth和uid=replication,cn=plain,cn=auth并根据http:// www的第15.2.5节。 openldap.org/doc/admin24/sasl.html这些DN不需要实际存在于树中(至less对于PLAIN和LOGIN ,它必须是真的,因为它在那里工作的很好)。
为了testing的目的,我目前使用olcAccess: to * by dn.regex="replication" read by * break来olcAccess: to * by dn.regex="replication" read by * break以确保复制login至less可以读取一切(是的,我知道这是不安全的,我会给它适当的主LDAP树中的权限)。
凭证位于/etc/sasldb2并且在使用PLAIN或LOGIN时成功进行检查(请参阅上文)。 作为参考,它看起来像这样:
# sasldblistusers2 replication@ldap-master: userPassword … # db_dump -p /etc/sasldb2 VERSION=3 format=print type=hash h_nelem=4 db_pagesize=4096 HEADER=END replication\00ldap-master\00userPassword PasswordCensored …
但是,在DIGEST-MD5和CRAM-MD5的情况下,它似乎根本就没有联系saslauthd (可能是因为我错过了一些东西或做错了什么),所以数据库也可能不会被咨询。
我的配方是OpenLDAP直接检查/etc/sasldb2 。
第一步:确保/etc/sasldb2由slapd用户拥有。
下一步:请不要在目录树中查找凭证,具体步骤如下:
dn: cn=config changetype: modify replace: olcSaslAuxprops olcSaslAuxprops: sasldb
稍后,您还需要一个olcAuthzRegexp规则,但是为了testingauth是否有效,这不是必需的。
这些设置正在从源代码构buildDebian GNU / Linux Jessie OpenLDAP-2.4.40。
使用“pwcheck_method:saslauthd”,CRAM-MD5和DIGEST-MD5方法是不可能的。 他们需要LDAP目录本身的普通,未encryption的密码。
我对sasldb不同凭据的各种configuration进行了大量testing。
总而言之,这个问题最令我困扰的是,根据哪个authentication方法( saslauthd vs. auxprop )被使用(依赖于所请求的authentication机制 – DIGEST-MD5 / CRAM-MD5 vs. PLAIN / LOGIN ),它正在寻找一个不同的domain 。 我没有想到,因为我在sasldb只有一个用户域对,所以没有find另一个用户域对。
我将列出我的一些结论和观察,希望能帮助其他人理解问题并解决问题:
PLAIN或LOGIN机制, slapd将使用/etc/ldap/sasl2/slapd.conf pwcheck_method下configuration的身份validation方法。 DIGEST-MD5或CRAM-MD5机制, slapd将始终使用auxprop方法,而不pipe为pwcheck_methodconfiguration了什么。 pwcheck_method: auxprop ,则可以对所有4种机制使用相同的方法。 或者,如果您为pwcheck_methodconfiguration了其他方法,则可以决定使用2种不同的方法。 auxprop_plugin中的auxprop_plugin被忽略。 slapd使用在其自己的configuration数据库中为olcSaslAuxpropsconfiguration的内容。 请注意,在请求DIGEST-MD5或CRAM-MD5机制时,隐式auxprop方法以及请求其他2种机制之一时明确configuration的pwcheck_method: auxprop都是如此。 saslauthd使用未经修改的主机名(即只是ldap-master )作为domain组件查找证书。 如果我要进行一个有教育的猜测,我会说它使用类似gethostname()来提出,所以这可能是可configuration的某种方式。 auxprop这种或另一种方式时, slapd使用完全限定的域名(即ldap-master.example.com )作为domain组件。 它可能从原始的请求URL(当我想要使用STARTTLS并希望能够正确validation服务器证书,要求匹配的域名时,我的生成请求的select是有限的),但它可能会通过在slapd的configuration数据库中设置olcSaslHost进行configuration。 请注意,我没有尝试过configuration它。 所以想出一个可行的configuration,你有几个select:
PLAIN和LOGIN机制覆盖STARTTLS,请根据需要在/etc/ldap/sasl2/slapd.confconfigurationpwcheck_method 。 如果它是auxprop ,还要在slapd的configuration数据库中configurationolcSaslAuxprops (例如,如果要使用/etc/sasldb2作为凭据存储,请将其设置为sasldb )。 DIGEST-MD5 (我通常会因为安全性差而推荐使用CRAM-MD5 ,所以试着避免它),在slapd的configuration数据库中设置olcSaslAuxprops ,因为要使用auxprop方法,重要的是你configurationpwcheck_method 。 DIGEST-MD5 , CRAM-MD5 (但是,尽量避免CRAM-MD5 )以及设置PLAIN , LOGIN (确保这些机制仅用于encryption连接,像一个STARTTLS-one),并且倾向于对它们使用相同的身份validation方法以及检查相同的凭据集,所以仅限于auxprop 。 在/etc/ldap/sasl2/slapd.confconfigurationpwcheck_method: auxprop ,并根据olcSaslAuxprops在slapd的configuration数据库中设置olcSaslAuxprops 。 如果你希望能够使用两套机制,同时使用不同的身份validation方法(对我来说听起来像一个pipe理的噩梦,但是你去了),那么在/etc/ldap/sasl2/slapd.confconfigurationpwcheck_method ,以便PLAIN和LOGIN ,记住你必须使用DIGEST-MD5 auxprop (如果你坚持使用CRAM-MD5 ),并根据olcSaslAuxprops在slapd的configuration数据库中设置olcSaslAuxprops 。
如果你碰巧把saslauthdconfigurationsaslauthd哈希机制,并确保saslauthd访问不同于slapd通过auxprop访问的数据库,或者为olcSaslAuxprops使用别的而不是sasldb ,那么你可以很好地分离它们,不必担心。
如果您碰巧为散列机制configuration了saslauthd ,并为散列机制configuration了sasldb ,并让它们访问相同的凭据数据库,则您有3个选项,按照优先级顺序排列:
saslauthd以及slapd直接通过auxprop访问sasldb查询具有相同domain的凭证(尝试设置olcSaslHost或强制saslauthd使用FQDN),因此您只需关心每个实体的一个凭证条目进行身份validation。 saslauthd使用userid – hostname.domain.name对作为非哈希机制,并通过auxprop为散列机制使用userid – hostname.domain.name对。