介绍
OpenLDAP 提供了一种灵活且得到良好支持的 LDAP 目录服务。 但是,开箱即用的服务器本身通过未加密的 Web 连接进行通信。 在本指南中,我们将演示如何使用 STARTTLS 加密与 OpenLDAP 的连接,以将传统连接升级到 TLS。 我们将使用 Ubuntu 14.04 作为我们的 LDAP 服务器。
先决条件
在开始使用本指南之前,您应该在服务器上设置一个具有 sudo
的非 root 用户。 要设置这种类型的用户,请按照我们的 Ubuntu 14.04 初始设置指南 。
我们将在本指南中介绍如何在 Ubuntu 14.04 服务器上安装 OpenLDAP。 如果您的服务器上已经安装了 OpenLDAP,则可以跳过相关的安装和配置步骤。
基于 SSL 的 LDAP 与使用 STARTTLS 的 LDAP
有两种方法可以使用 SSL/TLS 加密 LDAP 连接。
传统上,需要加密的 LDAP 连接在单独的端口上处理,通常是 636
。 整个连接将使用 SSL/TLS 包装。 此过程称为基于 SSL 的 LDAP,使用 ldaps://
协议。 现在不推荐使用这种加密方法。
STARTTLS 是一种替代方法,现在是加密 LDAP 连接的首选方法。 STARTTLS 通过在连接过程之后/期间使用 SSL/TLS 包装非加密连接来“升级”非加密连接。 这允许同一端口处理未加密和加密的连接。 本指南将使用 STARTTLS 来加密连接。
设置主机名和 FQDN
在开始之前,我们应该设置我们的服务器,以便它正确解析其主机名和完全限定域名 (FQDN)。 这对于我们的证书被客户验证是必要的。 我们将假设我们的 LDAP 服务器将托管在 FQDN 为 ldap.example.com
的机器上。
要在服务器上所有相关位置设置主机名,请使用带有 set-hostname
选项的 hostnamectl
命令。 将主机名设置为短主机名(不包括域名部分):
sudo hostnamectl set-hostname ldap
接下来,我们需要通过确保我们的 /etc/hosts
文件具有正确的信息来设置我们服务器的 FQDN:
sudo nano /etc/hosts
找到映射 127.0.1.1
IP 地址的行。 将 IP 地址后的第一个字段更改为服务器的 FQDN,将第二个字段更改为短主机名。 对于我们的示例,它看起来像这样:
/etc/hosts
. . . 127.0.1.1 ldap.example.com ldap 127.0.0.1 localhost . . .
完成后保存并关闭文件。
您可以通过键入以下内容来检查您是否正确配置了这些值:
hostname
这应该返回您的短主机名:
短主机名
ldap
通过键入以下内容检查 FQDN:
hostname -f
这应该返回 FQDN:
FQDN 设置
ldap.example.com
安装 LDAP 服务器和 GnuTLS 软件
确保您的主机名设置正确后,我们可以安装我们需要的软件。 如果您已经安装并配置了 OpenLDAP,则可以跳过第一小节。
安装 OpenLDAP 服务器
如果您还没有安装 OpenLDAP,那么现在是时候解决这个问题了。 通过键入以下内容更新服务器的本地包索引并安装软件:
sudo apt-get update sudo apt-get install slapd ldap-utils
系统将要求您提供 LDAP 管理密码。 随意跳过提示,因为我们将立即重新配置。
为了访问我们需要的一些额外提示,我们将在安装后重新配置包。 为此,请键入:
sudo dpkg-reconfigure slapd
使用以下信息作为起点,适当地回答提示:
- 省略 OpenLDAP 服务器配置? No(我们想要一个初始数据库和配置)
- DNS域名:example.com(使用服务器的域名,减去主机名。 这将用于创建信息树的基本条目)
- 组织名称:Example Inc(这将作为您的组织名称简单地添加到基本条目中)
- 管理员密码:[随便你]
- 确认密码:【必须与以上相符】
- 要使用的数据库后端:HDB(在两个选择中,这个功能最多)
- 您希望在清除 slapd 时删除数据库吗? (你的选择。 选择“是”以允许完全干净的删除,选择“否”以保存您的数据,即使软件已被删除)
- 移动旧数据库? 是
- 允许 LDAPv2 协议? 否
安装 SSL 组件
配置好 OpenLDAP 服务器后,我们可以继续安装用于加密连接的软件包。 Ubuntu OpenLDAP 包是针对 GnuTLS SSL 库编译的,因此我们将使用 GnuTLS 生成我们的 SSL 凭证:
sudo apt-get install gnutls-bin ssl-cert
安装所有工具后,我们可以开始创建加密连接所需的证书和密钥。
创建证书模板
为了加密我们的连接,我们需要配置一个证书颁发机构并使用它来签署我们基础设施中 LDAP 服务器的密钥。 因此,对于我们的单一服务器设置,我们将需要两组密钥/证书对:一组用于证书颁发机构本身,另一组与 LDAP 服务相关联。
为了创建代表这些实体所需的证书,我们将创建一些模板文件。 这些将包含 certtool
实用程序所需的信息,以便创建具有适当属性的证书。
首先创建一个目录来存储模板文件:
sudo mkdir /etc/ssl/templates
创建 CA 模板
首先为证书颁发机构创建模板。 我们将文件称为 ca_server.conf
。 在文本编辑器中创建并打开文件:
sudo nano /etc/ssl/templates/ca_server.conf
我们只需要提供几条信息就可以成功创建证书颁发机构。 我们需要通过添加 ca
选项来指定证书将用于 CA(证书颁发机构)。 我们还需要 cert_signing_key
选项以使生成的证书能够签署其他证书。 我们可以将 cn
设置为我们想要的证书颁发机构的任何描述性名称:
caserver.conf
cn = LDAP Server CA ca cert_signing_key
保存并关闭文件。
创建 LDAP 服务模板
接下来,我们可以为我们的 LDAP 服务器证书创建一个名为 ldap_server.conf
的模板。 使用 sudo
权限在文本编辑器中创建并打开文件:
sudo nano /etc/ssl/templates/ldap_server.conf
在这里,我们将提供一些不同的信息。 我们将提供我们组织的名称并设置 tls_www_server
、encryption_key
和 signing_key
选项,以便我们的证书具有所需的基本功能。
此模板 中的 cn
必须 与 LDAP 服务器的 FQDN 匹配。 如果此值不匹配,客户端将拒绝服务器的证书。 我们还将设置证书的到期日期。 我们将创建一个 10 年的证书,以避免必须管理频繁的续订:
ldapserver.conf
organization = "Example Inc" cn = ldap.example.com tls_www_server encryption_key signing_key expiration_days = 3652
完成后保存并关闭文件。
创建 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_server.pem
我们现在拥有证书颁发机构的私钥和证书对。 我们可以使用它来签署将用于实际加密 LDAP 会话的密钥。
创建 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_server.pem --load-ca-privkey /etc/ssl/private/ca_server.key --template /etc/ssl/templates/ldap_server.conf --outfile /etc/ssl/certs/ldap_server.pem
授予对 LDAP 服务器密钥的 OpenLDAP 访问权限
我们现在拥有我们需要的所有证书和密钥。 但是,目前,我们的 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 配置以使用我们创建的文件。 为此,我们将使用我们的配置更改创建一个 LDIF 文件并将其加载到我们的 LDAP 实例中。
移动到您的主目录并打开一个名为 addcerts.ldif
的文件。 我们将把我们的配置更改放在这个文件中:
cd ~ nano addcerts.ldif
要进行配置更改,我们需要定位配置 DIT 的 cn=config
条目。 我们需要指定我们要修改条目的属性。 之后我们需要添加 olcTLSCACertificateFile
、olcCertificateFile
和 olcCertificateKeyFile
属性并将它们设置到正确的文件位置。
最终结果将如下所示:
addcerts.ldif
dn: cn=config changetype: modify add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ssl/certs/ca_server.pem - add: olcTLSCertificateFile olcTLSCertificateFile: /etc/ssl/certs/ldap_server.pem - add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ssl/private/ldap_server.key
完成后保存并关闭文件。 使用 ldapmodify
命令将更改应用到您的 OpenLDAP 系统:
sudo ldapmodify -H ldapi:// -Y EXTERNAL -f addcerts.ldif
我们可以重新加载 OpenLDAP 以应用更改:
sudo service slapd force-reload
我们的客户现在可以使用 STARTTLS 通过传统的 ldap://
端口加密他们与服务器的连接。
设置客户端机器
为了连接到 LDAP 服务器并启动 STARTTLS 升级,客户端必须有权访问证书颁发机构证书并且必须请求升级。
在 OpenLDAP 服务器上
如果您从服务器本身与 OpenLDAP 服务器交互,您可以通过复制 CA 证书和调整客户端配置文件来设置客户端实用程序。
首先,将 CA 证书从 /etc/ssl/certs
目录复制到 /etc/ldap
目录内的文件中。 我们将此文件称为 ca_certs.pem
。 此文件可用于存储此机器上的客户端可能希望访问的所有 CA 证书。 出于我们的目的,这将只包含一个证书:
sudo cp /etc/ssl/certs/ca_server.pem /etc/ldap/ca_certs.pem
现在,我们可以调整 OpenLDAP 实用程序的系统范围配置文件。 使用 sudo
权限在文本编辑器中打开配置文件:
sudo nano /etc/ldap/ldap.conf
调整TLS_CACERT
选项的值指向我们刚刚创建的文件:
/etc/ldap/ldap.conf
. . . TLS_CACERT /etc/ldap/ca_certs.pem . . .
保存并关闭文件。
您现在应该能够通过在使用 OpenLDAP 实用程序时传递 -Z
选项来升级您的连接以使用 STARTTLS。 您可以通过传递两次来强制 STARTTLS 升级。 通过键入以下内容进行测试:
ldapwhoami -H ldap:// -x -ZZ
这会强制进行 STARTTLS 升级。 如果成功,您应该看到:
STARTTLS 成功
anonymous
如果您错误配置了某些内容,您可能会看到如下错误:
STARTTLS 失败
ldap_start_tls: Connect error (-11) additional info: (unknown error code)
配置远程客户端
如果您从远程服务器连接到您的 OpenLDAP 服务器,您将需要完成类似的过程。 首先,您必须将 CA 证书复制到客户端计算机。 您可以使用 scp
实用程序轻松完成此操作。
将 SSH 密钥转发给客户端
如果您使用 SSH 密钥连接到 OpenLDAP 服务器并且您的客户端计算机也是远程的,则您需要将它们添加到代理并在连接到客户端计算机时转发它们。
为此,在您的本地计算机上,键入以下命令启动 SSH 代理:
eval $(ssh-agent)
通过键入以下内容将您的 SSH 密钥添加到代理:
ssh-add
现在,您可以通过添加 -A
标志在连接到 LDAP 客户端计算机时转发 SSH 密钥:
ssh -A user@ldap_client
复制 CA 证书
连接到 OpenLDAP 客户端后,您可以通过键入以下内容来复制 CA 证书:
scp user@ldap.example.com:/etc/ssl/certs/ca_server.pem ~/
现在,将复制的证书附加到客户端知道的 CA 证书列表中。 如果证书已经存在,这会将证书附加到文件中,如果不存在,则会创建文件:
cat ~/ca_server.pem | sudo tee -a /etc/ldap/ca_certs.pem
调整客户端配置
接下来,我们可以调整 LDAP 实用程序的全局配置文件以指向我们的 ca_certs.pem
文件。 使用 sudo
权限打开文件:
sudo nano /etc/ldap/ldap.conf
找到 TLS_CACERT
选项并将其设置为 ca_certs.pem
文件:
/etc/ldap/ldap.conf
. . . TLS_CACERT /etc/ldap/ca_certs.pem . . .
完成后保存并关闭文件。
通过键入以下内容测试 STARTTLS 升级:
ldapwhoami -H ldap://ldap.example.com -x -ZZ
如果 STARTTLS 升级成功,您应该看到:
STARTTLS 成功
anonymous
强制连接使用 TLS(可选)
我们已经成功地配置了我们的 OpenLDAP 服务器,以便它可以通过 STARTTLS 进程将正常的 LDAP 连接无缝升级到 TLS。 但是,这仍然允许未加密的会话,这可能不是您想要的。
如果您希望对每个连接强制进行 STARTTLS 升级,您可以调整服务器的设置。 我们只会将此要求应用于常规 DIT,而不是在 cn=config
条目下可访问的配置 DIT。
首先,您需要找到合适的条目进行修改。 我们将打印 OpenLDAP 服务器拥有的所有 DIT(目录信息树:LDAP 服务器处理的条目的层次结构)的列表以及配置每个 DIT 的条目。
在您的 OpenLDAP 服务器上,键入:
sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=config" -LLL -Q "(olcSuffix=*)" dn olcSuffix
响应应如下所示:
OpenLDAP 服务的 DIT
dn: olcDatabase={1}hdb,cn=config olcSuffix: dc=example,dc=com
如果您的服务器配置为处理多个 DIT,您可能有更多的 DIT 和数据库对。 在这里,我们有一个 DIT,其基本条目为 dc=example,dc=com
,它是为 example.com
域创建的条目。 此 DIT 的配置由 olcDatabase={1}hdb,cn=config
条目处理。 记下要强制加密的 DIT 的 DN。
我们将使用 LDIF 文件进行更改。 在您的主目录中创建 LDIF 文件。 我们称之为forcetls.ldif
:
nano ~/forcetls.ldif
在内部,定位您要强制启用 TLS 的 DN。 在我们的例子中,这将是 dn: olcDatabase={1}hdb,cn=config
。 我们将 changetype
设置为“修改”并添加 olcSecurity
属性。 将该属性的值设置为“tls=1”以强制此 DIT 使用 TLS:
forcetls.ldif
dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcSecurity olcSecurity: tls=1
完成后保存并关闭文件。
要应用更改,请键入:
sudo ldapmodify -H ldapi:// -Y EXTERNAL -f forcetls.ldif
通过键入以下内容重新加载 OpenLDAP 服务:
sudo service slapd force-reload
现在,如果您搜索 dc=example,dc=com
DIT,如果您不使用 -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
TLS 要求成功
dn: dc=example,dc=com dn: cn=admin,dc=example,dc=com
结论
您现在应该有一个配置了 STARTTLS 加密的 OpenLDAP 服务器。 使用 TLS 加密与 OpenLDAP 服务器的连接允许您验证所连接服务器的身份。 它还可以保护您的流量免受中间方的影响。 通过开放网络连接时,加密流量至关重要。