[关闭]
@daduizhang 2019-01-11T14:08:54.000000Z 字数 18235 阅读 2939

Ubuntu16.04下配置OpenLdap


内容目录

介绍


OpenLdap的原理与概念

在安装和使用ldap之前我们需要简单的了解一下ldap的基本概念 :

3524478636-56fdf1ec719ed_articlex.png-16.4kB
这个就是ldap的目录结构(先不需要管这些dc、ou、cn等具体是什么)你可以很明显看到,他就好像一棵树,会有根节点枝干果实节点

1. Entry

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"。


2. Attribute

每个条目都可以有很多属性(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是一种特殊的属性。


3. ObjectClass

对象类是属性的集合,LDAP预想了很多人员组织机构中常见的对象,并将其封装成对象类。比如人员(person)含有姓(sn)、名(cn)、电话(telephoneNumber)、密码(userPassword)等属性,单位职工(organizationalPerson)是人员(person)的继承类,除了上述属性之外还含有职务(title)、邮政编码(postalCode)、通信地址(postalAddress)等属性。

通过对象类可以方便的定义条目类型。每个条目可以直接继承多个对象类,这样就继承了各种属性。如果2个对象类中有相同的属性,则条目继承后只会保留1个属性。对象类同时也规定了哪些属性是基本信息,必须含有(Must 活Required,必要属性):哪些属性是扩展信息,可以含有(May或Optional,可选属性)。

对象类有三种类型:结构类型(Structural)、抽象类型(Abstract)和辅助类型(Auxiliary)。结构类型是最基本的类型,它规定了对象实体的基本属性,每个条目属于且仅属于一个结构型对象类。抽象类型可以是结构类型或其他抽象类型父类,它将对象属性中共性的部分组织在一起,称为其他类的模板,条目不能直接集成抽象型对象类。辅助类型规定了对象实体的扩展属性。每个条目至少有一个结构性对象类。

对象类本身是可以相互继承的,所以对象类的根类是top抽象型对象类。以常用的人员类型为例,他们的继承关系:
3221858525-56fdf41d3cbae_articlex.jpg-37.5kB
下面是inetOrgPerson对象类的在schema中的定义,可以清楚的看到它的父类SUB和可选属性MAY、必要属性MUST(继承自organizationalPerson),关于各属性的语法则在schema中的attributetype定义。

  1. # inetOrgPerson
  2. # The inetOrgPerson represents people who are associated with an
  3. # organization in some way. It is a structural class and is derived
  4. # from the organizationalPerson which is defined in X.521 [X521].
  5. objectclass ( 2.16.840.1.113730.3.2.2
  6. NAME 'inetOrgPerson'
  7. DESC 'RFC2798: Internet Organizational Person'
  8. SUP organizationalPerson
  9. STRUCTURAL
  10. MAST(
  11. cn $ sn
  12. )
  13. MAY (
  14. audio $ businessCategory $ carLicense $ departmentNumber $
  15. displayName $ employeeNumber $ employeeType $ givenName $
  16. homePhone $ homePostalAddress $ initials $ jpegPhoto $
  17. labeledURI $ mail $ manager $ mobile $ o $ pager $
  18. photo $ roomNumber $ secretary $ uid $ userCertificate $
  19. x500uniqueIdentifier $ preferredLanguage $
  20. userSMIMECertificate $ userPKCS12 )
  21. )

4. Schema

schema 是OpenLDAP 软件的重要组成部分,主要用于控制目录树中各种条目所拥有的对象类以及各种属性的定义,并通过自身内部规范机制限定目录树条目所遵循的逻辑结构以及定义规范,保证整个目录树没有非法条目数据,避免不合法的条目存在目录树中,从而保障整个目录树信息的完整性、唯一性。
不过目前ldap中的schema通常无需自定义,使用ldap内置的即可满足绝大部分需求。


搭建LDAP

1. 安装

LDAP的安装可以源码安装,apt-get。我们只说用apt-get安装的方式,如果有想了解源码安装方式的话,可以去官网查看一下。
LDAP官方网址:http://www.openldap.org/doc/admin24/index.html

操作系统: ubuntu-16.04

$ sudo apt-get install slapd ldap-utils


2. 配置

系统将要求您提供LDAP管理密码。请随意跳过提示,因为我们将在之后立即重新配置。

为了访问我们需要的一些其他提示,我们将在安装后重新配置包。为此,请键入:

$ sudo dpkg-reconfigure slapd

dpkg是初始化一些应用的命令,感兴趣的同学可以了解一下

使用以下信息作为起点,适当地回答提示:

这样我们就将LAPD配置完成,这个时候我们已经可以正常使用了


我们需要是这一下客户端的配置

$ vim /etc/ldap/ldap.conf

ldap.conf

这个时候我们可以尝试着输入命令查看一下ldap中的内容

$ ldapsearch -x

当你看到这些内容时那么你的配置则没有问题

  1. #
  2. # LDAPv3
  3. # base <dc=example,dc=com> (default) with scope subtree
  4. # filter: (objectclass=*)
  5. # requesting: ALL
  6. #
  7. # example.com
  8. dn: dc=example,dc=com
  9. objectClass: top
  10. objectClass: dcObject
  11. objectClass: organization
  12. o: example
  13. dc: example
  14. # admin, example.com
  15. dn: cn=admin,dc=example,dc=com
  16. objectClass: simpleSecurityObject
  17. objectClass: organizationalRole
  18. cn: admin
  19. description: LDAP administrator
  20. # search result
  21. search: 2
  22. result: 0 Success

额外

  1. 在新版的ldap中已经不推荐slapd.conf的这种配置,在网上看到很多这种配置方式,这已经很古老了,目前所使用的是slapd.d的这种配置方式,通过建立一个独立DIT(目录信息树)的来达到这个目的,所有的配置需要以一种ldif格式的文件进行配置,这就使得我们可以动态地配置slapd而不需要重启服务。
  2. slapd.d的所有配置千万不要去手动修改,可能会发生一些不可预知的错误

给大家看一下slapd.d的配置目录结构:

slapd.d目录结构
也可以输入:

sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn

  1. cn=config: 全局设置
  2. cn=module{0},cn=config: 动态加载的模块
  3. cn=schema,cn=config: 包含硬编码的系统级模式
  4. cn={0}core,cn=schema,cn=config: 硬编码的核心模式
  5. cn={1}cosine,cn=schema,cn=config: 余弦架构
  6. cn={2}nis,cn=schema,cn=config: NIS方案
  7. cn={3}inetorgperson,cn=schema,cn=config: inetorgperson模式
  8. olcBackend={0}mdb,cn=config: 'mdb'后端存储类型
  9. olcDatabase={-1}frontend,cn=config: 前端数据库,其他数据库的默认设置
  10. olcDatabase={0}config,cn=config: slapd配置数据库(cn=config
  11. olcDatabase={1}mdb,cn=config: 你的数据库实例(dc=examledc=com

3. ldif文件

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:

  1. dn: ou=People,dc=example,dc=com
  2. objectClass: organizationalUnit
  3. ou: People
  4. dn: ou=Groups,dc=example,dc=com
  5. objectClass: organizationalUnit
  6. ou: Groups
  7. dn: cn=develop,ou=Groups,dc=example,dc=com
  8. objectClass: posixGroup
  9. cn: develop
  10. gidNumber: 5000
  11. dn: uid=huihui,ou=People,dc=example,dc=com
  12. objectClass: inetOrgPerson
  13. objectClass: posixAccount
  14. objectClass: top
  15. uid: huihui
  16. sn: hui
  17. givenName: huihui
  18. cn: hui
  19. uidNumber: 1000
  20. gidNumber: 500
  21. userPassword: 123456
  22. loginShell: /bin/sh
  23. homeDirectory: /home/users/huihui

tips:在你的目录中的uidNumber和gidNumber的值不与本地值冲突是很重要的。使用比较高的数值范围,比如从500开始。通过在ldap中设置较高的uid和gid值,允许你更容易地控制本地用户和ldap用户。

添加内容:

  1. $ ldapadd -x -D cn=admin,dc=example,dc=com -w 123456 -f add_content.ldif
  2. Enter LDAP Password: ********
  3. adding new entry "ou=People,dc=example,dc=com"
  4. adding new entry "ou=Groups,dc=example,dc=com"
  5. adding new entry "cn=develop,ou=Groups,dc=example,dc=com"
  6. adding new entry "uid=huihui,ou=People,dc=example,dc=com"

我们检查一下看看存储的数据是否正确:

  1. $ ldapsearch -x -LLL -b dc=shannonai,dc=com 'uid=huihui'
  2. dn: uid=huihui,ou=People,dc=shannonai,dc=com
  3. uid: huihui
  4. sn: hui
  5. givenName: huihui
  6. cn: huihui
  7. uidNumber: 1000
  8. gidNumber: 500
  9. loginShell: /bin/bash
  10. homeDirectory: /home/huihui
  11. objectClass: inetOrgPerson
  12. objectClass: posixAccount

参数:
1. -x : 简单认证
2. -LLL:禁用无关信息
3. -b 搜索的路径
4. uid=huihui:搜索条件

当然这样官方的写入数据是没有问题的但是也太麻烦了,每次都要写一个ldif文件,这个时候我们就需要一个简单的添加人员信息的软件,我比较推荐的是phpldapadminApache Directory Studio,可以更加直观且方便的插入、修改、删除人员信息。

微信截图_20190110164354.png-67.5kB

4. 日志

openldap默认是不启用日志功能,这时候需要我们自己来启动它。

我们首先查看一下日志

$ cat /etc/openldap/slapd.d/cn\=config.ldif | grep olcLogLevel 默认为none

必须先创建日志文件,并调整权限,再修改rsyslog.conf

  1. $ mkdir -p /var/log/slapd
  2. $ chown openldap:openldap /var/log/slapd/
  3. $ touch /var/log/slapd/slapd.log
  4. $ chown ldap . /var/log/slapd/slapd.log
  5. $ echo "local4.* /var/log/slapd/slapd.log" >> /etc/rsyslog.conf

重启使其生效:

$ systemctl restart rsyslog

修改数数据库配置文件:
创建一个修改配置文件的ldif文件,replace_log.ldif

  1. dn: cn=config
  2. changetype: modify
  3. replace: olcLogLevel
  4. olcLogLevel: 256

然后执行

  1. $ ldapmodify -LLL -Y EXTERNAL -H ldapi:/// -f replace_log.ldif
  2. SASL/EXTERNAL authentication started
  3. SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
  4. SASL SSF: 0
  5. modifying entry "cn=config"

5. 访问控制(ACL)

用户应该被赋予什么样的权限(读,写等等)的管理被称为访问控制。被涉及的配置指令被称为访问控制列表或者ACL。

当我们安装slapd包时,各种ACL已经被自动地设置。我们将看一些重要的默认配置,这样做,我们将知道ACL是怎么工作的和我们是如何配置的。

我们查看一下默认的acl:

  1. $ sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config '(olcDatabase=*)' olcAccess
  2. dn: olcDatabase={-1}frontend,cn=config
  3. olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external
  4. ,cn=auth manage by * break
  5. olcAccess: {1}to dn.exact="" by * read
  6. olcAccess: {2}to dn.base="cn=Subschema" by * read
  7. dn: olcDatabase={0}config,cn=config
  8. olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external
  9. ,cn=auth manage by * break
  10. dn: olcDatabase={1}mdb,cn=config
  11. olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
  12. olcAccess: {1}to attrs=shadowLastChange by self write by * read
  13. olcAccess: {2}to * by * read

tips:rootDN总是拥有对他的数据库的所有权限。在ACL中包含它确实提供了一个明确的配置

如果相对acl有更多的使用和了解可以访问官方讲解


6. TLS

有两种方法可以使用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,将第二个字段更改为短主机名。对于我们的示例,它看起来像这样:

  1. # /etc/hosts文件
  2. 127.0.1.1 ldap.example.com ldap
  3. 127.0.0.1 localhost

您可以通过输入以下内容来检查是否已正确配置这些值:

  1. # 这应该返回您的短主机名
  2. $ hostname
  3. ldap

输入以下命令检查FQDN

  1. # 这应该返回FQDN
  2. $ hostname -f
  3. 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模板'

  1. $ sudo vim /etc/ssl/templates/ca_server.conf
  2. # ca_server.conf
  3. cn = LDAP Server CA
  4. ca
  5. cert_signing_key

创建LDAP服务模板

  1. $ sudo vim /etc/ssl/templates/ldap_server.conf
  2. # ldap_server.conf
  3. organization = "Example Inc"
  4. cn = ldap.example.com
  5. tls_www_server
  6. encryption_key
  7. signing_key
  8. expiration_days = 3652

在这里,我们将提供一些不同的信息。我们会为我们的组织的名称和设置tls_www_server,encryption_key和signing_key选项,使我们的证书有它需要的基本功能。

在cn此模板必须 LDAP服务器的FQDN相匹配。如果此值不匹配,客户端将拒绝服务器的证书。我们还将设置证书的到期日期。我们将创建一个10年的证书,以避免频繁续订。

创建CA密钥和证书
使用该certtool实用程序生成私钥。该/etc/ssl/private目录受非root用户保护,是放置我们将生成的私钥的适当位置。我们需要的ca_server.key,通过输入以下内容生成私钥并将其写入此目录中调用的文件:

  1. $ sudo certtool -p --outfile /etc/ssl/private/ca_server.key

现在,我们可以使用刚刚生成的私钥和我们在上一节中创建的模板文件来创建证书颁发机构证书。我们将其写入/etc/ssl/certs名为的目录中的文件ca_server.pem:

  1. $ sudo certtool -s --load-privkey /etc/ssl/private/ca_server.key
  2. --template /etc/ssl/templates/ca_server.conf
  3. --outfile /etc/ssl/certs/ca_certs.pem

创建LDAP服务密钥和证书
接下来,我们需要为LDAP服务器生成私钥。/etc/ssl/private为了安全起见,我们将再次将生成的密钥放在目录中,并且ldap_server.key为了清楚起见,将调用该文件。

我们可以通过输入以下内容生成相应的键:

  1. $ sudo certtool -p --sec-param high --outfile /etc/ssl/private/ldap_server.key

一旦我们拥有LDAP服务器的私钥,我们就拥有了为服务器生成证书所需的一切。我们需要提供迄今为止我们创建的几乎所有组件(CA证书和密钥,LDAP服务器密钥和LDAP服务器模板)。

我们将证书放在/etc/ssl/certs目录中并命名ldap_server.pem。我们需要的命令是:

  1. $ sudo certtool -c --load-privkey /etc/ssl/private/ldap_server.key
  2. --load-ca-certificate /etc/ssl/certs/ca_certs.pem
  3. --load-ca-privkey /etc/ssl/private/ca_server.key
  4. --template /etc/ssl/templates/ldap_server.conf
  5. --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。我们将配置更改放在此文件中:

  1. # addcerts.ldif
  2. dn: cn=config
  3. changetype: modify
  4. add: olcTLSCACertificateFile
  5. olcTLSCACertificateFile: /etc/ssl/certs/ca_certs.pem
  6. -
  7. add: olcTLSCertificateFile
  8. olcTLSCertificateFile: /etc/ssl/certs/ldap_server.pem
  9. -
  10. add: olcTLSCertificateKeyFile
  11. olcTLSCertificateKeyFile: /etc/ssl/private/ldap_server.key
  12. -
  13. add: olcTLSVerifyClient
  14. olcTLSVerifyClient: never

执行:

  1. $ sudo ldapmodify -H ldapi:// -Y EXTERNAL -f addcerts.ldif
  2. SASL/EXTERNAL authentication started
  3. SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
  4. SASL SSF: 0
  5. modifying entry "cn=config"

重新加载OpenLDAP以应用更改:

$ sudo service slapd force-reload
我们的客户现在可以ldap://使用STARTTLS通过传统端口加密与服务器的连接。

设置客户端计算机

将CA证书从/etc/ssl/certs目录复制到目录中的文件/etc/ldap。我们将调用此文件ca_certs.pem

  1. $ sudo cp /etc/ssl/certs/ca_server.pem /etc/ldap/ca_certs.pem

调整TLS_CACERT选项的值以指向我们刚刚创建的文件:

  1. $ sudo vim /etc/ldap/ldap.conf
  2. # /etc/ldap/ldap.conf
  3. TLS_CACERT /etc/ldap/ca_certs.pem

现在应该能够通过-Z在使用OpenLDAP实用程序时传递选项来升级连接以使用STARTTLS 。您可以通过传递两次强制STARTTLS。输入以下命令测试:

  1. $ ldapwhoami -H ldap:// -x -ZZ
  2. anonymous

如果没有返回anonymous,则证书或其他配置出现问题

配置远程客户端
如果从远程服务器连接到OpenLDAP服务器,则需要完成类似的过程。首先,您必须将CA证书复制到客户端计算机。

只需调整/etc/ldap/ldap.conf

  1. $ sudo vim /etc/ldap/ldap.conf
  2. # /etc/ldap/ldap.conf
  3. TLS_CACERT /etc/ldap/ca_certs.pem

输入以下命令测试STARTTLS:

  1. $ ldapwhoami -H ldap://ldap.example.com -x -ZZ
  2. anonymous

如果没有返回anonymous,则证书或其他配置出现问题

强制连接使用TLS(可选)
我们已经成功配置了OpenLDAP服务器,以便通过STARTTLS流程将普通LDAP连接无缝升级到TLS。但是,这仍然允许未加密的会话,这可能不是你想要的。

如果您希望为每个连接强制STARTTLS升级,则可以调整服务器的设置。我们只会将此要求应用于常规DIT,而不是cn=config条目下可访问的配置DIT 。

在OpenLDAP服务器上,输入:

  1. $ sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=config" -LLL -Q "(olcSuffix=*)" dn olcSuffix
  2. # 返回信息如下
  3. dn: olcDatabase={1}hdb,cn=config
  4. 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:

  1. dn: olcDatabase={1}mdb,cn=config
  2. changetype: modify
  3. add: olcSecurity
  4. olcSecurity: tls=1

执行:

  1. sudo ldapmodify -H ldapi:// -Y EXTERNAL -f forcetls.ldif

重新加载OpenLDAP服务。

如果您搜索dc=example,dc=com,如果您不使用该-Z选项启动STARTTLS,您将被拒绝:

  1. $ ldapsearch -H ldap:// -x -b "dc=example,dc=com" -LLL dn
  2. # TLS失败
  3. Confidentiality required (13)
  4. Additional information: TLS confidentiality required

我们可以说STARTTLS连接仍能正常运行:

  1. $ ldapsearch -H ldap:// -x -b "dc=example,dc=com" -LLL -Z dn
  2. # 完美无瑕
  3. dn: dc=example,dc=com
  4. dn: cn=admin,dc=example,dc=com

到这里TLS就结束啦!如果你想了解更多可以去官网

7. memberOf

在我们应用的场景中,可能会有很多项目,如gitlab、openvpn、wiki、openssh或者是自己的项目,我们不会让所有人每个项目都可以去访问,我们又不可能每个项目为其建立一个账号,这样不雅的方式ldap不接受,memberOf 正是提供了这样的一个功能,如果某个组中通过 member 属性新增了一个用户,OpenLDAP 便会自动在该用户上创建一个 memberOf 属性,其值为该组的 dn/uid等。

遗憾的是,OpenLDAP 默认并不启用这个特性,因此我们需要通过相关的配置开启它。

首先我们创建一个wake_member.ldif文件

  1. dn: cn=module,cn=config
  2. cn: module
  3. objectClass: olcModuleList
  4. objectClass: top
  5. olcModulePath: /usr/lib/ldap
  6. olcModuleLoad: memberof.la
  7. dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config
  8. objectClass: olcConfig
  9. objectClass: olcMemberOf
  10. objectClass: olcOverlayConfig
  11. objectClass: top
  12. olcOverlay: memberof
  13. olcMemberOfDangling: ignore
  14. olcMemberOfRefInt: TRUE
  15. olcMemberOfGroupOC: groupOfNames
  16. olcMemberOfMemberAD: member
  17. olcMemberOfMemberOfAD: memberOf
  18. dn: cn=module,cn=config
  19. cn: module
  20. objectClass: olcModuleList
  21. objectClass: top
  22. olcModulePath: /usr/lib/ldap
  23. olcModuleLoad: refint.la
  24. dn: olcOverlay={1}refint,olcDatabase={1}mdb,cn=config
  25. objectClass: olcConfig
  26. objectClass: olcOverlayConfig
  27. objectClass: olcRefintConfig
  28. objectClass: top
  29. olcOverlay: {1}refint
  30. olcRefintAttribute: memberof member manager owner

执行:

  1. $ ldapadd -Y EXTERNAL -H ldapi:/// -f wake_member.ldif
  2. # 成功
  3. SASL/EXTERNAL authentication started
  4. SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
  5. SASL SSF: 0
  6. adding new entry "cn=module,cn=config"
  7. adding new entry "olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config"
  8. adding new entry "cn=module,cn=config"
  9. adding new entry "olcOverlay={1}refint,olcDatabase={1}mdb,cn=config"

执行成功后,你可以尝试建立一个ObjectClass为groupOfNames的项目组,再建立一个人员信息,将人员放在这个组中。

执行下面命令,你可以发现人员信息中加入了memberOf这条属性,则说明memberOf已经开启了

  1. $ ldapsearch -x -LLL -H ldap:/// -b uid=huihui,ou=people,dc=example,dc=com dn memberof
  2. dn: uid=huihui,ou=people,dc=shannonai,dc=com
  3. memberOf: cn=development,ou=grep,dc=shannonai,dc=com

8. docker容器化

对openldap容器化,最大的问题就是写入配置,和初始化的问题。这里可以使用debconf,Linux下实现软件的静默安装 。

输入debconf-show slapd查看ldap的预配置如下:

  1. slapd/internal/generated_adminpw: (password omitted) root密码
  2. slapd/internal/adminpw: (password omitted) 确认root密码
  3. * slapd/password2: (password omitted) admin密码
  4. * slapd/password1: (password omitted) 确认admin密码
  5. slapd/upgrade_slapcat_failure:
  6. slapd/unsafe_selfwrite_acl:
  7. * slapd/domain: example.com DNS域名
  8. * slapd/allow_ldap_v2: false 是否同意ldap_v2协议
  9. slapd/password_mismatch:
  10. * shared/organization: example.Inc 组织名称
  11. * slapd/no_configuration: false 省略ldap配置服务
  12. * slapd/backend: MDB 选择的数据库
  13. slapd/dump_database_destdir: /var/backups/slapd-VERSION 回收的数据存放路径
  14. slapd/invalid_config: true
  15. * slapd/move_old_database: true 丢弃历史数据
  16. * slapd/purge_database: false
  17. slapd/dump_database: when needed

静默安装脚本如下:

  1. # dpkg-slapd.sh
  2. #!/bin/bash
  3. cat <<-EOF | debconf-set-selections
  4. slapd slapd/no_configuration boolean false
  5. slapd slapd/password1 password 123456
  6. slapd slapd/password2 password 123456
  7. slapd shared/organization string example.Inc
  8. slapd slapd/domain string example.com
  9. slapd slapd/backend select MDB
  10. slapd slapd/allow_ldap_v2 boolean false
  11. slapd slapd/purge_database boolean false
  12. slapd slapd/move_old_database boolean true
  13. EOF
  14. dpkg-reconfigure -f noninteractive slapd >/dev/null 2>&1

还有咱们之前配置ldap的时候都是在启动后动态加载的配置,但是如果在docker想在不运行前配置ldap是如何的呢?

首先你可以先把所有的ldap配置导出:

  1. $ sudo slapcat -n0 -F /etc/ldap/slapd.d -l ./config.ldif
  2. dn: cn=config
  3. objectClass: olcGlobal
  4. cn: config
  5. ...
  6. ...
  7. createTimestamp: 20190110124335Z
  8. entryCSN: 20190110124335.025202Z#000000#000#000000
  9. modifiersName: cn=config
  10. modifyTimestamp: 20190110124335Z

在config.ldif中可能会存在上面这些一大串的数据。如果想把olcLogLevel 等级改变,直接使用sed将这个值改变即可,然后运行:

  1. # sed 更改olcLogLevel
  2. $ sed xxxxxx
  3. # 删除原来的配置
  4. $ sudo rm -rf /etc/ldap/slapd.d/*
  5. # 将新的配置导入
  6. $ sudo slapadd -n0 -F /etc/ldap/slapd.d -l ./config.ldif

或者你想添加一些,比如咱们上面写的memberOf的配置:

  1. $ sudo vim wake_member.ldif
  2. dn: cn=module,cn=config
  3. cn: module
  4. objectClass: olcModuleList
  5. objectClass: top
  6. olcModulePath: /usr/lib/ldap
  7. olcModuleLoad: memberof.la
  8. dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config
  9. objectClass: olcConfig
  10. objectClass: olcMemberOf
  11. objectClass: olcOverlayConfig
  12. objectClass: top
  13. olcOverlay: memberof
  14. olcMemberOfDangling: ignore
  15. olcMemberOfRefInt: TRUE
  16. olcMemberOfGroupOC: groupOfNames
  17. olcMemberOfMemberAD: member
  18. olcMemberOfMemberOfAD: memberOf
  19. dn: cn=module,cn=config
  20. cn: module
  21. objectClass: olcModuleList
  22. objectClass: top
  23. olcModulePath: /usr/lib/ldap
  24. olcModuleLoad: refint.la
  25. dn: olcOverlay={1}refint,olcDatabase={1}mdb,cn=config
  26. objectClass: olcConfig
  27. objectClass: olcOverlayConfig
  28. objectClass: olcRefintConfig
  29. objectClass: top
  30. olcOverlay: {1}refint
  31. olcRefintAttribute: memberof member manager owner

执行如下命令:

  1. # 不需要更改原来的内容,也就是不需要slapcat这些操作,只需要写好你想添加的模块执行下面的步骤
  2. $ slapadd -n0 -F /etc/ldap/slapd.d -l ./wake_member.ldif

这样就可以在服务器不启动时,预先的设置好自己想要的配置。

9. 后话

参考资料
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真的特别苦恼,因为网上很少有一份很全面的资料,不过终于跳出这个坑了,希望我的这份资料对大家有一定的帮助!

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注