1. openldap編譯
如果需要openldap支持SASL認證,需要在編譯時加上–enable-spasswd選項
安裝完cyrus-sasl,openssl(可選),BDB包后執行:
1
2
|
$ sudo ldconfig
$ export LD_LIBRARY_PATH="/usr/local/lib:/usr/local/BerkeleyDB.4.8/lib:/lib/i386-linux-gnu/"
|
注:
/usr/local/lib為 libsasl2.so.2所在目錄
/usr/local/BerkeleyDB.4.8/lib為 libdb-4.8.so所在目錄
/lib/i386-linux-gnu/為 libssl.so.1.0.0所在目錄
1
|
$ ./configure CPPFLAGS=-I/usr/local/BerkeleyDB.4.8/include --enable-spasswd
|
安裝完畢后
1
|
$ ldapsearch -x -s base -LLL supportedSASLMechanisms
|
輸出:
1
2
3
4
|
dn:
supportedSASLMechanisms: DIGEST-MD5
supportedSASLMechanisms: CRAM-MD5
supportedSASLMechanisms: OTP
|
可以看到默認已經提供DIGEST-MD5方式 的SASL機制。
2. slapd.conf配置
1
|
$ cat /usr/local/etc/openldap/slapd.conf | grep -v ^#
|
配置輸出:
1
2
3
4
5
6
7
8
9
10
11
12
|
include /usr/local/etc/openldap/schema/core.schema
include /usr/local/etc/openldap/schema/asterisk.schema
pidfile /usr/local/var/run/slapd.pid
argsfile /usr/local/var/run/slapd.args
database ldif
suffix "ou=accounts,dc=com"
rootdn "uid=manager,cn=digest-md5,cn=auth"
authz-regexp
uid=([^,]*),cn=digest-md5,cn=auth
AstAccountName=$1,ou=accounts,dc=com
password-hash {CLEARTEXT}
directory /usr/local/var/openldap-data
|
2.1 用戶密碼相關配置
參考http://www.openldap.org/doc/admin24/sasl.html#DIGEST-MD5
This section describes the use of the SASL DIGEST-MD5 mechanism using secrets stored either in the directory itself or in Cyrus SASL’s own database.
這里提到了兩種管理用戶密碼的方式
a.對於第一種:
To use secrets stored in sasldb, simply add users with the saslpasswd2 command:
1
|
saslpasswd2 -c <username>
|
The passwords for such users must be managed with the saslpasswd2 command.
b.對於第二種:
To use secrets stored in the LDAP directory, place plaintext passwords in the userPassword attribute. It will be necessary to add an option to slapd.conf to make sure that passwords set using the LDAP Password Modify Operation are stored in plaintext:
1
|
password-hash {CLEARTEXT}
|
Passwords stored in this way can be managed either with ldappasswd(1) or by simply modifying the userPassword attribute. Regardless of where the passwords are stored, a mapping will be needed from authentication request DN to user’s DN.
在 這里,我采用了第二種。根據文檔說明,這種方式的密碼是存在userPassword屬性中的,因此每個需要進行認證的用戶都必須有一個 userPassword屬性。並且通過在slapd.conf文件中通過指定password-hash {CLEARTEXT}來確保密碼存儲為明文的文本格式。
由於每個認證用戶都必須有一個userPassword屬性,因此對應的條目必須具有一個含有userPassword 屬性的objectclass,我采用 simpleSecurityObject這個objectclass,這是一個輔助objectclass(區別於structual objectclass),僅包含一個必要屬性userPassword.
參見core.schema:
1
2
3
4
|
objectclass ( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject'
DESC 'RFC1274: simple security object'
SUP top AUXILIARY
MUST userPassword )
|
因此可以將管理員用戶的ldif數據文件配置為:
manager.ldif:
1
2
3
4
5
6
7
|
dn: ou=accounts,dc=com
ou: accounts
objectclass: organizationalUnit
dn: AstAccountName=manager,ou=accounts,dc=com
userPassword: grandstream
objectClass: AsteriskAccount
objectClass: simpleSecurityObject
|
2.2 認證ID與實際條目映射
參考http://www.openldap.org/doc/admin24/sasl.html#Mapping%20Authentication%20Identities
The DIGEST-MD5 mechanism produces authentication IDs of the form:
1
|
uid=<username>,cn=<realm>,cn=digest-md5,cn=auth
|
If the default realm is used,the realm name is omitted from the ID, giving:
1
|
uid=<username>,cn=digest-md5,cn=auth
|
對於我們的例子,配置管理員認證ID為:
1
|
rootdn "uid=manager,cn=digest-md5,cn=auth"
|
認證ID與實際的LDAP條目之間有兩種映射方式:direct mapping和search-based mappings.
Where possible, direct mapping of the authentication request DN to the user’s DN is generally recommended. Aside from avoiding the expense of searching for the user’s DN, it allows mapping to DNs which refer to entries not held by this server.
基於以上原因,采用direct mapping方式。
The LDAP administrator will need to tell the slapd server how to map an authentication request DN to a user’s authentication DN. This is done by adding one or more authz-regexp directives to the slapd.conf(5) file. This directive takes two arguments:
1
|
authz-regexp <search pattern> <replacement pattern>
|
Suppose the authentication request DN is written as:
1
|
uid=adamson,cn=example.com,cn=gssapi,cn=auth
|
and the user’s actual LDAP entry is:
1
|
uid=adamson,ou=people,dc=example,dc=com
|
then the following authz-regexp directive in slapd.conf(5) would provide for direct mapping.
1
2
3
|
authz-regexp
uid=([^,]*),cn=example.com,cn=gssapi,cn=auth
uid=$1,ou=people,dc=example,dc=com
|
對於我們的例子則是:
1
2
3
|
authz-regexp
uid=([^,]*),cn=digest-md5,cn=auth
AstAccountName=$1,ou=accounts,dc=com
|
依據正則表達式的語法,([^,]*)匹配直到遇到逗號之前的字符,$1反向引用([^,]*)中的內容。
3 導入管理員用戶信息
采 用這種方式時認證用戶包括管理員的密碼都是存儲在ldap目錄中的,也就是說,管理員本身的信息也是需要導入的,而在這種方式下rootdn的配置不滿足 suffix的要求,不能設置rootpw選項,也就不能綁定管理員用戶使用ldapadd命令進行管理員信息導入了,那管理員本身的信息如何導入呢?可 以通過以下命令:
1
|
$ slapadd -l manager.ldif
|
4 數據操作
開啟openldap服務器
1
|
$ /usr/local/libexec/slapd&
|
導入ldif數據文件,添加數據
1
|
$ ldapadd -Y DIGEST-MD5 -U manager -f gs_phonebook.ldif -w grandstream
|
manager:管理員用戶的DN為AstAccountName=manager,ou=accounts,dc=com,根據映射關系,對應的uid就是這里的AstAccountName屬性的值manager。
grandstream:對應userPassword屬性的值,即管理員密碼。
gs_phonebook.ldif:要導入的ldif數據文件。
查詢數據
1
|
$ ldapsearch -Y DiGEST-MD5 -U manager -w grandstream -b ou=accounts,dc=com
|
刪除數據
1
|
$ ldapdelete -Y DiGEST-MD5 -U manager -w grandstream <DN1> <DN2> …<DNn>
|
或遞歸刪除
1
|
$ ldapdelete -Y DiGEST-MD5 -U manager -w grandstream -r <BaseDN>
|