LDAP学习笔记<三>深入管理openLDAP

  启动OpenLDAP服务器程序之后,接下来的操作就是通过客户端程序对目录进行操作,包括添加、修改、删除和搜索数据等操作。能对LDAP进行操作的客户端程序很多,下面简单介绍在Linux命令方式下进行这些操作的方法。

 

向目录数据库中添加数据


      初始状态下,LDAP是一个空目录,即没有任何数据。可通过程序代码向目录数据库中添加数据,也可使用OpenLDAP客户端工具ldapadd命令来完成添加数据的操作,该命令可将一个LDIF文件中的条目添加到目录。因此,需要首先创建一个LDIF文件,然后再进行添加操作。

 

1.LDIF文本条目格式

 

      LDIF用文本格式表示目录数据库的信息,以方便用户创建、阅读和修改。在LDIF文件中,一个条目的基本格式如下:

写道
# 注释
dn: 条目名
属性描述: 值
属性描述: 值
属性描述: 值
... ...
 

      dn行类似于关系数据库中一条记录的关键字,不能与其他dn重复。一个LDIF文件中可以包含多个条目,每个条目之间用一个空行分隔。
      例如,以下内容组成一个条目:

写道
1: dn: dc=dlw, dc=com
2: objectclass: top
3: objectclass: dcobject
4: objectclass: organization
5: dc: dlw
6: o: dlw,Inc.
 

在以上文本中,各行含义如下:

 

  • 第1行的dn定义该条目的标识。
  • 第2~4行定义该条目的objectcCass,可以定义多个属性,如上面代码中定义了3个objectClass。条目的属性根据objectClass的不同而不同,有的objectClass有必须设置的属性。在2~4行的3个objectClass中,top没有必须定义的属性,dcobject必须定义属性dc,用来表示一个域名的部分,而organization必须定义属性o,用来表示一个组织的名称。
  • 根据objectClass的要求,第5、6行分别定义属性dc和属性o的值。

2.了解objectClass


      LDAP中,一个条目必须包含一个objectClass属性,且需要赋予至少一个值。每一个值将用作一条LDAP条目进行数据存储的模板;模板中包含了一个条目必须被赋值的属性和可选的属性。
      objectClass有着严格的等级之分,最顶层是top和alias。例如,organizationalPerson这个objectClass就隶属于person,而person又隶属于top。

 

      objectClass可分为以下3类:

  • 结构型(Structural):如person和organizationUnit;
  • 辅助型(Auxiliary):如extensibeObject;
  • 抽象型(Abstract):如top,抽象型的objectClass不能直接使用。

在OpenLDAP的schema中定义了很多objectClass,下面列出部分常用的objectClass的名称。
  ● account
  ● alias
  ● dcobject
  ● domain
  ● ipHost
  ● organization
  ● organizationalRole
  ● organizationalUnit
  ● person
  ● organizationalPerson
  ● inetOrgPerson
  ● residentialPerson
  ● posixAccount
  ● posixGroup

 

3.了解Attribute


      属性(Attribute)类似于程序设计中的变量,可以被赋值。在OpenLDAP中声明了许多常用的Attribute(用户也可自己定义Attribute)。常见的Attribute含义如下:
  ● c:国家。
  ● cn:common name,指一个对象的名字。如果指人,需要使用其全名。
  ● dc:domain Component,常用来指一个域名的一部分。
  ● givenName:指一个人的名字,不能用来指姓。
  ● l:指一个地名,如一个城市或者其他地理区域的名字。
  ● mail:电子信箱地址。
  ● o:organizationName,指一个组织的名字。
  ● ou:organizationalUnitName,指一个组织单元的名字。
  ● sn:surname,指一个人的姓。
  ● telephoneNumber:电话号码,应该带有所在的国家的代码。
  ● uid:userid,通常指某个用户的登录名,与Linux系统中用户的uid不同。

 

提示:objectClass是一种特殊的Attribute,它包含其他用到的Attribute以及其自身。

 

      对于不同的objectClass,通常具有一些必设属性值和一些可选属性值。例如,可使用person这个objectClass来表示系统中一个用户的条目,对于系统中用户通常需要有这样一些信息:姓名、电话、密码、描述等。如下图所示,对于person,通过cn和sn设置用户的名和姓,这是必须设置的,而其他属性则是可选的。

 

 

下面列出部分常用objectClass要求必设的属性。
  ● account:userid。
  ● organization:o。
  ● person:cn和sn。
  ● organizationalPerson:与person相同。
  ● organizationalRole:cn。
  ● organizationUnit:ou。
  ● posixGroup:cn、gidNumber。
  ● posixAccount:cn、gidNumber、homeDirectory、uid、uidNumber。

4.创建LDIF文件


      对以上内容有一定了解之后,就可以编写输入LDIF文件,编辑需要向目录数据库添加的条目了。
      下面根据如下图所示的结构,创建LDIF文件dlw.com.ldif。

 

 

      对上图进行分析,该目录结构分为3层,有4个结点。根据上图可创建LDIF文件如下:
提示:每个结点可用一个dn表示,对于每个结点,又可继续添加新的结点。如在根结点中可添加其他部门ou,在ou=managers结点也可继续添加其他管理人员的信息。

 

写道
1: dn:dc=dlw,dc=com
2: objectclass:top
3: objectclass:dcobject
4: objectclass:organization
5: dc:dlw
6: o:dlw,Inc.
7:
8: dn:ou=managers, dc=dlw, dc=com
9: ou:managers
10: objectclass:organizationalUnit
11:
12: dn:cn=dlw,ou=managers,dc=dlw,dc=com
13: cn:dlw
14: sn:dongliwei
15: objectclass:person
16:
17: dn:cn=test,ou=managers,dc=dlw,dc=com
18: cn:test
19: sn:Test User
20: objectclass:person
 

以上文件中各行的含义如下:

 

  • 第1~6行创建根结点,这部分在前面也有介绍,就不再重复了。
  • 第7、11、16行为空行,用来分隔4个dn条目(4个结点)。
  • 第8~10行定义cn=managers结点的条目,该条目的objectClass为organizationalUnit,因此需要用ou属性定义组织名称。
  • 第12~15行定义cn=dlw结点的条目,该条目使用的objectClass为person,因此需设置cn和sn两个属性值。
  • 第17~20行与第12~15行的意义相同。

 

 

      在以上LDIF文件中,第1、8、12、17行以dn开头,这部分内容必须唯一,并且在向目录数据库添加这些数据时,也要确保这些数据不能与目录数据库中已有数据相同,否则,添加操作将中断。

 

5.从LDIF文件添加到目录数据库


      使用OpenLDAP客户端工具ldapadd命令,可将LDIF文件中的条目添加到目录数据库中,该命令的格式如下:
       ldappadd  选项  LDIF文件
      在ldappadd命令中常用的选项如下:

 

  • -x:进行简单认证。
  • -D:用来绑定服务器的dn。
  • -h:目录服务的地址。
  • -w:绑定dn的密码。
  • -f:使用LDIF文件进行条目添加的文件。

 

将前面编写的LDIF文件的条目数据添加到目录数据库中。
具体操作步骤如下:

(1)检查dlw.com.ldif文件中的内容,需要注意的是,每个冒号后面都需要空一格,而每行结束处不能留有空格字符。
(2)使用以下命令将dlw.com.ldif文件中的条目添加到目录中:

写道
# ldapadd -x -D "cn=root,dc=dlw,dc=com" -w secret -f dlw.com.ldif
 

执行以上命令,如果添加操作正常完成,将显示如下图所示的提示信息,表示添加了4个条目到目录数据库中。

 

 

提示:如果以上命令执行不成功,需要逐个字符检查dlw.com.ldif文件中的内容,特别注意空格的问题。

 

查询


      添加到目录中的条目被保存在目录数据库,在Linux命令界面下,可使用OpenLDAP客户端工具ldapsearch命令来进行查询。该命令的格式如下:


      ldapsearch  选项  过滤  属性值


常用的选项有以下几个:


  ● -x:进行简单认证。
  ● -D:用来绑定服务器的dn。
  ● -w:绑定dn的密码。
  ● -b:指定要查询的根节点。
  ● -H:制定要查询的服务器。

 

使用ldapsearch命令查询“dc=dlw, dc=com”下的所有条目,可使用以下命令:

# ldapsearch -x -b "dc=dlw,dc=com"  

# ldapsearch -x -b "dc=dlw,dc=com"
 

执行结果如下图所示。

 

 

而如果使用以下命令,将查询显示sn中以字符wu开头的条目,将得到如下图所示的查询结果,只找到一个条目。

# ldapsearch -x -b 'dc=dlw,dc=com' 'sn=wu*'  

# ldapsearch -x -b 'dc=dlw,dc=com' 'sn=wu*'
 

 

 

修改条目


      使用OpenLDAP客户端工具ldapmodify命令可对目录数据库中的条目进行修改。该命令的格式如下:


      ldapmodify  选项


      该命令的选项也很多,常用选项与ldapadd类似,这里就不再列出了。
      提示:使用ldapmodify命令不能修改条目的dn,但可以修改其他属性值。

使用ldapmodify命令修改条目信息可以有两种方式:一种是交互式进行修改,另一种是通过文件进行修改。

1.交互式修改


      修改前面创建的条目“cn=test, ou=managers, dc=dlw, dc=com”,将其sn属性修改为“Test User Modify”,并添加一个description属性,设置其值为“add Attribute”。
      首先输入以下命令,进行修改状态:

# ldapmodify -x -D "cn=root,dc=dlw,dc=com" -W secret  

# ldapmodify -x -D "cn=root,dc=dlw,dc=com" -W secret
 

执行以上命令后,终端将等候用户输入需要修改条目的dn,输入以下内容:

  1. dn: cn=test, ou=managers, dc=dlw, dc=com  
  2. changetype: modify  
  3. replace: sn  
  4. sn: Test User Modify  
dn: cn=test, ou=managers, dc=dlw, dc=comchangetype: modifyreplace: snsn: Test User Modify
 

      以上输入内容中,第1行查找需要修改的条目,第2行设置修改模式,第3行设置需要替换的属性sn,第4行给属性sn重新设置一个值,替换该属性原有的值。
      输入完以上内容之后再按Enter键,程序将按以上设置更新数据,然后按Ctrl+C键退出修改命令。执行过程如下图所示。

 

使用以上命令修改条目的数据之后,可使用以下命令查看是否修改成功:

#ldapsearch -x -b 'dc=dlw,dc=com' 'cn=test'  

#ldapsearch -x -b 'dc=dlw,dc=com' 'cn=test'
 

执行以上命令查看test条目的数据如下图所示,可以看到sn属性被修改了。

 

 

2.通过文件修改


    通过前面的方式对条目进行修改时,很不方便,如果在交互方式时输错了某个字符,只能中断命令后重新进行修改。因此,更好的修改方法是首先将修改时输入的文字保存到一个文件中,然后以该文件作为输入进行修改。用这种方式进行操作,首先需要创建一个临时文件,用来保存需要进行的修改操作,下面演示这种方式的修改过程。

【例子】 通过修改命令将前面LDAP数据库中的信息还原,即将sn属性由“Test User Modify”修改为“Test User”。
具体操作步骤如下:
(1)使用vi编辑器创建一个文件modify,在其中输入以下内容:

  1. dn: cn=test,ou=managers,dc=dlw,dc=com  
  2. changetype: modify  
  3. replace: sn  
  4. sn: Test User  
dn: cn=test,ou=managers,dc=dlw,dc=comchangetype: modifyreplace: snsn: Test User

 从以上输入内容可看到,与在交互式时输入的内容完全相同。
技巧:使用文件方式修改条目,可方便修改和检查,若某个地方有输入错误,可修改后再调用ldapmodify进行修改,减少输入量。

(2)使用以下命令调用modify的内容进行修改:

 # ldapmodify -x -D "cn=root,dc=dlw,dc=com" -w secret -f modify  

# ldapmodify -x -D "cn=root,dc=dlw,dc=com" -w secret -f modify
 

执行结果如下图所示。

 

 

删除条目


      对于目录数据库中不用的条目,也可使用ldapdelete命令将其删除。该命令的格式如下:


      ldapdelete  选项  删除条目


      该命令使用的选项与ldapadd类似,就不再列出来了。
      删除目录数据库中的“cn=test,ou=managers,dc=dlw,dc=com”条目,具体命令如下:

  1. # ldapdelete -x -D "cn=root,dc=dlw,dc=com" -w secret \  
  2. > "cn=test,ou=managers,dc=dlw,dc=com"  
# ldapdelete -x -D "cn=root,dc=dlw,dc=com" -w secret \> "cn=test,ou=managers,dc=dlw,dc=com"
 

      顺利执行以上命令后,终端上将不会有任何信息输出,表示完成了删除操作。
      使用ldapdelete命令只能删除树形结构中的叶结点条目,如果删除非叶结点条目,将出现错误提示。例如,执行以下命令删除根结点“dc=dlw,dc=com”,由于根结点下面还有结点,将显示如下图所示的错误提示信息:

 

 

Python代码   收藏代码
  1. # ldapdelete -x -D "cn=root,dc=dlw,dc=com" -w secret "dc=dlw,dc=com"  
# ldapdelete -x -D "cn=root,dc=dlw,dc=com" -w secret "dc=dlw,dc=com"
 

数据导出


      通过ldapadd命令可向目录数据库中添加数据,在某些情况下,可能还需要进行反向操作,即将目录数据库中的数据导出。
      使用ldapsearch命令对目录数据库进行搜索,然后通过重定向将搜索结果保存到一个文件中,可达到导出数据的目的。另外,导出数据更常用的是slapcat命令,该命令的格式如下:


      slapcat  选项


      最常用的选项就是-l,表示导出为LDIF文件格式。
      如将本章前面例子中创建的目录数据库导出为export.ldif文件,可使用以下命令:

#slapcat -l export.ldif  

#slapcat -l export.ldif
 

      执行以上命令将在当前工作目录得到文件export.ldif,打开文件将显示如下图所示的内容:

 

 

提示:从导出结果可看出,除了使用ldapadd命令添加到目录数据库中的条目数据外,还导出了很多其他信息,包括条目录UUID、时间戳等信息。

 

 

设置主从LDAP服务器


      在某些时候,为了对LDAP服务器进行负载均衡,可能希望设置多台LDAP服务器。对于设置多台LDAP服务器的关键问题是数据的同步问题,使用slurpd进程可进行主LDAP服务器向从LDAP服务器复制数据的操作。下面将介绍架设主从LDAP服务器的过程。

 

多台LDAP服务器工作过程


      对于多台LDAP服务器,可设置一台为主服务器,其他的为从服务器。本节介绍一台从服务器的配置,若是多台从服务器也可按此步骤进行操作。
注意:在进行配置之前应首先确保每个LDAP服务器都已安装好OpenLDAP服务器程序,并能正确工作。
      通过本节下面介绍的方法配置好主从LDAP服务器之后,在主服务器运行slurpd进程,该进程使用LDAP协议从主服务器的数据库更新从服务器的数据,具体操作过程如下:


(1)LDAP客户端向从服务器提交一个LDAP修改请求。
(2)从服务器给LDAP客户端返回一个指向主服务器的引用。
(3)LDAP客户端向主服务器提交LDAP修改请求。
(4)主服务器对数据库中的数据进行修改,并将改变写入本机的日志文件。
(5)在主服务器运行的slurpd进程检查到日志中有新内容,通过日志的信息将改变发送给从服务器。
(6)从服务器接收slurpd发来的信息,对本地数据进行修改。


      以上过程就是使用slurpd进程进行数据复制的过程。从以上过程可看出,需要在主服务器的配置文件中设置要向哪些从服务器发送复制信息、主服务器还要设置一个记录数据改变的日志文件,而从服务器需要设置一个指向主服务器的链接。

复制数据库


首先,把主从服务器关闭。通过以下三步操作静态同步主从服务器上的数据:

 

  • 把主服务器上/var/lib/ldap目录下的所有数据库文件全部拷贝到从服务器的同目录中,覆盖原有文件。
  • 把主服务器上的/etc/ldap/schema目录下的所有schema文件拷贝到从服务器的同目录中,覆盖原有文件。
  • 把主服务器上/etc/ldap/slapd.conf文件拷贝到从服务器的同目录中,覆盖原有文件。

 

设置主服务器


配置主服务器上的slapd.conf文件,取消replogfile指令前的注释符号,取消后的结果如下:

  1. # Replicas of this database  
  2. replogfile      /var/lib/ldap/replog  
# Replicas of this databasereplogfile      /var/lib/ldap/replog
 

增加replica指令,如:

  1. #replace config  
  2. replica uri=ldap://192.168.14.21:389     #指定从服务器主机名和端口号  
  3. binddn="cn=root,dc=dlw,dc=com"         #指定需同步的DN的管理员  
  4. bindmethod=simple credentials=111111  #指定验证方式和需同步的DN的管理员密码  
#replace configreplica uri=ldap://192.168.14.21:389     #指定从服务器主机名和端口号binddn="cn=root,dc=dlw,dc=com"         #指定需同步的DN的管理员bindmethod=simple credentials=111111  #指定验证方式和需同步的DN的管理员密码
 

设置从服务器


配置从服务器上的slapd.conf文件,增加updatedn指令,如:

  1. updatedn " cn=root,dc=dlw,dc=com"          #与主服务器的binddn对应  
updatedn " cn=root,dc=dlw,dc=com"          #与主服务器的binddn对应
 

在从服务器的配置文件中,不要包含replica和replogfile指令。


测试主从LDAP服务器


经过以上步骤的操作,主从LDAP服务器都已准备好,接下来就可以测试相关操作。


   1.启动主LDAP服务器
        在主LDAP服务器中启动slapd进程和slurpd进程。
   2.启动从LDAP服务器
        在主LDAP服务器中启动slapd进程。


【例子】测试主从LDAP服务器。
具体操作步骤如下:

(1)在主LDAP服务器中使用以下命令修改一个条目:

  1. #ldapmodify -x -D "cn=root,dc=dlw,dc=com" -w secret  
#ldapmodify -x -D "cn=root,dc=dlw,dc=com" -w secret
 

输入以下内容,修改cn=dlw条目的内容:

  1. dn: cn=dlw,ou=managers,dc=dlw,dc=com  
  2. changetype: modify  
  3. replace: sn  
  4. sn: dongliwei  
dn: cn=dlw,ou=managers,dc=dlw,dc=comchangetype: modifyreplace: snsn: dongliwei
 

输入后按Enter键完成修改,操作过程如图5-7所示(将sn修改为dongliwei)。

 

 

(2)在从LDAP服务器中进行操作,查看主LDAP服务器中的操作是否被复制到从LDAP服务器中来了。在从LDAP服务器中使用以下命令进行查询:

#ldapsearch -x -b "dc=dlw,dc=com" "cn=dlw"  

#ldapsearch -x -b "dc=dlw,dc=com" "cn=dlw"
 

执行结果如下图所示,从图中可看到其中的sn也被修改为dongliwei了(数据库中原来的内容为zhangsan.modi,是前面例子中修改的值),即被主LDAP服务器进行了同步复制。

 

 

 

OpenLDAP在用户认证的应用


      OpenLDAP经常用在用户登录认证方面,通过LDAP的数据复制功能,可让用户使用一个账户登录网络中使用LDAP服务的所有服务器。在主LDAP服务器中设置好用户账户数据,然后通过在网络中的任意客户端都可使用设置的账号进行登录操作。下面将简单介绍将用户认证迁移到LDAP的操作方法。

用户认证用到的ojbectClass


      在LDAP中用来保存用户认证条目的objectClass主要有以下3个,分别用来保存组、用户、密码等信息到目录的条目中。

  • posixGroup:可设置属性cn、userPassword、gidNumber等。
  • posixAccount:可设置属性cn、gidNumber、uid、uidNumber、homeDirectory、loginShell等。
  • shadowAccount:可设置属性uid、shadowExpire、shadowFlag、shadowInactive、shadowLastChange、shadowMax、shadowMin、shadowWarning、userPassword等。

提示:从上面列出的属性的名称可以很容易地与组、用户的相关信息联系起来。

 

使用迁移工具


      要使用LDAP进行用户认证,首先应该考虑的就是数据迁移的工作量。如果要操作员从/etc/passwd和/etc/group文件中逐个将信息重新录入,工作量将非常大。
      OpenLDAP为用户考虑到了这些迁移工作,提供了多个迁移工具的脚本程序,这些程序位于/usr/share/openldap/migration/目录中,在该目录中有很多扩展名为pl和sh的脚本文件,通过这些迁移工具,可以很方便地将系统中的用户迁移到LDAP目录数据库中。下面介绍具体的迁移步骤。

【例子】将系统中的用户信息迁移到LDAP目录数据库中。
具体操作步骤如下:
(1)修改/usr/share/openldap/migration/migrate_common.ph文件,在其中查找以下内容:

  1. $DEFAULT_BASE="dc=padl,dc=com";  
$DEFAULT_BASE="dc=padl,dc=com";
 

将其修改为目录服务器使用的根,如本章使用的例子要改为以下形式:

  1. $DEFAULT_BASE="dc=dlw,dc=com";  
$DEFAULT_BASE="dc=dlw,dc=com";
 

保存后退出。

 

 

(2)使用以下命令执行脚本migrate_base.pl,用来创建根项,并为Hosts、Networks、Group和People等创建低一级的组织单元(执行该命令将生成base.ldif文件):

  1. #./migrate_base.pl > base.ldif  
#./migrate_base.pl > base.ldif
 

(3)由于本章前面已在LDAP服务器中创建了根项“dc=dlw,dc=com”,因此将base.ldif文件中的第1个条目删除,另外,在用户认证中只用到组和用户,也将其他无关条目删除,只保存以下内容(例子):

  1. dn: ou=People,dc=dlw,dc=com  
  2. ou: People  
  3. objectClass: top  
  4. objectClass: organizationalUnit  
  5.   
  6. dn: ou=Group,dc=dlw,dc=com  
  7. ou: Group  
  8. objectClass: top  
  9. objectClass: organizationalUnit  
dn: ou=People,dc=dlw,dc=comou: PeopleobjectClass: topobjectClass: organizationalUnitdn: ou=Group,dc=dlw,dc=comou: GroupobjectClass: topobjectClass: organizationalUnit
 

(4)使用以下命令将base.ldif文件中的条目导入目录数据库:

# ldapadd -x -D "cn=root,dc=dlw,dc=com" -w secret -f  base.ldif  

# ldapadd -x -D "cn=root,dc=dlw,dc=com" -w secret -f  base.ldif
 

执行结果如下图所示。

 

 

(5)开始迁移组信息。使用以下命令将/etc/group中的组信息保存到临时文件group.tmp中:

#cat /etc/group > group.tmp  

#cat /etc/group > group.tmp
 

(6)系统组不导入LDAP目录数据库中,因此需对group.tmp文件中的信息进行编辑,只保留需要导入LDAP目录数据库的组的信息。


(7)使用以下命令将组的数据生成LDIF条目信息:
#./migrate_group.pl group.tmp > group.ldif  

#./migrate_group.pl group.tmp > group.ldif
 

(8)使用cat命令查看group.ldif的内容,可看到已按posixGroup这种objectClass将组的数据组织完成,如下图所示。

 

 

(9)类似地,使用以下命令导出/etc/passwd中的用户数据,并删除不需要的用户,然后使用migrate_passwd.pl脚本生成LDIF文件:

  1. #cat /etc/passwd > passwd.tmp  
  2. #./migrate_passwd.pl passwd.tmp > passwd.ldif  
  3. #cat passwd.ldif  
#cat /etc/passwd > passwd.tmp#./migrate_passwd.pl passwd.tmp > passwd.ldif#cat passwd.ldif
 

提示:从上面列出的属性的名称可以很容易地与组、用户的相关信息联系起来。

 

(10)使用以下命令将组和用户信息导入目录数据库

  1. #ldapadd -x -D "cn=root,dc=dlw,dc=com" -w 111111 -f group.ldif  
  2. #ldapadd -x -D "cn=root,dc=dlw,dc=com" -w 111111 -f passwd.ldif  
#ldapadd -x -D "cn=root,dc=dlw,dc=com" -w 111111 -f group.ldif#ldapadd -x -D "cn=root,dc=dlw,dc=com" -w 111111 -f passwd.ldif
 

执行以上命令的过程如下图所示。

 

 

(11)使用以下命令查看目录数据库中用户root的信息,用“uid=root”作查询条件:

  1. #ldapsearch -x -b 'dc=dlw,dc=com' 'uid=root'  
#ldapsearch -x -b 'dc=dlw,dc=com' 'uid=root'
 

查找结果如下图所示。

 

 

      通过以上的操作,就将需要导入的组和用户的信息导入到了目录数据库中,接下来还需要对客户端进行设置,使用LDAP进行登录验证操作。

 

 

设置客户端登录


若客户端要使用LDAP进行用户登录认证,则可使用本地计算机中不存在的用户名进行登录操作。
【例子】修改配置文件,设置客户端使用LDAP进行认证。
具体操作步骤如下:
(1)修改客户端计算机中的/etc/sysconfig/authconfig文件,将以下项都修改为yes:

  1. USELDAP=yes  
  2. USELDAPAUTH=yes  
  3. USEMD5=no  
  4. USESHADOW=yes  
  5. USELOCAUTHORIZE=yes  
USELDAP=yesUSELDAPAUTH=yesUSEMD5=noUSESHADOW=yesUSELOCAUTHORIZE=yes
 

(2)修改客户端计算机中的/etc/openldap/ldap.conf文件,修改内容如下:

  1. host 192.168.14.20  
  2. BASE dc=dlw,dc=com  
  3. ssl off  
host 192.168.14.20BASE dc=dlw,dc=comssl off
 

(3)修改客户端计算机中的/etc/nsswitch.conf文件,在passwd、shadow、group后面都加上ldap,如下图所示。

 

 

      经过以上配置以后,在客户端就可以使用LDAP目录数据库中的用户信息在客户端进行登录操作了。登录操作与使用本地用户账号相同,这里就不再演示了。

 

 

LDAP Schema


      Schema是LDAP的一个重要组成部分,类似于数据库的模式定义,LDAP的Schema定义了LDAP目录所应遵循的结构和规则,比如一个 objectclass会有哪些属性,这些属性又是什么结构等等,schema给LDAP服务器提供了LDAP目录中类别,属性等信息的识别方式,让这些可以被LDAP服务器识别。
在LDAP的schema中,有四个重要的元素:

    Objectclass
    objectclass定义了一个类别,这个类别会被不同的目录(在LDAP中就是一个Entry)用到,它说明了该目录应该有哪些属性,哪些属性是必须的,哪些又是可选的。一个objectclass的定义包括名称(NAME),说明(DESC),类型(STRUCTURAL或AUXILARY ,表示是结构型的还是辅助型的),必须属性(MUST),可选属性(MAY)等信息。

Python代码   收藏代码
  1. Objectclass格式:  
  2. objectclass = ( whsp  
  3. numericoid whsp //全局唯一的 OID  
  4. [ "NAME" qdescrs ] //类名称  
  5. [ "DESC" qdstring ] //类描述  
  6. [ "OBSOLETE" whsp ]  
  7. [ "SUP" oids ] ; //父类  
  8. [ ( "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" ) whsp ]  
  9. [ "MUST" oids ] ; //必填属性集合  
  10. [ "MAY" oids ] //选填属性集合  
  11. whsp ")"  
Objectclass格式:objectclass = ( whspnumericoid whsp //全局唯一的 OID[ "NAME" qdescrs ] //类名称[ "DESC" qdstring ] //类描述[ "OBSOLETE" whsp ][ "SUP" oids ] ; //父类[ ( "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" ) whsp ][ "MUST" oids ] ; //必填属性集合[ "MAY" oids ] //选填属性集合whsp ")"
 

例如:

  1. # Object Class Definitions   
  2. objectclass ( 1.3.6.1.4.1.7914.1.2.2.1 NAME 'kunmailUser'   
  3. DESC 'KunMail-LDAP User'   
  4. SUP top   
  5. STRUCTURAL  
  6. MUST(username$cn$vuid$vgid)  
  7. MAY(maildir$home$clearpw$forwardAddr$quota$storeHost$delivery$mailReplyText$active))  
# Object Class Definitions objectclass ( 1.3.6.1.4.1.7914.1.2.2.1 NAME 'kunmailUser' DESC 'KunMail-LDAP User' SUP top STRUCTURALMUST(username$cn$vuid$vgid)MAY(maildir$home$clearpw$forwardAddr$quota$storeHost$delivery$mailReplyText$active))
 

      这里kunmailUser这种数据,要包含maildir $ home $ clearpw $ forwardAddr $ quota $ storeHost $ delivery $ mailReplyText $ active等可选项,还要包括username $ cn $ vuid $ vgid 必选项。 可选项用MAY()来包含,必选项用MUST()来包含。DESC是说明项。SUP表示父类(有点像面向对象编程啊)top表示没有父类,他自己是顶级。STRUCTURAL是存储方式。一般来说每个节点都要包含一个ABSTRACT类("top" or "alias"), 至少一个STRUCTURAL类,0个或者多个AUXILIARY类。AUXILIARY表示辅助型、STRUCTURAL表示结构型(默认)、ABSTRACT表示摘要型。
      下面定义一个允许将myPhoto增加到任何已经存在的条目中的auxiliary对象类:

Python代码   收藏代码
  1. objectclass= ( 1.1.2.2.1 NAME 'myPhotoObject'  
  2. DESC 'mixin myPhoto'  
  3. AUXILIARY  
  4. MAY myPhoto )  
objectclass= ( 1.1.2.2.1 NAME 'myPhotoObject'DESC 'mixin myPhoto'AUXILIARYMAY myPhoto )
 

      如果您的组织需要一个私有的结构化对象类来表示用户,你可以子类化任何一个已经存在的person类,比如inetOrgPerson(RFC2798),然后增加需要的属性:

  1. objectclass =( 1.1.2.2.2 NAME 'myPerson'  
  2. DESC 'my person'  
  3. SUP inetOrgPerson  
  4. MUST ( 'myUniqueName' $ 'givenName' )  
  5. MAY 'myPhoto' )  
objectclass =( 1.1.2.2.2 NAME 'myPerson'DESC 'my person'SUP inetOrgPersonMUST ( 'myUniqueName' $ 'givenName' )MAY 'myPhoto' )
 

      该对象类从inetOrgPerson中继承允许的或者必须的属性,但是,要求myUniqueName和givenName,允许myPhoto。

 

 

Attribute


      attribute就是一个上面objectclass中可能包含的属性,对其的定义包括名称,数据类型,单值还是多值以及匹配规则等。后面用具体的例子来说明。

 

Attribute格式:

  1. attributeType ( whsp  
  2. numericoid whsp //全局唯一的 OID  
  3. [ "NAME" qdescrs ] //属性名称  
  4. [ "DESC" qdstring ] //属性描述  
  5. [ "OBSOLETE" whsp ]  
  6. [ "SUP" woid ] //本属性从其它属性中派生出来的  
  7. [ "EQUALITY" woid //相等性匹配  
  8. [ "ORDERING" woid//顺序匹配  
  9. [ "SUBSTR" woid ] //字符串匹配  
  10. [ "SYNTAX" whsp noidlen whsp ] //字段的数据类型的OID  
  11. [ "SINGLE-VALUE" whsp ] //定义本属性为单值(默认多值)  
  12. [ "COLLECTIVE" whsp ] //default not collective  
  13. [ "NO-USER-MODIFICATION" whsp ]//default user modifiable  
  14. [ "USAGE" whsp AttributeUsage ]//default userApplications  
  15. whsp ")"  
  16. AttributeUsage =  
  17. "userApplications" /  
  18. "directoryOperation" /  
  19. "distributedOperation" / ; DSA-shared  
attributeType ( whspnumericoid whsp //全局唯一的 OID[ "NAME" qdescrs ] //属性名称[ "DESC" qdstring ] //属性描述[ "OBSOLETE" whsp ][ "SUP" woid ] //本属性从其它属性中派生出来的[ "EQUALITY" woid //相等性匹配[ "ORDERING" woid//顺序匹配[ "SUBSTR" woid ] //字符串匹配[ "SYNTAX" whsp noidlen whsp ] //字段的数据类型的OID[ "SINGLE-VALUE" whsp ] //定义本属性为单值(默认多值)[ "COLLECTIVE" whsp ] //default not collective[ "NO-USER-MODIFICATION" whsp ]//default user modifiable[ "USAGE" whsp AttributeUsage ]//default userApplicationswhsp ")"AttributeUsage ="userApplications" /"directoryOperation" /"distributedOperation" / ; DSA-shared
 

whsp是空格的意思(' ')。numericoid 是全局唯一的 OID,是带.的十进制形式 (e.g. 1.1.0), qdescrs有一个或几个意思, woid 可以使名称或者是 OID 可选择的一定长度的后缀(e.g {10})。
例如,属性类型name和cn在core.schema中如下定义:

Python代码   收藏代码
  1. attributeType ( 2.5.4.41 NAME 'name'  
  2. DESC 'name(s) associated with the object'  
  3. EQUALITY caseIgnoreMatch  
  4. SUBSTR caseIgnoreSubstringsMatch  
  5. SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )  
  6. attributeType ( 2.5.4.3 NAME ( 'cn' $ 'commonName' )  
  7. DESC 'common name(s) assciated with the object'  
  8. SUP name )  
  9. attributetype ( 1.3.6.1.4.1.7914.1.2.1.6 NAME 'quota'   
  10. DESC 'The amount of space the user can use until all further messages get bounced.'   
  11. SYNTAX 1.3.6.1.4.1.1466.115.121.1.44   
  12. SINGLE-value )   
attributeType ( 2.5.4.41 NAME 'name'DESC 'name(s) associated with the object'EQUALITY caseIgnoreMatchSUBSTR caseIgnoreSubstringsMatchSYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )attributeType ( 2.5.4.3 NAME ( 'cn' $ 'commonName' )DESC 'common name(s) assciated with the object'SUP name )attributetype ( 1.3.6.1.4.1.7914.1.2.1.6 NAME 'quota' DESC 'The amount of space the user can use until all further messages get bounced.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-value ) 
 

请注意,每一个都定义了属性的OID,给出了一个短的名称,以及一个简短的描述。每一个名称都是OID的一个别名。Slapd(8)在返回结果的时候,将返回第1个列出的名称。
      第1个名称,name,保存了directoryString(UTF-8编码的Unicode)语法。该语法由OID说明。(1.3.6.1.4.1.1466.115.121.1.15标识了目录字符串语法)。还说明了一个推荐长度为32768的选项。服务器应该支持该长度的值,但是,也可以支持更长的值。该域没有指明长度限制,因此,在服务器上被忽略,并且服务器不会限制其大小。另外,相等和子串匹配使用不区分大小写的规则。下面是经常使用的语法和匹配规则(OpenLDAP支持这些,以及更多)
      第2个属性,cn,是name的一个子类型,因此,它继承了语法,匹配规则,并且使用name.commonName作为别名。
      两个属性都没有限制到单一值。都可以被用户应用程序所使用,都不存在过期,都不是集合。
      很多组织为用户保留唯一的名字(unique name),虽然用户可以使用displayName,但是这个属性(name)依旧由用户控制。而不是organization。我们可以从 inetorgperson.schema 拷贝displayName ,替换OID,name,和描述(description)。

  1. attributetype ( 1.1.2.1.1 NAME 'myUniqueName'  
  2. DESC 'unique name with my organization'  
  3. EQUALITY caseIgnoreMatch  
  4. SUBSTR caseIgnoreSubstringsMatch  
  5. SYNTAX 1.3.6.1.4.1.1466.115.121.1.15  
  6. SINGLE-VALUE )  
attributetype ( 1.1.2.1.1 NAME 'myUniqueName'DESC 'unique name with my organization'EQUALITY caseIgnoreMatchSUBSTR caseIgnoreSubstringsMatchSYNTAX 1.3.6.1.4.1.1466.115.121.1.15SINGLE-VALUE )
 

但是,如果我们要使name属性包含一个断言,这个属性可以被定义为name的子属性。

 

  1. attributetype ( 1.1.2.1.1 NAME 'myUniqueName'  
  2. DESC 'unique name with my organization'  
  3. SUP name )  
attributetype ( 1.1.2.1.1 NAME 'myUniqueName'DESC 'unique name with my organization'SUP name )
 

      很多的组织为每一个用户保留一个头像。myPhoto属性类型的定义可以用来保存用户的头像。当然用户可以选择jpegPhoto属性类型(RFC2798)(或其子类型)来保存头像。当然你只能在图片符合JPEG File Interchange Format时使用。
      当然,一个使用八进制语法的属性类型可以这样的定义:

 

  1. attributetype ( 1.1.2.1.2 NAME 'myPhoto'  
  2. DESC 'a photo (application defined format)'  
  3. SYNTAX 1.3.6.1.4.1.1466.115.121.1.40  
  4. SINGLE-VALUE )  
attributetype ( 1.1.2.1.2 NAME 'myPhoto'DESC 'a photo (application defined format)'SYNTAX 1.3.6.1.4.1.1466.115.121.1.40SINGLE-VALUE )
 

      在这,语法中并没有置顶photo的格式(format),这里假设访问属性的应用可以对其值进行处理。
      如果你想支持多种图片格式,你需要为每一个格式定义属性类型。为图片添加类型信息的前缀。或者使用ASN.1描述值,和use the ;binary transfer option。
      可以使图片属性能够保存URI,你可以在labeledURI(RFC2079)后创建一个属性,或者创建一个子类型。

 

  1. attributetype ( 1.1.2.1.3 NAME 'myPhotoURI'  
  2. DESC 'URI and optional label referring to a photo'  
  3. SUP labeledURI )  
attributetype ( 1.1.2.1.3 NAME 'myPhotoURI'DESC 'URI and optional label referring to a photo'SUP labeledURI )
 

Syntax


      syntax是LDAP中的“语法”,其实就是LDAP中会用到的数据类型和数据约束,这个语法是遵从X.500中数据约束的定义的。其定义需要有一个ID(遵从X.500)以及说明(DESP)

 

 

Commonly Used Syntaxes

Name

OID

Description

boolean

1.3.6.1.4.1.1466.115.121.1.7

boolean value

distinguishedName

1.3.6.1.4.1.1466.115.121.1.12

DN

directoryString

1.3.6.1.4.1.1466.115.121.1.15

UTF-8 string

IA5String

1.3.6.1.4.1.1466.115.121.1.26

ASCII string

Integer

1.3.6.1.4.1.1466.115.121.1.27

integer

Name and Optional UID

1.3.6.1.4.1.1466.115.121.1.34

DN plus UID

Numeric String

1.3.6.1.4.1.1466.115.121.1.36

numeric string

OID

1.3.6.1.4.1.1466.115.121.1.38

object identifier

Octet String

1.3.6.1.4.1.1466.115.121.1.40

arbitary octets

Printable String

1.3.6.1.4.1.1466.115.121.1.44

printable string

 

 

Matching Rules


      是用来指定某属性的匹配规则,实际上就是定义一个特殊的Syntax的别名,让LDAP服务器可以识别,并对定义的属性进行匹配。

 

 

Commonly Used Matching Rules

Name

Type

Description

booleanMatch

equality

boolean

octetStringMatch

equality

octet string

objectIdentiferMatch

equality

OID

distinguishedNameMatch

equality

DN

uniqueMemberMatch

equality

Name with optional UID

numericStringMatch

equality

numerical

numericStringOrderingMatch

ordering

numerical

numericStringSubstringsMatch

substrings

numerical

caseIgnoreMatch

equality

case insensitive, space insensitive

caseIgnoreOrderingMatch

ordering

case insensitive, space insensitive

caseIgnoreSubstringsMatch

substrings

case insensitive, space insensitive

caseExactMatch

equality

case sensitive, space insensitive

caseExactOrderingMatch

ordering

case sensitive, space insensitive

caseExactSubstringsMatch

substrings

case sensitive, space insensitive

caseIgnoreIA5Match

equality

case insensitive, space insensitive

caseIgnoreIA5OrderingMatch

ordering

case insensitive, space insensitive

caseIgnoreIA5SubstringsMatch

substrings

case insensitive, space insensitive

caseExactIA5Match

equality

case sensitive, space insensitive

caseExactIA5OrderingMatch

ordering

case sensitive, space insensitive

caseExactIA5SubstringsMatch

substrings

case sensitive, space insensitive

 

      LDAP的schema的主要元素就是这些了,下面列举出了一些LDAP规定好的或是现在比较通用的schema,一般的LDAP服务器都应该可以识别这些定义。
      这就是一个名为subschema的objectclass的定义:

 

  1. objectclass=(2.5.20.1 NAME 'subschema'  AUXILIARY  
  2.  MAY ( dITStructureRules $ nameForms $ ditContentRules $  
  3. objectClasses $ attributeTypes $ matchingRules $ matchingRuleUse ) )  
objectclass=(2.5.20.1 NAME 'subschema'  AUXILIARY MAY ( dITStructureRules $ nameForms $ ditContentRules $objectClasses $ attributeTypes $ matchingRules $ matchingRuleUse ) )
 

      首先是ID,这里是2.5.20.1,接着是NAME,AUXILIARY说明是辅助型,之后是可选属性的定义,subschema中没有定义必须属性,如果需要定义,应该和MAY一样,将属性放在MUST()中并用$隔开
      再来看一个属性定义:

 

  1. attributetype ( 2.5.4.3 NAME 'cn' SUP name EQUALITY caseIgnoreMatch )  
attributetype ( 2.5.4.3 NAME 'cn' SUP name EQUALITY caseIgnoreMatch )
 

      可以看到cn属性的父属性是name,它相等性匹配于caseIgnoreMatch(匹配原则为EQUALITY,还有如SUBSTR是字符串匹配,ORDERING是顺序匹配)
      syntax定义一般都比较简单,如:

 

  1. ( 1.3.6.1.4.1.1466.115.121.1.6  DESC  'String' )  
( 1.3.6.1.4.1.1466.115.121.1.6  DESC  'String' )
 

      这个定义说明,这一串数字1.3.6.1.4.1.1466.115.121.1.5就代表了LDAP中的字符串,这个数字串的定义和X.500相关,包括了它的存储方式,所占空间大小等。
      最后看看Matching Rule的例子,前面提到了caseIgnoreMatch,就看他的吧

 

  1. attributetype ( 2.5.13.2 NAME 'caseIgnoreMatch'  
  2.       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )  
attributetype ( 2.5.13.2 NAME 'caseIgnoreMatch'      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 

      其实1.3.6.1.4.1.1466.115.121.1.15 就是LDAP数据类型Directory String的ID,说明前面的cn需要等于这个数据类型才有效。
      还有很多常用schema的定义都在了RFC2252中,LDAP服务器都应该支持这些基本的schema。好了,现在基本对LDAP中的schema有个一个大致的说明,可能有不到位或不妥之处,还望大家指正。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值