OpenLDAP 安装与配置

yum 安装:

sudo yum install -y openldap openldap-clients openldap-servers

启动停止:

sudo service slapd start   # 启动
sudo service slapd stop    # 停止
sudo service slapd status  # 查看状态
netstat -ntlp | grep 389   # OpenLDAP use port 389

配置文件地址:

su -
cd /etc/openldap
cd /etc/openldap/slapd.d
cd /etc/openldap/slapd.d/cn=config

与登录相关的配置文件:

cat /etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb.ldif

# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 4b58ca71
dn: olcDatabase={2}hdb
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {2}hdb
olcDbDirectory: /var/lib/ldap
olcDbIndex: objectClass eq,pres
olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub
structuralObjectClass: olcHdbConfig
entryUUID: 3f094f68-657a-1039-98c0-a50ff8cb9a09
creatorsName: cn=config
createTimestamp: 20190907051526Z
olcRootDN: cn=root
olcSuffix:
olcRootPW:: e1NTSEF9Q2U3MHVJSXV6bytuRDVjak1ySXkvWWQ1S2JpeEVsM2I=
entryCSN: 20190907075320.357662Z#000000#000#000000
modifiersName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
modifyTimestamp: 20190907075320Z

olcRootDN 是登录用的管理员账户, olcRootPW 是登录用的管理员密码(非明文). 这个文件要求是: AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify., 所以我们需要使用 ldapmodify 命令修改里面的相关内容, 详见下一节.

而且到目前为止, 我们并未禁用匿名登录(我不会禁止也不打算禁止), 所以我们使用 LdapAdmin 工具, 使用匿名访问是可以登录的.

修改管理员账户密码:

# create password
slappasswd -s secret
{SSHA}Ce70uIIuzo+nD5cjMrIy/Yd5KbixEl3b  # would use as "olcRootPW"

# create a ldif file, say admin.ldif:
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN:cn=root
-
replace: olcSuffix
olcSuffix:
-
replace: olcRootPW
olcRootPW: {SSHA}Ce70uIIuzo+nD5cjMrIy/Yd5KbixEl3b
-
add: olcAccess
olcAccess: to dn.base="" by * read
-
add: olcAccess
olcAccess: to * by dn="cn=root" write by * read
# EOF

# update config using "ldapmodify" command
# must do this as "root"
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f admin.ldif

其中 slappasswd -s secret 里的 secret 是明文密码, 生成的结果是密文的密码, 该结果写入到 olcRootPW 栏. dn 栏的 olcDatabase={2}hdb,cn=config 具体可以通过 ll /etc/openldap/slapd.d/cn=config 的结果微调.

导入基本 Schema:

sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif

删除某些 Schema:

su -
cd /etc/openldap/slapd.d/cn=config/cn=schema
rm "cn={4}test.ldif"

导入自定义 Schema:

# sample schema file: test.ldif
dn: cn=test,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: test
# attribute adminPolicyDn
olcAttributeTypes: ( 1.3.6.1.4.1.7914.1.2.1.1
    NAME 'adminPolicyDN'
    EQUALITY distinguishedNameMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
# ...
olcObjectClasses: ( 1.3.6.1.4.1.7914.1.2.1.62
    NAME 'testuser'
    SUP top AUXILIARY
    MAY ( $ adminPolicyDn ) )
# EOF

# import
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f test.ldif

导入后, 会出现在 /etc/openldap/slapd.d/cn=config/cn=schema 路径下. 注意其中的 cn=schema,cn=config 的意思就是 /etc/openldap/slapd.d 路径下的 cn=config/cn=schema 文件夹结构. 而 cn=test 变成了 cn={4}test.ldif 文件.

# notice the file: cn={4}test.ldif
[root@vbox#1 ~]$ ll /etc/openldap/slapd.d/cn=config/cn=schema
total 72K
-rw------- 1 ldap ldap  16K Sep 11  2019 cn={0}core.ldif
-rw------- 1 ldap ldap  12K Sep 11  2019 cn={1}cosine.ldif
-rw------- 1 ldap ldap 6.5K Sep 11  2019 cn={2}nis.ldif
-rw------- 1 ldap ldap  14K Apr 12 10:29 cn={4}test.ldif

注意这个 cn={4}test.ldif 这个文件的名字不一定, 主要是 {4} 这个编号系统不一定给成什么值. 而且注意 cn=config/cn=schema/cn={4}test.ldif 就成了这个 schema 的 dn: cn={4}test.ldif,cn=schema,cn=config, 后面会讲到.

修改 Schema

可以有两个办法:

  1. 删除掉整个 schema 文件, 然后重新添加(ldifadd).
  2. 修改某个 schema 文件的一部分(ldifmodify).

方法一, 删除整个文件重新添加.

跟前面的方法一样, 只是注意需要停止 ldap 服务, 删除文件, 重启服务, 然后才能重新添加:

service slapd stop
rm /etc/openldap/slapd.d/cn=config/cn=schema/cn={4}test.ldif
service slapd start
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f test.ldif

方法二, 修改一部分:

准备一个用于修改的 ldif 文件, 然后使用 ldapmodify 命令修改:

# modification file: modify.ldif
dn: cn={4}test,cn=schema,cn=config
changetype: modify
add: olcObjectClasses
olcObjectClasses: ( 1.3.6.1.4.1.7914.1.2.1.69
    NAME 'testObject'
    SUP top AUXILIARY )
# EOF

# modify
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f modify.ldif

注意其中的 dn 跟之前添加文件时候使用的 dn 是不一样的, 添加文件到 ldap 服务器后, 系统会自己命名(前面提到过), 这里一定要根据实际情况修改, 需要到安装目录下去查找文件名, 根据文件名来确定 dn.


LDAP 命令行操作

添加普通 Entry:

add.ldif 的格式大致如下:

dn: mail=test@domain.com,dc=example,dc=com
mail: test@domain.com
base64item:: YmFzZTY0aXRlbQ==
objectclass: top
objectclass: person

其中第一行一定是 dn: xxx,yyy,zzz, 用于决定该 entry 被添加到的位置. 之后每一个行都是 key: value 的键值对. 其中值得注意的是, 如果要添加的 value 中有非 ASCII 字符的时候, 可以把这些 ASCII 字符转换为 base64 编码, 然后使用 key:: base64value 的格式记载. 如上例中的 base64item:: YmFzZTY0aXRlbQ==.

添加这个 entry:

ldapadd -x -h localhost -p 389 -D cn=root -w secret -f add.ldif

添加 Schema

其实 schema 的添加方式普通 entry 没有本质的区别, 回忆前面提到的自定义 schema 的例子:

dn: cn=test,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: test
olcAttributeTypes: ( 1.3.6.1.4.1.7914.1.2.1.1
    NAME 'adminPolicyDN'
    EQUALITY distinguishedNameMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
# ...
olcObjectClasses: ( 1.3.6.1.4.1.7914.1.2.1.62
    NAME 'testuser'
    SUP top AUXILIARY
    MAY ( $ adminPolicyDn ) )

其实是一样的, 第一行是 dn, 之后是键值对. 其中 objectClass, cn 是必须的, 照着例子写就行, cn 要注意和 dn 中最左边的值一致.

之后的 olcAttributeTypesolcObjectClasses 就是 schema 的内容, 分别指定可以添加的 attribute 和 objectclass, 可以指定多个. 具体语法有点复杂, 这里不讲了...

然后要注意添加这个 schema 的命令行必须用如下格式, 因为这里毕竟属于管理用的命令, 需要使用这种特殊操作, 而且需要管理员权限:

sudo ldapadd -Y EXTERNAL -H ldapi:/// -f schema.ldif

修改一个 entry:

可以使用 ldapmodify 命令来进行修改. 修改普通 entry 和 schema 的语法实际上也是一样的, 只要 dn 找对了即可:

dn: cn={4}test,cn=schema,cn=config
changetype: modify
add: olcObjectClasses
olcObjectClasses: ( 1.3.6.1.4.1.7914.1.2.1.69
    NAME 'testObject'
    SUP top AUXILIARY )

第一行指定 dn.

第二行指定修改的方式, changetype 的值可以是:

  • add (其实等效于 ldapadd)
  • delete (其实等效于 ldapdelete)
  • modify

第三行开始指定需要进行的操作的具体内容.

changetype: add:
dn: uid=jsmith1,ou=People,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
description: John Smith from Accounting.
cn: John Smith
sn: Smith
uid: jsmith1
changetype: delete:
dn: ou=othergroup,dc=example,dc=com
changetype: delete
changetype: modify:

该模式之下有 3 个选项:

  • add
  • replace
  • delete
dn: cn={4}test,cn=schema,cn=config
changetype: modify
add: olcObjectClasses
olcObjectClasses: ( 1.3.6.1.4.1.7914.1.2.1.69
    NAME 'testObject'
    SUP top AUXILIARY )
-
replace: mail
mail: sbrown2@example.com
-
delete: mail
mail: jsmith1@example.com

可见多个 attribute 之间需要用 - 隔开, add(或其他)后面指定 key, 下一行对 key 的 value 进行记载. 其中 delete 的时候可以只记载 key, 无需 value.

命令行执行:

ldapmodify -x -h localhost -p 389 -D cn=root -w secret -f modify.ldif

参考:

How To Use LDIF Files to Make Changes to an OpenLDAP System


其他

支持 ldapi:/// 访问

启动的时候需要加参数:

/usr/sbin/slapd -h "ldapi:// ldap://"

解决 [LDAP: error code 65 - invalid structural object class chain (domain/organization)]

一般来说, LDAPObjectClass 中只允许存在一个 STRUCTURAL 类型的属性, 同时设置两个的时候会报错:

error code 65 - invalid structural object class chain (domain/organization).

但是我们实际上是可以通过继承的方式来解决的:

# objectClass mailDomain
olcObjectClasses: ( 1.3.6.1.4.1.7914.1.2.1.70
    NAME 'mailDomain'
    SUP ( domain $ organization ) STRUCTURAL
    DESC 'make domain and organization exist at same time'
    MAY ( domainType
    $domainName ) )

这样一来, 设置 mailDomain 的时候, 就可以同时把两个父类记载上: domain, organization, 这样就实现了多个 STRUCTURAL 类型的属性同时存在.

参考: Appendix A - LDAP: ObjectClass Inheritance


相关 LDIF 文件与脚本, 公司以外环境无法访问:

open-ldap-script

Comments
Write a Comment