一、背景

OpenLDAP是开源的目录服务实现,AD是微软的目录服务现实。在我们的业务环境中可能会出现有的应用场景(应用、客户端)跟OpenLDAP结合比较容易;有的应用场景又必须要使用AD。几乎不可能弃用其中的任意一种。但同时维护两套系统意味着维护工作大量增加(不仅仅只是增加一倍,要考虑信息分别维护、同步等)、出错几率大大增加。

其中的一种较成熟、使用比较多的解决方案是:OpenLDAP使用AD的认证,即只在AD上维护一套用户密码,OpenLDAP将认证转发到微软AD上进行。

二、相关组件

  1. LDAP Client:这个是实际调用ldap服务的系统,也可以是类似ldapsearch之类的client程序
  2. OpenLDAP服务器:开源服务端,实际进程为slapd
  3. saslauthd:简单认证服务层的守护进程,该进程要安装在openldap服务器上
  4. 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分钟,旧密码失效。到此配置完成

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐