一、背景
OpenLDAP是开源的目录服务实现,AD是微软的目录服务现实。在我们的业务环境中可能会出现有的应用场景(应用、客户端)跟OpenLDAP结合比较容易;有的应用场景又必须要使用AD。几乎不可能弃用其中的任意一种。但同时维护两套系统意味着维护工作大量增加(不仅仅只是增加一倍,要考虑信息分别维护、同步等)、出错几率大大增加。
其中的一种较成熟、使用比较多的解决方案是:OpenLDAP使用AD的认证,即只在AD上维护一套用户密码,OpenLDAP将认证转发到微软AD上进行。
二、相关组件
- LDAP Client:这个是实际调用ldap服务的系统,也可以是类似ldapsearch之类的client程序
- OpenLDAP服务器:开源服务端,实际进程为slapd
- saslauthd:简单认证服务层的守护进程,该进程要安装在openldap服务器上
- AD:微软AD
三、部署
1、安装OpenLdap
(1)安装OpenLDAP服务
注:本文仅以OpenLDAP 2.4.44版本为例进行安装和配置说明,其他版本如有差异请以实际为准。
[root@localhost ~]# yum install -y openldap openldap-clients openldap-servers-sql compat-openldap openldap-devel openldap-servers
[root@localhost ~]# systemctl restart slapd.service
[root@localhost ~]# systemctl enable slapd.service
(2)配置OpenLDAP管理密码,并修改openldap配置
[root@localhost ~]# slappasswd
New password:
Re-enter new password:
{SSHA}zBfhcYEI5u6mUJUAk6f46rSxLPksOLQo
# 把上面生成的{SSHA}开头的字符串记下来,后面修改配置文件要用
创建一个ldif问用于修改openldap配置,旧版本的OpenLDAP修改配置是可以直接修改slapd.conf文件的,但是新版本的OpenLDAP的配置文件全部在/etc/openldap/slapd.d/目录下,不能随意使用vim修改,如果手动使用vim方式修改了配置文件,则会导致配置文件校验和不一致,可能会出现一些未知的问题。
# 新建一个ldif文件用于修改openldap配置
[root@localhost ~]# vim change_ldap_cfg.ldif
# 将以下内容写入
# 实际配置的时候建议把“#”后面的注释内容删掉,只保留配置内容
dn: olcDatabase={2}hdb,cn=config # 表示修改/etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb.ldif这个文件里的内容
changetype: modify # 表示我们需要为这个文件执行变更操作
replace: olcRootDN # 修改olcRootDN这个字段的内容
olcRootDN: cn=Manager,dc=test,dc=winad,dc=com # 把olcRootDN这个字段的内容修改成这样
- # 具体含义不知道,但是大概表示上面这个dn的配置还没修改完,下面还是修改这个dn的配置
replace: olcSuffix # 修改olcSuffix这个字段的内容
olcSuffix: dc=test,dc=winad,dc=com # 把olcSuffix这个字段的内容修改成这样
-
add: olcRootPW # 增加一个olcRootPW字段
olcRootPW: {SSHA}NKL0WdsiEPUSnjpCrz+ZbwJTuTK1inZh # 增加的olcRootPW这个字段的内容是这样
dn: olcDatabase={1}monitor,cn=config # 表示修改/etc/openldap/slapd.d/cn=config/olcDatabase={1}monitor.ldif这个文件里的内容
changetype: modify # 表示我们需要为这个文件执行变更操作
replace: olcAccess # 修改olcAccess这个字段的内容
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=extern
al,cn=auth" read by dn.base="cn=Manager,dc=test,dc=winad,dc=com" read by * none # 把olcAccess这个字段的内容修改成这样
上面的配置文件保存好之后,执行ldapmodify命令进行修改
[root@localhost ~]# ldapmodify -Y EXTERNAL -H ldapi:/// -f change_ldap_cfg.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "olcDatabase={2}hdb,cn=config"
modifying entry "olcDatabase={1}monitor,cn=config"
执行完了以后看下下面这两个文件,看看需要修改的字段改过来没有
/etc/openldap/slapd.d/cn=config/olcDatabase={1}monitor.ldif
/etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb.ldif
(3)创建管理员账号
# 新建一个ldif文件用于导入管理员账号
[root@localhost ~]# vim base.ldif
# 添加以下内容
dn: dc=test,dc=winad,dc=com
o: test winad com
dc: test
objectClass: top
objectClass: dcObject
objectclass: organization
dn: cn=Manager,dc=test,dc=winad,dc=com
cn: Manager
objectClass: organizationalRole
description: Directory Manager
上面的配置文件保存好之后,执行ldapadd命令导入
导入账号
[root@localhost ~]# ldapadd -x -D "cn=Manager,dc=test,dc=winad,dc=com" -W -f base.ldif
Enter LDAP Password: # 这里输的密码就是上面第二步的时候配置的那个密码
adding new entry "dc=test,dc=winad,dc=com"
adding new entry "cn=Manager,dc=test,dc=winad,dc=com"
(4)配置DB数据库
[root@localhost ~]# cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
[root@localhost ~]# chown ldap:ldap -R /var/lib/ldap
[root@localhost ~]# chmod 700 -R /var/lib/ldap
(5)验证OpenLDAP配置文件是否正确
[root@localhost ~]# slaptest -u
config file testing succeeded #验证成功,如果是返回其他内容则失败。
(6)给相关目录授权,否则启动服务时可能会报错,权限不足
[root@localhost ~]# chown ldap:ldap -R /var/run/openldap
[root@localhost ~]# chown ldap:ldap -R /etc/openldap/
(7)导入schema
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/collective.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/corba.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/core.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/duaconf.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/dyngroup.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/java.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/misc.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/openldap.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/pmi.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/ppolicy.ldif
(8)添加memberOf模块
因为我们是要和WindowsAD联动,所以需要将权限组这个模块提前准备好。如果提前没有准备好,后面再加的话,还得把建好的组全删掉再重建。这个模块的作用是当你建一个组的时候,把一些用户添加到这个组里去,它会自动给这些用户添加一个memberOf属性,有很多应用需要检查这个属性。
添加的时候比较麻烦,需要建3个ldif文件,然后1个执行ldapmodify,2个执行ldapadd,注意顺序,不能出错
新建一个memberof_config.ldif文件
# 在文件中写入以下内容
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
olcModuleLoad: memberof
olcModulePath: /usr/lib64/openldap # 这里请注意,请确认/usr/lib64/目录下是否有openldap目录
dn: olcOverlay={0}memberof,olcDatabase={2}hdb,cn=config # 这个意思是说在/etc/openldap/slapd.d/cn=config/目录下创建一个olcDatabase={2}hdb目录,然后在里面再创建一个olcOverlay={0}memberof.ldif文件
objectClass: olcConfig
objectClass: olcMemberOf
objectClass: olcOverlayConfig
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
文件保存好之后,执行ldapadd命令
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f memberof_config.ldif
执行完之后,检查你的/etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb/目录下,看是不是多了一个olcOverlay={0}memberof.ldif模块
然后检查你的/etc/openldap/slapd.d/cn=config/目录下,看是不是多了一个cn=module{0}.ldif模块,这个模块的数字编号直接影响下一步操作。
新建一个refint1.ldif文件
# 在文件中写入以下内容
dn: cn=module{0},cn=config # 这里的意思就是我们上面说的那个/etc/openldap/slapd.d/cn=config/目录下的cn=module{0}.ldif,我们这一次要修改这个文件
add: olcmoduleload
olcmoduleload: refint
如果你那边不是module{0}的话,那就看是几,是几就写几就行了,对于这个文件,我们要执行ldapmodify操作:
[root@localhost ~]# ldapmodify -Y EXTERNAL -H ldapi:/// -f refint1.ldif
接下来新建一个refint2.ldif文件
dn: olcOverlay={1}refint,olcDatabase={2}hdb,cn=config # 在/etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb目录下,再创建一个olcOverlay={1}refint.ldif文件
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcRefintConfig
objectClass: top
olcOverlay: {1}refint
olcRefintAttribute: memberof member manager owner
对这个文件执行ldapadd操作:
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f refint2.ldif
重启slapd服务
[root@localhost ~]# systemctl restart slapd.service
[root@localhost ~]# systemctl status slapd.service
● slapd.service - OpenLDAP Server Daemon
Loaded: loaded (/usr/lib/systemd/system/slapd.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2021-03-17 18:11:37 CST; 8s ago
Docs: man:slapd
man:slapd-config
man:slapd-hdb
man:slapd-mdb
file:///usr/share/doc/openldap-servers/guide.html
Process: 1144 ExecStart=/usr/sbin/slapd -u ldap -h ${SLAPD_URLS} $SLAPD_OPTIONS (code=exited, status=0/SUCCESS)
Process: 1113 ExecStartPre=/usr/libexec/openldap/check-config.sh (code=exited, status=0/SUCCESS)
Main PID: 1147 (slapd)
CGroup: /system.slice/slapd.service
└─1147 /usr/sbin/slapd -u ldap -h ldapi:/// ldap:///
Mar 17 18:11:36 localhost.localdomain runuser[1137]: pam_unix(runuser:session): ses...p
Mar 17 18:11:36 localhost.localdomain runuser[1139]: pam_unix(runuser:session): ses...)
Mar 17 18:11:36 localhost.localdomain runuser[1139]: pam_unix(runuser:session): ses...p
Mar 17 18:11:36 localhost.localdomain runuser[1141]: pam_unix(runuser:session): ses...)
Mar 17 18:11:36 localhost.localdomain runuser[1141]: pam_unix(runuser:session): ses...p
Mar 17 18:11:36 localhost.localdomain slapd[1144]: @(#) $OpenLDAP: slapd 2.4.44 (Se...$
mockbuild@x86-02.bsys.ce...d
Mar 17 18:11:36 localhost.localdomain slapd[1144]: ldif_read_file: checksum error o..."
Mar 17 18:11:36 localhost.localdomain slapd[1144]: ldif_read_file: checksum error o..."
Mar 17 18:11:37 localhost.localdomain slapd[1147]: slapd starting
Mar 17 18:11:37 localhost.localdomain systemd[1]: Started OpenLDAP Server Daemon.
Hint: Some lines were ellipsized, use -l to show in full.
检查OpenLDAP状态
执行ldapsearch -x检查是否有如下输出
[root@localhost ~]# ldapsearch -x -b '' -s base'(objectclass=*)'
# extended LDIF
#
# LDAPv3
# base <> with scope baseObject
# filter: (objectclass=*)
# requesting: ALL
#
#
dn:
objectClass: top
objectClass: OpenLDAProotDSE
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
2、部署Saslauthd
(1)安装saslauthd服务
[root@localhost ~]# yum install -y cyrus-sasl
[root@localhost ~]# systemctl restart saslauthd.service
[root@localhost ~]# systemctl enable saslauthd.service
(2)测试一下ldapsearch搜索WindowsAD是否正常
[root@localhost ~]# /usr/bin/ldapsearch -x -H ldap://test.winad.com "(&(objectClass=organizationalPerson)(!(objectClass=computer)))" dn objectClass cn description sAMAccountName email uSNCreated -D "CN=Administrator,CN=Users,DC=test,DC=winad,DC=com" -w "testtest" -b "OU=Test Users,DC=test,DC=winad,DC=com" -L
如果能搜索到用户,说明openldap访问Windows AD正常
(3)配置sasl访问ad
编辑/etc/sysconfig/saslauthd
[root@localhost ~]# vim /etc/sysconfig/saslauthd
# 修改下面两行
MECH=ldap
FLAGS="-O /etc/saslauthd2ad.conf"
然后新建一个 /etc/saslauthd2ad.conf ,写入下面内容
ldap_servers: ldap://test.winad.com
ldap_search_base: DC=test,DC=winad,DC=com
ldap_timeout: 60
ldap_filter: sAMAccountName=%U
ldap_bind_dn: CN=Administrator,CN=Users,DC=test,DC=winad,DC=com
ldap_password: testAD
ldap_deref: never
ldap_restart: yes
ldap_scope: sub
ldap_use_sasl: no
ldap_start_tls: no
ldap_version: 3
ldap_auth_method: bind
重启saslauthd服务
[root@localhost ~]# systemctl restart saslauthd.service
使用testsaslauthd命令测试WindowsAD上的用户是否认证成功
[root@localhost ~]# testsaslauthd -u Administrator -p testAD
0: OK "Success."
可进一步AD里面加用户、或改密码测试。需注意AD修改密码,老密码依然可用5分钟。如验证不通过检查 sasl的配置。
(4)配置openldap使用Saslauthd
编辑/etc/openldap/ldap.conf
[root@localhost ~]# vim /etc/openldap/ldap.conf
# 增加以下内容
TLS_REQCERT never
[root@localhost ~]# vim /etc/sasl2/slapd.conf
# 添加如下内容
mech_list: plain
pwcheck_method: saslauthd
saslauthd_path: /var/run/saslauthd/mux
重启saslauthd服务
[root@localhost ~]# systemctl restart saslauthd.service
验证openldap是否支持SASL
[root@localhost ~]# ldapsearch -x -H ldap://127.0.0.1 -ZZ -b "" -LLL -s base supportedSASLMechanisms
dn:
supportedSASLMechanisms: LOGIN
supportedSASLMechanisms: PLAIN
# 出现如上结果说明openldap已支持SASL认证
3、安装phpldapadmin
phpldapadmin提供了使用web页面管理OpenLDAP的方式
(1)安装php基础包和phpldapadmin
[root@localhost ~]# yum -y install httpd php php-ldap php-gd php-mbstring php-pear php-bcmath php-xml
[root@localhost ~]# yum install -y epel-release
[root@localhost ~]# yum install -y phpldapadmin
(2)配置phpldapadmin
[root@localhost ~]# vim /etc/httpd/conf.d/phpldapadmin.conf
添加以下内容
#
# Web-based tool for managing LDAP servers
#
Alias /phpldapadmin /usr/share/phpldapadmin/htdocs
Alias /ldapadmin /usr/share/phpldapadmin/htdocs
<Directory /usr/share/phpldapadmin/htdocs>
<IfModule mod_authz_core.c>
# Apache 2.4
Require local
Require all granted # 新增此行
</IfModule>
<IfModule !mod_authz_core.c> # 如果你的php是2.2版本才需要关注这里,否则不用关注。
# Apache 2.2
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
Allow from ::1
</IfModule>
</Directory>
(3)修改phpldapadmin配置文件
[root@localhost ~]# vim /etc/phpldapadmin/config.php
# 修改
$servers->setValue('login','attr','uid');
# 为
$servers->setValue('login','attr','dn');
(4)启动httpd服务
[root@localhost ~]# systemctl start httpd
[root@localhost ~]# systemctl enable httpd
[root@localhost ~]# systemctl status httpd
(5)登录验证
使用浏览器登录phpldapadmin
http://192.168.1.28/phpldapadmin 页面输入管理员的DN和密码即可登录
4、测试OpenLDAP使用AD密码进行认证
创建一个测试用户导入文件testuser.ldif
[root@localhost ~]# vim testuser.ldif
写入以下内容
dn: cn=testuset,dc=test,dc=winad,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn:: testuser
sn:: testuser
description: testuser
uid: testuser
userPassword: {SASL}testuser
导入测试用户
[root@localhost ~]# ldapadd -x -D "cn=Manager,dc=test,dc=winad,dc=com" -W -f testuser.ldif
Enter LDAP Password:
adding new entry "cn=testuser,dc=test,dc=winad,dc=com"
使用命令测试
[root@localhost ~]# ldapsearch -w testuser -H ldap://10.206.153.222 -D "cn=testuser,dc=test,dc=winad,dc=com" -b "dc=test,dc=winad,dc=com"
这个测试命令,testuser用户在openldap和Windows AD上都存在,IP是本机openldap的IP,DN,查询DN也都是openldap的信息,但是密码却是在windows AD上管理的。如成功,到windows AD上修改用户密码,用新密码验证,再等5分钟,旧密码失效。到此配置完成