简介
OpenLDAP提供了一个灵活且得到良好支持的LDAP目录服务。然而,默认情况下,服务器本身是通过未加密的网络连接进行通信的。在本指南中,我们将演示如何使用STARTTLS加密连接到OpenLDAP,以将传统连接升级为TLS。我们将使用Ubuntu 14.04作为我们的LDAP服务器。
先决条件
在开始本指南之前,您应该在服务器上设置一个具有sudo
权限的非root用户。要设置此类型的用户,请按照我们的Ubuntu 14.04初始设置指南进行操作。
在本指南中,我们将介绍如何在Ubuntu 14.04服务器上安装OpenLDAP。如果您的服务器上已经安装了OpenLDAP,可以跳过相关的安装和配置步骤。
SSL上的LDAP vs STARTTLS上的LDAP
有两种使用SSL/TLS加密LDAP连接的方式。
传统上,需要加密的LDAP连接是在单独的端口上处理的,通常是636
。整个连接将被SSL/TLS包装。这个过程称为LDAP over SSL,使用ldaps://
协议。这种加密方法现在已经被弃用。
STARTTLS是一种替代方法,现在是首选的加密LDAP连接的方法。STARTTLS通过在连接过程中/之后使用SSL/TLS“升级”非加密连接。这允许未加密和加密连接通过同一端口处理。本指南将利用STARTTLS来加密连接。
设置主机名和FQDN
在开始之前,我们应该设置服务器,以便它正确解析其主机名和完全限定域名(FQDN)。这将是为了使我们的证书能够被客户端验证。我们假设我们的LDAP服务器将托管在一个名为ldap.example.com
的机器上。
要在服务器的所有相关位置设置主机名,请使用hostnamectl
命令和set-hostname
选项。将主机名设置为短主机名(不包括域名组件):
sudo hostnamectl set-hostname ldap
接下来,我们需要通过确保我们的/etc/hosts
文件具有正确的信息来设置服务器的FQDN:
sudo nano /etc/hosts
找到映射127.0.1.1
IP地址的行。将IP地址后的第一个字段更改为服务器的FQDN,第二个字段更改为短主机名。对于我们的示例,它看起来可能是这样的:
. . . 127.0.1.1 ldap.example.com ldap 127.0.0.1 localhost . . .
完成后保存并关闭文件。
您可以通过输入以下命令来检查是否已正确配置这些值:
hostname
这应该返回您的短主机名:
ldap
通过输入以下命令来检查FQDN:
hostname -f
这应该返回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被清除时,您想要删除数据库吗?(您的选择。选择“是”以允许完全清除,选择“否”以在软件被移除时保存数据)
- 移动旧数据库? Yes
- 允许LDAPv2协议? No
安装 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
设置为我们想要为证书颁发机构使用的描述性名称:
cn = LDAP 服务器 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 年的证书,以避免频繁更新的管理:
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
给 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 配置,以使用我们制作的文件。我们将通过创建一个 LDIF 文件来进行配置更改,并将其加载到我们的 LDAP 实例中。
移动到你的主目录并打开一个名为 addcerts.ldif
的文件。我们将把我们的配置更改放入这个文件中:
cd ~ nano addcerts.ldif
为了进行配置更改,我们需要针对配置 DIT 的 cn=config
条目。我们需要指定我们要修改条目的属性。之后,我们需要添加 olcTLSCACertificateFile
、olcCertificateFile
和 olcCertificateKeyFile
属性,并将它们设置为正确的文件位置。
最终结果将如下所示:
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
现在,我们的客户端可以通过传统的 ldap://
端口加密连接到服务器,使用 STARTTLS。
设置客户端机器
为了连接到 LDAP 服务器并启动 STARTTLS 升级,客户端必须访问证书颁发机构证书并请求升级。
在 OpenLDAP 服务器上
如果你是从服务器本身与 OpenLDAP 服务器进行交互,你可以通过复制 CA 证书并调整客户端配置文件来设置客户端实用程序。
首先,从 /etc/ssl/certs
目录将 CA 证书复制到 /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
选项的值,指向我们刚刚创建的文件:
. . . TLS_CACERT /etc/ldap/ca_certs.pem . . .
保存并关闭文件。
现在,你应该能够通过在使用 OpenLDAP 实用程序时传递 -Z
选项来升级你的连接以使用 STARTTLS。你可以通过传递两次来强制进行 STARTTLS 升级。通过输入以下命令来测试:
ldapwhoami -H ldap:// -x -ZZ
这将强制进行 STARTTLS 升级。如果成功,你应该会看到:
anonymous
如果你配置错误,你可能会看到类似以下错误:
ldap_start_tls: Connect error (-11) additional info: (unknown error code)
配置远程客户端
如果你需要从远程服务器连接到你的 OpenLDAP 服务器,你需要完成类似的过程。首先,你需要将 CA 证书复制到客户端机器上。你可以使用 scp
工具轻松完成这一步。
将 SSH 密钥转发到客户端
如果你使用 SSH 密钥连接到你的 OpenLDAP 服务器,并且你的客户端机器也是远程的,你需要将它们添加到代理并在连接到客户端机器时进行转发。
在你的本地机器上,通过输入以下命令启动 SSH 代理:
eval $(ssh-agent)
通过输入以下命令将你的 SSH 密钥添加到代理:
ssh-add
现在,当你连接到 LDAP 客户端机器时,你可以通过添加 -A
标志来转发你的 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
文件:
. . . TLS_CACERT /etc/ldap/ca_certs.pem . . .
完成后保存并关闭文件。
通过输入以下命令测试 STARTTLS 升级:
ldapwhoami -H ldap://ldap.example.com -x -ZZ
如果 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
响应应该类似于:
dn: olcDatabase={1}hdb,cn=config olcSuffix: dc=example,dc=com
如果你的服务器配置为处理多个 DIT,则可能会有多个 DIT 和数据库对。在这里,我们有一个基础条目为 dc=example,dc=com
的单个 DIT,这将是为 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
设置为 “modify” 并添加 olcSecurity
属性。将属性的值设置为 “tls=1” 以强制对此 DIT 使用 TLS:
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
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
结论
现在您应该已经配置了启用了 STARTTLS 加密的 OpenLDAP 服务器。使用 TLS 加密连接到 OpenLDAP 服务器可以让您验证您正在连接的服务器的身份。它还可以保护您的流量免受中间人的干扰。在开放网络上连接时,加密流量是至关重要的。