如何让 SASL 身份验证与 DIGEST-MD5 一起用于 OpenLDAP?

blu*_*lub 10 openldap ldap saslauthd sasl

我正在slapdUbuntu 14.04 Trusty Tahr 上设置 OpenLDAP 。我希望某些不是用户的实例(复制等)能够通过SASL使用DIGEST-MD5机制登录。

与用户不同,他们应该在目录树中具有相应的 DN(以及密码)。相反,他们的凭据应该存储在外部,因此SASL.

我现在正在使用saslauthd(例如,如果可以直接访问 sasldb,这不是硬性要求)并且它使用机制工作正常PLAINLOGIN而使用机制DIGEST-MD5CRAM-MD5.

我错过了什么或做错了什么?我怎样才能让它工作DIGEST-MD5


OpenLDAP的配置为SASL/etc/ldap/sasl2/slapd.conf这样的:

mech_list: EXTERNAL DIGEST-MD5 CRAM-MD5 PLAIN LOGIN
pwcheck_method: saslauthd
saslauthd_path: /var/run/saslauthd/mux
Run Code Online (Sandbox Code Playgroud)


有趣的(改变的)选项/etc/default/saslauthd是:

START=yes
MECHANISMS="sasldb"
Run Code Online (Sandbox Code Playgroud)

它们导致saslauthd像这样启动:

/usr/sbin/saslauthd -a sasldb -c -m /var/run/saslauthd -n 5
Run Code Online (Sandbox Code Playgroud)


我用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
Run Code Online (Sandbox Code Playgroud)

slapd 日志中似乎失败的部分(日志记录打开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
Run Code Online (Sandbox Code Playgroud)

当我手动运行它时/var/log/auth.log,调试输出中也没有任何saslauthd内容,这可能表slapd明甚至没有将身份验证移交给saslauthd(与工作案例相反,见下文)。


我用PLAINLOGIN像这样重现工作案例:

# 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
…
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

两者/var/log/auth.logsaslauthd现在的调试输出都包含以下内容:

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
Run Code Online (Sandbox Code Playgroud)


显然,它与PLAINLOGINDIGEST-MD5和 的工作方式肯定存在一些差异CRAM-MD5


更新和澄清:

用于授权树访问域名是uid=replication,cn=digest-md5,cn=authuid=replication,cn=plain,cn=auth分别根据第15.2.5 http://www.openldap.org/doc/admin24/sasl.html那些DN不需要实际在树中存在(至少对于PLAIN并且LOGIN因为它在那里工作正常,这必须是正确的)。
出于测试目的,我目前正在使用olcAccess: to * by dn.regex="replication" read by * break以确保复制登录至少获得对主 LDAP 树中所有内容的读取访问权限(是的,我知道这不安全,我将为其授予适当的生产权限)。

凭据已存在,/etc/sasldb2并在使用PLAINor时成功检查它们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
…
Run Code Online (Sandbox Code Playgroud)

但是,在DIGEST-MD5CRAM-MD5它似乎根本没有联系的情况下saslauthd(由于我遗漏了某些东西或做错了什么,可能),因此也可能不会咨询数据库。

473*_*469 5

我的方法是让 OpenLDAP 直接检查/etc/sasldb2

第一步:确保/etc/sasldb2slapd 用户拥有。

下一步:不必slapd在目录树中查找凭据,具体操作如下:

dn: cn=config
changetype: modify
replace: olcSaslAuxprops
olcSaslAuxprops: sasldb
Run Code Online (Sandbox Code Playgroud)

稍后,您还需要一个olcAuthzRegexp规则,但为了测试 auth 是否有效,则没有必要。

这些设置适用于从源代码构建的 Debian GNU/Linux Jessie OpenLDAP-2.4.40。