1. LDAP基本模型
1.1. 信息模型:描述LDAP的信息表示方式
在LDAP中信息以树状方式组织,在树状信息中的基本数据单元是条目,而每个条目由属性构成,属性中存储有属性值;LDAP中的信息模式,类似于面向对象的概念,在LDAP中每个条目必须属于某个或多个对象类(Object Class),每个Object Class由多个属性类型组成,每个属性类型有所对应的语法和匹配规则;对象类和属性类型的定义均可以使用继承的概念。每个条目创建时,必须定义所属的对象类,必须提供对象类中的必选属性类型的属性值,在LDAP中一个属性类型可以对应多个值。
在LDAP中把对象类、属性类型、语法和匹配规则统称为Schema(图表),在LDAP中有许多系统对象类、属性类型、语法和匹配规则,这些系统Schema在LDAP标准中进行了规定,同时不同的应用领域也定义了自己的Schema,同时用户在应用时,也可以根据需要自定义Schema。这有些类似于XML,除了XML标准中的XML定义外,每个行业都有自己标准的DTD或DOM定义,用户也可以自扩展;也如同XML,在LDAP中也鼓励用户尽量使用标准的Schema,以增强信息的互联互通。
在Schema中最难理解的是匹配规则,这是LDAP中为了加快查询的速度,针对不同的数据类型,可以提供不同的匹配方法,如针对字符串类型的相等、模糊、大于小于均提供自己的匹配规则。
1.2. 命名模型:描述LDAP中的数据如何组织
LDAP中的命名模型,也即LDAP中的条目定位方式。在LDAP中每个条目均有自己的DN和RDN。DN是该条目在整个树中的唯一名称标识,RDN是条目在父节点下的唯一名称标识,如同文件系统中,带路径的文件名就是DN,文件名就是RDN。
1.3. 功能模型:描述LDAP中的数据操作访问
在LDAP中共有四类10种操作:查询类操作,如搜索、比较;更新类操作,如添加条目、删除条目、修改条目、修改条目名;认证类操作,如绑定、解绑定;其它操作,如放弃和扩展操作。除了扩展操作,另外9种是LDAP的标准操作;扩展操作是LDAP中为了增加新的功能,提供的一种标准的扩展框架,当前已经成为LDAP标准的扩展操作,有修改密码和StartTLS扩展,在新的RFC标准和草案中正在增加一些新的扩展操作,不同的LDAP厂商也均定义了自己的扩展操作。
1.4. 安全模型:描述LDAP中的安全机制
LDAP中的安全模型主要通过身份认证、安全通道和访问控制来实现。
1.4.1. 身份认证
在LDAP中提供三种认证机制,即匿名、基本认证和SASL(Simple Authentication and Secure Layer)认证。匿名认证即不对用户进行认证,该方法仅对完全公开的方式适用;基本认证均是通过用户名和密码进行身份识别,又分为简单密码和摘要密码认证;SASL认证即LDAP提供的在SSL和TLS安全通道基础上进行的身份认证,包括数字证书的认证。
1.4.2. 通讯安全
在LDAP中提供了基于SSL/TLS的通讯安全保障。SSL/TLS是基于PKI信息安全技术,是目前Internet上广泛采用的安全服务。LDAP通过StartTLS方式启动TLS服务,可以提供通讯中的数据保密性、完整性保护;通过强制客户端证书认证的TLS服务,同时可以实现对客户端身份和服务器端身份的双向验证。
1.4.3. 访问控制
虽然LDAP目前并无访问控制的标准,但从一些草案中或是事实上LDAP产品的访问控制情况,我们不难看出:LDAP访问控制异常的灵活和丰富,在LDAP中是基于访问控制策略语句来实现访问控制的,这不同于现有的关系型数据库系统和应用系统,它是通过基于访问控制列表来实现的,无论是基于组模式或角色模式,都摆脱不了这种限制。
在使用关系型数据库系统开发应用时,往往是通过几个固定的数据库用户名访问数据库。对于应用系统本身的访问控制,通常是需要建立专门的用户表,在应用系统内开发针对不同用户的访问控制授权代码,这样一旦访问控制策略变更时,往往需要代码进行变更。总之一句话,关系型数据库的应用中用户数据管理和数据库访问标识是分离的,复杂的数据访问控制需要通过应用来实现。
而对于LDAP,用户数据管理和访问标识是一体的,应用不需要关心访问控制的实现。这是由于在LDAP中的访问控制语句是基于策略语句来实现的,无论是访问控制的数据对象,还是访问控制的主体对象,均是与这些对象在树中的位置和对象本身的数据特征相关。
在LDAP中,可以把整个目录、目录的子树、制定条目、特定条目属性集或符合某过滤条件的条目作为控制对象进行授权;可以把特定用户、属于特定组或所有目录用户作为授权主体进行授权;最后,还可以定义对特定位置(例如IP地址或DNS名称)的访问权。
2. LDAP概念
2.1. 架构(Schema)
-
Schema 就是一个集合。所有的 objectClass 和 attribute 都定义在 Schema 里。
-
每一个 attribute 和 objectClass,包括其父级 attribute 和 objectClass 都必须定义在一个 Schema 里,且该 Schema 必须能够被 LDAP 服务器识别。
-
定义在一个 Schema 里的 attribute 可以被另一个 Schema 里的 objectClass 使用。
2.2. 对象类(objectClass)
-
objectClass 是 attribute 的集合。
-
objectClass 定义在 Shema 里。
-
objectClass 可以是下面的类型:
-
STRUCTURAL - 可以用于创建条目,即数据对象
-
AUXILIARY - 可以添加到任何条目
-
ABSTRACT - 不存在,抽象的。最常见的 ABSTRACT objectClass 是 top,表示每个 objectClass 层级的最高形式,用来结束一个层级。
-
-
objectClass 可以以层级的形式呈现,这里它可以继承来自父级的属性。也就是说,objectClass 可以是一个层级的一部分,这种情况下,objectClass 必须和它的父级 objectClass 保持同样的类型,即 STRUCTURAL 或者 AUXILIARY 类型。当父级是 top ABSTRACT 时无需遵守此规则,因为 top ABSTRACT 用结束任何层级结构。
-
一个 objectClass 可以有一个或多个父级的 objectClass。
-
objectClass 是用来包含属性的方式。
-
objectClass 定义一个 attribute 是否是必须的(MUST)或者是可选的(MAY)。
-
objectClass 遵守 ASN.1 注释标准。
示例1:下面是一个简单的 objectClass 定义
objectclass ( 2.5.6.2 NAME 'country' DESC 'RFC2256: a country'
SUP top STRUCTURAL
MUST c
MAY ( searchGuide $ description ) )
解释:
• objectClass 是关键字,指明这是一个 objectClass 的定义
• 2.5.6.2 NAME 'country' 定义 objectClass 的全局唯一识别名。它由两部分组成:
– NAME 'country' 为 objectClass 定义一个好理解的名字 country
– 2.5.6.2 定义全局唯一识别名,这种形式称之为 OID(ObjectIdentifier)。由哪个组织分配这个号码并不重要,但是必须是全局唯一的。通常推荐向 IANA申请一个 PEN (Private Enterprise Number)作为 OID 使用。
• SUP 'top' 表示该 objectClass 有一个父级的 objectClass,也就是说它是一个层级的一部分。一个 objectClass 可以有一个或多个父级的 objectClass。
• STRUCTURAL 表示该 objectClass 包含属性且可以形成目录信息树(DIT)里的条目(entry)。一个条目里只能包含一个 STRUCTURAL objectClass。objectClass 也可以是 AUXILIARY,这说明它包含 attributes,可以和任何 STRUCTURAL objectClass一起使用构成一个条目,但是不可以单独构成一个条目。
• DESC 'a country' 为可选值,用来描述 objectClass。
• MUST c 表示 c 属性是必须的。这里的属性 c (c 或者 countryName)必须存在,否则 objectClass 实例无法创建成功。如果要指明多个属性是必须的,写法是 ( attr1 $ attr2 $ attrn)。
• MAY ( searchGuide $ description ) 表示 searchGuide 和 description 是可选的,即创建 objectClass 时这两个属性不需要一定存在。
示例2:
attributetype ( 2.5.4.41 NAME 'name'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
解释:
• attributetype 同上。
• 2.5.4.41 NAME 'name' 同上。
• EQUALITY caseIgnoreMatch 定义了该属性在搜索过滤(serach filter)中的行为。比如,(name=andy)。这里指定该属性在搜索中大小写不敏感。这里的 caseIgnoreSubstringMatch 就是一个 matchingRule。
• SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} 是一个 OID,定义数据类型(data type)和要应用到数据的规则(data validation)。完整的定义可参考 RFC 2252 section 4.3.2。在本例中,OID 定义该属性为目录字符串(Directory String)类型(参考 RFC 2252 section 6.10)。 {32768} 定义字符串的最大长度,这是可选的。
2.3. 属性(Attribute)
-
attribute 定义在 Schema里。
-
一个 attribute 可以包含在一个或多个 objectClass 里。
-
一个 attribute 可以在包含它的 objectClass 里出现一次(SINGLE-VALUE)或多次(MULTI-VALUE)。默认为多次。
-
一个 attribute 可以是一个层级的一部分,此时它继承所有来自父级的属性。比如,commonName(cn),givenName(gn) 和 surname(sn)都是 name 属性的子类。
-
attribute 的定义包含它的类型(SYNTAX),比如,通过 matchingRules 定义字符串(string)或者数字(number)比较时是否大小写敏感。
-
attribute 定义遵守 ASN.1 注释标准
示例 1:下面是一个简单的 attribute 定义
attributetype ( 2.5.4.3 NAME ( 'cn' 'commonName' ) SUP name )
解释:
• attributetype 说明这是一个关于 attribute 的定义
• 2.5.4.3 NAME ('cn' 'commonName') 定义一个全局唯一识别名。该识别名由两部分组成:
– NAME ('cn' 'commonName') 定义一个可理解的名字 commonName 或者短别名 cn。原则上,短别名的个数没有限制。cn 排在第一位,它被称为主要名称(primary name)。这在为搜索优化做条目索引时非常重要。
– 2.5.4.3 定义全局唯一的 OID (ObjectIdentifier)。由哪个组织分配这个号码并不重要,但是必须是全局唯一的。通常推荐向 IANA申请一个 PEN (Private Enterprise Number)作为 OID 使用。
示例 2:
attributetype ( 2.5.4.41 NAME 'name'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
解释:
• attributetype 同上。
• 2.5.4.41 NAME 'name' 同上。
• EQUALITY caseIgnoreMatch 定义了该属性在搜索过滤(serach filter)中的行为。比如,(name=andy)。这里指定该属性在搜索中大小写不敏感。这里的 caseIgnoreSubstringMatch 就是一个 matchingRule。
• SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} 是一个 OID,定义数据类型(data type)和要应用到数据的规则(data validation)。完整的定义可参考 RFC 2252 section 4.3.2。在本例中,OID 定义该属性为目录字符串(Directory String)类型(参考 RFC 2252 section 6.10)。 {32768} 定义字符串的最大长度,这是可选的。
2.4. 条目(Entry)
-
目录信息树里 objectClass 的集合
-
entry 有且只能有一个 STRUCTURAL objectClass。一个 STRUCTURAL objectClass 可能有一个同为 STRUCTURAL 类型的父级。
-
entry 可以包含任意数目的 AUXILIARY objectClass。
-
entry 可以有子 entry(child entry),父 entry(parent entry),同级 entry(sibling entry)
-
entry 有三种类型:
– object entry - 最常见的一种,包含位于 objectClass 属性(attributes)里的用户数据
– alias entry - 带有单一属性 aliasedObjectName 的 objectClass 别名
– subentry - 用于存储与父 entry 相关的管理或者操作数据
下图是关于 objectClass, attribute 以及 entry 的示意图:
3. LDAP基本名词
- DC:domain component一般为公司名,例如:dc=163,dc=com
- OU:organization unit为组织单元,最多可以有四级,每级最长32个字符,可以为中文
- CN:common name为用户名或者服务器名,最长可以到80个字符,可以为中文
- DN:distinguished name为一条LDAP记录项的名字,有唯一性,例如:dn:“cn=admin,ou=developer,dc=163,dc=com”
| 关键字 | 英文全称 | 含义 |
|-|||
| dc | Domain Component | 域名的部分,其格式是将完整的域名分成几部分,如域名为example.com变成dc=example,dc=com(一条记录的所属位置) |
| uid | User Id | 用户Id zuoquantu (一条记录的ID) |
| ou | Organization Unit | 组织单位,组织单位可以包含在其他各种对象(包括其他组织单位),如”oa组” (一条记录的所属组) |
| cn | Common Name | 公共名称,如“Thomas Johansson”(一条记录的名称) |
| sn | Surname | 姓,如”许” |
| dn | Distinguished Name | “uid=songtao.xu,ou=oa组,dc=example,dc=com”,一条记录的位置(唯一) |
| rdn | Relative dn | 相对辨别名,类似于文件系统中的相对路径,它是与目录树结构无关的部分,如“uid=tom”或“cn= Thomas Johansson” |
| c | Country | 国家,如”CN”或”US”等 |
| o | Organization | 组织名,如:”中华人民共和国质检总局” |
4. 设计LDAP结构
5. Docker安装LDAP
docker run \
--name openldap -p 389:389 -p 636:636 --privileged=true \
-v /data/slapd/ldif:/container/service/slapd/ldif \
-v /data/slapd/database:/var/lib/ldap \
-v /data/slapd/config:/etc/ldap/slapd.d \
-e LDAP_ORGANISATION="uias" \
-e LDAP_DOMAIN="uias.com" \
-e LDAP_ADMIN_PASSWORD="310012" \
-d osixia/openldap
6. LDAP指令
6.1. 搜寻条目: ldapsearch
ldapsearch命令,在ldap搜索条目时很有用,只要适当调整filter就可以。
命令如下:
ldapsearch -h hostname -p port -b baseDN -D BIND_DN [options] filter [attribute]...
参数说明:
-h:主机名或ip地址
-p:端口号
-b:suffix dn
-D:使用搜索绑定的用户
其他参数一般很少使用。下面举几个例子看一下:
1)搜索所有条目:
ldapsearch -h host -b "dc=example,dc=com" "(objectclass=*)"
2)搜索cn为指定名字的条目
ldapsearch -h host -b "dc=example,dc=com" "(cn=Babs Jensen)"
3)使用filter文件进行搜索
filter文件内容:
sn=Francis
givenname=Barbara
指定搜索:
ldapsearch -b "dc=example,dc=com" -h host -f filters cn uid
4)模糊查询,uid包含test的条目
ldapsearch -h host -b "dc=example,dc=com" "(uid=*test*)"
5)同时满足多个属性,uid包含test,givenName包含test的条目
ldapsearch -h host -b "dc=example,dc=com" "(|(uid=*test*)(givenName=*test*))"
这里filter的书写规则和aci的filter中书写规则相同。
6.2. 设置密码: ldappassword
选项
-x 进行简单认证
-D 用来绑定服务器的DN
-w 绑定DN的密码
-S 提示的输入密码
-s pass 把密码设置为pass
-a pass 设置old passwd为pass
-A 提示的设置old passwd
-H 是指要绑定的服务器
-I 使用sasl会话方式
exp:
# ldappasswd -x -D 'cm=root,dc=it,dc=com' -w secret 'uid=zyx,dc=it,dc=com' -S
COPY
6.3. 数据导出: slapcat
选项
-l 表示导出为LDIF文件格式
exp:
# slapcat -l export.ldif
6.4. 数据增加: ldapadd
选项:
-x 进行简单认证
-D 用来绑定服务器的DN
-h 目录服务的地址
-w 绑定DN的密码
-f 使用ldif文件进行条目添加的文件
exp:
将test.ldif中的数据导入ldap
# ldapadd -x -D "cn=root,dc=example,dc=com" -w password -f /root/test.ldif
COPY
6.5. 数据删除: ldapdelete
选项:
-c 连续运行模式 (运行出错时跳过继续执行)
-f file 指定文件
-M 启用管理DSA IT控制
-P version 协议版本(default: 3)
-r 递归删除
exp:
# ldapdelete -x -D "cn=Manager,dc=example,dc=com" -w password "uid=test1,ou=People,dc=test,dc=com"
# ldapdelete -x -D 'cn=root,dc=it,dc=com' -w password 'uid=zyx,dc=it,dc=com'
COPY
6.5. 修改配置: ldapmodify
通过ldapmodify可以更改条目属性,下面简单介绍一下,ldapmodify在添加,删除,更新,更改dn的操作
1)添加条目,在使用ldapmodify添加条目的时候,可以手动输入要添加的条目的所有属性,也可以通过使用文件的方式进行添加;
文件内容如下(add.ldif):在编辑文件时须将必填属性,例如uid,cn,sn等写完整
dn: uid=bcubbins,ou=People,dc=example,dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: bcubbins
givenName: Bartholomew
sn: Cubbins
cn: Bartholomew Cubbins
mail: bcubbins@example.com
userPassword: bcubbins
facsimiletelephonenumber: +1 234 567 8910
使用命令:
ldapmodify -a -h host -D uid=bjensen,ou=people,dc=example,dc=com -w - -f add.ldif
如果不是用文件,则需要在命令行下手动输入如上内容,完成后按回车键。例如:
dn: uid=bcubbins,ou=People,dc=example,dc=com
changeType:add
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: bcubbins
givenName: Bartholomew
sn: Cubbins
cn: Bartholomew Cubbins
....
2)修该条目,修改条目和删除条目操作类似
通过文件修改:
dn: uid=bcubbins,ou=People,dc=example,dc=com
changetype: modify
add: description
description: Added with ldapmodify
-
replace: mail
mail: bart@example.com
执行ldapmodify命令
ldapmodify -h host -c -v -D uid=bjensen,ou=People,dc=example,dc=com -w - -f modify.ldif
如果不通过文件修改,则需手动输入如上所有红色字体内容
3,删除条目,删除条目是可以通过指定文件内容删除,手动输入需删除条目
ldapmodify -h host -D uid=bjensen,ou=People,dc=example,dc=com -w -
dn: uid=bcubbins,ou=People,dc=example,dc=com
changetype: delete
deleting entry uid=bcubbins,ou=People,dc=example,dc=com
4,移动条目,即更改条目uid,dn
ldapmodify -h host -D uid=hmiller,ou=people,dc=example,dc=com -w -
changetype: modrdn
newrdn: uid=jwallace
deleteoldrdn: 0
newsuperior: ou=special users,dc=example,dc=com
deleteoldrdn:0,保留原dn;1,删除原dn。再进行条目移动时,需具有import和export权限。
6.6. Option介绍
| Option | 说明 ||-||
| -H | ldapuri,格式为ldap://机器名或者IP:端口号,不能与-h和-p同时使用 |
| -h | LDAP服务器IP或者可解析的hostname,与-p可结合使用,不能与-H同时使用 |
| -p | LDAP服务器端口号,与-h可结合使用,不能与-H同时使用 |
| -x | 使用简单认证方式 |
| -D | 所绑定的服务器的DN |
| -w | 绑定DN的密码,与-W二者选一 |
| -W | 不输入密码,会交互式的提示用户输入密码,与-w二者选一 |
| -f | 指定ldif文件作为输入 |
| -a | 添加新的entry,ldapadd缺省使用,ldapmodify 可指定以达到同样作用 |
| -c | 出错后忽略当前错误继续执行,缺省情况下遇到错误即终止 |
| -n | 模拟操作但并不实际执行,用于验证,常与-v一同使用进行问题定位 |
| -v | 显示详细信息 |
| -d | 显示debug信息,可设定级别 |
| -e | 设置客户端证书 |
| -E | 设置客户端私钥 |
| -Q | 安静执行 |
|-Y EXTERNAL|外部认证|
|-Z[Z]|使用StartTL 扩展操作|
|-ZZ|命令强制使用StartTLS 握手成功|
|-M[M]| 打开manage DSA IT 控制|
|-MM| 把该控制设置为重要的|