@daduizhang
2019-01-11T14:08:54.000000Z
字数 18235
阅读 2939
在安装和使用ldap之前我们需要简单的了解一下ldap的基本概念 :
这个就是ldap的目录结构(先不需要管这些dc、ou、cn等具体是什么)你可以很明显看到,他就好像一棵树,会有根节点、枝干、果实节点
1. 条目,也叫记录项,是LDAP中最基本的颗粒,就像字典中的词条,或者是数据库中的记录。通常对LDAP的添加、删除、更改、检索都是以条目为基本对象的,也就是entry
2. dn:每一个条目都有一个唯一的标识名(distinguished Name=DN),就是所谓的"枝干", 如上图中一个 dn:"cn=baby,ou=marketing,ou=people,dc=mydomain,dc=org"。通过DN的层次型语法结构,可以方便地表示出条目在LDAP树中的位置,通常用于检索。
3. rdn:一般指dn逗号最左边的部分,也就是所谓的"子节点",如cn=baby。
4. Base DN:LDAP目录树的最顶部就是根,也就是所谓的"根节点",如"dc=mydomain,dc=org"。
每个条目都可以有很多属性(Attribute),比如常见的人都有姓名、地址、电话等属性。每个属性都有名称及对应的值,属性值可以有单个、多个,比如你有多个邮箱或者手机号。
属性不是随便定义的,需要符合一定的规则,而这个规则可以通过schema制定,而定制好的规则体现出来就是ObjectClass。比如,如果一个entry没有包含在 inetorgperson 这个 schema 中的objectClass: inetOrgPerson,那么就不能为它指定userPassword属性,因为userPassword是在inetOrgPerson中定义的,说的可能有点很难理解,不过先往后看
LDAP为人员组织机构中常见的对象都设计了属性(比如commonName,surname)。下面有一些常用的别名:
属性 | 别名 | 描述 | 举例 |
---|---|---|---|
commonName | cn | 姓名 | duanfei |
surname | sn | 姓 | duan |
organizationalUnitName | ou | 单位(部门)名称 | develop |
organization | o | 组织(公司)名称 | xxx company |
telephoneNumber | 电话号码 | 155xxxxxxx | |
objectClass | 内置属性 | inetorgperson |
这时候有同学会疑惑,为什么objectClass也是属性,这个不是定义的规则嘛,其实objectClass是一种特殊的属性。
对象类是属性的集合,LDAP预想了很多人员组织机构中常见的对象,并将其封装成对象类。比如人员(person)含有姓(sn)、名(cn)、电话(telephoneNumber)、密码(userPassword)等属性,单位职工(organizationalPerson)是人员(person)的继承类,除了上述属性之外还含有职务(title)、邮政编码(postalCode)、通信地址(postalAddress)等属性。
通过对象类可以方便的定义条目类型。每个条目可以直接继承多个对象类,这样就继承了各种属性。如果2个对象类中有相同的属性,则条目继承后只会保留1个属性。对象类同时也规定了哪些属性是基本信息,必须含有(Must 活Required,必要属性):哪些属性是扩展信息,可以含有(May或Optional,可选属性)。
对象类有三种类型:结构类型(Structural)、抽象类型(Abstract)和辅助类型(Auxiliary)。结构类型是最基本的类型,它规定了对象实体的基本属性,每个条目属于且仅属于一个结构型对象类。抽象类型可以是结构类型或其他抽象类型父类,它将对象属性中共性的部分组织在一起,称为其他类的模板,条目不能直接集成抽象型对象类。辅助类型规定了对象实体的扩展属性。每个条目至少有一个结构性对象类。
对象类本身是可以相互继承的,所以对象类的根类是top抽象型对象类。以常用的人员类型为例,他们的继承关系:
下面是inetOrgPerson对象类的在schema中的定义,可以清楚的看到它的父类SUB和可选属性MAY、必要属性MUST(继承自organizationalPerson),关于各属性的语法则在schema中的attributetype定义。
# inetOrgPerson
# The inetOrgPerson represents people who are associated with an
# organization in some way. It is a structural class and is derived
# from the organizationalPerson which is defined in X.521 [X521].
objectclass ( 2.16.840.1.113730.3.2.2
NAME 'inetOrgPerson'
DESC 'RFC2798: Internet Organizational Person'
SUP organizationalPerson
STRUCTURAL
MAST(
cn $ sn
)
MAY (
audio $ businessCategory $ carLicense $ departmentNumber $
displayName $ employeeNumber $ employeeType $ givenName $
homePhone $ homePostalAddress $ initials $ jpegPhoto $
labeledURI $ mail $ manager $ mobile $ o $ pager $
photo $ roomNumber $ secretary $ uid $ userCertificate $
x500uniqueIdentifier $ preferredLanguage $
userSMIMECertificate $ userPKCS12 )
)
schema 是OpenLDAP 软件的重要组成部分,主要用于控制目录树中各种条目所拥有的对象类以及各种属性的定义,并通过自身内部规范机制限定目录树条目所遵循的逻辑结构以及定义规范,保证整个目录树没有非法条目数据,避免不合法的条目存在目录树中,从而保障整个目录树信息的完整性、唯一性。
不过目前ldap中的schema通常无需自定义,使用ldap内置的即可满足绝大部分需求。
LDAP的安装可以源码安装,apt-get。我们只说用apt-get安装的方式,如果有想了解源码安装方式的话,可以去官网查看一下。
LDAP官方网址:http://www.openldap.org/doc/admin24/index.html
操作系统: ubuntu-16.04
$ sudo apt-get install slapd ldap-utils
系统将要求您提供LDAP管理密码。请随意跳过提示,因为我们将在之后立即重新配置。
为了访问我们需要的一些其他提示,我们将在安装后重新配置包。为此,请键入:
$ sudo dpkg-reconfigure slapd
dpkg是初始化一些应用的命令,感兴趣的同学可以了解一下
使用以下信息作为起点,适当地回答提示:
这样我们就将LAPD配置完成,这个时候我们已经可以正常使用了
我们需要是这一下客户端的配置
$ vim /etc/ldap/ldap.conf
这个时候我们可以尝试着输入命令查看一下ldap中的内容
$ ldapsearch -x
当你看到这些内容时那么你的配置则没有问题
#
# LDAPv3
# base <dc=example,dc=com> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# example.com
dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: example
dc: example
# admin, example.com
dn: cn=admin,dc=example,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
# search result
search: 2
result: 0 Success
给大家看一下slapd.d的配置目录结构:
也可以输入:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn
cn=config: 全局设置
cn=module{0},cn=config: 动态加载的模块
cn=schema,cn=config: 包含硬编码的系统级模式
cn={0}core,cn=schema,cn=config: 硬编码的核心模式
cn={1}cosine,cn=schema,cn=config: 余弦架构
cn={2}nis,cn=schema,cn=config: 在NIS方案
cn={3}inetorgperson,cn=schema,cn=config: inetorgperson模式
olcBackend={0}mdb,cn=config: 'mdb'后端存储类型
olcDatabase={-1}frontend,cn=config: 前端数据库,其他数据库的默认设置
olcDatabase={0}config,cn=config: slapd配置数据库(cn=config)
olcDatabase={1}mdb,cn=config: 你的数据库实例(dc=examle,dc=com)
LDIF(LDAP Data Interchanged Format)的轻量级目录访问协议数据交换格式的简称,是存储LDAP 配置信息及目录内容的标准文本文件格式,之所以使用文本文件来存储这些信息是为了方便读取和修改,这也是其他大多数服务配置文件所采取的格式。通常用来交换数据并在OpenLDAP服务器之间互相交换数据,并且可以通过LDIF 实现数据文件的导入、导出以及数据文件的添加、修改、重命名等操作,这些信息需要按照LDAP 中schema 的规范进行操作,并会接受schema 的检查,如果不符合OpenLDAP schema 规范要求,则会提示相关语法错误。
LDIF 文件特点
LDIF 语法格式
比如我们添加数据库的内容,我们将加入如下内容:
1. 一个叫做People的节点(用来存放users)
2. 一个叫做Group的节点(用来存放groups)
3. 一个组叫做develop
4. 一个用户叫做huihui
创建下面的LDIF文件,并叫做add_content.ldif:
dn: ou=People,dc=example,dc=com
objectClass: organizationalUnit
ou: People
dn: ou=Groups,dc=example,dc=com
objectClass: organizationalUnit
ou: Groups
dn: cn=develop,ou=Groups,dc=example,dc=com
objectClass: posixGroup
cn: develop
gidNumber: 5000
dn: uid=huihui,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
uid: huihui
sn: hui
givenName: huihui
cn: hui
uidNumber: 1000
gidNumber: 500
userPassword: 123456
loginShell: /bin/sh
homeDirectory: /home/users/huihui
tips:在你的目录中的uidNumber和gidNumber的值不与本地值冲突是很重要的。使用比较高的数值范围,比如从500开始。通过在ldap中设置较高的uid和gid值,允许你更容易地控制本地用户和ldap用户。
添加内容:
$ ldapadd -x -D cn=admin,dc=example,dc=com -w 123456 -f add_content.ldif
Enter LDAP Password: ********
adding new entry "ou=People,dc=example,dc=com"
adding new entry "ou=Groups,dc=example,dc=com"
adding new entry "cn=develop,ou=Groups,dc=example,dc=com"
adding new entry "uid=huihui,ou=People,dc=example,dc=com"
我们检查一下看看存储的数据是否正确:
$ ldapsearch -x -LLL -b dc=shannonai,dc=com 'uid=huihui'
dn: uid=huihui,ou=People,dc=shannonai,dc=com
uid: huihui
sn: hui
givenName: huihui
cn: huihui
uidNumber: 1000
gidNumber: 500
loginShell: /bin/bash
homeDirectory: /home/huihui
objectClass: inetOrgPerson
objectClass: posixAccount
参数:
1. -x : 简单认证
2. -LLL:禁用无关信息
3. -b 搜索的路径
4. uid=huihui:搜索条件
当然这样官方的写入数据是没有问题的但是也太麻烦了,每次都要写一个ldif文件,这个时候我们就需要一个简单的添加人员信息的软件,我比较推荐的是phpldapadmin和Apache Directory Studio,可以更加直观且方便的插入、修改、删除人员信息。
openldap默认是不启用日志功能,这时候需要我们自己来启动它。
我们首先查看一下日志
$ cat /etc/openldap/slapd.d/cn\=config.ldif | grep olcLogLevel 默认为none
必须先创建日志文件,并调整权限,再修改rsyslog.conf
$ mkdir -p /var/log/slapd
$ chown openldap:openldap /var/log/slapd/
$ touch /var/log/slapd/slapd.log
$ chown ldap . /var/log/slapd/slapd.log
$ echo "local4.* /var/log/slapd/slapd.log" >> /etc/rsyslog.conf
重启使其生效:
$ systemctl restart rsyslog
修改数数据库配置文件:
创建一个修改配置文件的ldif文件,replace_log.ldif
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: 256
然后执行
$ ldapmodify -LLL -Y EXTERNAL -H ldapi:/// -f replace_log.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"
用户应该被赋予什么样的权限(读,写等等)的管理被称为访问控制。被涉及的配置指令被称为访问控制列表或者ACL。
当我们安装slapd包时,各种ACL已经被自动地设置。我们将看一些重要的默认配置,这样做,我们将知道ACL是怎么工作的和我们是如何配置的。
我们查看一下默认的acl:
$ sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config '(olcDatabase=*)' olcAccess
dn: olcDatabase={-1}frontend,cn=config
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external
,cn=auth manage by * break
olcAccess: {1}to dn.exact="" by * read
olcAccess: {2}to dn.base="cn=Subschema" by * read
dn: olcDatabase={0}config,cn=config
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external
,cn=auth manage by * break
dn: olcDatabase={1}mdb,cn=config
olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to * by * read
tips:rootDN总是拥有对他的数据库的所有权限。在ACL中包含它确实提供了一个明确的配置
如果相对acl有更多的使用和了解可以访问官方讲解
有两种方法可以使用SSL / TLS加密LDAP连接。
传统上,需要加密的LDAP连接通常在单独的端口上处理636。整个连接将使用SSL/TLS包装。此过程称为LDAP over SSL,使用该ldaps://协议。此加密方法现已弃用。
STARTTLS是一种替代方法,现在是加密LDAP连接的首选方法。STARTTLS在连接过程之后/期间通过使用SSL/TLS包装来“升级”非加密连接。这允许未加密和加密的连接由同一端口处理。本指南将使用STARTTLS加密连接。
设置主机名和FQDN
我们应该设置我们的服务器,以便正确解析其主机名和完全限定的域名(FQDN)。这对于我们的证书由客户进行验证是必要的。我们假设我们的LDAP服务器将托管在FQDN为的机器上ldap.example.com。
要在服务器上的所有相关位置设置主机名,请使用hostnamectl带有该set-hostname选项的命令。将主机名设置为短主机名(不包括域名组件):
$ sudo hostnamectl set-hostname ldap
接下来,我们需要通过确保我们的/etc/hosts文件具有正确的信息来设置我们服务器的FQDN :
$ sudo vim /etc/hosts
找到映射127.0.1.1IP地址的行。将IP地址后的第一个字段更改为服务器的FQDN,将第二个字段更改为短主机名。对于我们的示例,它看起来像这样:
# /etc/hosts文件
127.0.1.1 ldap.example.com ldap
127.0.0.1 localhost
您可以通过输入以下内容来检查是否已正确配置这些值:
# 这应该返回您的短主机名
$ hostname
ldap
输入以下命令检查FQDN
# 这应该返回FQDN
$ hostname -f
ldap.example.com
安装SSL组件
这里我们将是我们自己的证书颁发机构,如何创建并签署我们自己的LDAP服务器证书,叫做CA。由于slapd使用gnutls库进行编译,我们将使用certtool工具来完成这些任务。
$ sudo apt-get install gnutls-bin ssl-cert
创建证书模板
要加密我们的连接,我们需要配置证书颁发机构并使用它来签署我们基础架构中LDAP服务器的密钥。因此,对于我们的单服务器设置,我们将需要两组密钥/证书对:一组用于证书颁发机构本身,另一组用于与LDAP服务相关联。
要创建表示这些实体所需的证书,我们将创建一些模板文件。这些将包含certtool实用程序为了使用适当的属性创建证书所需的信息。
首先创建一个目录来存储模板文件:
$ sudo mkdir /etc/ssl/templates
创建CA模板'
$ sudo vim /etc/ssl/templates/ca_server.conf
# ca_server.conf
cn = LDAP Server CA
ca
cert_signing_key
创建LDAP服务模板
$ sudo vim /etc/ssl/templates/ldap_server.conf
# ldap_server.conf
organization = "Example Inc"
cn = ldap.example.com
tls_www_server
encryption_key
signing_key
expiration_days = 3652
在这里,我们将提供一些不同的信息。我们会为我们的组织的名称和设置tls_www_server,encryption_key和signing_key选项,使我们的证书有它需要的基本功能。
在cn此模板必须 LDAP服务器的FQDN相匹配。如果此值不匹配,客户端将拒绝服务器的证书。我们还将设置证书的到期日期。我们将创建一个10年的证书,以避免频繁续订。
创建CA密钥和证书
使用该certtool实用程序生成私钥。该/etc/ssl/private目录受非root用户保护,是放置我们将生成的私钥的适当位置。我们需要的ca_server.key,通过输入以下内容生成私钥并将其写入此目录中调用的文件:
$ sudo certtool -p --outfile /etc/ssl/private/ca_server.key
现在,我们可以使用刚刚生成的私钥和我们在上一节中创建的模板文件来创建证书颁发机构证书。我们将其写入/etc/ssl/certs名为的目录中的文件ca_server.pem:
$ sudo certtool -s --load-privkey /etc/ssl/private/ca_server.key
--template /etc/ssl/templates/ca_server.conf
--outfile /etc/ssl/certs/ca_certs.pem
创建LDAP服务密钥和证书
接下来,我们需要为LDAP服务器生成私钥。/etc/ssl/private为了安全起见,我们将再次将生成的密钥放在目录中,并且ldap_server.key为了清楚起见,将调用该文件。
我们可以通过输入以下内容生成相应的键:
$ sudo certtool -p --sec-param high --outfile /etc/ssl/private/ldap_server.key
一旦我们拥有LDAP服务器的私钥,我们就拥有了为服务器生成证书所需的一切。我们需要提供迄今为止我们创建的几乎所有组件(CA证书和密钥,LDAP服务器密钥和LDAP服务器模板)。
我们将证书放在/etc/ssl/certs目录中并命名ldap_server.pem。我们需要的命令是:
$ sudo certtool -c --load-privkey /etc/ssl/private/ldap_server.key
--load-ca-certificate /etc/ssl/certs/ca_certs.pem
--load-ca-privkey /etc/ssl/private/ca_server.key
--template /etc/ssl/templates/ldap_server.conf
--outfile /etc/ssl/certs/ldap_server.pem
授予OpenLDAP对LDAP服务器密钥的访问权限
我们现在拥有所需的所有证书和密钥。但是,目前,我们的OpenLDAP流程无法访问自己的密钥。
ssl-cert已调用的组已作为/etc/ssl/private目录的组所有者存在。我们可以将我们的OpenLDAP流程在(openldap)下运行的用户添加到该组:
$ sudo usermod -aG ssl-cert openldap
现在,我们的OpenLDAP用户可以访问该目录。我们仍然需要为该组提供该ldap_server.key文件的所有权,以便我们允许读取访问权限。ssl-cert通过键入以下内容为该组提供组所有权:
$ sudo chown :ssl-cert /etc/ssl/private/ldap_server.key
现在,给ssl-cert组读取文件的读取权限:
$ sudo chmod 640 /etc/ssl/private/ldap_server.key
我们的OpenSSL流程现在可以正确访问密钥文件。
配置OpenLDAP以使用证书和密钥
配置OpenLDAP以使用证书和密钥
打开一个名为的文件addcerts.ldif。我们将配置更改放在此文件中:
# addcerts.ldif
dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/ca_certs.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/ldap_server.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/ldap_server.key
-
add: olcTLSVerifyClient
olcTLSVerifyClient: never
执行:
$ sudo ldapmodify -H ldapi:// -Y EXTERNAL -f addcerts.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"
重新加载OpenLDAP以应用更改:
$ sudo service slapd force-reload
我们的客户现在可以ldap://使用STARTTLS通过传统端口加密与服务器的连接。
设置客户端计算机
将CA证书从/etc/ssl/certs目录复制到目录中的文件/etc/ldap。我们将调用此文件ca_certs.pem
$ sudo cp /etc/ssl/certs/ca_server.pem /etc/ldap/ca_certs.pem
调整TLS_CACERT选项的值以指向我们刚刚创建的文件:
$ sudo vim /etc/ldap/ldap.conf
# /etc/ldap/ldap.conf
TLS_CACERT /etc/ldap/ca_certs.pem
现在应该能够通过-Z在使用OpenLDAP实用程序时传递选项来升级连接以使用STARTTLS 。您可以通过传递两次强制STARTTLS。输入以下命令测试:
$ ldapwhoami -H ldap:// -x -ZZ
anonymous
如果没有返回anonymous,则证书或其他配置出现问题
配置远程客户端
如果从远程服务器连接到OpenLDAP服务器,则需要完成类似的过程。首先,您必须将CA证书复制到客户端计算机。
只需调整/etc/ldap/ldap.conf
$ sudo vim /etc/ldap/ldap.conf
# /etc/ldap/ldap.conf
TLS_CACERT /etc/ldap/ca_certs.pem
输入以下命令测试STARTTLS:
$ ldapwhoami -H ldap://ldap.example.com -x -ZZ
anonymous
如果没有返回anonymous,则证书或其他配置出现问题
强制连接使用TLS(可选)
我们已经成功配置了OpenLDAP服务器,以便通过STARTTLS流程将普通LDAP连接无缝升级到TLS。但是,这仍然允许未加密的会话,这可能不是你想要的。
如果您希望为每个连接强制STARTTLS升级,则可以调整服务器的设置。我们只会将此要求应用于常规DIT,而不是cn=config条目下可访问的配置DIT 。
在OpenLDAP服务器上,输入:
$ sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=config" -LLL -Q "(olcSuffix=*)" dn olcSuffix
# 返回信息如下
dn: olcDatabase={1}hdb,cn=config
olcSuffix: dc=example,dc=com
我们有一个以dc=example,dc=com为base条目的DIT,它是为example.com域创建的条目,这个DIT的配置由olcDatabase={1}hdb,cn=config条目处理。
我们将使用LDIF文件进行更改,创建forcetls.ldif,
我们将设置changetype为“修改”并添加olcSecurity属性。将属性的值设置为“tls = 1”以强制此DIT的TLS:
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcSecurity
olcSecurity: tls=1
执行:
sudo ldapmodify -H ldapi:// -Y EXTERNAL -f forcetls.ldif
重新加载OpenLDAP服务。
如果您搜索dc=example,dc=com,如果您不使用该-Z选项启动STARTTLS,您将被拒绝:
$ ldapsearch -H ldap:// -x -b "dc=example,dc=com" -LLL dn
# TLS失败
Confidentiality required (13)
Additional information: TLS confidentiality required
我们可以说STARTTLS连接仍能正常运行:
$ ldapsearch -H ldap:// -x -b "dc=example,dc=com" -LLL -Z dn
# 完美无瑕
dn: dc=example,dc=com
dn: cn=admin,dc=example,dc=com
到这里TLS就结束啦!如果你想了解更多可以去官网。
在我们应用的场景中,可能会有很多项目,如gitlab、openvpn、wiki、openssh或者是自己的项目,我们不会让所有人每个项目都可以去访问,我们又不可能每个项目为其建立一个账号,这样不雅的方式ldap不接受,memberOf 正是提供了这样的一个功能,如果某个组中通过 member 属性新增了一个用户,OpenLDAP 便会自动在该用户上创建一个 memberOf 属性,其值为该组的 dn/uid等。
遗憾的是,OpenLDAP 默认并不启用这个特性,因此我们需要通过相关的配置开启它。
首先我们创建一个wake_member.ldif文件
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
objectClass: top
olcModulePath: /usr/lib/ldap
olcModuleLoad: memberof.la
dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config
objectClass: olcConfig
objectClass: olcMemberOf
objectClass: olcOverlayConfig
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
objectClass: top
olcModulePath: /usr/lib/ldap
olcModuleLoad: refint.la
dn: olcOverlay={1}refint,olcDatabase={1}mdb,cn=config
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcRefintConfig
objectClass: top
olcOverlay: {1}refint
olcRefintAttribute: memberof member manager owner
执行:
$ ldapadd -Y EXTERNAL -H ldapi:/// -f wake_member.ldif
# 成功
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=module,cn=config"
adding new entry "olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config"
adding new entry "cn=module,cn=config"
adding new entry "olcOverlay={1}refint,olcDatabase={1}mdb,cn=config"
执行成功后,你可以尝试建立一个ObjectClass为groupOfNames的项目组,再建立一个人员信息,将人员放在这个组中。
执行下面命令,你可以发现人员信息中加入了memberOf这条属性,则说明memberOf已经开启了
$ ldapsearch -x -LLL -H ldap:/// -b uid=huihui,ou=people,dc=example,dc=com dn memberof
dn: uid=huihui,ou=people,dc=shannonai,dc=com
memberOf: cn=development,ou=grep,dc=shannonai,dc=com
对openldap容器化,最大的问题就是写入配置,和初始化的问题。这里可以使用debconf,Linux下实现软件的静默安装 。
输入debconf-show slapd查看ldap的预配置如下:
slapd/internal/generated_adminpw: (password omitted) root密码
slapd/internal/adminpw: (password omitted) 确认root密码
* slapd/password2: (password omitted) admin密码
* slapd/password1: (password omitted) 确认admin密码
slapd/upgrade_slapcat_failure:
slapd/unsafe_selfwrite_acl:
* slapd/domain: example.com DNS域名
* slapd/allow_ldap_v2: false 是否同意ldap_v2协议
slapd/password_mismatch:
* shared/organization: example.Inc 组织名称
* slapd/no_configuration: false 省略ldap配置服务
* slapd/backend: MDB 选择的数据库
slapd/dump_database_destdir: /var/backups/slapd-VERSION 回收的数据存放路径
slapd/invalid_config: true
* slapd/move_old_database: true 丢弃历史数据
* slapd/purge_database: false
slapd/dump_database: when needed
静默安装脚本如下:
# dpkg-slapd.sh
#!/bin/bash
cat <<-EOF | debconf-set-selections
slapd slapd/no_configuration boolean false
slapd slapd/password1 password 123456
slapd slapd/password2 password 123456
slapd shared/organization string example.Inc
slapd slapd/domain string example.com
slapd slapd/backend select MDB
slapd slapd/allow_ldap_v2 boolean false
slapd slapd/purge_database boolean false
slapd slapd/move_old_database boolean true
EOF
dpkg-reconfigure -f noninteractive slapd >/dev/null 2>&1
还有咱们之前配置ldap的时候都是在启动后动态加载的配置,但是如果在docker想在不运行前配置ldap是如何的呢?
首先你可以先把所有的ldap配置导出:
$ sudo slapcat -n0 -F /etc/ldap/slapd.d -l ./config.ldif
dn: cn=config
objectClass: olcGlobal
cn: config
...
...
createTimestamp: 20190110124335Z
entryCSN: 20190110124335.025202Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20190110124335Z
在config.ldif中可能会存在上面这些一大串的数据。如果想把olcLogLevel 等级改变,直接使用sed将这个值改变即可,然后运行:
# sed 更改olcLogLevel
$ sed xxxxxx
# 删除原来的配置
$ sudo rm -rf /etc/ldap/slapd.d/*
# 将新的配置导入
$ sudo slapadd -n0 -F /etc/ldap/slapd.d -l ./config.ldif
或者你想添加一些,比如咱们上面写的memberOf的配置:
$ sudo vim wake_member.ldif
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
objectClass: top
olcModulePath: /usr/lib/ldap
olcModuleLoad: memberof.la
dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config
objectClass: olcConfig
objectClass: olcMemberOf
objectClass: olcOverlayConfig
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
objectClass: top
olcModulePath: /usr/lib/ldap
olcModuleLoad: refint.la
dn: olcOverlay={1}refint,olcDatabase={1}mdb,cn=config
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcRefintConfig
objectClass: top
olcOverlay: {1}refint
olcRefintAttribute: memberof member manager owner
执行如下命令:
# 不需要更改原来的内容,也就是不需要slapcat这些操作,只需要写好你想添加的模块执行下面的步骤
$ slapadd -n0 -F /etc/ldap/slapd.d -l ./wake_member.ldif
这样就可以在服务器不启动时,预先的设置好自己想要的配置。
参考资料
https://wiki.shileizcc.com/confluence/display/openldap/Docker+OpenLDAP
https://help.ubuntu.com/lts/serverguide/openldap-server.html.zh-CN
https://blog.csdn.net/m1213642578/article/details/52578360
openldap还有很多内容在这里并没有涉及到,比如备份、复制、主从、密码强化等,所以如果想详细的研究还是需要靠大家自己去发掘了,当时这个写这个openldap真的特别苦恼,因为网上很少有一份很全面的资料,不过终于跳出这个坑了,希望我的这份资料对大家有一定的帮助!