如何使用 STARTTLS 加密 OpenLDAP 连接
介绍
OpenLDAP 提供灵活且支持良好的 LDAP 目录服务。但是,开箱即用,服务器本身通过未加密的 Web 连接进行通信。在本指南中,我们将演示如何使用 STARTTLS 加密与 OpenLDAP 的连接,以将传统连接升级到 TLS。我们将使用 Ubuntu 14.04 作为我们的 LDAP 服务器。
先决条件
在开始本指南之前,您应该sudo
在服务器上设置非 root 用户。要设置此类用户,请遵循我们的Ubuntu 14.04 初始设置指南。
本指南将介绍如何在 Ubuntu 14.04 服务器上安装 OpenLDAP。如果您的服务器上已安装 OpenLDAP,则可以跳过相关的安装和配置步骤。
LDAP Over SSL 与 LDAP with STARTTLS
有两种方法可以使用 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 nano /etc/hosts
找到映射 IP 地址的行127.0.1.1
。将 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 服务器配置?不(我们需要初始数据库和配置)
- 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
证书颁发机构设置为我们想要的任何描述性名称:
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 年证书,以避免管理频繁的续订:
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
要进行配置更改,我们需要定位cn=config
配置 DIT 的条目。我们需要指定我们想要修改条目的属性。之后,我们需要添加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 证书和调整客户端配置文件来设置客户端实用程序。
首先,将 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
以指向我们刚刚创建的文件:
. . .
TLS_CACERT /etc/ldap/ca_certs.pem
. . .
保存并关闭文件。
You should now be able to upgrade your connections to use STARTTLS by passing the -Z
option when using the OpenLDAP utilities. You can force STARTTLS upgrade by passing it twice. Test this by typing:
ldapwhoami -H ldap:// -x -ZZ
This forces a STARTTLS upgrade. If this is successful, you should see:
anonymous
If you mis-configured something, you will likely see an error like this:
ldap_start_tls: Connect error (-11)
additional info: (unknown error code)
Configuring Remote Clients
If you are connecting to your OpenLDAP server from remote servers, you will need to complete a similar process. First, you must copy the CA certificate to the client machine. You can do this easily with the scp
utility.
Forwarding SSH Keys to the Client
If you connect to your OpenLDAP server using SSH keys and your client machine is also remote, you will need to add them to an agent and forward them when connecting to your client machine.
To do this, on your local machine, start the SSH agent by typing:
eval $(ssh-agent)
Add your SSH key to the agent by typing:
ssh-add
Now, you can forward your SSH keys when you connect to your LDAP client machine by adding the -A
flag:
ssh -A user@ldap_client
Copying the CA Certificate
Once you are connected to the OpenLDAP client, you can copy the CA certificate by typing:
scp user@ldap.example.com:/etc/ssl/certs/ca_server.pem ~/
Now, append the copied certificate to the list of CA certificates that the client knows about. This will append the certificate to the file if it already exists and will create the file if it doesn’t:
cat ~/ca_server.pem | sudo tee -a /etc/ldap/ca_certs.pem
Adjust the Client Configuration
Next, we can adjust the global configuration file for the LDAP utilities to point to our ca_certs.pem
file. Open the file with sudo
privileges:
sudo nano /etc/ldap/ldap.conf
Find the TLS_CACERT
option and set it to the ca_certs.pem
file:
. . .
TLS_CACERT /etc/ldap/ca_certs.pem
. . .
Save and close the file when you are finished.
Test the STARTTLS upgrade by typing this:
ldapwhoami -H ldap://ldap.example.com -x -ZZ
If the STARTTLS upgrade is successful, you should see:
anonymous
Force Connections to Use TLS (Optional)
We’ve successfully configured our OpenLDAP server so that it can seamlessly upgrade normal LDAP connections to TLS through the STARTTLS process. However, this still allows unencrypted sessions, which may not be what you want.
If you wish to force STARTTLS upgrades for every connection, you can adjust your server’s settings. We will only be applying this requirement to the regular DIT, not the configuration DIT accessible beneath the cn=config
entry.
First, you need to find the appropriate entry to modify. We will print a list of all of the DITs (directory information trees: the hierarchies of entries that an LDAP server handles) that the OpenLDAP server has information about as well as the entry that configures each DIT.
On your OpenLDAP server, type:
sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=config" -LLL -Q "(olcSuffix=*)" dn olcSuffix
The response should look something like this:
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:
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 服务器的连接,可以让您验证所连接的服务器的身份。它还可以保护您的流量免受中间方的影响。当通过开放网络连接时,加密您的流量至关重要。