一、OpenLDAP介绍
1、什么是ldap
LDAP是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP。按照我们对文件目录的理解,ldap可以看成一个文件系统,类似目录和文件树。
2、ldap的软件
ldap并不是一款软件,而是一个协议。
现在市场上有关LDAP的产品已有很多,各大软件公司都在他们的产品中集成了LDAP服务,如Microsoft的ActiveDirectory、Lotus的Domino Directory、IBM的WebSphere中也集成了LDAP服务。LDAP的开源实现是OpenLDAP,它比商业产品一点也不差,而且源码开放。
OpenLDAP是最常用的目录服务之一,它是一个由开源社区及志愿者开发和管理的一个开源项目,提供了目录服务的所有功能,包括目录搜索、身份认证、安全通道、过滤器等等。大多数的 Linux 发行版里面都带有 OpenLDAP的安装包。OpenLDAP 服务默认使用非加密的 TCP/IP 协议来接收服务的请求,并将查询结果传回到客户端。由于大多数目录服务都是用于系统的安全认证部分比如:用户登录和身份验证,所以它也支持使用基于SSL/TLS 的加密协议来保证数据传送的保密性和完整性。OpenLDAP 是使用 OpenSSL 来实现 SSL/TLS 加密通信的。
3、OpenLDAP结构
在LDAP中,目录条目以分层树状结构排列。传统上,这种结构反映了地理和/或组织边界。代表国家/地区的条目显示在树的顶部。下面是代表国家和国家组织的条目。
该树也可以基于互联网域名进行排列。这种命名方法越来越受欢迎,因为它允许使用DNS定位目录服务。
4、ldap的信息模型
LDAP的信息模型是建立在"条目"(entries)的基础上。一个条目是一些属性的集合,并且具有一个全局唯一的"可区分名称"DN,一个条目可以通过DN来引用。每一个条目的属性具有一个类型和一个或者多个值。类型通常是容易记忆的名称,比如"cn"是通用名称(common name) ,或者"mail"是电子邮件地址。条目的值的语法取决于属性类型。比如,cn属性可能具有一个值"Babs Jensen" 。一个mail属性可能包含"bbs@kevin.com" 。一个jpegphoto属性可能包含一幅JPEG(二进制)格式的图片。
5、为什么需要OpenLDAP
早期,公司是没有统一认证这个东西的,所以各自玩各自的。于是, confluence一个用户体系,gitlab一个用户体系,Jenkins一个用户体系等等, 开发中要用到的开源软件数不胜数,每个软件都要认证, 必须想办法统一账号。ldap就产生了,用于统一认证操作,一次注册多系统使用。
二、OpenLDAP对象介绍
1、LDAP的objectClass
LDAP通过属性objectClass来控制哪一个属性必须出现或允许出现在一个条目中,它的值决定了该条目必须遵守的模式规则。可以理解为关系数据库的表结构。
接下来会用到的objectClass有:
objectClass | 含义 |
---|---|
olcGlobal | 全局配置文件类型, 主要是cn=config.ldif 的配置项 |
top | 顶层的对象 |
organization | 组织,比如公司名称,顶层的对象 |
organizationalUnit | 重要, 一个目录节点,通常是group,或者部门这样的含义 |
inetOrgPerson | 重要, 我们真正的用户节点类型,person类型, 叶子节点 |
groupOfNames | 重要, 分组的group类型,标记一个group节点 |
olcModuleList | 配置模块的对象 |
2、LDAP常用关键字列表
ldap的entry是由各种字段构成,可以理解为关系数据库的字段。
关键字 | 英文全称 | 含义 |
---|---|---|
dc | Domain Component | 域名的部分,其格式是将完整的域名分成几部分,如域名为example.com变成dc=example,dc=com |
uid | User Id | 用户ID,如“tom” |
ou | Organization Unit | 组织单位,类似于Linux文件系统中的子目录,它是一个容器对象,组织单位可以包含其他各种对象(包括其他组织单元),如“market” |
cn | Common Name | 公共名称,如“Thomas Johansson” |
sn | Surname | 姓,如“Johansson” |
dn | Distinguished Name | 惟一辨别名,类似于Linux文件系统中的绝对路径,每个对象都有一个惟一的名称,如“uid= tom,ou=market,dc=example,dc=com”,在一个目录树中DN总是惟一的 |
rdn | Relative dn | 相对辨别名,类似于文件系统中的相对路径,它是与目录树结构无关的部分,如“uid=tom”或“cn= Thomas Johansson” |
c | Country | 国家,如“CN”或“US”等。 |
o | Organization | 组织名,如“Example, Inc.” |
这里,我们把dn当做用户唯一主键, cn是common name,应该等同于用户名,因为用户名必须唯一,通常为邮箱前缀,比如ryan.miao. sn作为姓氏, uid作为用户id。通常用户id也是唯一的。所以在使用ldap做认证的时候, 大概逻辑如下:
-
配置ldap host, admin, admin pass
-
用户登录时传递username
-
读取配置的ldap信息,查询cn或者uid等于username的数据
-
取出第一个记录, 获得dn, 根据dn和password再次去ldap服务器认证。即我们必须保证cn或uid是全局唯一的,认证通常需要进行两次。原因就在于dn没办法根据用户名计算出来。
三、部署
1、容器部署方式
使用bitnami/openldap:latest镜像
docker pull bitnami/openldap:latest
Bitnami Docker OpenLDAP可以通过以下环境变量轻松设置:
LDAP_PORT_NUMBER:OpenLDAP正在侦听请求的端口。默认值:1389(非特权端口)
LDAP_ROOT:LDAP树的基于LDAP的DN(或后缀)。默认值:dc=example,dc=org
LDAP_ADMIN_USERNAME:LDAP数据库管理用户。默认值:admin
LDAP_ADMIN_PASSWORD:LDAP数据库管理员密码。默认值:adminpassword
LDAP_ADMIN_PASSWORD_FILE:包含LDAP数据库管理员用户密码的文件的路径。这将覆盖LDAP_ADMIN_PASSWORD中指定的值。没有默认值。
LDAP_CONFIG_ADMIN_ENABLED:是否创建配置管理员用户。默认值:否。
LDAP_CONFIG_ADMIN_USERNAME:LDAP配置管理用户。这与LDAP_ADMIN_USERNAME是分开的。默认值:admin。
LDAP_CONFIG_ADMIN_PASSWORD:LDAP配置管理员密码。默认值:configpassword。
LDAP_CONFIG_ADMIN_PASSWORD_FILE:包含LDAP配置管理员用户密码的文件的路径。这将覆盖LDAP_CONFIG_ADMIN_PASSWORD中指定的值。没有默认值。
LDAP_USERS:要在默认LDAP树中创建的LDAP用户的逗号分隔列表。默认值:user01、user02
LDAP_PASSWORDS:LDAP用户使用的以逗号分隔的密码列表。默认值:bitnam1,bitnam2
LDAP_USER_DC:用户组织单位的DC。默认值:users
LDAP_GROUP:用于对创建的用户进行分组的组。默认值:readers
LDAP_ADD_SCHEMAS:是否添加LDAP_EXTRA_SCHEMAS中指定的架构。默认值:是
LDAP_EXTRA_SCHEMAS:在OpenLDAP的分布式模式中添加额外的模式。默认值:cosine、inetorgperson、nis
LDAP_SKIP_DEFAULT_TREE:是否跳过基于LDAP_USERS、LDAP_PASSWORDS、LDAP_USER_DC和LDAP_GROUP创建默认LDAP树。请注意,这不会跳过添加模式或导入LDIF文件。默认值:否
LDAP_CUSTOM_LDIF_DIR:目录的位置,该目录包含应该用于引导数据库的LDIF文件。将只使用以.ldif结尾的文件。当使用LDAP_CUSTOM_LDIF_DIR时,将跳过基于LDAP_USERS、LDAP_PASSWORDS、LDAP_USER_DC和LDAP_GROUP的默认LDAP树。使用此选项时,它将覆盖LDAP_USERS、LDAP_PASSWORDS、LDAP_USER_DC和LDAP_GROUP的使用。您应该将LDAP_ROOT设置为基础,以确保数据库上配置的olcSuffix与从LDIF文件导入的内容匹配。默认值:/ldifs
LDAP_CUSTOM_SCHEMA_FILE:无法添加为自定义ldif文件的自定义内部架构文件的位置(即包含一些structuralObjectClass)。默认值为/schema/custom.ldif“
LDAP_CUSTOM_SCHEMA_DIR:包含无法作为自定义ldif文件添加的自定义内部架构文件的目录的位置(即,包含一些structuralObjectClass)。这可以与LDAP_CUSTOM_SCHEMA_FILE(如上)一起使用,也可以代替LDAP_CUSOM_SCHEMA-FILE(上)来添加多个模式文件。默认值:/schemas
LDAP_ULIT_NOFILES:打开的文件描述符的最大数量。默认值:1024。
LDAP_ALLOW_ANON_BINDING:允许匿名绑定到LDAP服务器。默认值:是。
LDAP_LOGLEVEL:设置OpenLDAP服务器的日志级别。默认值:256。
Level Keyword Description
-1 any enable all debugging
0 no debugging
1 (0x1 trace) trace function calls
2 (0x2 packets) debug packet handling
4 (0x4 args) heavy trace debugging
8 (0x8 conns) connection management
16 (0x10 BER) print out packets sent and received
32 (0x20 filter) search filter processing
64 (0x40 config) configuration processing
128 (0x80 ACL) access control list processing
256 (0x100 stats) stats log connections/operations/results
512 (0x200 stats2) stats log entries sent
1024 (0x400 shell) print communication with shell backends
2048 (0x800 parse) print entry parsing debugging
16384 (0x4000 sync) syncrepl consumer processing
32768 (0x8000 none) only messages that get logged regardless of configured log level
保护OpenLDAP流量
OpenLDAP客户端和服务器能够使用传输层安全性(TLS)框架来提供完整性和机密性保护,并支持使用SASL EXTERNAL机制的LDAP身份验证。如果您希望启用此可选功能,可以使用以下环境变量来配置应用程序:
LDAP_ENABLE_TLS:是否为流量启用TLS。默认为否。
LDAP_LDAPS_PORT_NUMBER:用于TLS安全通信的端口。默认值为1636。
LDAP_TLS_CERT_FILE:包含TLS通信的证书文件的文件。没有默认值。
LDAP_TLS_KEY_FILE:包含证书密钥的文件。没有默认值。
LDAP_TLS_CA_FILE:包含证书的CA的文件。没有默认值。
LDAP_TLS_DH_PARAMS_FILE:包含DH参数的文件。没有默认值。
使用Docker创建
docker run --detach --name openldap \
-e LDAP_ADMIN_USERNAME=admin \
-e LDAP_ADMIN_PASSWORD=123456 \
-e LDAP_USERS=zhang \
-e LDAP_PASSWORDS=123456 \
-e LDAP_ROOT=dc=zd,dc=com \
--network=host \
bitnami/openldap:latest
2、Yum安装
yum install -y openldap openldap-clients openldap-servers
# 软件安装完成后,/usr/share/openldap-servers目录下会有一个文件DB_CONFIG.example,用来做配置初始化;
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
# 注意进行授权给ldap用户
chown -R ldap:ldap /var/lib/ldap
# 启动服务
systemctl enable --now slapd.service
# 设置OpenLDAP的管理员密码:
slappasswd -s 123456
{SSHA}ABsyE4qKEXfLMxqTx1IXKop8GqffsTQm
# 使用ldapmodify,编辑一个新的db.ldif文件,注意修改olcRootDN和olcSuffix,改成你需要的域名相关信息,同时修改olcRootPW内容,这个值就是上一节返回的管理员密码加密字符串:
vim db.ldif
########
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=zd,dc=com
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=admin,dc=zd,dc=com
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: {SSHA}ABsyE4qKEXfLMxqTx1IXKop8GqffsTQm
# 执行ldapmodify进行更新:hbd.ldif文件
ldapmodify -Y EXTERNAL -H ldapi:/// -f db.ldif
# 编辑一个新的monitor.ldif文件,注意修改域名相关信息:
vim monitor.ldif
###########
dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external, cn=auth" read by dn.base="cn=admin,dc=zd,dc=com" read by * none
# 执行ldapmodify进行更新:monitor.ldif
ldapmodify -Y EXTERNAL -H ldapi:/// -f monitor.ldif
# 输出
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "olcDatabase={1}monitor,cn=config"
# 检测配置文件是否有错
slaptest -u
# 输出
config file testing succeeded
2.1 添加模式
什么是schema 在openldap的目录树中,schema用来指定一个条目所包含的对象类(objectClass)以及每个对象类所包含的属性值(attribute),其中属性值又包含必要属性和可选属性。
schema是一个数据模型,定义对象类,对象类包含属性的定义,对象类和属性组合成条目,在添加数据条目时,会检查是否符合对象类(objectClass)及属性,通过则添加成功,否则打印错误信息。
如何理解schema 不管是在学习OpenLDAP时还是学习数据库时,都会遇到一个很迷糊的Schema的概念。
在数据库中,对数据库的设计可以称之为schema。即schema约束了数据库的设计结构,并提供了整个数据库的描述。schema仅展示数据库的设计,如表字段的类型,表与表之间的关联。
在ldap中schema与database中的schema一样,如列出的schema中,这些代表了对应的ldap结构的设计。
schema包含什么 在openldap的schema中,有四个重要的元素:
Objectclass
Objectclass定义了一个类别,这个类别会被不同的目录(在LDAP中就是一个Entry)用到,它说明了该目录应该有哪些属性,哪些属性是必须的,哪些又是可选的。一个objectclass的定义包括名称(NAME),说明(DESC),类型(STRUCTURAL或AUXILARY),表示是结构型的还是辅助型的),必须属性(MUST),可选属性(MAY)等信息。
Attribute
Attribute就是一个上面Objectclass中可能包含的属性,对其的定义包括名称,数据类型,单值还是多值以及匹配规则等。后面用具体的例子来说明。
Syntax
syntax是LDAP中的“语法”,其实就是LDAP中会用到的数据类型和数据约束,这个语法是遵从X.500中数据约束的定义的。其定义需要有一个ID(遵从X.500)以及说明(DESP)
Matching Rules
是用来指定某属性的匹配规则,实际上就是定义一个特殊的Syntax的别名,让LDAP服务器可以识别,并对定义的属性进行匹配。
Schema Files OpenLDAP随附了一些schema,在/usr/local/etc/openldap/chema目录中
文件 | 说明 |
---|---|
core.schema | OpenLDAP core (required) |
cosine.schema | Cosine 和 Internet X.500 |
inetorgperson.schema | 在添加账号时,额外的objectClass。 |
misc.schema | |
nis.schema | 网络信息服务(FYI),也是一种集中账号管理实现。 |
openldap.schema | OpenLDAP Project(experimental) |
dyngroup.schema | 定义组时使用的schema,包括要使用sudo.schema时,也需要它 |
ppolicy.schema | 需要做密码策略时,需要导入此schema |
sudo.schema | 定义sudo规则 |
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/core.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/collective.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/corba.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/duaconf.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/dyngroup.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/java.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/misc.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/openldap.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/pmi.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/ppolicy.ldif
2.2 创建域文件
LDIF文件书写规则
ldif是存储LDAP配置信息及目录内容的标准文本文件格式,通常用来交换数据并在OpenLDAP服务器之间互相交换数据,并且可以通过LDIF实现数据文件的导入、导出以及数据文件的添加、修改、重命名等操作,这些信息需要按照LDAP中schema的规范进行操作,并会接受schema的检查,如果不符合OpenLDAP schema规范要求,则会提示相关语法错误。
-
LDIF文件每行的结尾不允许有空格或者制表符;
-
LDIF文件允许相关属性可以重复赋值并使用;
-
LDIF文件以.ldif结尾命名;
-
LDIF文件中以#号开头的一行为注释,可以作为解释使用;
-
LDIF文件所有的赋值方式为:属性:[空格]属性值;
-
LDIF文件通过空行来定义一个条目,空格前为一个条目,空格后为另一个条目的开始。
# 创建一个ldif文件zd.ldif
vim zd.ldif
######
# 创建一个组织organization(公司)
dn: dc=zd,dc=com
objectClass: dcObject
objectClass: organization
dc: zd
o: alibaba.inc
# 创建一个组织单元(部门)
dn: ou=main,dc=zd,dc=com
objectClass: organizationalUnit
ou: main
# 添加一个wangwu用户
dn: cn=wangwu,ou=main,dc=zd,dc=com #
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: wangwu
gidNumber: 1002
homeDirectory: /home/wangwu #目录
sn:: 546L5LqU
uid: wangwu
uidNumber: 1002
userPassword:: MTIzNDU2 #默认密码123456
# 导入生效:
ldapadd -x -W -D "cn=admin,dc=zd,dc=com" -f zd.ldif
# 添加完成后通过ldapsearch命令查看结果:
ldapsearch -h localhost -p 389 -x -D "cn=admin,dc=zd,dc=com" -w '123456' -b 'dc=zd,dc=com' '(objectClass=*)'
2.3 OpenLDAP命令使用
一、OpenLDAP命令汇总
-
ldapsearch:搜索 OpenLDAP 目录树条目。
-
ldapadd:通过 LDIF 格式,添加目录树条目。
-
ldapdelete:删除 OpenLDAP 目录树条目。
-
ldapmodify:修改 OpenLDAP 目录树条目。
-
ldapwhoami:效验 OpenLDAP 用户的身份。
-
ldapmodrdn:判断 OpenLDAP 目录树 DN 条目。
-
ldapcompare:判断 DN 值和指定参数值是否属于同一个条目。
-
ldappasswd:修改 OpenLDAP 目录树用户条目实现密码重置。
-
slaptest:验证 slapd.conf 文件或 cn=配置目录。
-
slapindex:创建 OpenLDAP 目录树索引,提供查询效率。
-
slapcat:将数据小牧转换为 OpenLDAP 的 LDIF 文件。
#ldapsearch 命令可根据用户定义的查询条件,对 OpenLDAP 目录树进行查找以及检索目录树相关条目。
# 1. 查找目录树所有条目
ldapsearch -x -b "dc=zd,dc=com"
# 2. 根据过滤条件查找条目
ldapsearch -x -b "dc=zd,dc=com" '(cn=zdgroup)' #根据cn过滤
ldapsearch -x -b "dc=zd,dc=com" '(uid=zd)' #根据用户id过滤
#ldapadd 命令
# 根据 ldif 文件添加条目
ldapadd -x -w <pwd> -D "cn=admin,dc=zd,dc=com" -f base.ldif
#ldapmodify 命令
# ldapmodify 命令是固定的,主要是通过配置文件实现不同的修改功能。
ldapmodify -x -D "cn=admin,dc=zd,dc=com" -w <pwd> -f modi.ldif
# 1. 向条目下添加成员参数
# modi.ldif 文件如下,表示向 admin 这个组中添加成员 zd。
dn: cn=admin,ou=Group,dc=dc=zd,dc=com
changetype: modify
add: memberUid
memberUid: zd
#2. 修改条目的某个值
# modi.ldif 文件如下,表示修改 uid=zd 这个用户的 uidNumber 参数。
dn: uid=zd,ou=People,dc=zd,dc=com
changetype: modify
replace: uidNumber
uidNumber:
#3. 删除条目下某个参数
##modi.ldif 文件如下,表示删除 uid=zd 这个用户下 pwdAccountLockedTime 参数。
dn: uid=zd,ou=People,dc=zd,dc=com
changetype: modify
delete: pwdAccountLockedTime
#ldapdelete 命令
#从当前目录树中删除 uid 为 zd 的用户,删除前需要使用 ldapsearch 查看 zd 的 DN 名称。
ldapsearch -x -b "dc=zd,dc=com" '(uid=zd)' # 查看uid=zd的dn名称,然后执行删除操作
ldapdelete -x -D cn=admin,dc=zd,dc=com -w <pwd> "uid=zd,ou=People,dc=zd,dc=com"
工具使用
下载以上工具,Linux版本,百度搜索其他版本
填写信息
没有问题会提示以下内容
下一步
之后就可以使用工具管理